serial: msm_serial_hs: Add extra delay during close with pending tx
In some cases the userspace can do a back to back write() followed by close(). In such cases the tty framework does account for this by asking the driver the status of the tx buffer and if not empty wait for a timeout computed as a function of the current port baud rate. However in some cases, this timeout doesn't seem sufficient, so when checking the state of the tx buffer insert an extra delay if not empty before returning to the framework. This will do a double wait at driver and at framework, but this shouldn't adversely affect timing of usecases and the flip side of having a pending byte in the tx buffer can result in the peer hardware being left in a bad state. Change-Id: I372e2e1c68f13f5d537ea33980eb63487f31d589 CRs-Fixed: 1044170 Signed-off-by: Girish Mahadevan <girishm@codeaurora.org>
This commit is contained in:
parent
e94b446eac
commit
d64c7bb096
1 changed files with 14 additions and 2 deletions
|
@ -44,6 +44,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
@ -1237,16 +1238,27 @@ static void msm_hs_set_termios(struct uart_port *uport,
|
|||
unsigned int msm_hs_tx_empty(struct uart_port *uport)
|
||||
{
|
||||
unsigned int data;
|
||||
unsigned int isr;
|
||||
unsigned int ret = 0;
|
||||
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
|
||||
|
||||
msm_hs_resource_vote(msm_uport);
|
||||
data = msm_hs_read(uport, UART_DM_SR);
|
||||
isr = msm_hs_read(uport, UART_DM_ISR);
|
||||
msm_hs_resource_unvote(msm_uport);
|
||||
MSM_HS_DBG("%s(): SR Reg Read 0x%x", __func__, data);
|
||||
MSM_HS_INFO("%s(): SR:0x%x ISR:0x%x ", __func__, data, isr);
|
||||
|
||||
if (data & UARTDM_SR_TXEMT_BMSK)
|
||||
if (data & UARTDM_SR_TXEMT_BMSK) {
|
||||
ret = TIOCSER_TEMT;
|
||||
} else
|
||||
/*
|
||||
* Add an extra sleep here because sometimes the framework's
|
||||
* delay (based on baud rate) isn't good enough.
|
||||
* Note that this won't happen during every port close, only
|
||||
* on select occassions when the userspace does back to back
|
||||
* write() and close().
|
||||
*/
|
||||
usleep_range(5000, 7000);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue