diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2017-05-24 15:38:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-25 08:35:53 -0400 |
commit | 6df765dca378bddf994cfd2044acafa501bd800f (patch) | |
tree | 4cd135416b95cf7a0239629624c440c35997c222 | |
parent | 46e3813d72abb018f0cd6e72389004db8728c738 (diff) |
serial: imx: ensure UCR3 and UFCR are setup correctly
Commit e61c38d85b73 ("serial: imx: setup DCEDTE early and ensure DCD and
RI irqs to be off") has a flaw: While UCR3 and UFCR were modified using
read-modify-write before it switched to write register values
independent of the previous state. That's a good idea in principle (and
that's why I did it) but needs more care.
This patch reinstates read-modify-write for UFCR and for UCR3 ensures
that RXDMUXSEL and ADNIMP are set for post imx1.
Fixes: e61c38d85b73 ("serial: imx: setup DCEDTE early and ensure DCD and RI irqs to be off")
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Mika Penttilä <mika.penttila@nextfour.com>
Tested-by: Mika Penttilä <mika.penttila@nextfour.com>
Acked-by: Steve Twiss <stwiss.opensource@diasemi.com>
Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/serial/imx.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 33509b4beaec..bbefddd92bfe 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -2184,7 +2184,9 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
2184 | * and DCD (when they are outputs) or enables the respective | 2184 | * and DCD (when they are outputs) or enables the respective |
2185 | * irqs. So set this bit early, i.e. before requesting irqs. | 2185 | * irqs. So set this bit early, i.e. before requesting irqs. |
2186 | */ | 2186 | */ |
2187 | writel(UFCR_DCEDTE, sport->port.membase + UFCR); | 2187 | reg = readl(sport->port.membase + UFCR); |
2188 | if (!(reg & UFCR_DCEDTE)) | ||
2189 | writel(reg | UFCR_DCEDTE, sport->port.membase + UFCR); | ||
2188 | 2190 | ||
2189 | /* | 2191 | /* |
2190 | * Disable UCR3_RI and UCR3_DCD irqs. They are also not | 2192 | * Disable UCR3_RI and UCR3_DCD irqs. They are also not |
@@ -2195,7 +2197,15 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
2195 | sport->port.membase + UCR3); | 2197 | sport->port.membase + UCR3); |
2196 | 2198 | ||
2197 | } else { | 2199 | } else { |
2198 | writel(0, sport->port.membase + UFCR); | 2200 | unsigned long ucr3 = UCR3_DSR; |
2201 | |||
2202 | reg = readl(sport->port.membase + UFCR); | ||
2203 | if (reg & UFCR_DCEDTE) | ||
2204 | writel(reg & ~UFCR_DCEDTE, sport->port.membase + UFCR); | ||
2205 | |||
2206 | if (!is_imx1_uart(sport)) | ||
2207 | ucr3 |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP; | ||
2208 | writel(ucr3, sport->port.membase + UCR3); | ||
2199 | } | 2209 | } |
2200 | 2210 | ||
2201 | clk_disable_unprepare(sport->clk_ipg); | 2211 | clk_disable_unprepare(sport->clk_ipg); |