mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 07:00:48 +00:00
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: channing <chao.bi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2ac4ad2a14
commit
31fe990488
@ -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' */
|
||||
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 */
|
||||
tty->driver_data = ifx_dev;
|
||||
|
||||
/* allows flip string push from int context */
|
||||
tty->low_latency = 1;
|
||||
|
||||
/* set flag to allows data transfer */
|
||||
set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -590,6 +597,7 @@ static void ifx_port_shutdown(struct tty_port *port)
|
||||
struct ifx_spi_device *ifx_dev =
|
||||
container_of(port, struct ifx_spi_device, tty_port);
|
||||
|
||||
clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
|
||||
mrdy_set_low(ifx_dev);
|
||||
clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
|
||||
tasklet_kill(&ifx_dev->io_work_tasklet);
|
||||
@ -745,7 +753,8 @@ static void ifx_spi_io(unsigned long data)
|
||||
int retval;
|
||||
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)
|
||||
ifx_dev->gpio.unack_srdy_int_nb--;
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#define IFX_SPI_STATE_IO_IN_PROGRESS 1
|
||||
#define IFX_SPI_STATE_IO_READY 2
|
||||
#define IFX_SPI_STATE_TIMER_PENDING 3
|
||||
#define IFX_SPI_STATE_IO_AVAILABLE 4
|
||||
|
||||
/* flow control bitfields */
|
||||
#define IFX_SPI_DCD 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user