RFC: WIP: sc16is7xx [v0.4]
PATCH 1/1 RFC: WIP: sc16is7xx [v0.4]
From: Jon Ringle <[email protected]>
I started over and rewrote this driver patternized on sccnxp.c
However, I am still experiencing major latency problems with this driver at 19200 speeds.
The method that I'm testing is simply transferring a small file just over 4k in size.
On the target platform I do:
$ socat /dev/ttySC0,raw,echo=0,b19200 - > rx-file
On my development machine, I do:
$ socat /dev/ttyUSB1,echo=0,raw,time=1,min=255,b19200 FILE:./tx-file
When the socat running on the development machine returns to the prompt, it has transmitted all the bytes in tx-file. I then kill the socat running on the target platform. Success is defined as rx-file being identical to tx-file. However, I find that even at only 19200, this driver fails to receive all bytes sent.
I welcome any and all comments.
Thank you,
Jon
--- drivers/tty/serial/Kconfig | 7 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/sc16is7xx.c | 730 +++++++++++++++++++++++++++++++++++++++ include/uapi/linux/serial_core.h | 3 + 4 files changed, 741 insertions(+) create mode 100644 drivers/tty/serial/sc16is7xx.c
drivers/tty/serial/Kconfig +7 -0
@@ -1179,6 +1179,13 @@ config SERIAL_SCCNXP_CONSOLE help Support for console on SCCNXP serial ports. +config SERIAL_SC16IS7XX + tristate "SC16IS7xx RS485 serial support" + select SERIAL_CORE + default n + help + This selects support for SC16IS7xx for use as a RS485 serial port + config SERIAL_BFIN_SPORT tristate "Blackfin SPORT emulate UART" depends on BLACKFIN
drivers/tty/serial/Makefile +1 -0
@@ -49,6 +49,7 @@ obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o +obj-$(CONFIG_SERIAL_SC16IS7XX) += sc16is7xx.o obj-$(CONFIG_SERIAL_JSM) += jsm/ obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
drivers/tty/serial/sc16is7xx.c new file +730 -0
730 lines not on this page · raw message
include/uapi/linux/serial_core.h +3 -0
@@ -238,4 +238,7 @@/* Tilera TILE-Gx UART */ #define PORT_TILEGX 106 +/* SC16IS74xx */ +#define PORT_SC16IS7XX 107 +#endif /* _UAPILINUX_SERIAL_CORE_H */
Signature · 6 lines
1.8.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Понедельник, 10 марта 2014, 2:26 -04:00 от [email protected]:
Quoted 1 line
From: Jon Ringle <[email protected]>
...
drivers/tty/serial/Kconfig config SERIAL_SCCNXP_CONSOLE · line 1187
Quoted 6 lines
drivers/tty/serial/Kconfig +6
-0+config SERIAL_SC16IS7XX + tristate "SC16IS7xx RS485 serial support" + select SERIAL_CORE + default n + help + This selects support for SC16IS7xx for use as a RS485 serial port
Documentation says:
The SC16IS740/750/760 is a slave I²C-bus/SPI interface to a single-channel high performance UART.
...
The SC16IS740/750/760 also provides additional advanced features such as auto hardware and software flow control, automatic RS-485 support...
So why do you position this chip as RS485 only? Automatic direction for RS485 is just a feature as an addition for standart UART.
---
Quoted 17 lines · Alexander Shiyan
Понедельник, 10 марта 2014, 2:26 -04:00 от [email protected]:
Quoted 1 line
From: Jon Ringle <[email protected]>
...
drivers/tty/serial/Kconfig config SERIAL_SCCNXP_CONSOLE · line 1187
Quoted 6 lines
drivers/tty/serial/Kconfig +6
-0+config SERIAL_SC16IS7XX + tristate "SC16IS7xx RS485 serial support" + select SERIAL_CORE + default n + help + This selects support for SC16IS7xx for use as a RS485 serial portDocumentation says:
The SC16IS740/750/760 is a slave I²C-bus/SPI interface to a single-channel high performance UART.
...
The SC16IS740/750/760 also provides additional advanced features such as auto hardware and software flow control, automatic RS-485 support...
Quoted 2 lines
So why do you position this chip as RS485 only? Automatic direction for RS485 is just a feature as an addition for standart UART.
You're right. This is just how we are using the chip in our board. Would a configuration flag in platform_data make sense to use the auto rs485 direction?
Any thoughts as to the latency issue I report?
Thanks.
Regards,
Jon
Quoted 20 lines · On Mon, 10 Mar 2014 07:50:12 -0400 (EDT) Jon Ringle <[email protected]> wrote:
Quoted 17 lines · Alexander Shiyan
Понедельник, 10 марта 2014, 2:26 -04:00 от [email protected]:
Quoted 1 line
From: Jon Ringle <[email protected]>
...
drivers/tty/serial/Kconfig config SERIAL_SCCNXP_CONSOLE · line 1187
Quoted 6 lines
drivers/tty/serial/Kconfig +6
-0+config SERIAL_SC16IS7XX + tristate "SC16IS7xx RS485 serial support" + select SERIAL_CORE + default n + help + This selects support for SC16IS7xx for use as a RS485 serial portDocumentation says:
The SC16IS740/750/760 is a slave I²C-bus/SPI interface to a single-channel high performance UART.
...
The SC16IS740/750/760 also provides additional advanced features such as auto hardware and software flow control, automatic RS-485 support...
Quoted 6 lines
Quoted 2 lines
So why do you position this chip as RS485 only? Automatic direction for RS485 is just a feature as an addition for standart UART.
You're right. This is just how we are using the chip in our board. Would a configuration flag in
platform_datamake sense to use the auto rs485 direction?
We have interfaces for RS485 runtime configuration so it could be extended to set a lot of parameters that way, but I think for now it might not be a bad idea to support rs485 auto direction in/out/off in the platform data.
Alan
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Понедельник, 10 марта 2014, 7:50 -04:00 от Jon Ringle <[email protected]>:
Quoted 20 lines · Alexander Shiyan
Quoted 18 lines
Понедельник, 10 марта 2014, 2:26 -04:00 от [email protected]:
Quoted 1 line
From: Jon Ringle <[email protected]>
...
drivers/tty/serial/Kconfig config SERIAL_SCCNXP_CONSOLE · line 1187
Quoted 6 lines
drivers/tty/serial/Kconfig +6
-0+config SERIAL_SC16IS7XX + tristate "SC16IS7xx RS485 serial support" + select SERIAL_CORE + default n + help + This selects support for SC16IS7xx for use as a RS485 serial portDocumentation says:
The SC16IS740/750/760 is a slave I²C-bus/SPI interface to a single-channel high performance UART.
...
The SC16IS740/750/760 also provides additional advanced features such as auto hardware and software flow control, automatic RS-485 support...
Quoted 6 lines
Quoted 2 lines
So why do you position this chip as RS485 only? Automatic direction for RS485 is just a feature as an addition for standart UART.
You're right. This is just how we are using the chip in our board. Would a configuration flag in
platform_datamake sense to use the auto rs485 direction?
You don't need a flag, just use IOCTLs.
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/tty/serial/max310x.c?id=55367c620aed6bc27a82bb1763366931d7f2ee66
Quoted 1 line
Any thoughts as to the latency issue I report?
I do not understand why you chose the sccnxp driver as a template. Use as a template max310x driver from linux-next branch. I'm sure it will be better.
About latency.
I'm not exactly understand the problem, but I can say the following:
Since you're using the I2C bus, maximum UART daudrate can be predicted from the I2C bus bandwidth.
Count how many I2C clocks spent on reception and transmission of one byte through UART.
---
Quoted 28 lines · Alexander Shiyan
Понедельник, 10 марта 2014, 7:50 -04:00 от Jon Ringle <[email protected]>:
Quoted 20 lines · Alexander Shiyan
Quoted 18 lines
Понедельник, 10 марта 2014, 2:26 -04:00 от [email protected]:
Quoted 1 line
From: Jon Ringle <[email protected]>
...
drivers/tty/serial/Kconfig config SERIAL_SCCNXP_CONSOLE · line 1187
Quoted 6 lines
drivers/tty/serial/Kconfig +6
-0+config SERIAL_SC16IS7XX + tristate "SC16IS7xx RS485 serial support" + select SERIAL_CORE + default n + help + This selects support for SC16IS7xx for use as a RS485 serial portDocumentation says:
The SC16IS740/750/760 is a slave I²C-bus/SPI interface to a single-channel high performance UART.
...
The SC16IS740/750/760 also provides additional advanced features such as auto hardware and software flow control, automatic RS-485 support...Quoted 6 lines
Quoted 2 lines
So why do you position this chip as RS485 only? Automatic direction for RS485 is just a feature as an addition for standart UART.
You're right. This is just how we are using the chip in our board. Would a configuration flag in
platform_datamake sense to use the auto rs485 direction?
Quoted 8 lines
You don't need a flag, just use IOCTLs.
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/tty/serial/max310x.c?id=55367c620aed6bc27a82bb1763366931d7f2ee66Quoted 1 line
Any thoughts as to the latency issue I report?
I do not understand why you chose the sccnxp driver as a template. Use as a template max310x driver from linux-next branch. I'm sure it will be better.
I followed your advice on using max310x as a template. One thing that I'm struggling to get right is the regmap. The datasheet[1] specifies the register bits as follows:
Table 33. Register address byte (I2C) Bit Name Function 7 - not used 6:3 A[3:0] UART's internal register select 2:1 CH1,0 channel select: CH1 = 0, CH0 = 0 Other values are reserved and should not be used. 0 - not used
So, I need to shift the register address by 3. Here is how I have defined the regmap stuff:
------>8 [relevant code] >8-------
/* SC16IS7XX register definitions */
#define SC16IS7XX_RHR_REG (0x00) /* RX FIFO */
#define SC16IS7XX_THR_REG (0x00) /* TX FIFO */
#define SC16IS7XX_IER_REG (0x01) /* Interrupt enable */
#define SC16IS7XX_IIR_REG (0x02) /* Interrupt Ident */
#define SC16IS7XX_FCR_REG (0x02) /* FIFO control */
#define SC16IS7XX_LCR_REG (0x03) /* Line Control */
#define SC16IS7XX_MCR_REG (0x04) /* Modem Control */
#define SC16IS7XX_LSR_REG (0x05) /* Line Status */
#define SC16IS7XX_MSR_REG (0x06) /* Modem Status */
#define SC16IS7XX_SPR_REG (0x07) /* Scratch Pad */
#define SC16IS7XX_TXLVL_REG (0x08) /* TX FIFO level */
#define SC16IS7XX_RXLVL_REG (0x09) /* RX FIFO level */
#define SC16IS7XX_IODIR_REG (0x0a) /* I/O Dir (750/760) */
#define SC16IS7XX_IOSTATE_REG (0x0b) /* I/O State (750/760) */
#define SC16IS7XX_IOINTENA_REG (0x0c) /* I/O Int Enable (750/760) */
#define SC16IS7XX_IOCONTROL_REG (0x0e) /* I/O Control (750/760) */
#define SC16IS7XX_EFCR_REG (0x0f) /* Extra Feature Control */
/* TX/Trigger Registers: Only if ((MCR[2] == 0) && (EFR[4] == 1)) */
#define SC16IS7XX_TCR_REG (0x06) /* Transmit control */
#define SC16IS7XX_TLR_REG (0x07) /* Trigger level */
/* Special Register set: Only if ((LCR[7] == 1) && (LCR != 0xBF)) */
#define SC16IS7XX_DLL_REG (0x00) /* Divisor Latch Low */
#define SC16IS7XX_DLH_REG (0x01) /* Divisor Latch High */
/* Enhanced Register set: Only if (LCR == 0xBF) */
#define SC16IS7XX_EFR_REG (0x02) /* Enhanced Features */
#define SC16IS7XX_XON1_REG (0x04) /* Xon1 word */
#define SC16IS7XX_XON2_REG (0x05) /* Xon2 word */
#define SC16IS7XX_XOFF1_REG (0x06) /* Xoff1 word */
#define SC16IS7XX_XOFF2_REG (0x07) /* Xoff2 word */
#define SC16IS7XX_REG_SHIFT 3
static bool sc16is7xx_reg_writeable(struct device *dev, unsigned int reg)
{
switch ((reg >> SC16IS7XX_REG_SHIFT) & 0xf) {
case SC16IS7XX_LSR_REG:
case SC16IS7XX_MSR_REG:
case SC16IS7XX_TXLVL_REG:
case SC16IS7XX_RXLVL_REG:
return false;
default:
break;
}
return true;
}static bool sc16is7xx_reg_volatile(struct device *dev, unsigned int reg)
{
switch ((reg >> SC16IS7XX_REG_SHIFT) & 0xf) {
case SC16IS7XX_RHR_REG:
case SC16IS7XX_IIR_REG:
case SC16IS7XX_LSR_REG:
case SC16IS7XX_MSR_REG:
case SC16IS7XX_TXLVL_REG:
case SC16IS7XX_RXLVL_REG:
case SC16IS7XX_IOSTATE_REG:
return true;
default:
break;
}
return false;
}static bool sc16is7xx_reg_precious(struct device *dev, unsigned int reg)
{
switch ((reg >> SC16IS7XX_REG_SHIFT) & 0xf) {
case SC16IS7XX_RHR_REG:
case SC16IS7XX_IIR_REG:
case SC16IS7XX_MSR_REG:
return true;
default:
break;
}
return false;
}static struct regmap_config regcfg = {
.reg_bits = 8,
.reg_stride = (1 << SC16IS7XX_REG_SHIFT),
.val_bits = 8,
.max_register = (0xf << SC16IS7XX_REG_SHIFT),
.cache_type = REGCACHE_RBTREE,
.writeable_reg = sc16is7xx_reg_writeable,
.volatile_reg = sc16is7xx_reg_volatile,
.precious_reg = sc16is7xx_reg_precious,
};------------->8-----------------
I'm not sure that I have this defined correctly. I also saw in regmap_config pad_bits, which I've tried setting to SC16IS7XX_REG_SHIFT, but when I do that, I get -EINVAL failure.
Thanks,
Jon
[1] http://www.nxp.com/documents/data_sheet/SC16IS740_750_760.pdf
I left out some relevant functions (sc16is7xx_port_read(), sc16is7xx_port_write(), sc16is7xx_port_update()) in my previous email...
Quoted 6 lines · Alexander Shiyan
Понедельник, 10 марта 2014, 7:50 -04:00 от Jon Ringle <[email protected]>:
Quoted 2 lines · Alexander Shiyan
I do not understand why you chose the sccnxp driver as a template. Use as a template max310x driver from linux-next branch. I'm sure it will be better.
I followed your advice on using max310x as a template. One thing that I'm struggling to get right is the regmap. The datasheet[1] specifies the register bits as follows:
Table 33. Register address byte (I2C) Bit Name Function 7 - not used 6:3 A[3:0] UART's internal register select 2:1 CH1,0 channel select: CH1 = 0, CH0 = 0 Other values are reserved and should not be used. 0 - not used
So, I need to shift the register address by 3. Here is how I have defined the regmap stuff:
------>8 [relevant code] >8-------
/* SC16IS7XX register definitions */
#define SC16IS7XX_RHR_REG (0x00) /* RX FIFO */
#define SC16IS7XX_THR_REG (0x00) /* TX FIFO */
#define SC16IS7XX_IER_REG (0x01) /* Interrupt enable */
#define SC16IS7XX_IIR_REG (0x02) /* Interrupt Ident */
#define SC16IS7XX_FCR_REG (0x02) /* FIFO control */
#define SC16IS7XX_LCR_REG (0x03) /* Line Control */
#define SC16IS7XX_MCR_REG (0x04) /* Modem Control */
#define SC16IS7XX_LSR_REG (0x05) /* Line Status */
#define SC16IS7XX_MSR_REG (0x06) /* Modem Status */
#define SC16IS7XX_SPR_REG (0x07) /* Scratch Pad */
#define SC16IS7XX_TXLVL_REG (0x08) /* TX FIFO level */
#define SC16IS7XX_RXLVL_REG (0x09) /* RX FIFO level */
#define SC16IS7XX_IODIR_REG (0x0a) /* I/O Dir (750/760) */
#define SC16IS7XX_IOSTATE_REG (0x0b) /* I/O State (750/760) */
#define SC16IS7XX_IOINTENA_REG (0x0c) /* I/O Int Enable (750/760) */
#define SC16IS7XX_IOCONTROL_REG (0x0e) /* I/O Control (750/760) */
#define SC16IS7XX_EFCR_REG (0x0f) /* Extra Feature Control */
/* TX/Trigger Registers: Only if ((MCR[2] == 0) && (EFR[4] == 1)) */
#define SC16IS7XX_TCR_REG (0x06) /* Transmit control */
#define SC16IS7XX_TLR_REG (0x07) /* Trigger level */
/* Special Register set: Only if ((LCR[7] == 1) && (LCR != 0xBF)) */
#define SC16IS7XX_DLL_REG (0x00) /* Divisor Latch Low */
#define SC16IS7XX_DLH_REG (0x01) /* Divisor Latch High */
/* Enhanced Register set: Only if (LCR == 0xBF) */
#define SC16IS7XX_EFR_REG (0x02) /* Enhanced Features */
#define SC16IS7XX_XON1_REG (0x04) /* Xon1 word */
#define SC16IS7XX_XON2_REG (0x05) /* Xon2 word */
#define SC16IS7XX_XOFF1_REG (0x06) /* Xoff1 word */
#define SC16IS7XX_XOFF2_REG (0x07) /* Xoff2 word */
#define SC16IS7XX_REG_SHIFT 3
static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg)
{
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
unsigned int val = 0;
regmap_read(s->regmap, reg << SC16IS7XX_REG_SHIFT, &val);
return val;
}static void sc16is7xx_port_write(struct uart_port *port, u8 reg, u8 val)
{
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
regmap_write(s->regmap, reg << SC16IS7XX_REG_SHIFT, val);
}static void sc16is7xx_port_update(struct uart_port *port, u8 reg, u8 mask, u8 val)
{
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
regmap_update_bits(s->regmap, reg << SC16IS7XX_REG_SHIFT, mask, val);
}static bool sc16is7xx_reg_writeable(struct device *dev, unsigned int reg)
{
switch ((reg >> SC16IS7XX_REG_SHIFT) & 0xf) {
case SC16IS7XX_LSR_REG:
case SC16IS7XX_MSR_REG:
case SC16IS7XX_TXLVL_REG:
case SC16IS7XX_RXLVL_REG:
return false;
default:
break;
}
return true;
}static bool sc16is7xx_reg_volatile(struct device *dev, unsigned int reg)
{
switch ((reg >> SC16IS7XX_REG_SHIFT) & 0xf) {
case SC16IS7XX_RHR_REG:
case SC16IS7XX_IIR_REG:
case SC16IS7XX_LSR_REG:
case SC16IS7XX_MSR_REG:
case SC16IS7XX_TXLVL_REG:
case SC16IS7XX_RXLVL_REG:
case SC16IS7XX_IOSTATE_REG:
return true;
default:
break;
}
return false;
}static bool sc16is7xx_reg_precious(struct device *dev, unsigned int reg)
{
switch ((reg >> SC16IS7XX_REG_SHIFT) & 0xf) {
case SC16IS7XX_RHR_REG:
case SC16IS7XX_IIR_REG:
case SC16IS7XX_MSR_REG:
return true;
default:
break;
}
return false;
}static struct regmap_config regcfg = {
.reg_bits = 8,
.reg_stride = (1 << SC16IS7XX_REG_SHIFT),
.val_bits = 8,
.max_register = (0xf << SC16IS7XX_REG_SHIFT),
.cache_type = REGCACHE_RBTREE,
.writeable_reg = sc16is7xx_reg_writeable,
.volatile_reg = sc16is7xx_reg_volatile,
.precious_reg = sc16is7xx_reg_precious,
};------------->8-----------------
I'm not sure that I have this defined correctly. I also saw in regmap_config pad_bits, which I've tried setting to SC16IS7XX_REG_SHIFT, but when I do that, I get -EINVAL failure.
Thanks,
Jon
[1] http://www.nxp.com/documents/data_sheet/SC16IS740_750_760.pdf
Вторник, 11 марта 2014, 14:44 -04:00 от Jon Ringle <[email protected]>:
Quoted 12 lines
I left out some relevant functions (
sc16is7xx_port_read(),sc16is7xx_port_write(),sc16is7xx_port_update()) in my previous email...Quoted 6 lines · Alexander Shiyan
Понедельник, 10 марта 2014, 7:50 -04:00 от Jon Ringle <[email protected]>:
Quoted 2 lines · Alexander Shiyan
I do not understand why you chose the sccnxp driver as a template. Use as a template max310x driver from linux-next branch. I'm sure it will be better.
Here are the approximate changes:
Quoted 1 line
#define
SC16IS7XX_REG_SHIFT3
#define SC16IS7XX_REG_SHIFT 2
Quoted 6 lines
static u8
sc16is7xx_port_read(struct uart_port *port, u8 reg){ struct sc16is7xx_port *s = dev_get_drvdata(port->dev); unsigned int val = 0; regmap_read(s->regmap, reg << SC16IS7XX_REG_SHIFT, &val);
regmap_read(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | port->index, &val);
Same for "write" and "update".
Quoted 2 lines
static struct regmap_config regcfg = {
.reg_bits = 8,.reg_bits = 7,
Quoted 1 line
.reg_stride = (1 << SC16IS7XX_REG_SHIFT),
Kill this line (.reg_stride), but add:
.pad_bits = 1,
---
drivers/tty/serial/sc16is7xx.c line 54
Quoted 4 lines
drivers/tty/serial/sc16is7xx.c new file +4
-0+#define DRV_NAME "sc16is7xx" +#define DRV_VERSION "0.4" +#define SC16IS7XX_MAJOR 204 +#define SC16IS7XX_MINOR 8
Use dynamic minors for any new device
Quoted 1 line
+static inline u8
sc16is7xx_read(struct uart_port *port, u8 reg)
I wouldn't inline this - the compiler will figure it out for you and you've got a fair bit code there.
Quoted 1 line
+static void
sc16is7xx_handle_rx(struct uart_port *port)
This gets called from handle_events which gets called from the ist handler with IRQs disabled. I'm surprised it works at all but you definitely don't want to be doing all this work with interrupts blocked. That may be part of your problem.
Quoted 1 line
+static void
sc16is7xx_handle_tx(struct uart_port *port)
Ditto
Quoted 24 lines
drivers/tty/serial/sc16is7xx.c new file +24
-0+static void sc16is7xx_set_termios (struct uart_port *port, +struct ktermios *termios,struct ktermios *old) +{ +struct sc16is7xx_port *s =dev_get_drvdata (port->dev); +unsigned long flags; +u8 cval; +u8 fcr; +int baud; + +spin_lock_irqsave (&s->lock, flags); + +/* Mask termios capabilities we don't support */ + termios->c_cflag &= ~CMSPAR ; + +/* Disable RX & TX, reset break condition, status and FIFOs */ + fcr =sc16is7xx_read (port,UART_FCR ); + fcr |=UART_FCR_CLEAR_RCVR |UART_FCR_CLEAR_XMIT ; + fcr &= ~UART_FCR_ENABLE_FIFO ; +sc16is7xx_write (port,UART_FCR , fcr); + +/* Word size */ +switch (termios->c_cflag &CSIZE ) { +case CS5 : + cval =UART_LCR_WLEN5 ;
drivers/tty/serial/sc16is7xx.c line 431
Quoted 10 lines
drivers/tty/serial/sc16is7xx.c new file +10
-0+break ; +case CS6 : + cval =UART_LCR_WLEN6 ; +break ; +case CS7 : + cval =UART_LCR_WLEN7 ; +break ; +case CS8 : +default : + cval =UART_LCR_WLEN8 ;
(for the unknown case you also need to do
termios->c_cflag &= ~CSIZE; termios->c_cflag |= CS8;
so the caller gets informed they didn't get their requested feature
Likewise btw for unsupported features. In this case CMSPAR appears not to be supported ?)
Reading drivers/tty/serial/max310x.c may be helpful with regards to the locking. It is SPI based so also has to defer some of the processing from the IRQ handler. The threaded IRQ support we now have may also help you.
Alan