Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

chao bi and committed by
Greg Kroah-Hartman
31fe9904 2ac4ad2a

+11 -1
+10 -1
drivers/tty/serial/ifx6x60.c
··· 569 569 /* clear any old data; can't do this in 'close' */ 570 570 kfifo_reset(&ifx_dev->tx_fifo); 571 571 572 + /* clear any flag which may be set in port shutdown procedure */ 573 + clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags); 574 + clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags); 575 + 572 576 /* put port data into this tty */ 573 577 tty->driver_data = ifx_dev; 574 578 575 579 /* allows flip string push from int context */ 576 580 tty->low_latency = 1; 581 + 582 + /* set flag to allows data transfer */ 583 + set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); 577 584 578 585 return 0; 579 586 } ··· 597 590 struct ifx_spi_device *ifx_dev = 598 591 container_of(port, struct ifx_spi_device, tty_port); 599 592 593 + clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); 600 594 mrdy_set_low(ifx_dev); 601 595 clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); 602 596 tasklet_kill(&ifx_dev->io_work_tasklet); ··· 753 745 int retval; 754 746 struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data; 755 747 756 - if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags)) { 748 + if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) && 749 + test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) { 757 750 if (ifx_dev->gpio.unack_srdy_int_nb > 0) 758 751 ifx_dev->gpio.unack_srdy_int_nb--; 759 752
+1
drivers/tty/serial/ifx6x60.h
··· 41 41 #define IFX_SPI_STATE_IO_IN_PROGRESS 1 42 42 #define IFX_SPI_STATE_IO_READY 2 43 43 #define IFX_SPI_STATE_TIMER_PENDING 3 44 + #define IFX_SPI_STATE_IO_AVAILABLE 4 44 45 45 46 /* flow control bitfields */ 46 47 #define IFX_SPI_DCD 0