* [PATCH 1/7] serial: imx: only set DMA rx-ing when DMA starts
2017-06-30 12:04 [PATCH 0/7] serial: imx: various improvements Romain Perier
@ 2017-06-30 12:04 ` Romain Perier
2017-07-03 6:48 ` Uwe Kleine-König
2017-06-30 12:04 ` [PATCH 2/7] serial: imx: move log from error to debug type Romain Perier
` (5 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Romain Perier @ 2017-06-30 12:04 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-serial, linux-arm-kernel, linux-kernel, Nandor Han, Romain Perier
From: Nandor Han <nandor.han@ge.com>
Avoid the situation when `dma_is_rxing` could incorrectly signal that
DMA RX channel is receiving data in case DMA preparation or sg mapping
fails.
Signed-off-by: Nandor Han <nandor.han@ge.com>
Signed-off-by: Romain Perier <romain.perier@collabora.com>
---
drivers/tty/serial/imx.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 5437b34..1d35293 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -725,11 +725,11 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void imx_disable_rx_int(struct imx_port *sport)
+static void imx_disable_rx_int(struct imx_port *sport, bool is_rxing)
{
unsigned long temp;
- sport->dma_is_rxing = 1;
+ sport->dma_is_rxing = is_rxing;
/* disable the receiver ready and aging timer interrupts */
temp = readl(sport->port.membase + UCR1);
@@ -762,7 +762,7 @@ static void imx_dma_rxint(struct imx_port *sport)
temp = readl(sport->port.membase + USR2);
if ((temp & USR2_RDR) && !sport->dma_is_rxing) {
- imx_disable_rx_int(sport);
+ imx_disable_rx_int(sport, false);
/* tell the DMA to receive the data. */
start_rx_dma(sport);
@@ -1083,6 +1083,7 @@ static int start_rx_dma(struct imx_port *sport)
desc->callback_param = sport;
dev_dbg(dev, "RX: prepare for the DMA.\n");
+ sport->dma_is_rxing = 1;
sport->rx_cookie = dmaengine_submit(desc);
dma_async_issue_pending(chan);
return 0;
@@ -1362,7 +1363,7 @@ static int imx_startup(struct uart_port *port)
spin_unlock(&tty->files_lock);
if (readcnt > 0) {
- imx_disable_rx_int(sport);
+ imx_disable_rx_int(sport, true);
start_rx_dma(sport);
}
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 1/7] serial: imx: only set DMA rx-ing when DMA starts
2017-06-30 12:04 ` [PATCH 1/7] serial: imx: only set DMA rx-ing when DMA starts Romain Perier
@ 2017-07-03 6:48 ` Uwe Kleine-König
2017-07-04 8:55 ` Romain Perier
0 siblings, 1 reply; 19+ messages in thread
From: Uwe Kleine-König @ 2017-07-03 6:48 UTC (permalink / raw)
To: Romain Perier
Cc: Greg Kroah-Hartman, Nandor Han, linux-arm-kernel, linux-serial,
linux-kernel
Hello,
On Fri, Jun 30, 2017 at 02:04:40PM +0200, Romain Perier wrote:
> From: Nandor Han <nandor.han@ge.com>
>
> Avoid the situation when `dma_is_rxing` could incorrectly signal that
> DMA RX channel is receiving data in case DMA preparation or sg mapping
> fails.
Just from reading the commit log and the patch I didn't understand the
problem that is supposed to be fixed here. After looking at it for some
I understood. I don't suggest a new commit log here as it has to look
different if you pick up my comment below.
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 5437b34..1d35293 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -725,11 +725,11 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
> return IRQ_HANDLED;
> }
>
> -static void imx_disable_rx_int(struct imx_port *sport)
> +static void imx_disable_rx_int(struct imx_port *sport, bool is_rxing)
> {
> unsigned long temp;
>
> - sport->dma_is_rxing = 1;
> + sport->dma_is_rxing = is_rxing;
>
> /* disable the receiver ready and aging timer interrupts */
> temp = readl(sport->port.membase + UCR1);
> @@ -762,7 +762,7 @@ static void imx_dma_rxint(struct imx_port *sport)
> temp = readl(sport->port.membase + USR2);
> if ((temp & USR2_RDR) && !sport->dma_is_rxing) {
>
> - imx_disable_rx_int(sport);
> + imx_disable_rx_int(sport, false);
>
> /* tell the DMA to receive the data. */
> start_rx_dma(sport);
> @@ -1083,6 +1083,7 @@ static int start_rx_dma(struct imx_port *sport)
> desc->callback_param = sport;
>
> dev_dbg(dev, "RX: prepare for the DMA.\n");
> + sport->dma_is_rxing = 1;
> sport->rx_cookie = dmaengine_submit(desc);
> dma_async_issue_pending(chan);
> return 0;
> @@ -1362,7 +1363,7 @@ static int imx_startup(struct uart_port *port)
> spin_unlock(&tty->files_lock);
>
> if (readcnt > 0) {
> - imx_disable_rx_int(sport);
> + imx_disable_rx_int(sport, true);
I wonder if it would be saner to not assign to dma_is_rxing in
imx_disable_rx_int() at all but do this only in start_rx_dma() and
imx_dma_rxint().
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/7] serial: imx: only set DMA rx-ing when DMA starts
2017-07-03 6:48 ` Uwe Kleine-König
@ 2017-07-04 8:55 ` Romain Perier
0 siblings, 0 replies; 19+ messages in thread
From: Romain Perier @ 2017-07-04 8:55 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Greg Kroah-Hartman, Nandor Han, linux-arm-kernel, linux-serial,
linux-kernel
Hello,
Le 03/07/2017 à 08:48, Uwe Kleine-König a écrit :
> Hello,
>
> On Fri, Jun 30, 2017 at 02:04:40PM +0200, Romain Perier wrote:
>> From: Nandor Han <nandor.han@ge.com>
>>
>> Avoid the situation when `dma_is_rxing` could incorrectly signal that
>> DMA RX channel is receiving data in case DMA preparation or sg mapping
>> fails.
> Just from reading the commit log and the patch I didn't understand the
> problem that is supposed to be fixed here. After looking at it for some
> I understood. I don't suggest a new commit log here as it has to look
> different if you pick up my comment below.
>
>> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
>> index 5437b34..1d35293 100644
>> --- a/drivers/tty/serial/imx.c
>> +++ b/drivers/tty/serial/imx.c
>> @@ -725,11 +725,11 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
>> return IRQ_HANDLED;
>> }
>>
>> -static void imx_disable_rx_int(struct imx_port *sport)
>> +static void imx_disable_rx_int(struct imx_port *sport, bool is_rxing)
>> {
>> unsigned long temp;
>>
>> - sport->dma_is_rxing = 1;
>> + sport->dma_is_rxing = is_rxing;
>>
>> /* disable the receiver ready and aging timer interrupts */
>> temp = readl(sport->port.membase + UCR1);
>> @@ -762,7 +762,7 @@ static void imx_dma_rxint(struct imx_port *sport)
>> temp = readl(sport->port.membase + USR2);
>> if ((temp & USR2_RDR) && !sport->dma_is_rxing) {
>>
>> - imx_disable_rx_int(sport);
>> + imx_disable_rx_int(sport, false);
>>
>> /* tell the DMA to receive the data. */
>> start_rx_dma(sport);
>> @@ -1083,6 +1083,7 @@ static int start_rx_dma(struct imx_port *sport)
>> desc->callback_param = sport;
>>
>> dev_dbg(dev, "RX: prepare for the DMA.\n");
>> + sport->dma_is_rxing = 1;
>> sport->rx_cookie = dmaengine_submit(desc);
>> dma_async_issue_pending(chan);
>> return 0;
>> @@ -1362,7 +1363,7 @@ static int imx_startup(struct uart_port *port)
>> spin_unlock(&tty->files_lock);
>>
>> if (readcnt > 0) {
>> - imx_disable_rx_int(sport);
>> + imx_disable_rx_int(sport, true);
> I wonder if it would be saner to not assign to dma_is_rxing in
> imx_disable_rx_int() at all but do this only in start_rx_dma() and
> imx_dma_rxint().
It was "mostly" done, in 4.11 in fact. dma_is_rxing was set to 0 from
imx_dma_rxint() and was not set
at all from start_rx_dma(), resulting to the same issue. We could move
assignment of dma_is_rxing out of imx_disable_rx_int()
and set it to one from start_rx_dma() only. What do you think ?
Best Regards,
Romain
>
> Best regards
> Uwe
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 2/7] serial: imx: move log from error to debug type
2017-06-30 12:04 [PATCH 0/7] serial: imx: various improvements Romain Perier
2017-06-30 12:04 ` [PATCH 1/7] serial: imx: only set DMA rx-ing when DMA starts Romain Perier
@ 2017-06-30 12:04 ` Romain Perier
2017-07-03 6:50 ` Uwe Kleine-König
2017-06-30 12:04 ` [PATCH 3/7] serial: imx: init dma_is_{rx|tx}ing variables Romain Perier
` (4 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Romain Perier @ 2017-06-30 12:04 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-serial, linux-arm-kernel, linux-kernel, Nandor Han, Romain Perier
From: Nandor Han <nandor.han@ge.com>
During DMA startup we have a data race condition since UART port can
receive data that can generate different type of errors.
This is not necessarily an error since DMA didn't yet started. The
situation is minimized but still present even if we try to clear up the
error before starting the DMA.
Therefore changing the log to debug type we avoid having "false" error
messages.
Signed-off-by: Nandor Han <nandor.han@ge.com>
Signed-off-by: Romain Perier <romain.perier@collabora.com>
---
drivers/tty/serial/imx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 1d35293..188063d 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -994,7 +994,7 @@ static void dma_rx_callback(void *data)
status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state);
if (status == DMA_ERROR) {
- dev_err(sport->port.dev, "DMA transaction error.\n");
+ dev_dbg(sport->port.dev, "DMA transaction error.\n");
clear_rx_errors(sport);
return;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 2/7] serial: imx: move log from error to debug type
2017-06-30 12:04 ` [PATCH 2/7] serial: imx: move log from error to debug type Romain Perier
@ 2017-07-03 6:50 ` Uwe Kleine-König
0 siblings, 0 replies; 19+ messages in thread
From: Uwe Kleine-König @ 2017-07-03 6:50 UTC (permalink / raw)
To: Romain Perier
Cc: Greg Kroah-Hartman, Nandor Han, linux-arm-kernel, linux-serial,
linux-kernel
On Fri, Jun 30, 2017 at 02:04:41PM +0200, Romain Perier wrote:
> From: Nandor Han <nandor.han@ge.com>
>
> During DMA startup we have a data race condition since UART port can
> receive data that can generate different type of errors.
>
> This is not necessarily an error since DMA didn't yet started. The
> situation is minimized but still present even if we try to clear up the
> error before starting the DMA.
>
> Therefore changing the log to debug type we avoid having "false" error
> messages.
This doesn't look right. You say the message "DMA transaction error." is
wrong sometimes and so hide it a bit by using dev_dbg instead of
dev_err.
I don't like that.
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/7] serial: imx: init dma_is_{rx|tx}ing variables
2017-06-30 12:04 [PATCH 0/7] serial: imx: various improvements Romain Perier
2017-06-30 12:04 ` [PATCH 1/7] serial: imx: only set DMA rx-ing when DMA starts Romain Perier
2017-06-30 12:04 ` [PATCH 2/7] serial: imx: move log from error to debug type Romain Perier
@ 2017-06-30 12:04 ` Romain Perier
2017-06-30 12:13 ` Lothar Waßmann
2017-06-30 12:04 ` [PATCH 4/7] serial: imx: Simplify DMA disablement Romain Perier
` (3 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Romain Perier @ 2017-06-30 12:04 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-serial, linux-arm-kernel, linux-kernel, Nandor Han, Romain Perier
From: Nandor Han <nandor.han@ge.com>
Initialize both dma_is_{rx|tx}ing variables when DMA is enabled to avoid
checking uninitialized variables if port shutdown is requested before
DMA channels get a chance to start.
Signed-off-by: Nandor Han <nandor.han@ge.com>
Signed-off-by: Romain Perier <romain.perier@collabora.com>
---
drivers/tty/serial/imx.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 188063d..81fb413 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1225,6 +1225,9 @@ static void imx_enable_dma(struct imx_port *sport)
imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA);
+ sport->dma_is_rxing = 0;
+ sport->dma_is_txing = 0;
+
sport->dma_is_enabled = 1;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] serial: imx: init dma_is_{rx|tx}ing variables
2017-06-30 12:04 ` [PATCH 3/7] serial: imx: init dma_is_{rx|tx}ing variables Romain Perier
@ 2017-06-30 12:13 ` Lothar Waßmann
2017-07-03 6:52 ` Uwe Kleine-König
0 siblings, 1 reply; 19+ messages in thread
From: Lothar Waßmann @ 2017-06-30 12:13 UTC (permalink / raw)
To: Romain Perier
Cc: Greg Kroah-Hartman, Nandor Han, linux-arm-kernel, linux-serial,
linux-kernel
Hi,
On Fri, 30 Jun 2017 14:04:42 +0200 Romain Perier wrote:
> From: Nandor Han <nandor.han@ge.com>
>
> Initialize both dma_is_{rx|tx}ing variables when DMA is enabled to avoid
> checking uninitialized variables if port shutdown is requested before
> DMA channels get a chance to start.
>
> Signed-off-by: Nandor Han <nandor.han@ge.com>
> Signed-off-by: Romain Perier <romain.perier@collabora.com>
> ---
> drivers/tty/serial/imx.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 188063d..81fb413 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -1225,6 +1225,9 @@ static void imx_enable_dma(struct imx_port *sport)
>
> imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA);
>
> + sport->dma_is_rxing = 0;
> + sport->dma_is_txing = 0;
> +
> sport->dma_is_enabled = 1;
> }
>
sport is devm_kzalloc()ed, so the variables are initialized to 0 anyway.
Lothar Waßmann
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] serial: imx: init dma_is_{rx|tx}ing variables
2017-06-30 12:13 ` Lothar Waßmann
@ 2017-07-03 6:52 ` Uwe Kleine-König
2017-07-05 10:14 ` Romain Perier
0 siblings, 1 reply; 19+ messages in thread
From: Uwe Kleine-König @ 2017-07-03 6:52 UTC (permalink / raw)
To: Romain Perier
Cc: Lothar Waßmann, Greg Kroah-Hartman, Nandor Han,
linux-arm-kernel, linux-serial, linux-kernel
On Fri, Jun 30, 2017 at 02:13:29PM +0200, Lothar Waßmann wrote:
> Hi,
>
> On Fri, 30 Jun 2017 14:04:42 +0200 Romain Perier wrote:
> > From: Nandor Han <nandor.han@ge.com>
> >
> > Initialize both dma_is_{rx|tx}ing variables when DMA is enabled to avoid
> > checking uninitialized variables if port shutdown is requested before
> > DMA channels get a chance to start.
> >
> > Signed-off-by: Nandor Han <nandor.han@ge.com>
> > Signed-off-by: Romain Perier <romain.perier@collabora.com>
> > ---
> > drivers/tty/serial/imx.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> > index 188063d..81fb413 100644
> > --- a/drivers/tty/serial/imx.c
> > +++ b/drivers/tty/serial/imx.c
> > @@ -1225,6 +1225,9 @@ static void imx_enable_dma(struct imx_port *sport)
> >
> > imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA);
> >
> > + sport->dma_is_rxing = 0;
> > + sport->dma_is_txing = 0;
> > +
> > sport->dma_is_enabled = 1;
> > }
> >
> sport is devm_kzalloc()ed, so the variables are initialized to 0 anyway.
I'd agree to Lothar's statement. Did you find this issue by inspection,
or does it fix a compiler warning? Do you think there is an actual
problem?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] serial: imx: init dma_is_{rx|tx}ing variables
2017-07-03 6:52 ` Uwe Kleine-König
@ 2017-07-05 10:14 ` Romain Perier
2017-07-05 11:58 ` Uwe Kleine-König
0 siblings, 1 reply; 19+ messages in thread
From: Romain Perier @ 2017-07-05 10:14 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Lothar Waßmann, Greg Kroah-Hartman, Nandor Han,
linux-arm-kernel, linux-serial, linux-kernel
Hello,
Le 03/07/2017 à 08:52, Uwe Kleine-König a écrit :
> On Fri, Jun 30, 2017 at 02:13:29PM +0200, Lothar Waßmann wrote:
>> Hi,
>>
>> On Fri, 30 Jun 2017 14:04:42 +0200 Romain Perier wrote:
>>> From: Nandor Han <nandor.han@ge.com>
>>>
>>> Initialize both dma_is_{rx|tx}ing variables when DMA is enabled to avoid
>>> checking uninitialized variables if port shutdown is requested before
>>> DMA channels get a chance to start.
>>>
>>> Signed-off-by: Nandor Han <nandor.han@ge.com>
>>> Signed-off-by: Romain Perier <romain.perier@collabora.com>
>>> ---
>>> drivers/tty/serial/imx.c | 3 +++
>>> 1 file changed, 3 insertions(+)
>>>
>>> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
>>> index 188063d..81fb413 100644
>>> --- a/drivers/tty/serial/imx.c
>>> +++ b/drivers/tty/serial/imx.c
>>> @@ -1225,6 +1225,9 @@ static void imx_enable_dma(struct imx_port *sport)
>>>
>>> imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA);
>>>
>>> + sport->dma_is_rxing = 0;
>>> + sport->dma_is_txing = 0;
>>> +
>>> sport->dma_is_enabled = 1;
>>> }
>>>
>> sport is devm_kzalloc()ed, so the variables are initialized to 0 anyway.
> I'd agree to Lothar's statement. Did you find this issue by inspection,
> or does it fix a compiler warning? Do you think there is an actual
> problem?
>
> Best regards
> Uwe
>
What does happen if the UART port is shutdown and then re-enabled ? I
don't think that kzalloc will work in this case
Regards,
Romain
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] serial: imx: init dma_is_{rx|tx}ing variables
2017-07-05 10:14 ` Romain Perier
@ 2017-07-05 11:58 ` Uwe Kleine-König
0 siblings, 0 replies; 19+ messages in thread
From: Uwe Kleine-König @ 2017-07-05 11:58 UTC (permalink / raw)
To: Romain Perier
Cc: Greg Kroah-Hartman, linux-kernel, linux-serial, Nandor Han,
linux-arm-kernel, Lothar Waßmann
Hello Romain,
On Wed, Jul 05, 2017 at 12:14:57PM +0200, Romain Perier wrote:
> Le 03/07/2017 à 08:52, Uwe Kleine-König a écrit :
> > On Fri, Jun 30, 2017 at 02:13:29PM +0200, Lothar Waßmann wrote:
> >> On Fri, 30 Jun 2017 14:04:42 +0200 Romain Perier wrote:
> >>> From: Nandor Han <nandor.han@ge.com>
> >>>
> >>> Initialize both dma_is_{rx|tx}ing variables when DMA is enabled to avoid
> >>> checking uninitialized variables if port shutdown is requested before
> >>> DMA channels get a chance to start.
> >>>
> >>> Signed-off-by: Nandor Han <nandor.han@ge.com>
> >>> Signed-off-by: Romain Perier <romain.perier@collabora.com>
> >>> ---
> >>> drivers/tty/serial/imx.c | 3 +++
> >>> 1 file changed, 3 insertions(+)
> >>>
> >>> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> >>> index 188063d..81fb413 100644
> >>> --- a/drivers/tty/serial/imx.c
> >>> +++ b/drivers/tty/serial/imx.c
> >>> @@ -1225,6 +1225,9 @@ static void imx_enable_dma(struct imx_port *sport)
> >>>
> >>> imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA);
> >>>
> >>> + sport->dma_is_rxing = 0;
> >>> + sport->dma_is_txing = 0;
> >>> +
> >>> sport->dma_is_enabled = 1;
> >>> }
> >>>
> >> sport is devm_kzalloc()ed, so the variables are initialized to 0 anyway.
> > I'd agree to Lothar's statement. Did you find this issue by inspection,
> > or does it fix a compiler warning? Do you think there is an actual
> > problem?
> >
> > Best regards
> > Uwe
> >
> What does happen if the UART port is shutdown and then re-enabled ? I
> don't think that kzalloc will work in this case
imx_shutdown has:
if (sport->dma_is_enabled) {
sport->dma_is_rxing = 0;
sport->dma_is_txing = 0;
which might be good enough. Can dma_is_[rt]xing be != 0 if
dma_is_enabled is false? It seems it cannot, the only place where
dma_is_enabled is set to 0 (apart from the kzalloc where dma_is_[rt]xing
is set to zero) is imx_disable_dma(). The only caller sets both
dma_is_[rt]xing to zero before.
So this patch should be dropped or its commit log improved to point out
the actual problem.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 4/7] serial: imx: Simplify DMA disablement
2017-06-30 12:04 [PATCH 0/7] serial: imx: various improvements Romain Perier
` (2 preceding siblings ...)
2017-06-30 12:04 ` [PATCH 3/7] serial: imx: init dma_is_{rx|tx}ing variables Romain Perier
@ 2017-06-30 12:04 ` Romain Perier
2017-07-03 6:58 ` Uwe Kleine-König
2017-06-30 12:04 ` [PATCH 5/7] serial: imx: umap sg buffers when DMA channel is released Romain Perier
` (2 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Romain Perier @ 2017-06-30 12:04 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-serial, linux-arm-kernel, linux-kernel, Nandor Han, Romain Perier
From: Nandor Han <nandor.han@ge.com>
This commits simplify the function imx_disable_dma() by moving
the code for disabling RX and TX DMAs to dedicated functions.
Also move away CTSC and CTS as this is not related to DMA.
Signed-off-by: Nandor Han <nandor.han@ge.com>
Signed-off-by: Romain Perier <romain.perier@collabora.com>
---
drivers/tty/serial/imx.c | 31 ++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 81fb413..e8cf7cf 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1208,6 +1208,24 @@ static int imx_uart_dma_init(struct imx_port *sport)
return ret;
}
+static void imx_stop_tx_dma(struct imx_port *sport)
+{
+ unsigned long temp;
+
+ temp = readl(sport->port.membase + UCR1);
+ temp &= ~UCR1_TDMAEN;
+ writel(temp, sport->port.membase + UCR1);
+}
+
+static void imx_stop_rx_dma(struct imx_port *sport)
+{
+ unsigned long temp;
+
+ temp = readl(sport->port.membase + UCR1);
+ temp &= ~(UCR1_RDMAEN | UCR1_ATDMAEN);
+ writel(temp, sport->port.membase + UCR1);
+}
+
static void imx_enable_dma(struct imx_port *sport)
{
unsigned long temp;
@@ -1233,17 +1251,8 @@ static void imx_enable_dma(struct imx_port *sport)
static void imx_disable_dma(struct imx_port *sport)
{
- unsigned long temp;
-
- /* clear UCR1 */
- temp = readl(sport->port.membase + UCR1);
- temp &= ~(UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN);
- writel(temp, sport->port.membase + UCR1);
-
- /* clear UCR2 */
- temp = readl(sport->port.membase + UCR2);
- temp &= ~(UCR2_CTSC | UCR2_CTS | UCR2_ATEN);
- writel(temp, sport->port.membase + UCR2);
+ imx_stop_rx_dma(sport);
+ imx_stop_tx_dma(sport);
imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 4/7] serial: imx: Simplify DMA disablement
2017-06-30 12:04 ` [PATCH 4/7] serial: imx: Simplify DMA disablement Romain Perier
@ 2017-07-03 6:58 ` Uwe Kleine-König
0 siblings, 0 replies; 19+ messages in thread
From: Uwe Kleine-König @ 2017-07-03 6:58 UTC (permalink / raw)
To: Romain Perier
Cc: Greg Kroah-Hartman, linux-serial, linux-arm-kernel, linux-kernel,
Nandor Han, kernel
On Fri, Jun 30, 2017 at 02:04:43PM +0200, Romain Perier wrote:
> From: Nandor Han <nandor.han@ge.com>
>
> This commits simplify the function imx_disable_dma() by moving
> the code for disabling RX and TX DMAs to dedicated functions.
I'd point out there that this prepares the next commit because in the
current state I'd prefer just improved comments.
> Also move away CTSC and CTS as this is not related to DMA.
Hmm, maybe this is related to the rs485 breakage we're seeing and
deserves a separate commit?
This also has the advantage that the refactoring change is semantically
a no-op.
> Signed-off-by: Nandor Han <nandor.han@ge.com>
> Signed-off-by: Romain Perier <romain.perier@collabora.com>
> ---
> drivers/tty/serial/imx.c | 31 ++++++++++++++++++++-----------
> 1 file changed, 20 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 81fb413..e8cf7cf 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -1208,6 +1208,24 @@ static int imx_uart_dma_init(struct imx_port *sport)
> return ret;
> }
>
> +static void imx_stop_tx_dma(struct imx_port *sport)
> +{
> + unsigned long temp;
> +
> + temp = readl(sport->port.membase + UCR1);
> + temp &= ~UCR1_TDMAEN;
> + writel(temp, sport->port.membase + UCR1);
> +}
> +
> +static void imx_stop_rx_dma(struct imx_port *sport)
> +{
> + unsigned long temp;
> +
> + temp = readl(sport->port.membase + UCR1);
> + temp &= ~(UCR1_RDMAEN | UCR1_ATDMAEN);
> + writel(temp, sport->port.membase + UCR1);
> +}
> +
> static void imx_enable_dma(struct imx_port *sport)
> {
> unsigned long temp;
> @@ -1233,17 +1251,8 @@ static void imx_enable_dma(struct imx_port *sport)
>
> static void imx_disable_dma(struct imx_port *sport)
> {
> - unsigned long temp;
> -
> - /* clear UCR1 */
> - temp = readl(sport->port.membase + UCR1);
> - temp &= ~(UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN);
> - writel(temp, sport->port.membase + UCR1);
> -
> - /* clear UCR2 */
> - temp = readl(sport->port.membase + UCR2);
> - temp &= ~(UCR2_CTSC | UCR2_CTS | UCR2_ATEN);
You also dropped clearing ATEN without mentioning that in the commit
log. Is this done on purpose?
> - writel(temp, sport->port.membase + UCR2);
> + imx_stop_rx_dma(sport);
> + imx_stop_tx_dma(sport);
>
> imx_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/7] serial: imx: umap sg buffers when DMA channel is released
2017-06-30 12:04 [PATCH 0/7] serial: imx: various improvements Romain Perier
` (3 preceding siblings ...)
2017-06-30 12:04 ` [PATCH 4/7] serial: imx: Simplify DMA disablement Romain Perier
@ 2017-06-30 12:04 ` Romain Perier
2017-07-03 7:01 ` Uwe Kleine-König
2017-06-30 12:04 ` [PATCH 6/7] serial: imx: update the stop rx,tx procedures Romain Perier
2017-06-30 12:04 ` [PATCH 7/7] serial: imx: Fix imx_shutdown procedure Romain Perier
6 siblings, 1 reply; 19+ messages in thread
From: Romain Perier @ 2017-06-30 12:04 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-serial, linux-arm-kernel, linux-kernel, Nandor Han, Romain Perier
From: Nandor Han <nandor.han@ge.com>
This commits unmaps sg buffers when the DMA channel is released
Signed-off-by: Nandor Han <nandor.han@ge.com>
Signed-off-by: Romain Perier <romain.perier@collabora.com>
---
drivers/tty/serial/imx.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index e8cf7cf..58d6b1c 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1215,6 +1215,12 @@ static void imx_stop_tx_dma(struct imx_port *sport)
temp = readl(sport->port.membase + UCR1);
temp &= ~UCR1_TDMAEN;
writel(temp, sport->port.membase + UCR1);
+
+ if (sport->dma_is_txing) {
+ dma_unmap_sg(sport->port.dev, &sport->tx_sgl[0],
+ sport->dma_tx_nents, DMA_TO_DEVICE);
+ sport->dma_is_txing = 0;
+ }
}
static void imx_stop_rx_dma(struct imx_port *sport)
@@ -1224,6 +1230,12 @@ static void imx_stop_rx_dma(struct imx_port *sport)
temp = readl(sport->port.membase + UCR1);
temp &= ~(UCR1_RDMAEN | UCR1_ATDMAEN);
writel(temp, sport->port.membase + UCR1);
+
+ if (sport->dma_is_rxing) {
+ dma_unmap_sg(sport->port.dev, &sport->rx_sgl, 1,
+ DMA_FROM_DEVICE);
+ sport->dma_is_rxing = 0;
+ }
}
static void imx_enable_dma(struct imx_port *sport)
--
1.8.3.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 5/7] serial: imx: umap sg buffers when DMA channel is released
2017-06-30 12:04 ` [PATCH 5/7] serial: imx: umap sg buffers when DMA channel is released Romain Perier
@ 2017-07-03 7:01 ` Uwe Kleine-König
0 siblings, 0 replies; 19+ messages in thread
From: Uwe Kleine-König @ 2017-07-03 7:01 UTC (permalink / raw)
To: Romain Perier
Cc: Greg Kroah-Hartman, linux-serial, linux-arm-kernel, linux-kernel,
Nandor Han
$Subject ~= s/umap/unmap/
On Fri, Jun 30, 2017 at 02:04:44PM +0200, Romain Perier wrote:
> From: Nandor Han <nandor.han@ge.com>
>
> This commits unmaps sg buffers when the DMA channel is released
>
> Signed-off-by: Nandor Han <nandor.han@ge.com>
> Signed-off-by: Romain Perier <romain.perier@collabora.com>
> ---
> drivers/tty/serial/imx.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index e8cf7cf..58d6b1c 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -1215,6 +1215,12 @@ static void imx_stop_tx_dma(struct imx_port *sport)
> temp = readl(sport->port.membase + UCR1);
> temp &= ~UCR1_TDMAEN;
> writel(temp, sport->port.membase + UCR1);
> +
> + if (sport->dma_is_txing) {
> + dma_unmap_sg(sport->port.dev, &sport->tx_sgl[0],
> + sport->dma_tx_nents, DMA_TO_DEVICE);
> + sport->dma_is_txing = 0;
You don't motivate setting dma_is_txing to zero in the commit log.
Does this mean the driver leaks memory in the current state?
> + }
> }
>
> static void imx_stop_rx_dma(struct imx_port *sport)
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 6/7] serial: imx: update the stop rx,tx procedures
2017-06-30 12:04 [PATCH 0/7] serial: imx: various improvements Romain Perier
` (4 preceding siblings ...)
2017-06-30 12:04 ` [PATCH 5/7] serial: imx: umap sg buffers when DMA channel is released Romain Perier
@ 2017-06-30 12:04 ` Romain Perier
2017-07-03 7:03 ` Uwe Kleine-König
2017-06-30 12:04 ` [PATCH 7/7] serial: imx: Fix imx_shutdown procedure Romain Perier
6 siblings, 1 reply; 19+ messages in thread
From: Romain Perier @ 2017-06-30 12:04 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-serial, linux-arm-kernel, linux-kernel, Nandor Han, Romain Perier
From: Nandor Han <nandor.han@ge.com>
According to "Documentation/serial/driver" both procedures should stop
receiving or sending data. Based on this the procedures should stop the
activity regardless if DMA is enabled or not.
This commit updates both imx_stop_{rx|tx} procedures to stop the
activity and disable the interrupts related to that. In case DMA is used
the sg buffers are also un-maped.
Signed-off-by: Nandor Han <nandor.han@ge.com>
Signed-off-by: Romain Perier <romain.perier@collabora.com>
---
drivers/tty/serial/imx.c | 39 ++++++++++++++++++++-------------------
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 58d6b1c..d5b6e09 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -360,6 +360,9 @@ static void imx_port_rts_auto(struct imx_port *sport, unsigned long *ucr2)
*ucr2 |= UCR2_CTSC;
}
+static void imx_stop_rx_dma(struct imx_port *sport);
+static void imx_stop_tx_dma(struct imx_port *sport);
+
/*
* interrupts disabled on entry
*/
@@ -368,15 +371,14 @@ static void imx_stop_tx(struct uart_port *port)
struct imx_port *sport = (struct imx_port *)port;
unsigned long temp;
- /*
- * We are maybe in the SMP context, so if the DMA TX thread is running
- * on other cpu, we have to wait for it to finish.
- */
- if (sport->dma_is_enabled && sport->dma_is_txing)
- return;
+ sport->tx_bytes = 0;
+
+ if (sport->dma_is_enabled)
+ imx_stop_tx_dma(sport);
temp = readl(port->membase + UCR1);
- writel(temp & ~UCR1_TXMPTYEN, port->membase + UCR1);
+ temp &= ~(UCR1_TXMPTYEN | UCR1_TRDYEN | UCR1_RTSDEN);
+ writel(temp, port->membase + UCR1);
/* in rs485 mode disable transmitter if shifter is empty */
if (port->rs485.flags & SER_RS485_ENABLED &&
@@ -403,21 +405,20 @@ static void imx_stop_rx(struct uart_port *port)
struct imx_port *sport = (struct imx_port *)port;
unsigned long temp;
- if (sport->dma_is_enabled && sport->dma_is_rxing) {
- if (sport->port.suspended) {
- dmaengine_terminate_all(sport->dma_chan_rx);
- sport->dma_is_rxing = 0;
- } else {
- return;
- }
- }
+ if (sport->dma_is_enabled)
+ imx_stop_rx_dma(sport);
+
+ temp = readl(sport->port.membase + UCR1);
+ temp &= ~UCR1_RRDYEN;
+ writel(temp, sport->port.membase + UCR1);
temp = readl(sport->port.membase + UCR2);
- writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2);
+ temp &= ~UCR2_ATEN;
+ writel(temp, sport->port.membase + UCR2);
- /* disable the `Receiver Ready Interrrupt` */
- temp = readl(sport->port.membase + UCR1);
- writel(temp & ~UCR1_RRDYEN, sport->port.membase + UCR1);
+ temp = readl(sport->port.membase + UCR3);
+ temp &= ~UCR3_AWAKEN;
+ writel(temp, sport->port.membase + UCR3);
}
/*
--
1.8.3.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 6/7] serial: imx: update the stop rx,tx procedures
2017-06-30 12:04 ` [PATCH 6/7] serial: imx: update the stop rx,tx procedures Romain Perier
@ 2017-07-03 7:03 ` Uwe Kleine-König
0 siblings, 0 replies; 19+ messages in thread
From: Uwe Kleine-König @ 2017-07-03 7:03 UTC (permalink / raw)
To: Romain Perier
Cc: Greg Kroah-Hartman, Nandor Han, linux-arm-kernel, linux-serial,
linux-kernel, kernel
On Fri, Jun 30, 2017 at 02:04:45PM +0200, Romain Perier wrote:
> From: Nandor Han <nandor.han@ge.com>
>
> According to "Documentation/serial/driver" both procedures should stop
> receiving or sending data. Based on this the procedures should stop the
> activity regardless if DMA is enabled or not.
>
> This commit updates both imx_stop_{rx|tx} procedures to stop the
> activity and disable the interrupts related to that. In case DMA is used
> the sg buffers are also un-maped.
This unmapping is implicit, becuae imx_stop_rx_dma unmaps since the
previous commit, right?
>
> Signed-off-by: Nandor Han <nandor.han@ge.com>
> Signed-off-by: Romain Perier <romain.perier@collabora.com>
> ---
> drivers/tty/serial/imx.c | 39 ++++++++++++++++++++-------------------
> 1 file changed, 20 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 58d6b1c..d5b6e09 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -360,6 +360,9 @@ static void imx_port_rts_auto(struct imx_port *sport, unsigned long *ucr2)
> *ucr2 |= UCR2_CTSC;
> }
>
> +static void imx_stop_rx_dma(struct imx_port *sport);
> +static void imx_stop_tx_dma(struct imx_port *sport);
Is it possible to reshuffle the order of functions to make this forward
declaration redundant?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 7/7] serial: imx: Fix imx_shutdown procedure
2017-06-30 12:04 [PATCH 0/7] serial: imx: various improvements Romain Perier
` (5 preceding siblings ...)
2017-06-30 12:04 ` [PATCH 6/7] serial: imx: update the stop rx,tx procedures Romain Perier
@ 2017-06-30 12:04 ` Romain Perier
2017-07-03 7:08 ` Uwe Kleine-König
6 siblings, 1 reply; 19+ messages in thread
From: Romain Perier @ 2017-06-30 12:04 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-serial, linux-arm-kernel, linux-kernel, Nandor Han, Romain Perier
From: Nandor Han <nandor.han@ge.com>
In some cases, It looks that interrupts can happen after the dma was
disabled and port was not yet shutdown. This will result in interrupts
handled by imx_rxint.
This commits updates the shutdown function to ensure that underlying
components are disabled in the right order. This disables RX and TX
blocks, then it disabled interrupts. In case DMA is enabled, it disables
DMA and free corresponding resources. It disables UART port and stop
clocks.
Signed-off-by: Nandor Han <nandor.han@ge.com>
Signed-off-by: Romain Perier <romain.perier@collabora.com>
---
drivers/tty/serial/imx.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index d5b6e09..7dc6f0c 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1404,44 +1404,44 @@ static void imx_shutdown(struct uart_port *port)
unsigned long temp;
unsigned long flags;
- if (sport->dma_is_enabled) {
- sport->dma_is_rxing = 0;
- sport->dma_is_txing = 0;
- dmaengine_terminate_sync(sport->dma_chan_tx);
- dmaengine_terminate_sync(sport->dma_chan_rx);
-
+ if (!sport->port.suspended) {
spin_lock_irqsave(&sport->port.lock, flags);
imx_stop_tx(port);
imx_stop_rx(port);
- imx_disable_dma(sport);
spin_unlock_irqrestore(&sport->port.lock, flags);
- imx_uart_dma_exit(sport);
}
- mctrl_gpio_disable_ms(sport->gpios);
+ if (sport->dma_is_inited) {
+ if (sport->dma_is_enabled) {
+ spin_lock_irqsave(&sport->port.lock, flags);
+ imx_disable_dma(sport);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ }
+ imx_uart_dma_exit(sport);
+ }
spin_lock_irqsave(&sport->port.lock, flags);
temp = readl(sport->port.membase + UCR2);
- temp &= ~(UCR2_TXEN);
+ temp &= ~(UCR2_TXEN | UCR2_RXEN);
writel(temp, sport->port.membase + UCR2);
+ temp = readl(sport->port.membase + UCR4);
+ temp &= ~UCR4_OREN;
+ writel(temp, sport->port.membase + UCR4);
spin_unlock_irqrestore(&sport->port.lock, flags);
- /*
- * Stop our timer.
- */
- del_timer_sync(&sport->timer);
+ mctrl_gpio_disable_ms(sport->gpios);
- /*
- * Disable all interrupts, port and break condition.
- */
+ /* Stop our timer. */
+ del_timer_sync(&sport->timer);
+ /* Disable port. */
spin_lock_irqsave(&sport->port.lock, flags);
temp = readl(sport->port.membase + UCR1);
- temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
-
+ temp &= ~UCR1_UARTEN;
writel(temp, sport->port.membase + UCR1);
spin_unlock_irqrestore(&sport->port.lock, flags);
+ /* Disable clocks. */
clk_disable_unprepare(sport->clk_per);
clk_disable_unprepare(sport->clk_ipg);
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 7/7] serial: imx: Fix imx_shutdown procedure
2017-06-30 12:04 ` [PATCH 7/7] serial: imx: Fix imx_shutdown procedure Romain Perier
@ 2017-07-03 7:08 ` Uwe Kleine-König
0 siblings, 0 replies; 19+ messages in thread
From: Uwe Kleine-König @ 2017-07-03 7:08 UTC (permalink / raw)
To: Romain Perier
Cc: Greg Kroah-Hartman, linux-serial, linux-arm-kernel, linux-kernel,
Nandor Han, kernel
On Fri, Jun 30, 2017 at 02:04:46PM +0200, Romain Perier wrote:
> From: Nandor Han <nandor.han@ge.com>
>
> In some cases, It looks that interrupts can happen after the dma was
s/It/it/
> disabled and port was not yet shutdown. This will result in interrupts
> handled by imx_rxint.
>
> This commits updates the shutdown function to ensure that underlying
> components are disabled in the right order. This disables RX and TX
> blocks, then it disabled interrupts. In case DMA is enabled, it disables
> DMA and free corresponding resources. It disables UART port and stop
> clocks.
>
> Signed-off-by: Nandor Han <nandor.han@ge.com>
> Signed-off-by: Romain Perier <romain.perier@collabora.com>
> ---
> drivers/tty/serial/imx.c | 38 +++++++++++++++++++-------------------
> 1 file changed, 19 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index d5b6e09..7dc6f0c 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -1404,44 +1404,44 @@ static void imx_shutdown(struct uart_port *port)
> unsigned long temp;
> unsigned long flags;
>
> - if (sport->dma_is_enabled) {
> - sport->dma_is_rxing = 0;
> - sport->dma_is_txing = 0;
> - dmaengine_terminate_sync(sport->dma_chan_tx);
> - dmaengine_terminate_sync(sport->dma_chan_rx);
> -
> + if (!sport->port.suspended) {
> spin_lock_irqsave(&sport->port.lock, flags);
> imx_stop_tx(port);
> imx_stop_rx(port);
> - imx_disable_dma(sport);
> spin_unlock_irqrestore(&sport->port.lock, flags);
> - imx_uart_dma_exit(sport);
> }
>
> - mctrl_gpio_disable_ms(sport->gpios);
> + if (sport->dma_is_inited) {
> + if (sport->dma_is_enabled) {
> + spin_lock_irqsave(&sport->port.lock, flags);
> + imx_disable_dma(sport);
> + spin_unlock_irqrestore(&sport->port.lock, flags);
> + }
> + imx_uart_dma_exit(sport);
> + }
>
> spin_lock_irqsave(&sport->port.lock, flags);
> temp = readl(sport->port.membase + UCR2);
> - temp &= ~(UCR2_TXEN);
> + temp &= ~(UCR2_TXEN | UCR2_RXEN);
> writel(temp, sport->port.membase + UCR2);
> + temp = readl(sport->port.membase + UCR4);
> + temp &= ~UCR4_OREN;
> + writel(temp, sport->port.membase + UCR4);
> spin_unlock_irqrestore(&sport->port.lock, flags);
The function already had two critical blocks protected by
spin_lock_irqsave on sport->port.lock. With your patch there are three.
Is it possible to grab the lock only once?
>
> - /*
> - * Stop our timer.
> - */
> - del_timer_sync(&sport->timer);
> + mctrl_gpio_disable_ms(sport->gpios);
>
> - /*
> - * Disable all interrupts, port and break condition.
> - */
> + /* Stop our timer. */
Updating the comment style in such a commit makes the diff unnecessarily
hard to read.
> + del_timer_sync(&sport->timer);
>
> + /* Disable port. */
> spin_lock_irqsave(&sport->port.lock, flags);
> temp = readl(sport->port.membase + UCR1);
> - temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
> -
> + temp &= ~UCR1_UARTEN;
> writel(temp, sport->port.membase + UCR1);
> spin_unlock_irqrestore(&sport->port.lock, flags);
>
> + /* Disable clocks. */
> clk_disable_unprepare(sport->clk_per);
> clk_disable_unprepare(sport->clk_ipg);
> }
> --
> 1.8.3.1
>
> --
> 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
>
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 19+ messages in thread