diff options
author | Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> | 2011-04-11 11:12:15 +0530 |
---|---|---|
committer | Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | 2011-04-11 20:42:23 +0200 |
commit | 344b77d42e1311a609075f72af5de8d8290fe374 (patch) | |
tree | f655d35bfc8c0f56417cb5484964445e573f9499 | |
parent | cb5179811c190759e56c3edcb1cdb13e77e4a510 (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.c | 180 |
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); } } |