summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com>2011-11-17 17:28:12 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:02:33 +0200
commite2f33da595d1f9ff8c44b5b7a2de17953cea1484 (patch)
tree81fa6fedc02c201f0aaf137f7cbbcdbf42dbdb52
parent76f377bd4a4189929b0322e018c21073c364fea2 (diff)
u5500: pl011: Workaround for UART registers lockup
Deadlock situation which occurs during continuous transfer of data for long duration over uart with hardware flow control. It is observed that CTS interrupt cannot be cleared in uart interrupt register (ICR). Hence further transfer over uart gets blocked. amba-pl011 has mechanism to detect the situation, handle the register configuration backup, hold the uart transfer till workaround is excuting, restoring the registers and resuming the trasfer afterwards. This patch provides the platform reset function to do a soft reset using PRCC_K_SOFTRST_SET/CLEAR of UART-3 on which the issue is observed. ST-Ericsson ID: 355971 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: If48863522c9ca3fced3cdce7689eff8d98cd1bbf Signed-off-by: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/38194 Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r--arch/arm/mach-ux500/board-u5500.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
index 0e200d1f6b8..6ec8e5e28fe 100644
--- a/arch/arm/mach-ux500/board-u5500.c
+++ b/arch/arm/mach-ux500/board-u5500.c
@@ -15,6 +15,7 @@
#ifdef CONFIG_STM_I2S
#include <linux/i2s/i2s.h>
#endif
+#include <linux/delay.h>
#include <linux/led-lm3530.h>
#include <../drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h>
#include <linux/input/matrix_keypad.h>
@@ -648,6 +649,38 @@ static long u5500_panic_blink(int state)
return 0;
}
+#define PRCC_K_SOFTRST_SET 0x18
+#define PRCC_K_SOFTRST_CLEAR 0x1C
+/* pl011 reset */
+static void ux500_uart3_reset(void)
+{
+ void __iomem *prcc_rst_set, *prcc_rst_clr;
+
+ prcc_rst_set = __io_address(U5500_CLKRST5_BASE +
+ PRCC_K_SOFTRST_SET);
+ prcc_rst_clr = __io_address(U5500_CLKRST5_BASE +
+ PRCC_K_SOFTRST_CLEAR);
+
+ /*
+ * Activate soft reset PRCC_K_SOFTRST_CLEAR
+ *
+ * As we are dealing with IP register lockup
+ * so to make double sure that IP gets reset
+ * and reset pulse remains for more than one
+ * clock cycle a delay is added.
+ */
+ writel((readl(prcc_rst_clr) | 0x08), prcc_rst_clr);
+ udelay(1);
+
+ /* Release soft reset PRCC_K_SOFTRST_SET */
+ writel((readl(prcc_rst_set) | 0x08), prcc_rst_set);
+ udelay(1);
+}
+
+static struct amba_pl011_data uart3_plat = {
+ .reset = ux500_uart3_reset,
+};
+
static void __init u5500_i2c_init(struct device *parent)
{
db5500_add_i2c1(pareent, &u5500_i2c1_data);
@@ -677,7 +710,7 @@ static void __init u5500_uart_init(struct device *parent)
db5500_add_uart0(parent, NULL);
db5500_add_uart1(parent, NULL);
db5500_add_uart2(parent, NULL);
- db5500_add_uart3(parent, NULL);
+ db5500_add_uart3(parent, &uart3_plat);
}
static void __init u5500_cryp1_hash1_init(void)