]>
Commit | Line | Data |
---|---|---|
45426b3c GKH |
1 | From 8cd774ad30c22b9d89823f1f05d845f4cdaba9e8 Mon Sep 17 00:00:00 2001 |
2 | From: Dongdong Deng <dongdong.deng@windriver.com> | |
3 | Date: Thu, 17 Jun 2010 11:13:40 +0800 | |
4 | Subject: serial: cpm_uart: implement the cpm_uart_early_write() function for console poll | |
5 | ||
6 | From: Dongdong Deng <dongdong.deng@windriver.com> | |
7 | ||
8 | commit 8cd774ad30c22b9d89823f1f05d845f4cdaba9e8 upstream. | |
9 | ||
10 | The cpm_uart_early_write() function which was used for console poll | |
11 | isn't implemented in the cpm uart driver. | |
12 | ||
13 | Implementing this function both fixes the build when CONFIG_CONSOLE_POLL | |
14 | is set and allows kgdboc to work via the cpm uart. | |
15 | ||
16 | Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com> | |
17 | Reviewed-by: Bruce Ashfield <bruce.ashfield@windriver.com> | |
18 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
19 | ||
20 | --- | |
21 | drivers/serial/cpm_uart/cpm_uart_core.c | 143 +++++++++++++++++--------------- | |
22 | 1 file changed, 79 insertions(+), 64 deletions(-) | |
23 | ||
24 | --- a/drivers/serial/cpm_uart/cpm_uart_core.c | |
25 | +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |
26 | @@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct | |
27 | } | |
28 | } | |
29 | ||
30 | +#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) | |
31 | +/* | |
32 | + * Write a string to the serial port | |
33 | + * Note that this is called with interrupts already disabled | |
34 | + */ | |
35 | +static void cpm_uart_early_write(struct uart_cpm_port *pinfo, | |
36 | + const char *string, u_int count) | |
37 | +{ | |
38 | + unsigned int i; | |
39 | + cbd_t __iomem *bdp, *bdbase; | |
40 | + unsigned char *cpm_outp_addr; | |
41 | + | |
42 | + /* Get the address of the host memory buffer. | |
43 | + */ | |
44 | + bdp = pinfo->tx_cur; | |
45 | + bdbase = pinfo->tx_bd_base; | |
46 | + | |
47 | + /* | |
48 | + * Now, do each character. This is not as bad as it looks | |
49 | + * since this is a holding FIFO and not a transmitting FIFO. | |
50 | + * We could add the complexity of filling the entire transmit | |
51 | + * buffer, but we would just wait longer between accesses...... | |
52 | + */ | |
53 | + for (i = 0; i < count; i++, string++) { | |
54 | + /* Wait for transmitter fifo to empty. | |
55 | + * Ready indicates output is ready, and xmt is doing | |
56 | + * that, not that it is ready for us to send. | |
57 | + */ | |
58 | + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | |
59 | + ; | |
60 | + | |
61 | + /* Send the character out. | |
62 | + * If the buffer address is in the CPM DPRAM, don't | |
63 | + * convert it. | |
64 | + */ | |
65 | + cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), | |
66 | + pinfo); | |
67 | + *cpm_outp_addr = *string; | |
68 | + | |
69 | + out_be16(&bdp->cbd_datlen, 1); | |
70 | + setbits16(&bdp->cbd_sc, BD_SC_READY); | |
71 | + | |
72 | + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | |
73 | + bdp = bdbase; | |
74 | + else | |
75 | + bdp++; | |
76 | + | |
77 | + /* if a LF, also do CR... */ | |
78 | + if (*string == 10) { | |
79 | + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | |
80 | + ; | |
81 | + | |
82 | + cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), | |
83 | + pinfo); | |
84 | + *cpm_outp_addr = 13; | |
85 | + | |
86 | + out_be16(&bdp->cbd_datlen, 1); | |
87 | + setbits16(&bdp->cbd_sc, BD_SC_READY); | |
88 | + | |
89 | + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | |
90 | + bdp = bdbase; | |
91 | + else | |
92 | + bdp++; | |
93 | + } | |
94 | + } | |
95 | + | |
96 | + /* | |
97 | + * Finally, Wait for transmitter & holding register to empty | |
98 | + * and restore the IER | |
99 | + */ | |
100 | + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | |
101 | + ; | |
102 | + | |
103 | + pinfo->tx_cur = bdp; | |
104 | +} | |
105 | +#endif | |
106 | + | |
107 | #ifdef CONFIG_CONSOLE_POLL | |
108 | /* Serial polling routines for writing and reading from the uart while | |
109 | * in an interrupt or debug context. | |
110 | @@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uar | |
111 | static char ch[2]; | |
112 | ||
113 | ch[0] = (char)c; | |
114 | - cpm_uart_early_write(pinfo->port.line, ch, 1); | |
115 | + cpm_uart_early_write(pinfo, ch, 1); | |
116 | } | |
117 | #endif /* CONFIG_CONSOLE_POLL */ | |
118 | ||
119 | @@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struc | |
120 | u_int count) | |
121 | { | |
122 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; | |
123 | - unsigned int i; | |
124 | - cbd_t __iomem *bdp, *bdbase; | |
125 | - unsigned char *cp; | |
126 | unsigned long flags; | |
127 | int nolock = oops_in_progress; | |
128 | ||
129 | @@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(struc | |
130 | spin_lock_irqsave(&pinfo->port.lock, flags); | |
131 | } | |
132 | ||
133 | - /* Get the address of the host memory buffer. | |
134 | - */ | |
135 | - bdp = pinfo->tx_cur; | |
136 | - bdbase = pinfo->tx_bd_base; | |
137 | - | |
138 | - /* | |
139 | - * Now, do each character. This is not as bad as it looks | |
140 | - * since this is a holding FIFO and not a transmitting FIFO. | |
141 | - * We could add the complexity of filling the entire transmit | |
142 | - * buffer, but we would just wait longer between accesses...... | |
143 | - */ | |
144 | - for (i = 0; i < count; i++, s++) { | |
145 | - /* Wait for transmitter fifo to empty. | |
146 | - * Ready indicates output is ready, and xmt is doing | |
147 | - * that, not that it is ready for us to send. | |
148 | - */ | |
149 | - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | |
150 | - ; | |
151 | - | |
152 | - /* Send the character out. | |
153 | - * If the buffer address is in the CPM DPRAM, don't | |
154 | - * convert it. | |
155 | - */ | |
156 | - cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); | |
157 | - *cp = *s; | |
158 | - | |
159 | - out_be16(&bdp->cbd_datlen, 1); | |
160 | - setbits16(&bdp->cbd_sc, BD_SC_READY); | |
161 | - | |
162 | - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | |
163 | - bdp = bdbase; | |
164 | - else | |
165 | - bdp++; | |
166 | - | |
167 | - /* if a LF, also do CR... */ | |
168 | - if (*s == 10) { | |
169 | - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | |
170 | - ; | |
171 | - | |
172 | - cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); | |
173 | - *cp = 13; | |
174 | - | |
175 | - out_be16(&bdp->cbd_datlen, 1); | |
176 | - setbits16(&bdp->cbd_sc, BD_SC_READY); | |
177 | - | |
178 | - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | |
179 | - bdp = bdbase; | |
180 | - else | |
181 | - bdp++; | |
182 | - } | |
183 | - } | |
184 | - | |
185 | - /* | |
186 | - * Finally, Wait for transmitter & holding register to empty | |
187 | - * and restore the IER | |
188 | - */ | |
189 | - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | |
190 | - ; | |
191 | - | |
192 | - pinfo->tx_cur = bdp; | |
193 | + cpm_uart_early_write(pinfo, s, count); | |
194 | ||
195 | if (unlikely(nolock)) { | |
196 | local_irq_restore(flags); |