aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com>2011-04-11 11:12:15 +0530
committerSrinidhi KASAGAR <srinidhi.kasagar@stericsson.com>2011-04-11 20:42:23 +0200
commit344b77d42e1311a609075f72af5de8d8290fe374 (patch)
treef655d35bfc8c0f56417cb5484964445e573f9499
parentcb5179811c190759e56c3edcb1cdb13e77e4a510 (diff)
ux500: uart: fix save/restore_uart functionsu8500-android-2.3_v0.56
This patch corrects the set of registers to be saved and restored and in proper sequence in save/restore_uart functions. ST-Ericsson ID: 325732 Change-Id: Ia0b95d77b67b28aa11aaaf57e6e7397b400a5596 Signed-off-by: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/20436 Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r--arch/arm/mach-ux500/uart-db8500.c180
1 files changed, 77 insertions, 103 deletions
diff --git a/arch/arm/mach-ux500/uart-db8500.c b/arch/arm/mach-ux500/uart-db8500.c
index b3da7ad5287..a2836da9cec 100644
--- a/arch/arm/mach-ux500/uart-db8500.c
+++ b/arch/arm/mach-ux500/uart-db8500.c
@@ -24,8 +24,8 @@
static struct {
struct clk *uart_clk;
void __iomem *base;
- u32 dr;
- u32 rsr_err;
+ /* dr */
+ /* rsr_err */
u32 dma_wm;
u32 timeout;
/* fr */
@@ -46,10 +46,10 @@ static struct {
u32 xon2;
u32 xoff1;
u32 xoff2;
- u32 itcr;
- u32 itip;
- u32 itop;
- u32 tdr;
+ /* itcr */
+ /* itip */
+ /* itop */
+ /* tdr */
u32 abcr;
/* absr */
/* abfmt */
@@ -76,61 +76,34 @@ static struct {
static void save_uart(void)
{
int i;
+ void __iomem *membase;
for (i = 0; i < UX500_NR_UARTS; i++) {
if (i != CONFIG_UX500_DEBUG_UART)
continue;
+ membase = context_uart[i].base;
clk_enable(context_uart[i].uart_clk);
- context_uart[i].dr =
- readl(context_uart[i].base + UART01x_DR);
- context_uart[i].rsr_err =
- readl(context_uart[i].base + UART01x_RSR);
- context_uart[i].dma_wm =
- readl(context_uart[i].base + ST_UART011_DMAWM);
- context_uart[i].timeout =
- readl(context_uart[i].base + ST_UART011_TIMEOUT);
- context_uart[i].lcrh_rx =
- readl(context_uart[i].base + ST_UART011_LCRH_RX);
- context_uart[i].ilpr =
- readl(context_uart[i].base + UART01x_ILPR);
- context_uart[i].ibrd =
- readl(context_uart[i].base + UART011_IBRD);
- context_uart[i].fbrd =
- readl(context_uart[i].base + UART011_FBRD);
- context_uart[i].lcrh_tx =
- readl(context_uart[i].base + ST_UART011_LCRH_TX);
- context_uart[i].cr =
- readl(context_uart[i].base + UART011_CR);
- context_uart[i].ifls =
- readl(context_uart[i].base + UART011_IFLS);
- context_uart[i].imsc =
- readl(context_uart[i].base + UART011_IMSC);
- context_uart[i].dmacr =
- readl(context_uart[i].base + UART011_DMACR);
- context_uart[i].xfcr =
- readl(context_uart[i].base + ST_UART011_XFCR);
- context_uart[i].xon1 =
- readl(context_uart[i].base + ST_UART011_XON1);
- context_uart[i].xon2 =
- readl(context_uart[i].base + ST_UART011_XON2);
- context_uart[i].xoff1 =
- readl(context_uart[i].base + ST_UART011_XOFF1);
- context_uart[i].xoff2 =
- readl(context_uart[i].base + ST_UART011_XOFF2);
- context_uart[i].itcr =
- readl(context_uart[i].base + ST_UART011_ITCR);
- context_uart[i].itip =
- readl(context_uart[i].base + ST_UART011_ITIP);
- context_uart[i].itop =
- readl(context_uart[i].base + ST_UART011_ITOP);
- context_uart[i].tdr =
- readl(context_uart[i].base + ST_UART011_TDR);
- context_uart[i].abcr =
- readl(context_uart[i].base + ST_UART011_ABCR);
- context_uart[i].abimsc =
- readl(context_uart[i].base + ST_UART011_ABIMSC);
+ context_uart[i].dma_wm = readl(membase + ST_UART011_DMAWM);
+ context_uart[i].timeout = readl(membase + ST_UART011_TIMEOUT);
+ context_uart[i].lcrh_rx = readl(membase + ST_UART011_LCRH_RX);
+ context_uart[i].ilpr = readl(membase + UART01x_ILPR);
+ context_uart[i].ibrd = readl(membase + UART011_IBRD);
+ context_uart[i].fbrd = readl(membase + UART011_FBRD);
+ context_uart[i].lcrh_tx = readl(membase + ST_UART011_LCRH_TX);
+ context_uart[i].cr = readl(membase + UART011_CR);
+ context_uart[i].ifls = readl(membase + UART011_IFLS);
+ context_uart[i].imsc = readl(membase + UART011_IMSC);
+ context_uart[i].dmacr = readl(membase + UART011_DMACR);
+ context_uart[i].xfcr = readl(membase + ST_UART011_XFCR);
+ context_uart[i].xon1 = readl(membase + ST_UART011_XON1);
+ context_uart[i].xon2 = readl(membase + ST_UART011_XON2);
+ context_uart[i].xoff1 = readl(membase + ST_UART011_XOFF1);
+ context_uart[i].xoff2 = readl(membase + ST_UART011_XOFF2);
+ context_uart[i].abcr = readl(membase + ST_UART011_ABCR);
+ context_uart[i].abimsc = readl(membase + ST_UART011_ABIMSC);
+
clk_disable(context_uart[i].uart_clk);
}
}
@@ -138,29 +111,49 @@ static void save_uart(void)
static void restore_uart(void)
{
int i, cnt;
+ int retries = 100;
+ unsigned int cr;
+ void __iomem *membase;
for (i = 0; i < UX500_NR_UARTS; i++) {
if (i != CONFIG_UX500_DEBUG_UART)
continue;
+ membase = context_uart[i].base;
clk_enable(context_uart[i].uart_clk);
- writel(context_uart[i].dr,
- context_uart[i].base + UART01x_DR);
- writel(context_uart[i].rsr_err,
- context_uart[i].base + UART01x_RSR);
- writel(context_uart[i].dma_wm,
- context_uart[i].base + ST_UART011_DMAWM);
- writel(context_uart[i].timeout,
- context_uart[i].base + ST_UART011_TIMEOUT);
- writel(context_uart[i].lcrh_rx,
- context_uart[i].base + ST_UART011_LCRH_RX);
- writel(context_uart[i].ilpr,
- context_uart[i].base + UART01x_ILPR);
- writel(context_uart[i].ibrd,
- context_uart[i].base + UART011_IBRD);
- writel(context_uart[i].fbrd,
- context_uart[i].base + UART011_FBRD);
+ writew(context_uart[i].ifls, membase + UART011_IFLS);
+ cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
+
+ writew(cr, membase + UART011_CR);
+ writew(0, membase + UART011_FBRD);
+ writew(1, membase + UART011_IBRD);
+ writew(0, membase + ST_UART011_LCRH_RX);
+ if (context_uart[i].lcrh_tx != ST_UART011_LCRH_RX) {
+ int i;
+ /*
+ * Wait 10 PCLKs before writing LCRH_TX register,
+ * to get this delay write read only register 10 times
+ */
+ for (i = 0; i < 10; ++i)
+ writew(0xff, membase + UART011_MIS);
+ writew(0, membase + ST_UART011_LCRH_TX);
+ }
+ writew(0, membase + UART01x_DR);
+ do {
+ if (!(readw(membase + UART01x_FR) & UART01x_FR_BUSY))
+ break;
+ } while (retries-- > 0);
+ if (retries < 0)
+ pr_warning("%s:uart tx busy\n", __func__);
+ barrier();
+
+ writel(context_uart[i].dma_wm, membase + ST_UART011_DMAWM);
+ writel(context_uart[i].timeout, membase + ST_UART011_TIMEOUT);
+ writel(context_uart[i].lcrh_rx, membase + ST_UART011_LCRH_RX);
+ writel(context_uart[i].ilpr, membase + UART01x_ILPR);
+ writel(context_uart[i].ibrd, membase + UART011_IBRD);
+ writel(context_uart[i].fbrd, membase + UART011_FBRD);
/*
* Wait 10 PCLKs before writing LCRH_TX register,
* to get this delay write read only register 10-3
@@ -168,40 +161,21 @@ static void restore_uart(void)
* ST_UART011_LCRH_RX
*/
for (cnt = 0; cnt < 7; cnt++)
- writew(0xff, context_uart[i].base + UART011_MIS);
+ writew(0xff, membase + UART011_MIS);
+
+ writel(context_uart[i].lcrh_tx, membase + ST_UART011_LCRH_TX);
+ writel(context_uart[i].ifls, membase + UART011_IFLS);
+ writel(context_uart[i].dmacr, membase + UART011_DMACR);
+ writel(context_uart[i].xfcr, membase + ST_UART011_XFCR);
+ writel(context_uart[i].xon1, membase + ST_UART011_XON1);
+ writel(context_uart[i].xon2, membase + ST_UART011_XON2);
+ writel(context_uart[i].xoff1, membase + ST_UART011_XOFF1);
+ writel(context_uart[i].xoff2, membase + ST_UART011_XOFF2);
+ writel(context_uart[i].abcr, membase + ST_UART011_ABCR);
+ writel(context_uart[i].abimsc, membase + ST_UART011_ABIMSC);
+ writel(context_uart[i].cr, membase + UART011_CR);
+ writel(context_uart[i].imsc, membase + UART011_IMSC);
- writel(context_uart[i].lcrh_tx,
- context_uart[i].base + ST_UART011_LCRH_TX);
- writel(context_uart[i].cr,
- context_uart[i].base + UART011_CR);
- writel(context_uart[i].ifls,
- context_uart[i].base + UART011_IFLS);
- writel(context_uart[i].imsc,
- context_uart[i].base + UART011_IMSC);
- writel(context_uart[i].dmacr,
- context_uart[i].base + UART011_DMACR);
- writel(context_uart[i].xfcr,
- context_uart[i].base + ST_UART011_XFCR);
- writel(context_uart[i].xon1,
- context_uart[i].base + ST_UART011_XON1);
- writel(context_uart[i].xon2,
- context_uart[i].base + ST_UART011_XON2);
- writel(context_uart[i].xoff1,
- context_uart[i].base + ST_UART011_XOFF1);
- writel(context_uart[i].xoff2,
- context_uart[i].base + ST_UART011_XOFF2);
- writel(context_uart[i].itcr,
- context_uart[i].base + ST_UART011_ITCR);
- writel(context_uart[i].itip,
- context_uart[i].base + ST_UART011_ITIP);
- writel(context_uart[i].abcr,
- context_uart[i].base + ST_UART011_ABCR);
- writel(context_uart[i].itop,
- context_uart[i].base + ST_UART011_ITOP);
- writel(context_uart[i].tdr,
- context_uart[i].base + ST_UART011_TDR);
- writel(context_uart[i].abimsc,
- context_uart[i].base + ST_UART011_ABIMSC);
clk_disable(context_uart[i].uart_clk);
}
}