1 From 48ab619dd6e308c57dac3e5d022a3099806bf79e Mon Sep 17 00:00:00 2001
2 From: Stephen Boyd <sboyd@codeaurora.org>
3 Date: Tue, 14 Jan 2014 12:34:55 -0800
4 Subject: [PATCH 086/182] msm_serial: Add support for poll_{get,put}_char()
6 Implement the polling functionality for the MSM serial driver.
7 This allows us to use KGDB on this hardware.
9 Cc: David Brown <davidb@codeaurora.org>
10 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
11 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 drivers/tty/serial/msm_serial.c | 140 ++++++++++++++++++++++++++++++++++++++-
14 drivers/tty/serial/msm_serial.h | 9 +++
15 2 files changed, 146 insertions(+), 3 deletions(-)
17 --- a/drivers/tty/serial/msm_serial.c
18 +++ b/drivers/tty/serial/msm_serial.c
21 #include "msm_serial.h"
31 struct uart_port uart;
33 @@ -309,6 +316,8 @@ static unsigned int msm_get_mctrl(struct
35 static void msm_reset(struct uart_port *port)
37 + struct msm_port *msm_port = UART_TO_MSM(port);
39 /* reset everything */
40 msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
41 msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
42 @@ -316,6 +325,10 @@ static void msm_reset(struct uart_port *
43 msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
44 msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
45 msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
47 + /* Disable DM modes */
48 + if (msm_port->is_uartdm)
49 + msm_write(port, 0, UARTDM_DMEN);
52 static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
53 @@ -711,6 +724,117 @@ static void msm_power(struct uart_port *
57 +#ifdef CONFIG_CONSOLE_POLL
58 +static int msm_poll_init(struct uart_port *port)
60 + struct msm_port *msm_port = UART_TO_MSM(port);
62 + /* Enable single character mode on RX FIFO */
63 + if (msm_port->is_uartdm >= UARTDM_1P4)
64 + msm_write(port, UARTDM_DMEN_RX_SC_ENABLE, UARTDM_DMEN);
69 +static int msm_poll_get_char_single(struct uart_port *port)
71 + struct msm_port *msm_port = UART_TO_MSM(port);
72 + unsigned int rf_reg = msm_port->is_uartdm ? UARTDM_RF : UART_RF;
74 + if (!(msm_read(port, UART_SR) & UART_SR_RX_READY))
75 + return NO_POLL_CHAR;
77 + return msm_read(port, rf_reg) & 0xff;
80 +static int msm_poll_get_char_dm_1p3(struct uart_port *port)
85 + unsigned char *sp = (unsigned char *)&slop;
87 + /* Check if a previous read had more than one char */
89 + c = sp[sizeof(slop) - count];
91 + /* Or if FIFO is empty */
92 + } else if (!(msm_read(port, UART_SR) & UART_SR_RX_READY)) {
94 + * If RX packing buffer has less than a word, force stale to
95 + * push contents into RX FIFO
97 + count = msm_read(port, UARTDM_RXFS);
98 + count = (count >> UARTDM_RXFS_BUF_SHIFT) & UARTDM_RXFS_BUF_MASK;
100 + msm_write(port, UART_CR_CMD_FORCE_STALE, UART_CR);
101 + slop = msm_read(port, UARTDM_RF);
107 + /* FIFO has a word */
109 + slop = msm_read(port, UARTDM_RF);
111 + count = sizeof(slop) - 1;
117 +static int msm_poll_get_char(struct uart_port *port)
121 + struct msm_port *msm_port = UART_TO_MSM(port);
123 + /* Disable all interrupts */
124 + imr = msm_read(port, UART_IMR);
125 + msm_write(port, 0, UART_IMR);
127 + if (msm_port->is_uartdm == UARTDM_1P3)
128 + c = msm_poll_get_char_dm_1p3(port);
130 + c = msm_poll_get_char_single(port);
132 + /* Enable interrupts */
133 + msm_write(port, imr, UART_IMR);
138 +static void msm_poll_put_char(struct uart_port *port, unsigned char c)
141 + struct msm_port *msm_port = UART_TO_MSM(port);
143 + /* Disable all interrupts */
144 + imr = msm_read(port, UART_IMR);
145 + msm_write(port, 0, UART_IMR);
147 + if (msm_port->is_uartdm)
148 + reset_dm_count(port, 1);
150 + /* Wait until FIFO is empty */
151 + while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
154 + /* Write a character */
155 + msm_write(port, c, msm_port->is_uartdm ? UARTDM_TF : UART_TF);
157 + /* Wait until FIFO is empty */
158 + while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
161 + /* Enable interrupts */
162 + msm_write(port, imr, UART_IMR);
168 static struct uart_ops msm_uart_pops = {
169 .tx_empty = msm_tx_empty,
170 .set_mctrl = msm_set_mctrl,
171 @@ -729,6 +853,11 @@ static struct uart_ops msm_uart_pops = {
172 .config_port = msm_config_port,
173 .verify_port = msm_verify_port,
175 +#ifdef CONFIG_CONSOLE_POLL
176 + .poll_init = msm_poll_init,
177 + .poll_get_char = msm_poll_get_char,
178 + .poll_put_char = msm_poll_put_char,
182 static struct msm_port msm_uart_ports[] = {
183 @@ -900,7 +1029,10 @@ static struct uart_driver msm_uart_drive
184 static atomic_t msm_uart_next_id = ATOMIC_INIT(0);
186 static const struct of_device_id msm_uartdm_table[] = {
187 - { .compatible = "qcom,msm-uartdm" },
188 + { .compatible = "qcom,msm-uartdm-v1.1", .data = (void *)UARTDM_1P1 },
189 + { .compatible = "qcom,msm-uartdm-v1.2", .data = (void *)UARTDM_1P2 },
190 + { .compatible = "qcom,msm-uartdm-v1.3", .data = (void *)UARTDM_1P3 },
191 + { .compatible = "qcom,msm-uartdm-v1.4", .data = (void *)UARTDM_1P4 },
195 @@ -909,6 +1041,7 @@ static int __init msm_serial_probe(struc
196 struct msm_port *msm_port;
197 struct resource *resource;
198 struct uart_port *port;
199 + const struct of_device_id *id;
203 @@ -923,8 +1056,9 @@ static int __init msm_serial_probe(struc
204 port->dev = &pdev->dev;
205 msm_port = UART_TO_MSM(port);
207 - if (of_match_device(msm_uartdm_table, &pdev->dev))
208 - msm_port->is_uartdm = 1;
209 + id = of_match_device(msm_uartdm_table, &pdev->dev);
211 + msm_port->is_uartdm = (unsigned long)id->data;
213 msm_port->is_uartdm = 0;
215 --- a/drivers/tty/serial/msm_serial.h
216 +++ b/drivers/tty/serial/msm_serial.h
218 #define UART_CR_CMD_RESET_RFR (14 << 4)
219 #define UART_CR_CMD_PROTECTION_EN (16 << 4)
220 #define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
221 +#define UART_CR_CMD_FORCE_STALE (4 << 8)
222 #define UART_CR_CMD_RESET_TX_READY (3 << 8)
223 #define UART_CR_TX_DISABLE (1 << 3)
224 #define UART_CR_TX_ENABLE (1 << 2)
226 #define GSBI_PROTOCOL_UART 0x40
227 #define GSBI_PROTOCOL_IDLE 0x0
229 +#define UARTDM_RXFS 0x50
230 +#define UARTDM_RXFS_BUF_SHIFT 0x7
231 +#define UARTDM_RXFS_BUF_MASK 0x7
233 +#define UARTDM_DMEN 0x3C
234 +#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
235 +#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
237 #define UARTDM_DMRX 0x34
238 #define UARTDM_NCF_TX 0x40
239 #define UARTDM_RX_TOTAL_SNAP 0x38