* [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown
@ 2013-10-01 16:18 Hector Palacios
2013-10-01 19:48 ` Uwe Kleine-König
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Hector Palacios @ 2013-10-01 16:18 UTC (permalink / raw)
To: linux-serial
Cc: u.kleine-koenig, b32955, gregkh, shawn.guo, fabio.estevam, marex,
hector.palacios
The shutdown function was not waiting for the DMA buffer to flush
before disabling the AUART. This lead to many bytes not being
transferred (specially at low baudrates), as they were still in the
DMA buffer when the AUART was shutdown.
This patch also adds the check for the BUSY flag.
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
https://jira.digi.com/browse/DEL-616
---
drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index f85b8e6..0d8b2ca 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u)
return 0;
}
+static unsigned int mxs_auart_tx_empty(struct uart_port *u);
+
static void mxs_auart_shutdown(struct uart_port *u)
{
struct mxs_auart_port *s = to_auart_port(u);
+ unsigned int to;
+
+ if (auart_dma_enabled(s)) {
+ /* Wait enough time to flush DMA buffer completely */
+ to = u->timeout * UART_XMIT_SIZE / u->fifosize;
+ while (!mxs_auart_tx_empty(u) && to--)
+ mdelay(1);
- if (auart_dma_enabled(s))
mxs_auart_dma_exit(s);
+ }
+
+ /* Wait for transmitter to become empty ... */
+ to = u->timeout;
+ while ((readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) && to--)
+ mdelay(1);
writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
--
1.8.4
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-01 16:18 [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown Hector Palacios @ 2013-10-01 19:48 ` Uwe Kleine-König 2013-10-02 7:31 ` Hector Palacios 2013-10-01 19:56 ` Marek Vasut 2013-10-02 8:24 ` Hector Palacios 2 siblings, 1 reply; 12+ messages in thread From: Uwe Kleine-König @ 2013-10-01 19:48 UTC (permalink / raw) To: Hector Palacios Cc: linux-serial, b32955, gregkh, shawn.guo, fabio.estevam, marex Hello Hector, On Tue, Oct 01, 2013 at 06:18:35PM +0200, Hector Palacios wrote: > The shutdown function was not waiting for the DMA buffer to flush > before disabling the AUART. This lead to many bytes not being > transferred (specially at low baudrates), as they were still in the > DMA buffer when the AUART was shutdown. > This patch also adds the check for the BUSY flag. > > Signed-off-by: Hector Palacios <hector.palacios@digi.com> > > https://jira.digi.com/browse/DEL-616 What is this? This isn't available in public DNS. > --- > drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) > > diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c > index f85b8e6..0d8b2ca 100644 > --- a/drivers/tty/serial/mxs-auart.c > +++ b/drivers/tty/serial/mxs-auart.c > @@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u) > return 0; > } > > +static unsigned int mxs_auart_tx_empty(struct uart_port *u); > + > static void mxs_auart_shutdown(struct uart_port *u) > { > struct mxs_auart_port *s = to_auart_port(u); > + unsigned int to; > + > + if (auart_dma_enabled(s)) { > + /* Wait enough time to flush DMA buffer completely */ > + to = u->timeout * UART_XMIT_SIZE / u->fifosize; u->timeout is the time needed to send one char, right? UART_XMIT_SIZE is the size of the circular buffer, fifosize is the size of the fifo. I don't get what you get by dividing by the fifosize. I would have expected something like: u->timeout * min(UART_XMIT_SIZE, u->fifosize) Can you explain, maybe in a comment along the code for the next person not understanding? I wonder if the individual driver is the right place this must be fixed in or if there should be (or even exists) some help form the serial framework?! Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ | -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-01 19:48 ` Uwe Kleine-König @ 2013-10-02 7:31 ` Hector Palacios 2013-10-02 7:44 ` Uwe Kleine-König 2013-10-02 8:36 ` Uwe Kleine-König 0 siblings, 2 replies; 12+ messages in thread From: Hector Palacios @ 2013-10-02 7:31 UTC (permalink / raw) To: Uwe Kleine-König Cc: linux-serial@vger.kernel.org, b32955@freescale.com, gregkh@linuxfoundation.org, shawn.guo@linaro.org, fabio.estevam@freescale.com, marex@denx.de Hello Uwe, On 10/01/2013 09:48 PM, Uwe Kleine-König wrote: > Hello Hector, > > On Tue, Oct 01, 2013 at 06:18:35PM +0200, Hector Palacios wrote: >> The shutdown function was not waiting for the DMA buffer to flush >> before disabling the AUART. This lead to many bytes not being >> transferred (specially at low baudrates), as they were still in the >> DMA buffer when the AUART was shutdown. >> This patch also adds the check for the BUSY flag. >> >> Signed-off-by: Hector Palacios <hector.palacios@digi.com> >> >> https://jira.digi.com/browse/DEL-616 > What is this? This isn't available in public DNS. Sorry, copy&paste error. I'll remove it. >> --- >> drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++- >> 1 file changed, 15 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c >> index f85b8e6..0d8b2ca 100644 >> --- a/drivers/tty/serial/mxs-auart.c >> +++ b/drivers/tty/serial/mxs-auart.c >> @@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u) >> return 0; >> } >> >> +static unsigned int mxs_auart_tx_empty(struct uart_port *u); >> + >> static void mxs_auart_shutdown(struct uart_port *u) >> { >> struct mxs_auart_port *s = to_auart_port(u); >> + unsigned int to; >> + >> + if (auart_dma_enabled(s)) { >> + /* Wait enough time to flush DMA buffer completely */ >> + to = u->timeout * UART_XMIT_SIZE / u->fifosize; > u->timeout is the time needed to send one char, right? UART_XMIT_SIZE is > the size of the circular buffer, fifosize is the size of the fifo. I > don't get what you get by dividing by the fifosize. I would have > expected something like: > > u->timeout * min(UART_XMIT_SIZE, u->fifosize) > > Can you explain, maybe in a comment along the code for the next person > not understanding? u->timeout is *not* the time needed to send one char but the time needed to flush the complete port fifo (see uart_update_timeout() in serial_core.c where it is set). UART_XMIT_SIZE is the number of bytes in the DMA buffer, so I divide the max number of bytes in the FIFO by the FIFO size and multiply by the FIFO timeout. > I wonder if the individual driver is the right place this must be fixed > in or if there should be (or even exists) some help form the serial > framework?! Good question, the issue should exit in other DMA drivers as well. Best regards, -- Hector Palacios -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-02 7:31 ` Hector Palacios @ 2013-10-02 7:44 ` Uwe Kleine-König 2013-10-02 8:09 ` Hector Palacios 2013-10-02 8:36 ` Uwe Kleine-König 1 sibling, 1 reply; 12+ messages in thread From: Uwe Kleine-König @ 2013-10-02 7:44 UTC (permalink / raw) To: Hector Palacios Cc: linux-serial@vger.kernel.org, b32955@freescale.com, gregkh@linuxfoundation.org, shawn.guo@linaro.org, fabio.estevam@freescale.com, marex@denx.de, Jiri Slaby, linux-arm-kernel Hello, On Wed, Oct 02, 2013 at 09:31:16AM +0200, Hector Palacios wrote: > On 10/01/2013 09:48 PM, Uwe Kleine-König wrote: > >On Tue, Oct 01, 2013 at 06:18:35PM +0200, Hector Palacios wrote: > >>The shutdown function was not waiting for the DMA buffer to flush > >>before disabling the AUART. This lead to many bytes not being > >>transferred (specially at low baudrates), as they were still in the > >>DMA buffer when the AUART was shutdown. > >>This patch also adds the check for the BUSY flag. > >> > >>Signed-off-by: Hector Palacios <hector.palacios@digi.com> > >> > >>[...] > >>--- > >> drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++- > >> 1 file changed, 15 insertions(+), 1 deletion(-) > >> > >>diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c > >>index f85b8e6..0d8b2ca 100644 > >>--- a/drivers/tty/serial/mxs-auart.c > >>+++ b/drivers/tty/serial/mxs-auart.c > >>@@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u) > >> return 0; > >> } > >> > >>+static unsigned int mxs_auart_tx_empty(struct uart_port *u); > >>+ > >> static void mxs_auart_shutdown(struct uart_port *u) > >> { > >> struct mxs_auart_port *s = to_auart_port(u); > >>+ unsigned int to; > >>+ > >>+ if (auart_dma_enabled(s)) { > >>+ /* Wait enough time to flush DMA buffer completely */ > >>+ to = u->timeout * UART_XMIT_SIZE / u->fifosize; > >u->timeout is the time needed to send one char, right? UART_XMIT_SIZE is > >the size of the circular buffer, fifosize is the size of the fifo. I > >don't get what you get by dividing by the fifosize. I would have > >expected something like: > > > > u->timeout * min(UART_XMIT_SIZE, u->fifosize) > > > >Can you explain, maybe in a comment along the code for the next person > >not understanding? > > u->timeout is *not* the time needed to send one char but the time > needed to flush the complete port fifo (see uart_update_timeout() in > serial_core.c where it is set). Ah, right. (BTW, uart_update_timeout should better round up instead of round down, i.e. - port->timeout = (HZ * bits) / baud + HZ/50; + port->timeout = DIV_ROUND_UP(HZ * bits, baud) + HZ/50; ) > UART_XMIT_SIZE is the number of bytes in the DMA buffer, so I divide > the max number of bytes in the FIFO by the FIFO size and multiply by > the FIFO timeout. ditto here, better round up. Although I think using a completion could shorten the timeout considerably because there are often less than UART_XMIT_SIZE chars in the buffer?! > >I wonder if the individual driver is the right place this must be fixed > >in or if there should be (or even exists) some help form the serial > >framework?! > > Good question, the issue should exit in other DMA drivers as well. Added Jiri and lakml to Cc:. Maybe someone can say something about that topic? Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ | -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-02 7:44 ` Uwe Kleine-König @ 2013-10-02 8:09 ` Hector Palacios 2013-10-02 8:30 ` Uwe Kleine-König 0 siblings, 1 reply; 12+ messages in thread From: Hector Palacios @ 2013-10-02 8:09 UTC (permalink / raw) To: Uwe Kleine-König Cc: linux-serial@vger.kernel.org, b32955@freescale.com, gregkh@linuxfoundation.org, shawn.guo@linaro.org, fabio.estevam@freescale.com, marex@denx.de, Jiri Slaby, linux-arm-kernel@lists.infradead.org Hello Uwe, On 10/02/2013 09:44 AM, Uwe Kleine-König wrote: > Hello, > > On Wed, Oct 02, 2013 at 09:31:16AM +0200, Hector Palacios wrote: >> On 10/01/2013 09:48 PM, Uwe Kleine-König wrote: >>> On Tue, Oct 01, 2013 at 06:18:35PM +0200, Hector Palacios wrote: >>>> The shutdown function was not waiting for the DMA buffer to flush >>>> before disabling the AUART. This lead to many bytes not being >>>> transferred (specially at low baudrates), as they were still in the >>>> DMA buffer when the AUART was shutdown. >>>> This patch also adds the check for the BUSY flag. >>>> >>>> Signed-off-by: Hector Palacios <hector.palacios@digi.com> >>>> >>>> [...] >>>> --- >>>> drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++- >>>> 1 file changed, 15 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c >>>> index f85b8e6..0d8b2ca 100644 >>>> --- a/drivers/tty/serial/mxs-auart.c >>>> +++ b/drivers/tty/serial/mxs-auart.c >>>> @@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u) >>>> return 0; >>>> } >>>> >>>> +static unsigned int mxs_auart_tx_empty(struct uart_port *u); >>>> + >>>> static void mxs_auart_shutdown(struct uart_port *u) >>>> { >>>> struct mxs_auart_port *s = to_auart_port(u); >>>> + unsigned int to; >>>> + >>>> + if (auart_dma_enabled(s)) { >>>> + /* Wait enough time to flush DMA buffer completely */ >>>> + to = u->timeout * UART_XMIT_SIZE / u->fifosize; >>> u->timeout is the time needed to send one char, right? UART_XMIT_SIZE is >>> the size of the circular buffer, fifosize is the size of the fifo. I >>> don't get what you get by dividing by the fifosize. I would have >>> expected something like: >>> >>> u->timeout * min(UART_XMIT_SIZE, u->fifosize) >>> >>> Can you explain, maybe in a comment along the code for the next person >>> not understanding? >> >> u->timeout is *not* the time needed to send one char but the time >> needed to flush the complete port fifo (see uart_update_timeout() in >> serial_core.c where it is set). > Ah, right. (BTW, uart_update_timeout should better round up instead of > round down, i.e. > - port->timeout = (HZ * bits) / baud + HZ/50; > + port->timeout = DIV_ROUND_UP(HZ * bits, baud) + HZ/50; > ) > >> UART_XMIT_SIZE is the number of bytes in the DMA buffer, so I divide >> the max number of bytes in the FIFO by the FIFO size and multiply by >> the FIFO timeout. > ditto here, better round up. Although I think using a completion could > shorten the timeout considerably because there are often less than > UART_XMIT_SIZE chars in the buffer?! I'm not really waiting the full timeout. I'm checking for TX fifo empty every 1ms and for a maximum of 'to' ms. >>> I wonder if the individual driver is the right place this must be fixed >>> in or if there should be (or even exists) some help form the serial >>> framework?! >> >> Good question, the issue should exit in other DMA drivers as well. > Added Jiri and lakml to Cc:. Maybe someone can say something about that > topic? > > Best regards > Uwe > Best regards, -- Hector Palacios -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-02 8:09 ` Hector Palacios @ 2013-10-02 8:30 ` Uwe Kleine-König 2013-10-02 8:46 ` Hector Palacios 0 siblings, 1 reply; 12+ messages in thread From: Uwe Kleine-König @ 2013-10-02 8:30 UTC (permalink / raw) To: Hector Palacios Cc: fabio.estevam@freescale.com, marex@denx.de, gregkh@linuxfoundation.org, b32955@freescale.com, linux-serial@vger.kernel.org, shawn.guo@linaro.org, Jiri Slaby, linux-arm-kernel@lists.infradead.org Hello Hector, On Wed, Oct 02, 2013 at 10:09:10AM +0200, Hector Palacios wrote: > On 10/02/2013 09:44 AM, Uwe Kleine-König wrote: > >On Wed, Oct 02, 2013 at 09:31:16AM +0200, Hector Palacios wrote: > >>On 10/01/2013 09:48 PM, Uwe Kleine-König wrote: > >>>On Tue, Oct 01, 2013 at 06:18:35PM +0200, Hector Palacios wrote: > >>>>+ /* Wait enough time to flush DMA buffer completely */ > >>>>+ to = u->timeout * UART_XMIT_SIZE / u->fifosize; > >>>u->timeout is the time needed to send one char, right? UART_XMIT_SIZE is > >>>the size of the circular buffer, fifosize is the size of the fifo. I > >>>don't get what you get by dividing by the fifosize. I would have > >>>expected something like: > >>> > >>> u->timeout * min(UART_XMIT_SIZE, u->fifosize) > >>> > >>>Can you explain, maybe in a comment along the code for the next person > >>>not understanding? > >> > >>u->timeout is *not* the time needed to send one char but the time > >>needed to flush the complete port fifo (see uart_update_timeout() in > >>serial_core.c where it is set). > >Ah, right. (BTW, uart_update_timeout should better round up instead of > >round down, i.e. > >- port->timeout = (HZ * bits) / baud + HZ/50; > >+ port->timeout = DIV_ROUND_UP(HZ * bits, baud) + HZ/50; > >) > > > >>UART_XMIT_SIZE is the number of bytes in the DMA buffer, so I divide > >>the max number of bytes in the FIFO by the FIFO size and multiply by > >>the FIFO timeout. > >ditto here, better round up. Although I think using a completion could > >shorten the timeout considerably because there are often less than > >UART_XMIT_SIZE chars in the buffer?! > > I'm not really waiting the full timeout. I'm checking for TX fifo > empty every 1ms and for a maximum of 'to' ms. Correct. Still using DIV_ROUND_UP would be better, right? Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ | -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-02 8:30 ` Uwe Kleine-König @ 2013-10-02 8:46 ` Hector Palacios 2013-10-02 9:59 ` Uwe Kleine-König 0 siblings, 1 reply; 12+ messages in thread From: Hector Palacios @ 2013-10-02 8:46 UTC (permalink / raw) To: Uwe Kleine-König Cc: fabio.estevam@freescale.com, marex@denx.de, gregkh@linuxfoundation.org, b32955@freescale.com, linux-serial@vger.kernel.org, shawn.guo@linaro.org, Jiri Slaby, linux-arm-kernel@lists.infradead.org Hi Uwe, On 10/02/2013 10:30 AM, Uwe Kleine-König wrote: > Hello Hector, > > On Wed, Oct 02, 2013 at 10:09:10AM +0200, Hector Palacios wrote: >> On 10/02/2013 09:44 AM, Uwe Kleine-König wrote: >>> On Wed, Oct 02, 2013 at 09:31:16AM +0200, Hector Palacios wrote: >>>> On 10/01/2013 09:48 PM, Uwe Kleine-König wrote: >>>>> On Tue, Oct 01, 2013 at 06:18:35PM +0200, Hector Palacios wrote: >>>>>> + /* Wait enough time to flush DMA buffer completely */ >>>>>> + to = u->timeout * UART_XMIT_SIZE / u->fifosize; >>>>> u->timeout is the time needed to send one char, right? UART_XMIT_SIZE is >>>>> the size of the circular buffer, fifosize is the size of the fifo. I >>>>> don't get what you get by dividing by the fifosize. I would have >>>>> expected something like: >>>>> >>>>> u->timeout * min(UART_XMIT_SIZE, u->fifosize) >>>>> >>>>> Can you explain, maybe in a comment along the code for the next person >>>>> not understanding? >>>> >>>> u->timeout is *not* the time needed to send one char but the time >>>> needed to flush the complete port fifo (see uart_update_timeout() in >>>> serial_core.c where it is set). >>> Ah, right. (BTW, uart_update_timeout should better round up instead of >>> round down, i.e. >>> - port->timeout = (HZ * bits) / baud + HZ/50; >>> + port->timeout = DIV_ROUND_UP(HZ * bits, baud) + HZ/50; >>> ) >>> >>>> UART_XMIT_SIZE is the number of bytes in the DMA buffer, so I divide >>>> the max number of bytes in the FIFO by the FIFO size and multiply by >>>> the FIFO timeout. >>> ditto here, better round up. Although I think using a completion could >>> shorten the timeout considerably because there are often less than >>> UART_XMIT_SIZE chars in the buffer?! >> >> I'm not really waiting the full timeout. I'm checking for TX fifo >> empty every 1ms and for a maximum of 'to' ms. > Correct. Still using DIV_ROUND_UP would be better, right? I think it is not really needed, after all the code is adding HZ/50 of slop which acts like a round up, doesn't it? /* * Figure the timeout to send the above number of bits. * Add .02 seconds of slop */ port->timeout = (HZ * bits) / baud + HZ/50; Best regards, -- Hector Palacios -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-02 8:46 ` Hector Palacios @ 2013-10-02 9:59 ` Uwe Kleine-König 0 siblings, 0 replies; 12+ messages in thread From: Uwe Kleine-König @ 2013-10-02 9:59 UTC (permalink / raw) To: Hector Palacios Cc: fabio.estevam@freescale.com, marex@denx.de, gregkh@linuxfoundation.org, b32955@freescale.com, linux-serial@vger.kernel.org, shawn.guo@linaro.org, Jiri Slaby, linux-arm-kernel@lists.infradead.org Hi Hector, On Wed, Oct 02, 2013 at 10:46:28AM +0200, Hector Palacios wrote: > On 10/02/2013 10:30 AM, Uwe Kleine-König wrote: > >On Wed, Oct 02, 2013 at 10:09:10AM +0200, Hector Palacios wrote: > >>On 10/02/2013 09:44 AM, Uwe Kleine-König wrote: > >>>Ah, right. (BTW, uart_update_timeout should better round up instead of > >>>round down, i.e. > >>>- port->timeout = (HZ * bits) / baud + HZ/50; > >>>+ port->timeout = DIV_ROUND_UP(HZ * bits, baud) + HZ/50; > >>>) > >>> > >>>>UART_XMIT_SIZE is the number of bytes in the DMA buffer, so I divide > >>>>the max number of bytes in the FIFO by the FIFO size and multiply by > >>>>the FIFO timeout. > >>>ditto here, better round up. Although I think using a completion could > >>>shorten the timeout considerably because there are often less than > >>>UART_XMIT_SIZE chars in the buffer?! > >> > >>I'm not really waiting the full timeout. I'm checking for TX fifo > >>empty every 1ms and for a maximum of 'to' ms. > >Correct. Still using DIV_ROUND_UP would be better, right? > > I think it is not really needed, after all the code is adding HZ/50 > of slop which acts like a round up, doesn't it? > > /* > * Figure the timeout to send the above number of bits. > * Add .02 seconds of slop > */ > port->timeout = (HZ * bits) / baud + HZ/50; According to my understanding (which could well be wrong) the slop of HZ/50 isn't there to fix rounding issues in the previous division. But yes, if it's calculated generously there is no technical need to fix the rounding issue. Still it might be worth to fix it to be a better reference. I don't care much. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ | -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-02 7:31 ` Hector Palacios 2013-10-02 7:44 ` Uwe Kleine-König @ 2013-10-02 8:36 ` Uwe Kleine-König 2013-10-02 8:53 ` Hector Palacios 1 sibling, 1 reply; 12+ messages in thread From: Uwe Kleine-König @ 2013-10-02 8:36 UTC (permalink / raw) To: Hector Palacios Cc: linux-serial@vger.kernel.org, b32955@freescale.com, gregkh@linuxfoundation.org, shawn.guo@linaro.org, fabio.estevam@freescale.com, marex@denx.de Hello Hector, On Wed, Oct 02, 2013 at 09:31:16AM +0200, Hector Palacios wrote: > On 10/01/2013 09:48 PM, Uwe Kleine-König wrote: > >Hello Hector, > > > >On Tue, Oct 01, 2013 at 06:18:35PM +0200, Hector Palacios wrote: > >>The shutdown function was not waiting for the DMA buffer to flush > >>before disabling the AUART. This lead to many bytes not being > >>transferred (specially at low baudrates), as they were still in the > >>DMA buffer when the AUART was shutdown. > >>This patch also adds the check for the BUSY flag. > >> > >>Signed-off-by: Hector Palacios <hector.palacios@digi.com> > >>--- > >> drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++- > >> 1 file changed, 15 insertions(+), 1 deletion(-) > >> > >>diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c > >>index f85b8e6..0d8b2ca 100644 > >>--- a/drivers/tty/serial/mxs-auart.c > >>+++ b/drivers/tty/serial/mxs-auart.c > >>@@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u) > >> return 0; > >> } > >> > >>+static unsigned int mxs_auart_tx_empty(struct uart_port *u); > >>+ > >> static void mxs_auart_shutdown(struct uart_port *u) > >> { > >> struct mxs_auart_port *s = to_auart_port(u); > >>+ unsigned int to; > >>+ > >>+ if (auart_dma_enabled(s)) { > >>+ /* Wait enough time to flush DMA buffer completely */ > >>+ to = u->timeout * UART_XMIT_SIZE / u->fifosize; > >u->timeout is the time needed to send one char, right? UART_XMIT_SIZE is > >the size of the circular buffer, fifosize is the size of the fifo. I > >don't get what you get by dividing by the fifosize. I would have > >expected something like: > > > > u->timeout * min(UART_XMIT_SIZE, u->fifosize) > > > >Can you explain, maybe in a comment along the code for the next person > >not understanding? > > u->timeout is *not* the time needed to send one char but the time > needed to flush the complete port fifo (see uart_update_timeout() in > serial_core.c where it is set). > UART_XMIT_SIZE is the number of bytes in the DMA buffer, so I divide > the max number of bytes in the FIFO by the FIFO size and multiply by > the FIFO timeout. Another thought: Does that mean that from the framework's POV the fifosize is UART_XMIT_SIZE instead in the DMA case? That would enable you to just use u->timeout. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ | -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-02 8:36 ` Uwe Kleine-König @ 2013-10-02 8:53 ` Hector Palacios 0 siblings, 0 replies; 12+ messages in thread From: Hector Palacios @ 2013-10-02 8:53 UTC (permalink / raw) To: Uwe Kleine-König Cc: linux-serial@vger.kernel.org, b32955@freescale.com, gregkh@linuxfoundation.org, shawn.guo@linaro.org, fabio.estevam@freescale.com, marex@denx.de, Jiri Slaby, linux-arm-kernel@lists.infradead.org On 10/02/2013 10:36 AM, Uwe Kleine-König wrote: > Hello Hector, > > On Wed, Oct 02, 2013 at 09:31:16AM +0200, Hector Palacios wrote: >> On 10/01/2013 09:48 PM, Uwe Kleine-König wrote: >>> Hello Hector, >>> >>> On Tue, Oct 01, 2013 at 06:18:35PM +0200, Hector Palacios wrote: >>>> The shutdown function was not waiting for the DMA buffer to flush >>>> before disabling the AUART. This lead to many bytes not being >>>> transferred (specially at low baudrates), as they were still in the >>>> DMA buffer when the AUART was shutdown. >>>> This patch also adds the check for the BUSY flag. >>>> >>>> Signed-off-by: Hector Palacios <hector.palacios@digi.com> >>>> --- >>>> drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++- >>>> 1 file changed, 15 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c >>>> index f85b8e6..0d8b2ca 100644 >>>> --- a/drivers/tty/serial/mxs-auart.c >>>> +++ b/drivers/tty/serial/mxs-auart.c >>>> @@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u) >>>> return 0; >>>> } >>>> >>>> +static unsigned int mxs_auart_tx_empty(struct uart_port *u); >>>> + >>>> static void mxs_auart_shutdown(struct uart_port *u) >>>> { >>>> struct mxs_auart_port *s = to_auart_port(u); >>>> + unsigned int to; >>>> + >>>> + if (auart_dma_enabled(s)) { >>>> + /* Wait enough time to flush DMA buffer completely */ >>>> + to = u->timeout * UART_XMIT_SIZE / u->fifosize; >>> u->timeout is the time needed to send one char, right? UART_XMIT_SIZE is >>> the size of the circular buffer, fifosize is the size of the fifo. I >>> don't get what you get by dividing by the fifosize. I would have >>> expected something like: >>> >>> u->timeout * min(UART_XMIT_SIZE, u->fifosize) >>> >>> Can you explain, maybe in a comment along the code for the next person >>> not understanding? >> >> u->timeout is *not* the time needed to send one char but the time >> needed to flush the complete port fifo (see uart_update_timeout() in >> serial_core.c where it is set). >> UART_XMIT_SIZE is the number of bytes in the DMA buffer, so I divide >> the max number of bytes in the FIFO by the FIFO size and multiply by >> the FIFO timeout. > Another thought: Does that mean that from the framework's POV the > fifosize is UART_XMIT_SIZE instead in the DMA case? That would enable > you to just use u->timeout. Hum, I think you hit the point. I just saw they do this in amba_pl011.c driver: /* The DMA buffer is now the FIFO the TTY subsystem can use */ uap->port.fifosize = PL011_DMA_BUFFER_SIZE; I'll rework the patch and try. Best regards, -- Hector Palacios -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-01 16:18 [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown Hector Palacios 2013-10-01 19:48 ` Uwe Kleine-König @ 2013-10-01 19:56 ` Marek Vasut 2013-10-02 8:24 ` Hector Palacios 2 siblings, 0 replies; 12+ messages in thread From: Marek Vasut @ 2013-10-01 19:56 UTC (permalink / raw) To: Hector Palacios Cc: linux-serial, u.kleine-koenig, b32955, gregkh, shawn.guo, fabio.estevam Dear Hector Palacios, > The shutdown function was not waiting for the DMA buffer to flush > before disabling the AUART. This lead to many bytes not being > transferred (specially at low baudrates), as they were still in the > DMA buffer when the AUART was shutdown. > This patch also adds the check for the BUSY flag. > > Signed-off-by: Hector Palacios <hector.palacios@digi.com> > > https://jira.digi.com/browse/DEL-616 The link doesn't work. Otherwise makes sense Reviewed-by: Marek Vasut <marex@denx.de> > --- > drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) > > diff --git a/drivers/tty/serial/mxs-auart.c > b/drivers/tty/serial/mxs-auart.c index f85b8e6..0d8b2ca 100644 > --- a/drivers/tty/serial/mxs-auart.c > +++ b/drivers/tty/serial/mxs-auart.c > @@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u) > return 0; > } > > +static unsigned int mxs_auart_tx_empty(struct uart_port *u); > + > static void mxs_auart_shutdown(struct uart_port *u) > { > struct mxs_auart_port *s = to_auart_port(u); > + unsigned int to; > + > + if (auart_dma_enabled(s)) { > + /* Wait enough time to flush DMA buffer completely */ > + to = u->timeout * UART_XMIT_SIZE / u->fifosize; > + while (!mxs_auart_tx_empty(u) && to--) > + mdelay(1); > > - if (auart_dma_enabled(s)) > mxs_auart_dma_exit(s); > + } > + > + /* Wait for transmitter to become empty ... */ > + to = u->timeout; > + while ((readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) && to--) > + mdelay(1); > > writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); Best regards, Marek Vasut ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown 2013-10-01 16:18 [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown Hector Palacios 2013-10-01 19:48 ` Uwe Kleine-König 2013-10-01 19:56 ` Marek Vasut @ 2013-10-02 8:24 ` Hector Palacios 2 siblings, 0 replies; 12+ messages in thread From: Hector Palacios @ 2013-10-02 8:24 UTC (permalink / raw) To: linux-serial@vger.kernel.org Cc: u.kleine-koenig@pengutronix.de, b32955@freescale.com, gregkh@linuxfoundation.org, shawn.guo@linaro.org, fabio.estevam@freescale.com, marex@denx.de On 10/01/2013 06:18 PM, Hector Palacios wrote: > The shutdown function was not waiting for the DMA buffer to flush > before disabling the AUART. This lead to many bytes not being > transferred (specially at low baudrates), as they were still in the > DMA buffer when the AUART was shutdown. > This patch also adds the check for the BUSY flag. > > Signed-off-by: Hector Palacios <hector.palacios@digi.com> > > https://jira.digi.com/browse/DEL-616 > --- > drivers/tty/serial/mxs-auart.c | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) > > diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c > index f85b8e6..0d8b2ca 100644 > --- a/drivers/tty/serial/mxs-auart.c > +++ b/drivers/tty/serial/mxs-auart.c > @@ -750,12 +750,26 @@ static int mxs_auart_startup(struct uart_port *u) > return 0; > } > > +static unsigned int mxs_auart_tx_empty(struct uart_port *u); > + > static void mxs_auart_shutdown(struct uart_port *u) > { > struct mxs_auart_port *s = to_auart_port(u); > + unsigned int to; > + > + if (auart_dma_enabled(s)) { > + /* Wait enough time to flush DMA buffer completely */ > + to = u->timeout * UART_XMIT_SIZE / u->fifosize; > + while (!mxs_auart_tx_empty(u) && to--) > + mdelay(1); > > - if (auart_dma_enabled(s)) > mxs_auart_dma_exit(s); > + } > + > + /* Wait for transmitter to become empty ... */ > + to = u->timeout; > + while ((readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) && to--) Just noticed a bug. It should be u->membase. I'll fix it in V2. Best regards, -- Hector Palacios ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-10-02 9:59 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-10-01 16:18 [PATCH] serial: mxs-auart: wait for DMA buffer to flush before shutdown Hector Palacios 2013-10-01 19:48 ` Uwe Kleine-König 2013-10-02 7:31 ` Hector Palacios 2013-10-02 7:44 ` Uwe Kleine-König 2013-10-02 8:09 ` Hector Palacios 2013-10-02 8:30 ` Uwe Kleine-König 2013-10-02 8:46 ` Hector Palacios 2013-10-02 9:59 ` Uwe Kleine-König 2013-10-02 8:36 ` Uwe Kleine-König 2013-10-02 8:53 ` Hector Palacios 2013-10-01 19:56 ` Marek Vasut 2013-10-02 8:24 ` Hector Palacios
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).