提交 31fe9904 编写于 作者: C chao bi 提交者: Greg Kroah-Hartman

serial:ifx6x60:Prevent data transfer when IFX6x60 port is shutdown

This patch is to implement following 2 places to avoid potential error when IFX6x60 port shutdown:
1) Clear Flag IFX_SPI_STATE_IO_AVAILABLE to disable data transfer when Modem port is shutdown;
2) Clear Flag IFX_SPI_STATE_IO_IN_PROGRESS and IFX_SPI_STATE_IO_READY when reopen port.
This is because last port shutdown may happen when SPI/DMA transfer is in progress, if the last
data transfer is not completed(for example due to modem reset), the Flag IFX_SPI_STATE_IO_IN_PROGRESS
will be set forever, so when IFX port is activated again, IFX_SPI_STATE_IO_IN_PROGRESS will prevent
transferring data forever. And if don't clear IFX_SPI_STATE_IO_READY, it may cause one more SPI frame
transferring in spit there is not data need to be transfer.

cc: liu chuansheng <chuansheng.liu@intel.com>
cc: Chen Jun <jun.d.chen@intel.com>
Signed-off-by: Nchanning <chao.bi@intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 2ac4ad2a
...@@ -569,12 +569,19 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty) ...@@ -569,12 +569,19 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty)
/* clear any old data; can't do this in 'close' */ /* clear any old data; can't do this in 'close' */
kfifo_reset(&ifx_dev->tx_fifo); kfifo_reset(&ifx_dev->tx_fifo);
/* clear any flag which may be set in port shutdown procedure */
clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags);
clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags);
/* put port data into this tty */ /* put port data into this tty */
tty->driver_data = ifx_dev; tty->driver_data = ifx_dev;
/* allows flip string push from int context */ /* allows flip string push from int context */
tty->low_latency = 1; tty->low_latency = 1;
/* set flag to allows data transfer */
set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
return 0; return 0;
} }
...@@ -590,6 +597,7 @@ static void ifx_port_shutdown(struct tty_port *port) ...@@ -590,6 +597,7 @@ static void ifx_port_shutdown(struct tty_port *port)
struct ifx_spi_device *ifx_dev = struct ifx_spi_device *ifx_dev =
container_of(port, struct ifx_spi_device, tty_port); container_of(port, struct ifx_spi_device, tty_port);
clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
mrdy_set_low(ifx_dev); mrdy_set_low(ifx_dev);
clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
tasklet_kill(&ifx_dev->io_work_tasklet); tasklet_kill(&ifx_dev->io_work_tasklet);
...@@ -745,7 +753,8 @@ static void ifx_spi_io(unsigned long data) ...@@ -745,7 +753,8 @@ static void ifx_spi_io(unsigned long data)
int retval; int retval;
struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data; struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data;
if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags)) { if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) &&
test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) {
if (ifx_dev->gpio.unack_srdy_int_nb > 0) if (ifx_dev->gpio.unack_srdy_int_nb > 0)
ifx_dev->gpio.unack_srdy_int_nb--; ifx_dev->gpio.unack_srdy_int_nb--;
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#define IFX_SPI_STATE_IO_IN_PROGRESS 1 #define IFX_SPI_STATE_IO_IN_PROGRESS 1
#define IFX_SPI_STATE_IO_READY 2 #define IFX_SPI_STATE_IO_READY 2
#define IFX_SPI_STATE_TIMER_PENDING 3 #define IFX_SPI_STATE_TIMER_PENDING 3
#define IFX_SPI_STATE_IO_AVAILABLE 4
/* flow control bitfields */ /* flow control bitfields */
#define IFX_SPI_DCD 0 #define IFX_SPI_DCD 0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册