summaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
diff options
context:
space:
mode:
authorJohn Crispin <john@openwrt.org>2014-08-30 09:32:58 +0000
committerJohn Crispin <john@openwrt.org>2014-08-30 09:32:58 +0000
commit3c1f6e358d4f1da4cf79083996544ce909f21b5f (patch)
tree212892dbf4b51bc026d8aca5a12f45cafcef1b84 /target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
parent926f000b99d31b9d4495c112149377c0da66dbc1 (diff)
downloadmaster-31e0f0ae-3c1f6e358d4f1da4cf79083996544ce909f21b5f.tar.gz
master-31e0f0ae-3c1f6e358d4f1da4cf79083996544ce909f21b5f.tar.bz2
master-31e0f0ae-3c1f6e358d4f1da4cf79083996544ce909f21b5f.zip
ipq806x: Add support for IPQ806x chip family
Patches are generated using the "format-patch" command from the following location: *https://www.codeaurora.org/cgit/quic/kernel/galak-msm/log/?h=apq_ipq_base *rev=0771849495b4128cac2faf7d49c85c729fc48b20 Patches numbered 76/77/102/103 have already been integrated in 3.14.12, so they're not in this list. All these patches are either integrated are pending integration into kernel.org, therefore these patches should go away once the kernel gets upgraded to 3.16. Support is currently limited to AP148 board but can be extended to other platforms in the future. These changes do not cover ethernet connectivity. Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org> SVN-Revision: 42334
Diffstat (limited to 'target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch')
-rw-r--r--target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch246
1 files changed, 246 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch b/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
new file mode 100644
index 0000000000..afc293bfbd
--- /dev/null
+++ b/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
@@ -0,0 +1,246 @@
+From 48ab619dd6e308c57dac3e5d022a3099806bf79e Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Tue, 14 Jan 2014 12:34:55 -0800
+Subject: [PATCH 086/182] msm_serial: Add support for poll_{get,put}_char()
+
+Implement the polling functionality for the MSM serial driver.
+This allows us to use KGDB on this hardware.
+
+Cc: David Brown <davidb@codeaurora.org>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/msm_serial.c | 140 ++++++++++++++++++++++++++++++++++++++-
+ drivers/tty/serial/msm_serial.h | 9 +++
+ 2 files changed, 146 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
+index b5d779c..053b98e 100644
+--- a/drivers/tty/serial/msm_serial.c
++++ b/drivers/tty/serial/msm_serial.c
+@@ -39,6 +39,13 @@
+
+ #include "msm_serial.h"
+
++enum {
++ UARTDM_1P1 = 1,
++ UARTDM_1P2,
++ UARTDM_1P3,
++ UARTDM_1P4,
++};
++
+ struct msm_port {
+ struct uart_port uart;
+ char name[16];
+@@ -309,6 +316,8 @@ static unsigned int msm_get_mctrl(struct uart_port *port)
+
+ static void msm_reset(struct uart_port *port)
+ {
++ struct msm_port *msm_port = UART_TO_MSM(port);
++
+ /* reset everything */
+ msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
+ msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
+@@ -316,6 +325,10 @@ static void msm_reset(struct uart_port *port)
+ msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
+ msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
+ msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
++
++ /* Disable DM modes */
++ if (msm_port->is_uartdm)
++ msm_write(port, 0, UARTDM_DMEN);
+ }
+
+ static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
+@@ -711,6 +724,117 @@ static void msm_power(struct uart_port *port, unsigned int state,
+ }
+ }
+
++#ifdef CONFIG_CONSOLE_POLL
++static int msm_poll_init(struct uart_port *port)
++{
++ struct msm_port *msm_port = UART_TO_MSM(port);
++
++ /* Enable single character mode on RX FIFO */
++ if (msm_port->is_uartdm >= UARTDM_1P4)
++ msm_write(port, UARTDM_DMEN_RX_SC_ENABLE, UARTDM_DMEN);
++
++ return 0;
++}
++
++static int msm_poll_get_char_single(struct uart_port *port)
++{
++ struct msm_port *msm_port = UART_TO_MSM(port);
++ unsigned int rf_reg = msm_port->is_uartdm ? UARTDM_RF : UART_RF;
++
++ if (!(msm_read(port, UART_SR) & UART_SR_RX_READY))
++ return NO_POLL_CHAR;
++ else
++ return msm_read(port, rf_reg) & 0xff;
++}
++
++static int msm_poll_get_char_dm_1p3(struct uart_port *port)
++{
++ int c;
++ static u32 slop;
++ static int count;
++ unsigned char *sp = (unsigned char *)&slop;
++
++ /* Check if a previous read had more than one char */
++ if (count) {
++ c = sp[sizeof(slop) - count];
++ count--;
++ /* Or if FIFO is empty */
++ } else if (!(msm_read(port, UART_SR) & UART_SR_RX_READY)) {
++ /*
++ * If RX packing buffer has less than a word, force stale to
++ * push contents into RX FIFO
++ */
++ count = msm_read(port, UARTDM_RXFS);
++ count = (count >> UARTDM_RXFS_BUF_SHIFT) & UARTDM_RXFS_BUF_MASK;
++ if (count) {
++ msm_write(port, UART_CR_CMD_FORCE_STALE, UART_CR);
++ slop = msm_read(port, UARTDM_RF);
++ c = sp[0];
++ count--;
++ } else {
++ c = NO_POLL_CHAR;
++ }
++ /* FIFO has a word */
++ } else {
++ slop = msm_read(port, UARTDM_RF);
++ c = sp[0];
++ count = sizeof(slop) - 1;
++ }
++
++ return c;
++}
++
++static int msm_poll_get_char(struct uart_port *port)
++{
++ u32 imr;
++ int c;
++ struct msm_port *msm_port = UART_TO_MSM(port);
++
++ /* Disable all interrupts */
++ imr = msm_read(port, UART_IMR);
++ msm_write(port, 0, UART_IMR);
++
++ if (msm_port->is_uartdm == UARTDM_1P3)
++ c = msm_poll_get_char_dm_1p3(port);
++ else
++ c = msm_poll_get_char_single(port);
++
++ /* Enable interrupts */
++ msm_write(port, imr, UART_IMR);
++
++ return c;
++}
++
++static void msm_poll_put_char(struct uart_port *port, unsigned char c)
++{
++ u32 imr;
++ struct msm_port *msm_port = UART_TO_MSM(port);
++
++ /* Disable all interrupts */
++ imr = msm_read(port, UART_IMR);
++ msm_write(port, 0, UART_IMR);
++
++ if (msm_port->is_uartdm)
++ reset_dm_count(port, 1);
++
++ /* Wait until FIFO is empty */
++ while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
++ cpu_relax();
++
++ /* Write a character */
++ msm_write(port, c, msm_port->is_uartdm ? UARTDM_TF : UART_TF);
++
++ /* Wait until FIFO is empty */
++ while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
++ cpu_relax();
++
++ /* Enable interrupts */
++ msm_write(port, imr, UART_IMR);
++
++ return;
++}
++#endif
++
+ static struct uart_ops msm_uart_pops = {
+ .tx_empty = msm_tx_empty,
+ .set_mctrl = msm_set_mctrl,
+@@ -729,6 +853,11 @@ static struct uart_ops msm_uart_pops = {
+ .config_port = msm_config_port,
+ .verify_port = msm_verify_port,
+ .pm = msm_power,
++#ifdef CONFIG_CONSOLE_POLL
++ .poll_init = msm_poll_init,
++ .poll_get_char = msm_poll_get_char,
++ .poll_put_char = msm_poll_put_char,
++#endif
+ };
+
+ static struct msm_port msm_uart_ports[] = {
+@@ -900,7 +1029,10 @@ static struct uart_driver msm_uart_driver = {
+ static atomic_t msm_uart_next_id = ATOMIC_INIT(0);
+
+ static const struct of_device_id msm_uartdm_table[] = {
+- { .compatible = "qcom,msm-uartdm" },
++ { .compatible = "qcom,msm-uartdm-v1.1", .data = (void *)UARTDM_1P1 },
++ { .compatible = "qcom,msm-uartdm-v1.2", .data = (void *)UARTDM_1P2 },
++ { .compatible = "qcom,msm-uartdm-v1.3", .data = (void *)UARTDM_1P3 },
++ { .compatible = "qcom,msm-uartdm-v1.4", .data = (void *)UARTDM_1P4 },
+ { }
+ };
+
+@@ -909,6 +1041,7 @@ static int __init msm_serial_probe(struct platform_device *pdev)
+ struct msm_port *msm_port;
+ struct resource *resource;
+ struct uart_port *port;
++ const struct of_device_id *id;
+ int irq;
+
+ if (pdev->id == -1)
+@@ -923,8 +1056,9 @@ static int __init msm_serial_probe(struct platform_device *pdev)
+ port->dev = &pdev->dev;
+ msm_port = UART_TO_MSM(port);
+
+- if (of_match_device(msm_uartdm_table, &pdev->dev))
+- msm_port->is_uartdm = 1;
++ id = of_match_device(msm_uartdm_table, &pdev->dev);
++ if (id)
++ msm_port->is_uartdm = (unsigned long)id->data;
+ else
+ msm_port->is_uartdm = 0;
+
+diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
+index 469fda5..1e9b68b 100644
+--- a/drivers/tty/serial/msm_serial.h
++++ b/drivers/tty/serial/msm_serial.h
+@@ -59,6 +59,7 @@
+ #define UART_CR_CMD_RESET_RFR (14 << 4)
+ #define UART_CR_CMD_PROTECTION_EN (16 << 4)
+ #define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
++#define UART_CR_CMD_FORCE_STALE (4 << 8)
+ #define UART_CR_CMD_RESET_TX_READY (3 << 8)
+ #define UART_CR_TX_DISABLE (1 << 3)
+ #define UART_CR_TX_ENABLE (1 << 2)
+@@ -113,6 +114,14 @@
+ #define GSBI_PROTOCOL_UART 0x40
+ #define GSBI_PROTOCOL_IDLE 0x0
+
++#define UARTDM_RXFS 0x50
++#define UARTDM_RXFS_BUF_SHIFT 0x7
++#define UARTDM_RXFS_BUF_MASK 0x7
++
++#define UARTDM_DMEN 0x3C
++#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
++#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
++
+ #define UARTDM_DMRX 0x34
+ #define UARTDM_NCF_TX 0x40
+ #define UARTDM_RX_TOTAL_SNAP 0x38
+--
+1.7.10.4
+