ralink: various i2c related fixes
[oweals/openwrt.git] / target / linux / ipq806x / patches / 0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
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()
5
6 Implement the polling functionality for the MSM serial driver.
7 This allows us to use KGDB on this hardware.
8
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>
12 ---
13  drivers/tty/serial/msm_serial.c |  140 ++++++++++++++++++++++++++++++++++++++-
14  drivers/tty/serial/msm_serial.h |    9 +++
15  2 files changed, 146 insertions(+), 3 deletions(-)
16
17 --- a/drivers/tty/serial/msm_serial.c
18 +++ b/drivers/tty/serial/msm_serial.c
19 @@ -39,6 +39,13 @@
20  
21  #include "msm_serial.h"
22  
23 +enum {
24 +       UARTDM_1P1 = 1,
25 +       UARTDM_1P2,
26 +       UARTDM_1P3,
27 +       UARTDM_1P4,
28 +};
29 +
30  struct msm_port {
31         struct uart_port        uart;
32         char                    name[16];
33 @@ -309,6 +316,8 @@ static unsigned int msm_get_mctrl(struct
34  
35  static void msm_reset(struct uart_port *port)
36  {
37 +       struct msm_port *msm_port = UART_TO_MSM(port);
38 +
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);
46 +
47 +       /* Disable DM modes */
48 +       if (msm_port->is_uartdm)
49 +               msm_write(port, 0, UARTDM_DMEN);
50  }
51  
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 *
54         }
55  }
56  
57 +#ifdef CONFIG_CONSOLE_POLL
58 +static int msm_poll_init(struct uart_port *port)
59 +{
60 +       struct msm_port *msm_port = UART_TO_MSM(port);
61 +
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);
65 +
66 +       return 0;
67 +}
68 +
69 +static int msm_poll_get_char_single(struct uart_port *port)
70 +{
71 +       struct msm_port *msm_port = UART_TO_MSM(port);
72 +       unsigned int rf_reg = msm_port->is_uartdm ? UARTDM_RF : UART_RF;
73 +
74 +       if (!(msm_read(port, UART_SR) & UART_SR_RX_READY))
75 +               return NO_POLL_CHAR;
76 +       else
77 +               return msm_read(port, rf_reg) & 0xff;
78 +}
79 +
80 +static int msm_poll_get_char_dm_1p3(struct uart_port *port)
81 +{
82 +       int c;
83 +       static u32 slop;
84 +       static int count;
85 +       unsigned char *sp = (unsigned char *)&slop;
86 +
87 +       /* Check if a previous read had more than one char */
88 +       if (count) {
89 +               c = sp[sizeof(slop) - count];
90 +               count--;
91 +       /* Or if FIFO is empty */
92 +       } else if (!(msm_read(port, UART_SR) & UART_SR_RX_READY)) {
93 +               /*
94 +                * If RX packing buffer has less than a word, force stale to
95 +                * push contents into RX FIFO
96 +                */
97 +               count = msm_read(port, UARTDM_RXFS);
98 +               count = (count >> UARTDM_RXFS_BUF_SHIFT) & UARTDM_RXFS_BUF_MASK;
99 +               if (count) {
100 +                       msm_write(port, UART_CR_CMD_FORCE_STALE, UART_CR);
101 +                       slop = msm_read(port, UARTDM_RF);
102 +                       c = sp[0];
103 +                       count--;
104 +               } else {
105 +                       c = NO_POLL_CHAR;
106 +               }
107 +       /* FIFO has a word */
108 +       } else {
109 +               slop = msm_read(port, UARTDM_RF);
110 +               c = sp[0];
111 +               count = sizeof(slop) - 1;
112 +       }
113 +
114 +       return c;
115 +}
116 +
117 +static int msm_poll_get_char(struct uart_port *port)
118 +{
119 +       u32 imr;
120 +       int c;
121 +       struct msm_port *msm_port = UART_TO_MSM(port);
122 +
123 +       /* Disable all interrupts */
124 +       imr = msm_read(port, UART_IMR);
125 +       msm_write(port, 0, UART_IMR);
126 +
127 +       if (msm_port->is_uartdm == UARTDM_1P3)
128 +               c = msm_poll_get_char_dm_1p3(port);
129 +       else
130 +               c = msm_poll_get_char_single(port);
131 +
132 +       /* Enable interrupts */
133 +       msm_write(port, imr, UART_IMR);
134 +
135 +       return c;
136 +}
137 +
138 +static void msm_poll_put_char(struct uart_port *port, unsigned char c)
139 +{
140 +       u32 imr;
141 +       struct msm_port *msm_port = UART_TO_MSM(port);
142 +
143 +       /* Disable all interrupts */
144 +       imr = msm_read(port, UART_IMR);
145 +       msm_write(port, 0, UART_IMR);
146 +
147 +       if (msm_port->is_uartdm)
148 +               reset_dm_count(port, 1);
149 +
150 +       /* Wait until FIFO is empty */
151 +       while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
152 +               cpu_relax();
153 +
154 +       /* Write a character */
155 +       msm_write(port, c, msm_port->is_uartdm ? UARTDM_TF : UART_TF);
156 +
157 +       /* Wait until FIFO is empty */
158 +       while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
159 +               cpu_relax();
160 +
161 +       /* Enable interrupts */
162 +       msm_write(port, imr, UART_IMR);
163 +
164 +       return;
165 +}
166 +#endif
167 +
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,
174         .pm = msm_power,
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,
179 +#endif
180  };
181  
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);
185  
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 },
192         { }
193  };
194  
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;
200         int irq;
201  
202         if (pdev->id == -1)
203 @@ -923,8 +1056,9 @@ static int __init msm_serial_probe(struc
204         port->dev = &pdev->dev;
205         msm_port = UART_TO_MSM(port);
206  
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);
210 +       if (id)
211 +               msm_port->is_uartdm = (unsigned long)id->data;
212         else
213                 msm_port->is_uartdm = 0;
214  
215 --- a/drivers/tty/serial/msm_serial.h
216 +++ b/drivers/tty/serial/msm_serial.h
217 @@ -59,6 +59,7 @@
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)
225 @@ -113,6 +114,14 @@
226  #define GSBI_PROTOCOL_UART     0x40
227  #define GSBI_PROTOCOL_IDLE     0x0
228  
229 +#define UARTDM_RXFS            0x50
230 +#define UARTDM_RXFS_BUF_SHIFT  0x7
231 +#define UARTDM_RXFS_BUF_MASK   0x7
232 +
233 +#define UARTDM_DMEN            0x3C
234 +#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
235 +#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
236 +
237  #define UARTDM_DMRX            0x34
238  #define UARTDM_NCF_TX          0x40
239  #define UARTDM_RX_TOTAL_SNAP   0x38