* [PATCH V2 0/2] Fix RX cancel command failure @ 2020-02-25 13:54 satya priya 2020-02-25 13:54 ` [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe satya priya 2020-02-25 13:54 ` [PATCH V2 2/2] tty: serial: qcom_geni_serial: Fix RX cancel command failure satya priya 0 siblings, 2 replies; 8+ messages in thread From: satya priya @ 2020-02-25 13:54 UTC (permalink / raw) To: gregkh Cc: swboyd, mgautam, linux-arm-msm, linux-serial, akashast, rojay, msavaliy, satya priya Changes in V2: - Add patch to allocate port->rx_fifo buffer in probe to resolve NULL pointer dereference crash reported by stephen. The crash is caused due to set_termios call starting RX engine and RX engine is sampling some garbage data from line, and by the time startup is called, we have few data to read but port->rx_fifo buffer is not allocated causing NULL pointer dereference. satya priya (2): tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe tty: serial: qcom_geni_serial: Fix RX cancel command failure drivers/tty/serial/qcom_geni_serial.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe 2020-02-25 13:54 [PATCH V2 0/2] Fix RX cancel command failure satya priya @ 2020-02-25 13:54 ` satya priya 2020-02-28 22:54 ` Stephen Boyd 2020-02-28 23:01 ` Stephen Boyd 2020-02-25 13:54 ` [PATCH V2 2/2] tty: serial: qcom_geni_serial: Fix RX cancel command failure satya priya 1 sibling, 2 replies; 8+ messages in thread From: satya priya @ 2020-02-25 13:54 UTC (permalink / raw) To: gregkh Cc: swboyd, mgautam, linux-arm-msm, linux-serial, akashast, rojay, msavaliy, satya priya To fix the RX cancel command failure, rx_fifo buffer needs to be flushed in stop_rx() by calling handle_rx(). If set_termios is called before startup, by this time memory is not allocated to port->rx_fifo buffer, which leads to a NULL pointer dereference. To avoid this NULL pointer dereference allocate memory to port->rx_fifo in probe itself. Signed-off-by: satya priya <skakit@codeaurora.org> --- drivers/tty/serial/qcom_geni_serial.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 191abb1..d2a909c 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -858,12 +858,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) false, false, true); geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); geni_se_select_mode(&port->se, GENI_SE_FIFO); - if (!uart_console(uport)) { - port->rx_fifo = devm_kcalloc(uport->dev, - port->rx_fifo_depth, sizeof(u32), GFP_KERNEL); - if (!port->rx_fifo) - return -ENOMEM; - } port->setup = true; return 0; @@ -1274,6 +1268,13 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS; port->tx_fifo_width = DEF_FIFO_WIDTH_BITS; + if (!console) { + port->rx_fifo = devm_kcalloc(uport->dev, + port->rx_fifo_depth, sizeof(u32), GFP_KERNEL); + if (!port->rx_fifo) + return -ENOMEM; + } + port->name = devm_kasprintf(uport->dev, GFP_KERNEL, "qcom_geni_serial_%s%d", uart_console(uport) ? "console" : "uart", uport->line); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe 2020-02-25 13:54 ` [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe satya priya @ 2020-02-28 22:54 ` Stephen Boyd 2020-03-04 13:38 ` skakit 2020-02-28 23:01 ` Stephen Boyd 1 sibling, 1 reply; 8+ messages in thread From: Stephen Boyd @ 2020-02-28 22:54 UTC (permalink / raw) To: gregkh, satya priya Cc: mgautam, linux-arm-msm, linux-serial, akashast, rojay, msavaliy, satya priya Quoting satya priya (2020-02-25 05:54:21) > To fix the RX cancel command failure, rx_fifo buffer needs to be > flushed in stop_rx() by calling handle_rx(). > > If set_termios is called before startup, by this time memory is not > allocated to port->rx_fifo buffer, which leads to a NULL pointer > dereference. > > To avoid this NULL pointer dereference allocate memory to port->rx_fifo > in probe itself. > > Signed-off-by: satya priya <skakit@codeaurora.org> Please give me reported-by credit. Reported-by: Stephen Boyd <swboyd@chromium.org> > --- > drivers/tty/serial/qcom_geni_serial.c | 13 +++++++------ > 1 file changed, 7 insertions(+), 6 deletions(-) > > diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c > index 191abb1..d2a909c 100644 > --- a/drivers/tty/serial/qcom_geni_serial.c > +++ b/drivers/tty/serial/qcom_geni_serial.c > @@ -858,12 +858,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) > false, false, true); > geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); > geni_se_select_mode(&port->se, GENI_SE_FIFO); > - if (!uart_console(uport)) { > - port->rx_fifo = devm_kcalloc(uport->dev, > - port->rx_fifo_depth, sizeof(u32), GFP_KERNEL); > - if (!port->rx_fifo) > - return -ENOMEM; > - } > port->setup = true; > > return 0; > @@ -1274,6 +1268,13 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) > port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS; > port->tx_fifo_width = DEF_FIFO_WIDTH_BITS; > > + if (!console) { > + port->rx_fifo = devm_kcalloc(uport->dev, > + port->rx_fifo_depth, sizeof(u32), GFP_KERNEL); > + if (!port->rx_fifo) > + return -ENOMEM; > + } Is there any reason the rx_fifo pointer is a u32 instead of a u8 or void pointer? ioread32_rep() doesn't care what the pointer is and then we have to cast it, so it seems like we should do something like below too. -----8<----- diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 191abb18fc2a..b4875dfef6aa 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -113,7 +113,7 @@ struct qcom_geni_serial_port { unsigned int baud; unsigned int tx_bytes_pw; unsigned int rx_bytes_pw; - u32 *rx_fifo; + u8 *rx_fifo; u32 loopback; bool brk; @@ -504,7 +504,6 @@ static int handle_rx_console(struct uart_port *uport, u32 bytes, bool drop) static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) { - unsigned char *buf; struct tty_port *tport; struct qcom_geni_serial_port *port = to_dev_port(uport, uport); u32 num_bytes_pw = port->tx_fifo_width / BITS_PER_BYTE; @@ -516,8 +515,7 @@ static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) if (drop) return 0; - buf = (unsigned char *)port->rx_fifo; - ret = tty_insert_flip_string(tport, buf, bytes); + ret = tty_insert_flip_string(tport, port->rx_fifo, bytes); if (ret != bytes) { dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n", __func__, ret, bytes); ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe 2020-02-28 22:54 ` Stephen Boyd @ 2020-03-04 13:38 ` skakit 0 siblings, 0 replies; 8+ messages in thread From: skakit @ 2020-03-04 13:38 UTC (permalink / raw) To: Stephen Boyd Cc: gregkh, mgautam, linux-arm-msm, linux-serial, akashast, rojay, msavaliy On 2020-02-29 04:24, Stephen Boyd wrote: > Quoting satya priya (2020-02-25 05:54:21) >> To fix the RX cancel command failure, rx_fifo buffer needs to be >> flushed in stop_rx() by calling handle_rx(). >> >> If set_termios is called before startup, by this time memory is not >> allocated to port->rx_fifo buffer, which leads to a NULL pointer >> dereference. >> >> To avoid this NULL pointer dereference allocate memory to >> port->rx_fifo >> in probe itself. >> >> Signed-off-by: satya priya <skakit@codeaurora.org> > > Please give me reported-by credit. > > Reported-by: Stephen Boyd <swboyd@chromium.org> Ok. > >> --- >> drivers/tty/serial/qcom_geni_serial.c | 13 +++++++------ >> 1 file changed, 7 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/tty/serial/qcom_geni_serial.c >> b/drivers/tty/serial/qcom_geni_serial.c >> index 191abb1..d2a909c 100644 >> --- a/drivers/tty/serial/qcom_geni_serial.c >> +++ b/drivers/tty/serial/qcom_geni_serial.c >> @@ -858,12 +858,6 @@ static int qcom_geni_serial_port_setup(struct >> uart_port *uport) >> false, false, true); >> geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); >> geni_se_select_mode(&port->se, GENI_SE_FIFO); >> - if (!uart_console(uport)) { >> - port->rx_fifo = devm_kcalloc(uport->dev, >> - port->rx_fifo_depth, sizeof(u32), GFP_KERNEL); >> - if (!port->rx_fifo) >> - return -ENOMEM; >> - } >> port->setup = true; >> >> return 0; >> @@ -1274,6 +1268,13 @@ static int qcom_geni_serial_probe(struct >> platform_device *pdev) >> port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS; >> port->tx_fifo_width = DEF_FIFO_WIDTH_BITS; >> >> + if (!console) { >> + port->rx_fifo = devm_kcalloc(uport->dev, >> + port->rx_fifo_depth, sizeof(u32), GFP_KERNEL); >> + if (!port->rx_fifo) >> + return -ENOMEM; >> + } > > Is there any reason the rx_fifo pointer is a u32 instead of a u8 or > void > pointer? ioread32_rep() doesn't care what the pointer is and then we > have to cast it, so it seems like we should do something like below > too. > Yes, we can use void instead of u32, will add this change in next patch. > -----8<----- > > diff --git a/drivers/tty/serial/qcom_geni_serial.c > b/drivers/tty/serial/qcom_geni_serial.c > index 191abb18fc2a..b4875dfef6aa 100644 > --- a/drivers/tty/serial/qcom_geni_serial.c > +++ b/drivers/tty/serial/qcom_geni_serial.c > @@ -113,7 +113,7 @@ struct qcom_geni_serial_port { > unsigned int baud; > unsigned int tx_bytes_pw; > unsigned int rx_bytes_pw; > - u32 *rx_fifo; > + u8 *rx_fifo; > u32 loopback; > bool brk; > > @@ -504,7 +504,6 @@ static int handle_rx_console(struct uart_port > *uport, u32 bytes, bool drop) > > static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool > drop) > { > - unsigned char *buf; > struct tty_port *tport; > struct qcom_geni_serial_port *port = to_dev_port(uport, uport); > u32 num_bytes_pw = port->tx_fifo_width / BITS_PER_BYTE; > @@ -516,8 +515,7 @@ static int handle_rx_uart(struct uart_port *uport, > u32 bytes, bool drop) > if (drop) > return 0; > > - buf = (unsigned char *)port->rx_fifo; > - ret = tty_insert_flip_string(tport, buf, bytes); > + ret = tty_insert_flip_string(tport, port->rx_fifo, bytes); > if (ret != bytes) { > dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n", > __func__, ret, bytes); ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe 2020-02-25 13:54 ` [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe satya priya 2020-02-28 22:54 ` Stephen Boyd @ 2020-02-28 23:01 ` Stephen Boyd 2020-03-04 13:34 ` skakit 1 sibling, 1 reply; 8+ messages in thread From: Stephen Boyd @ 2020-02-28 23:01 UTC (permalink / raw) To: gregkh, satya priya Cc: mgautam, linux-arm-msm, linux-serial, akashast, rojay, msavaliy, satya priya Quoting satya priya (2020-02-25 05:54:21) > To fix the RX cancel command failure, rx_fifo buffer needs to be > flushed in stop_rx() by calling handle_rx(). > > If set_termios is called before startup, by this time memory is not > allocated to port->rx_fifo buffer, which leads to a NULL pointer > dereference. Also, clearly set_termios() isn't being called in the warning stack that I sent last round: pc : handle_rx_uart+0x64/0x278 lr : qcom_geni_serial_handle_rx+0x84/0x90 sp : ffffff814348f960 x29: ffffff814348f960 x28: ffffffd01ac24288 x27: 0000000000000018 x26: 0000000000000002 x25: 0000000000000001 x24: ffffff8146341348 x23: ffffff8146341000 x22: ffffffd01accc978 x21: ffffff8146341000 x20: 0000000000000001 x19: 0000000000000001 x18: ffffffd01b22d000 x17: 0000000000008000 x16: 00000000000000b0 x15: ffffffd01afdbdd0 x14: ffffffd01b3edde0 x13: ffffffd01b7fb000 x12: 0000000000000001 x11: 0000000000000000 x10: 0000000000000000 x9 : ffffffd010344780 x8 : 0000000000000000 x7 : ffffffd019d8e768 x6 : 0000000000000000 x5 : ffffffd01adbb000 x4 : 0000000000008004 x3 : 0000000000000001 x2 : 0000000000000001 x1 : 0000000000000001 x0 : ffffffd01accc978 Call trace: handle_rx_uart+0x64/0x278 qcom_geni_serial_handle_rx+0x84/0x90 qcom_geni_serial_stop_rx+0x110/0x180 qcom_geni_serial_port_setup+0x68/0x1b0 qcom_geni_serial_startup+0x24/0x70 uart_startup+0x164/0x28c uart_port_activate+0x6c/0xbc tty_port_open+0xa8/0x114 uart_open+0x28/0x38 ttyport_open+0x7c/0x164 serdev_device_open+0x38/0xe4 hci_uart_register_device+0x54/0x2e8 [hci_uart] qca_serdev_probe+0x1c4/0x374 [hci_uart] serdev_drv_probe+0x3c/0x64 really_probe+0x144/0x3f8 driver_probe_device+0x70/0x140 __driver_attach_async_helper+0x7c/0xa8 async_run_entry_fn+0x60/0x178 process_one_work+0x33c/0x640 worker_thread+0x2a0/0x470 kthread+0x128/0x138 ret_from_fork+0x10/0x18 Code: 1aca096a 911e0129 b940012b 7100054a (b800450b) This shows that uart_startup() is the one that is calling qcom_geni_serial_startup() and that's running the newly added cancel path. So even if we allocate the buffer in probe vs. in startup we're going to flip a buffer full of junk that we're trying to cancel out of the fifo into the tty layer. That seems wrong. We should have a different qcom_geni_serial_stop_rx() function that knows we're starting up vs. handling a normal rx event and call something besides handle_rx() because that pushes bytes up into the tty layer. > > To avoid this NULL pointer dereference allocate memory to port->rx_fifo > in probe itself. > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe 2020-02-28 23:01 ` Stephen Boyd @ 2020-03-04 13:34 ` skakit 2020-03-04 17:48 ` Stephen Boyd 0 siblings, 1 reply; 8+ messages in thread From: skakit @ 2020-03-04 13:34 UTC (permalink / raw) To: Stephen Boyd Cc: gregkh, mgautam, linux-arm-msm, linux-serial, akashast, rojay, msavaliy On 2020-02-29 04:31, Stephen Boyd wrote: > Quoting satya priya (2020-02-25 05:54:21) >> To fix the RX cancel command failure, rx_fifo buffer needs to be >> flushed in stop_rx() by calling handle_rx(). >> >> If set_termios is called before startup, by this time memory is not >> allocated to port->rx_fifo buffer, which leads to a NULL pointer >> dereference. > > Also, clearly set_termios() isn't being called in the warning stack > that > I sent last round: > > pc : handle_rx_uart+0x64/0x278 > > > lr : qcom_geni_serial_handle_rx+0x84/0x90 > > > sp : ffffff814348f960 > > > x29: ffffff814348f960 x28: ffffffd01ac24288 > > > x27: 0000000000000018 x26: 0000000000000002 > > > x25: 0000000000000001 x24: ffffff8146341348 > > > x23: ffffff8146341000 x22: ffffffd01accc978 > > > x21: ffffff8146341000 x20: 0000000000000001 > > > x19: 0000000000000001 x18: ffffffd01b22d000 > > > x17: 0000000000008000 x16: 00000000000000b0 > > > x15: ffffffd01afdbdd0 x14: ffffffd01b3edde0 > > > x13: ffffffd01b7fb000 x12: 0000000000000001 > > > x11: 0000000000000000 x10: 0000000000000000 > > > x9 : ffffffd010344780 x8 : 0000000000000000 > > > x7 : ffffffd019d8e768 x6 : 0000000000000000 > > > x5 : ffffffd01adbb000 x4 : 0000000000008004 > > > x3 : 0000000000000001 x2 : 0000000000000001 > > > x1 : 0000000000000001 x0 : ffffffd01accc978 > > > Call trace: > > > handle_rx_uart+0x64/0x278 > > > qcom_geni_serial_handle_rx+0x84/0x90 > > > qcom_geni_serial_stop_rx+0x110/0x180 > > > qcom_geni_serial_port_setup+0x68/0x1b0 > > > qcom_geni_serial_startup+0x24/0x70 > > > uart_startup+0x164/0x28c > > > uart_port_activate+0x6c/0xbc > > > tty_port_open+0xa8/0x114 > > > uart_open+0x28/0x38 > > > ttyport_open+0x7c/0x164 > > > serdev_device_open+0x38/0xe4 > > > hci_uart_register_device+0x54/0x2e8 [hci_uart] > > > qca_serdev_probe+0x1c4/0x374 [hci_uart] > > > serdev_drv_probe+0x3c/0x64 > > > really_probe+0x144/0x3f8 > > > driver_probe_device+0x70/0x140 > > > __driver_attach_async_helper+0x7c/0xa8 > > > async_run_entry_fn+0x60/0x178 > > > process_one_work+0x33c/0x640 > > > worker_thread+0x2a0/0x470 > > > kthread+0x128/0x138 > > > ret_from_fork+0x10/0x18 > > > Code: 1aca096a 911e0129 b940012b 7100054a (b800450b) > > > This shows that uart_startup() is the one that is calling > qcom_geni_serial_startup() and that's running the newly added cancel > path. So even if we allocate the buffer in probe vs. in startup we're > going to flip a buffer full of junk that we're trying to cancel out of > the fifo into the tty layer. That seems wrong. We should have a > different qcom_geni_serial_stop_rx() function that knows we're starting > up vs. handling a normal rx event and call something besides > handle_rx() > because that pushes bytes up into the tty layer. > As we mentioned in the V1 patch, we are passing drop="true" to handle_rx function so it will read and discard whatever data present in RX FIFO, it won't send to upper layers. static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) { .... ioread32_rep(uport->membase + SE_GENI_RX_FIFOn, port->rx_fifo, words); if (drop) return 0; .... } In general uart_startup() is called before set_termios() ,but as per the crash logs shared, it seems RX engine is active(which can only happen from set_termios) before startup() is called.So, if we allocate port->rx_fifo in probe we can overcome this crash. >> >> To avoid this NULL pointer dereference allocate memory to >> port->rx_fifo >> in probe itself. >> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe 2020-03-04 13:34 ` skakit @ 2020-03-04 17:48 ` Stephen Boyd 0 siblings, 0 replies; 8+ messages in thread From: Stephen Boyd @ 2020-03-04 17:48 UTC (permalink / raw) To: skakit Cc: gregkh, mgautam, linux-arm-msm, linux-serial, akashast, rojay, msavaliy Quoting skakit@codeaurora.org (2020-03-04 05:34:20) > As we mentioned in the V1 patch, we are passing drop="true" to handle_rx > function so it will read and discard whatever data present in RX FIFO, > it won't send to upper layers. > static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) > { > .... > ioread32_rep(uport->membase + SE_GENI_RX_FIFOn, port->rx_fifo, > words); > if (drop) > return 0; > .... > } > In general uart_startup() is called before set_termios() ,but as per the > crash logs shared, it seems RX engine is active(which can only happen > from set_termios) before startup() is called.So, if we allocate > port->rx_fifo in probe we can overcome this crash. Ok. Thanks for clarifying. Can you please mention in the commit text that the fifo contents are read into rx_fifo but then dropped? ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH V2 2/2] tty: serial: qcom_geni_serial: Fix RX cancel command failure 2020-02-25 13:54 [PATCH V2 0/2] Fix RX cancel command failure satya priya 2020-02-25 13:54 ` [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe satya priya @ 2020-02-25 13:54 ` satya priya 1 sibling, 0 replies; 8+ messages in thread From: satya priya @ 2020-02-25 13:54 UTC (permalink / raw) To: gregkh Cc: swboyd, mgautam, linux-arm-msm, linux-serial, akashast, rojay, msavaliy, satya priya RX cancel command fails when BT is switched on and off multiple times. To handle this, poll for the cancel bit in SE_GENI_S_IRQ_STATUS register instead of SE_GENI_S_CMD_CTRL_REG. As per the HPG update, handle the RX last bit after cancel command and flush out the RX FIFO buffer. Signed-off-by: satya priya <skakit@codeaurora.org> --- drivers/tty/serial/qcom_geni_serial.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index d2a909c..22d99b0 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -129,6 +129,7 @@ static int handle_rx_console(struct uart_port *uport, u32 bytes, bool drop); static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop); static unsigned int qcom_geni_serial_tx_empty(struct uart_port *port); static void qcom_geni_serial_stop_rx(struct uart_port *uport); +static void qcom_geni_serial_handle_rx(struct uart_port *uport, bool drop); static const unsigned long root_freq[] = {7372800, 14745600, 19200000, 29491200, 32000000, 48000000, 64000000, 80000000, @@ -599,7 +600,7 @@ static void qcom_geni_serial_stop_rx(struct uart_port *uport) u32 irq_en; u32 status; struct qcom_geni_serial_port *port = to_dev_port(uport, uport); - u32 irq_clear = S_CMD_DONE_EN; + u32 s_irq_status; irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN); irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN); @@ -615,10 +616,19 @@ static void qcom_geni_serial_stop_rx(struct uart_port *uport) return; geni_se_cancel_s_cmd(&port->se); - qcom_geni_serial_poll_bit(uport, SE_GENI_S_CMD_CTRL_REG, - S_GENI_CMD_CANCEL, false); + qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS, + S_CMD_CANCEL_EN, true); + /* + * If timeout occurs secondary engine remains active + * and Abort sequence is executed. + */ + s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); + /* Flush the Rx buffer */ + if (s_irq_status & S_RX_FIFO_LAST_EN) + qcom_geni_serial_handle_rx(uport, true); + writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR); + status = readl(uport->membase + SE_GENI_STATUS); - writel(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR); if (status & S_GENI_CMD_ACTIVE) qcom_geni_serial_abort_rx(uport); } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-03-04 17:48 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-02-25 13:54 [PATCH V2 0/2] Fix RX cancel command failure satya priya 2020-02-25 13:54 ` [PATCH V2 1/2] tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe satya priya 2020-02-28 22:54 ` Stephen Boyd 2020-03-04 13:38 ` skakit 2020-02-28 23:01 ` Stephen Boyd 2020-03-04 13:34 ` skakit 2020-03-04 17:48 ` Stephen Boyd 2020-02-25 13:54 ` [PATCH V2 2/2] tty: serial: qcom_geni_serial: Fix RX cancel command failure satya priya
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.