diff options
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r-- | drivers/serial/sh-sci.c | 563 |
1 files changed, 176 insertions, 387 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 165fc010978c..557b54ab2f25 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #ifdef CONFIG_SUPERH | 51 | #ifdef CONFIG_SUPERH |
52 | #include <asm/clock.h> | 52 | #include <asm/clock.h> |
53 | #include <asm/sh_bios.h> | 53 | #include <asm/sh_bios.h> |
54 | #include <asm/kgdb.h> | ||
55 | #endif | 54 | #endif |
56 | 55 | ||
57 | #include "sh-sci.h" | 56 | #include "sh-sci.h" |
@@ -65,10 +64,6 @@ struct sci_port { | |||
65 | /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ | 64 | /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ |
66 | unsigned int irqs[SCIx_NR_IRQS]; | 65 | unsigned int irqs[SCIx_NR_IRQS]; |
67 | 66 | ||
68 | /* Port pin configuration */ | ||
69 | void (*init_pins)(struct uart_port *port, | ||
70 | unsigned int cflag); | ||
71 | |||
72 | /* Port enable callback */ | 67 | /* Port enable callback */ |
73 | void (*enable)(struct uart_port *port); | 68 | void (*enable)(struct uart_port *port); |
74 | 69 | ||
@@ -85,10 +80,6 @@ struct sci_port { | |||
85 | #endif | 80 | #endif |
86 | }; | 81 | }; |
87 | 82 | ||
88 | #ifdef CONFIG_SH_KGDB | ||
89 | static struct sci_port *kgdb_sci_port; | ||
90 | #endif | ||
91 | |||
92 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 83 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE |
93 | static struct sci_port *serial_console_port; | 84 | static struct sci_port *serial_console_port; |
94 | #endif | 85 | #endif |
@@ -101,21 +92,26 @@ static void sci_stop_tx(struct uart_port *port); | |||
101 | static struct sci_port sci_ports[SCI_NPORTS]; | 92 | static struct sci_port sci_ports[SCI_NPORTS]; |
102 | static struct uart_driver sci_uart_driver; | 93 | static struct uart_driver sci_uart_driver; |
103 | 94 | ||
104 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && \ | 95 | static inline struct sci_port * |
105 | defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) | 96 | to_sci_port(struct uart_port *uart) |
97 | { | ||
98 | return container_of(uart, struct sci_port, port); | ||
99 | } | ||
100 | |||
101 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | ||
102 | |||
103 | #ifdef CONFIG_CONSOLE_POLL | ||
106 | static inline void handle_error(struct uart_port *port) | 104 | static inline void handle_error(struct uart_port *port) |
107 | { | 105 | { |
108 | /* Clear error flags */ | 106 | /* Clear error flags */ |
109 | sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); | 107 | sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); |
110 | } | 108 | } |
111 | 109 | ||
112 | static int get_char(struct uart_port *port) | 110 | static int sci_poll_get_char(struct uart_port *port) |
113 | { | 111 | { |
114 | unsigned long flags; | ||
115 | unsigned short status; | 112 | unsigned short status; |
116 | int c; | 113 | int c; |
117 | 114 | ||
118 | spin_lock_irqsave(&port->lock, flags); | ||
119 | do { | 115 | do { |
120 | status = sci_in(port, SCxSR); | 116 | status = sci_in(port, SCxSR); |
121 | if (status & SCxSR_ERRORS(port)) { | 117 | if (status & SCxSR_ERRORS(port)) { |
@@ -123,23 +119,21 @@ static int get_char(struct uart_port *port) | |||
123 | continue; | 119 | continue; |
124 | } | 120 | } |
125 | } while (!(status & SCxSR_RDxF(port))); | 121 | } while (!(status & SCxSR_RDxF(port))); |
122 | |||
126 | c = sci_in(port, SCxRDR); | 123 | c = sci_in(port, SCxRDR); |
127 | sci_in(port, SCxSR); /* Dummy read */ | 124 | |
125 | /* Dummy read */ | ||
126 | sci_in(port, SCxSR); | ||
128 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); | 127 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); |
129 | spin_unlock_irqrestore(&port->lock, flags); | ||
130 | 128 | ||
131 | return c; | 129 | return c; |
132 | } | 130 | } |
133 | #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ | 131 | #endif |
134 | 132 | ||
135 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || defined(CONFIG_SH_KGDB) | 133 | static void sci_poll_put_char(struct uart_port *port, unsigned char c) |
136 | static void put_char(struct uart_port *port, char c) | ||
137 | { | 134 | { |
138 | unsigned long flags; | ||
139 | unsigned short status; | 135 | unsigned short status; |
140 | 136 | ||
141 | spin_lock_irqsave(&port->lock, flags); | ||
142 | |||
143 | do { | 137 | do { |
144 | status = sci_in(port, SCxSR); | 138 | status = sci_in(port, SCxSR); |
145 | } while (!(status & SCxSR_TDxE(port))); | 139 | } while (!(status & SCxSR_TDxE(port))); |
@@ -147,96 +141,22 @@ static void put_char(struct uart_port *port, char c) | |||
147 | sci_in(port, SCxSR); /* Dummy read */ | 141 | sci_in(port, SCxSR); /* Dummy read */ |
148 | sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); | 142 | sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); |
149 | sci_out(port, SCxTDR, c); | 143 | sci_out(port, SCxTDR, c); |
150 | |||
151 | spin_unlock_irqrestore(&port->lock, flags); | ||
152 | } | 144 | } |
153 | #endif | 145 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ |
154 | |||
155 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
156 | static void put_string(struct sci_port *sci_port, const char *buffer, int count) | ||
157 | { | ||
158 | struct uart_port *port = &sci_port->port; | ||
159 | const unsigned char *p = buffer; | ||
160 | int i; | ||
161 | |||
162 | #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) | ||
163 | int checksum; | ||
164 | int usegdb=0; | ||
165 | |||
166 | #ifdef CONFIG_SH_STANDARD_BIOS | ||
167 | /* This call only does a trap the first time it is | ||
168 | * called, and so is safe to do here unconditionally | ||
169 | */ | ||
170 | usegdb |= sh_bios_in_gdb_mode(); | ||
171 | #endif | ||
172 | #ifdef CONFIG_SH_KGDB | ||
173 | usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port)); | ||
174 | #endif | ||
175 | |||
176 | if (usegdb) { | ||
177 | /* $<packet info>#<checksum>. */ | ||
178 | do { | ||
179 | unsigned char c; | ||
180 | put_char(port, '$'); | ||
181 | put_char(port, 'O'); /* 'O'utput to console */ | ||
182 | checksum = 'O'; | ||
183 | |||
184 | for (i=0; i<count; i++) { /* Don't use run length encoding */ | ||
185 | int h, l; | ||
186 | |||
187 | c = *p++; | ||
188 | h = hex_asc_hi(c); | ||
189 | l = hex_asc_lo(c); | ||
190 | put_char(port, h); | ||
191 | put_char(port, l); | ||
192 | checksum += h + l; | ||
193 | } | ||
194 | put_char(port, '#'); | ||
195 | put_char(port, hex_asc_hi(checksum)); | ||
196 | put_char(port, hex_asc_lo(checksum)); | ||
197 | } while (get_char(port) != '+'); | ||
198 | } else | ||
199 | #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ | ||
200 | for (i=0; i<count; i++) { | ||
201 | if (*p == 10) | ||
202 | put_char(port, '\r'); | ||
203 | put_char(port, *p++); | ||
204 | } | ||
205 | } | ||
206 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | ||
207 | |||
208 | #ifdef CONFIG_SH_KGDB | ||
209 | static int kgdb_sci_getchar(void) | ||
210 | { | ||
211 | int c; | ||
212 | |||
213 | /* Keep trying to read a character, this could be neater */ | ||
214 | while ((c = get_char(&kgdb_sci_port->port)) < 0) | ||
215 | cpu_relax(); | ||
216 | |||
217 | return c; | ||
218 | } | ||
219 | |||
220 | static inline void kgdb_sci_putchar(int c) | ||
221 | { | ||
222 | put_char(&kgdb_sci_port->port, c); | ||
223 | } | ||
224 | #endif /* CONFIG_SH_KGDB */ | ||
225 | 146 | ||
226 | #if defined(__H8300S__) | 147 | #if defined(__H8300S__) |
227 | enum { sci_disable, sci_enable }; | 148 | enum { sci_disable, sci_enable }; |
228 | 149 | ||
229 | static void h8300_sci_config(struct uart_port* port, unsigned int ctrl) | 150 | static void h8300_sci_config(struct uart_port *port, unsigned int ctrl) |
230 | { | 151 | { |
231 | volatile unsigned char *mstpcrl=(volatile unsigned char *)MSTPCRL; | 152 | volatile unsigned char *mstpcrl = (volatile unsigned char *)MSTPCRL; |
232 | int ch = (port->mapbase - SMR0) >> 3; | 153 | int ch = (port->mapbase - SMR0) >> 3; |
233 | unsigned char mask = 1 << (ch+1); | 154 | unsigned char mask = 1 << (ch+1); |
234 | 155 | ||
235 | if (ctrl == sci_disable) { | 156 | if (ctrl == sci_disable) |
236 | *mstpcrl |= mask; | 157 | *mstpcrl |= mask; |
237 | } else { | 158 | else |
238 | *mstpcrl &= ~mask; | 159 | *mstpcrl &= ~mask; |
239 | } | ||
240 | } | 160 | } |
241 | 161 | ||
242 | static inline void h8300_sci_enable(struct uart_port *port) | 162 | static inline void h8300_sci_enable(struct uart_port *port) |
@@ -251,7 +171,7 @@ static inline void h8300_sci_disable(struct uart_port *port) | |||
251 | #endif | 171 | #endif |
252 | 172 | ||
253 | #if defined(__H8300H__) || defined(__H8300S__) | 173 | #if defined(__H8300H__) || defined(__H8300S__) |
254 | static void sci_init_pins_sci(struct uart_port* port, unsigned int cflag) | 174 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) |
255 | { | 175 | { |
256 | int ch = (port->mapbase - SMR0) >> 3; | 176 | int ch = (port->mapbase - SMR0) >> 3; |
257 | 177 | ||
@@ -266,141 +186,99 @@ static void sci_init_pins_sci(struct uart_port* port, unsigned int cflag) | |||
266 | /* tx mark output*/ | 186 | /* tx mark output*/ |
267 | H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx; | 187 | H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx; |
268 | } | 188 | } |
269 | #else | 189 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
270 | #define sci_init_pins_sci NULL | 190 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
271 | #endif | ||
272 | |||
273 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) | ||
274 | static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) | ||
275 | { | 191 | { |
276 | unsigned int fcr_val = 0; | 192 | if (port->mapbase == 0xA4400000) { |
277 | 193 | __raw_writew(__raw_readw(PACR) & 0xffc0, PACR); | |
278 | if (cflag & CRTSCTS) | 194 | __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR); |
279 | fcr_val |= SCFCR_MCE; | 195 | } else if (port->mapbase == 0xA4410000) |
280 | 196 | __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR); | |
281 | sci_out(port, SCFCR, fcr_val); | ||
282 | } | ||
283 | #else | ||
284 | #define sci_init_pins_irda NULL | ||
285 | #endif | ||
286 | |||
287 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | ||
288 | static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag) | ||
289 | { | ||
290 | unsigned int fcr_val = 0; | ||
291 | |||
292 | set_sh771x_scif_pfc(port); | ||
293 | if (cflag & CRTSCTS) { | ||
294 | fcr_val |= SCFCR_MCE; | ||
295 | } | ||
296 | sci_out(port, SCFCR, fcr_val); | ||
297 | } | 197 | } |
298 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) | 198 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) |
299 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 199 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
300 | { | 200 | { |
301 | unsigned int fcr_val = 0; | ||
302 | unsigned short data; | 201 | unsigned short data; |
303 | 202 | ||
304 | if (cflag & CRTSCTS) { | 203 | if (cflag & CRTSCTS) { |
305 | /* enable RTS/CTS */ | 204 | /* enable RTS/CTS */ |
306 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ | 205 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ |
307 | /* Clear PTCR bit 9-2; enable all scif pins but sck */ | 206 | /* Clear PTCR bit 9-2; enable all scif pins but sck */ |
308 | data = ctrl_inw(PORT_PTCR); | 207 | data = __raw_readw(PORT_PTCR); |
309 | ctrl_outw((data & 0xfc03), PORT_PTCR); | 208 | __raw_writew((data & 0xfc03), PORT_PTCR); |
310 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ | 209 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ |
311 | /* Clear PVCR bit 9-2 */ | 210 | /* Clear PVCR bit 9-2 */ |
312 | data = ctrl_inw(PORT_PVCR); | 211 | data = __raw_readw(PORT_PVCR); |
313 | ctrl_outw((data & 0xfc03), PORT_PVCR); | 212 | __raw_writew((data & 0xfc03), PORT_PVCR); |
314 | } | 213 | } |
315 | fcr_val |= SCFCR_MCE; | ||
316 | } else { | 214 | } else { |
317 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ | 215 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ |
318 | /* Clear PTCR bit 5-2; enable only tx and rx */ | 216 | /* Clear PTCR bit 5-2; enable only tx and rx */ |
319 | data = ctrl_inw(PORT_PTCR); | 217 | data = __raw_readw(PORT_PTCR); |
320 | ctrl_outw((data & 0xffc3), PORT_PTCR); | 218 | __raw_writew((data & 0xffc3), PORT_PTCR); |
321 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ | 219 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ |
322 | /* Clear PVCR bit 5-2 */ | 220 | /* Clear PVCR bit 5-2 */ |
323 | data = ctrl_inw(PORT_PVCR); | 221 | data = __raw_readw(PORT_PVCR); |
324 | ctrl_outw((data & 0xffc3), PORT_PVCR); | 222 | __raw_writew((data & 0xffc3), PORT_PVCR); |
325 | } | 223 | } |
326 | } | 224 | } |
327 | sci_out(port, SCFCR, fcr_val); | ||
328 | } | 225 | } |
329 | #elif defined(CONFIG_CPU_SH3) | 226 | #elif defined(CONFIG_CPU_SH3) |
330 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ | 227 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ |
331 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 228 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
332 | { | 229 | { |
333 | unsigned int fcr_val = 0; | ||
334 | unsigned short data; | 230 | unsigned short data; |
335 | 231 | ||
336 | /* We need to set SCPCR to enable RTS/CTS */ | 232 | /* We need to set SCPCR to enable RTS/CTS */ |
337 | data = ctrl_inw(SCPCR); | 233 | data = __raw_readw(SCPCR); |
338 | /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ | 234 | /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ |
339 | ctrl_outw(data & 0x0fcf, SCPCR); | 235 | __raw_writew(data & 0x0fcf, SCPCR); |
340 | 236 | ||
341 | if (cflag & CRTSCTS) | 237 | if (!(cflag & CRTSCTS)) { |
342 | fcr_val |= SCFCR_MCE; | ||
343 | else { | ||
344 | /* We need to set SCPCR to enable RTS/CTS */ | 238 | /* We need to set SCPCR to enable RTS/CTS */ |
345 | data = ctrl_inw(SCPCR); | 239 | data = __raw_readw(SCPCR); |
346 | /* Clear out SCP7MD1,0, SCP4MD1,0, | 240 | /* Clear out SCP7MD1,0, SCP4MD1,0, |
347 | Set SCP6MD1,0 = {01} (output) */ | 241 | Set SCP6MD1,0 = {01} (output) */ |
348 | ctrl_outw((data & 0x0fcf) | 0x1000, SCPCR); | 242 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); |
349 | 243 | ||
350 | data = ctrl_inb(SCPDR); | 244 | data = ctrl_inb(SCPDR); |
351 | /* Set /RTS2 (bit6) = 0 */ | 245 | /* Set /RTS2 (bit6) = 0 */ |
352 | ctrl_outb(data & 0xbf, SCPDR); | 246 | ctrl_outb(data & 0xbf, SCPDR); |
353 | } | 247 | } |
354 | |||
355 | sci_out(port, SCFCR, fcr_val); | ||
356 | } | 248 | } |
357 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 249 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
358 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 250 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
359 | { | 251 | { |
360 | unsigned int fcr_val = 0; | ||
361 | unsigned short data; | 252 | unsigned short data; |
362 | 253 | ||
363 | if (port->mapbase == 0xffe00000) { | 254 | if (port->mapbase == 0xffe00000) { |
364 | data = ctrl_inw(PSCR); | 255 | data = __raw_readw(PSCR); |
365 | data &= ~0x03cf; | 256 | data &= ~0x03cf; |
366 | if (cflag & CRTSCTS) | 257 | if (!(cflag & CRTSCTS)) |
367 | fcr_val |= SCFCR_MCE; | ||
368 | else | ||
369 | data |= 0x0340; | 258 | data |= 0x0340; |
370 | 259 | ||
371 | ctrl_outw(data, PSCR); | 260 | __raw_writew(data, PSCR); |
372 | } | 261 | } |
373 | /* SCIF1 and SCIF2 should be setup by board code */ | ||
374 | |||
375 | sci_out(port, SCFCR, fcr_val); | ||
376 | } | ||
377 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
378 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | ||
379 | { | ||
380 | /* Nothing to do here.. */ | ||
381 | sci_out(port, SCFCR, 0); | ||
382 | } | 262 | } |
383 | #else | ||
384 | /* For SH7750 */ | ||
385 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | ||
386 | { | ||
387 | unsigned int fcr_val = 0; | ||
388 | |||
389 | if (cflag & CRTSCTS) { | ||
390 | fcr_val |= SCFCR_MCE; | ||
391 | } else { | ||
392 | #if defined(CONFIG_CPU_SUBTYPE_SH7343) || defined(CONFIG_CPU_SUBTYPE_SH7366) | ||
393 | /* Nothing */ | ||
394 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | 263 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
395 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 264 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
396 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 265 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
397 | defined(CONFIG_CPU_SUBTYPE_SHX3) | 266 | defined(CONFIG_CPU_SUBTYPE_SHX3) |
398 | ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ | 267 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
268 | { | ||
269 | if (!(cflag & CRTSCTS)) | ||
270 | __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */ | ||
271 | } | ||
272 | #elif defined(CONFIG_CPU_SH4) && !defined(CONFIG_CPU_SH4A) | ||
273 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
274 | { | ||
275 | if (!(cflag & CRTSCTS)) | ||
276 | __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */ | ||
277 | } | ||
399 | #else | 278 | #else |
400 | ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ | 279 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
401 | #endif | 280 | { |
402 | } | 281 | /* Nothing to do */ |
403 | sci_out(port, SCFCR, fcr_val); | ||
404 | } | 282 | } |
405 | #endif | 283 | #endif |
406 | 284 | ||
@@ -419,18 +297,26 @@ static inline int scif_rxroom(struct uart_port *port) | |||
419 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 297 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
420 | static inline int scif_txroom(struct uart_port *port) | 298 | static inline int scif_txroom(struct uart_port *port) |
421 | { | 299 | { |
422 | if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/ | 300 | if ((port->mapbase == 0xffe00000) || |
301 | (port->mapbase == 0xffe08000)) { | ||
302 | /* SCIF0/1*/ | ||
423 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); | 303 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); |
424 | else /* SCIF2 */ | 304 | } else { |
305 | /* SCIF2 */ | ||
425 | return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); | 306 | return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); |
307 | } | ||
426 | } | 308 | } |
427 | 309 | ||
428 | static inline int scif_rxroom(struct uart_port *port) | 310 | static inline int scif_rxroom(struct uart_port *port) |
429 | { | 311 | { |
430 | if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/ | 312 | if ((port->mapbase == 0xffe00000) || |
313 | (port->mapbase == 0xffe08000)) { | ||
314 | /* SCIF0/1*/ | ||
431 | return sci_in(port, SCRFDR) & 0xff; | 315 | return sci_in(port, SCRFDR) & 0xff; |
432 | else /* SCIF2 */ | 316 | } else { |
317 | /* SCIF2 */ | ||
433 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; | 318 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; |
319 | } | ||
434 | } | 320 | } |
435 | #else | 321 | #else |
436 | static inline int scif_txroom(struct uart_port *port) | 322 | static inline int scif_txroom(struct uart_port *port) |
@@ -446,12 +332,12 @@ static inline int scif_rxroom(struct uart_port *port) | |||
446 | 332 | ||
447 | static inline int sci_txroom(struct uart_port *port) | 333 | static inline int sci_txroom(struct uart_port *port) |
448 | { | 334 | { |
449 | return ((sci_in(port, SCxSR) & SCI_TDRE) != 0); | 335 | return (sci_in(port, SCxSR) & SCI_TDRE) != 0; |
450 | } | 336 | } |
451 | 337 | ||
452 | static inline int sci_rxroom(struct uart_port *port) | 338 | static inline int sci_rxroom(struct uart_port *port) |
453 | { | 339 | { |
454 | return ((sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0); | 340 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; |
455 | } | 341 | } |
456 | 342 | ||
457 | /* ********************************************************************** * | 343 | /* ********************************************************************** * |
@@ -469,11 +355,10 @@ static void sci_transmit_chars(struct uart_port *port) | |||
469 | status = sci_in(port, SCxSR); | 355 | status = sci_in(port, SCxSR); |
470 | if (!(status & SCxSR_TDxE(port))) { | 356 | if (!(status & SCxSR_TDxE(port))) { |
471 | ctrl = sci_in(port, SCSCR); | 357 | ctrl = sci_in(port, SCSCR); |
472 | if (uart_circ_empty(xmit)) { | 358 | if (uart_circ_empty(xmit)) |
473 | ctrl &= ~SCI_CTRL_FLAGS_TIE; | 359 | ctrl &= ~SCI_CTRL_FLAGS_TIE; |
474 | } else { | 360 | else |
475 | ctrl |= SCI_CTRL_FLAGS_TIE; | 361 | ctrl |= SCI_CTRL_FLAGS_TIE; |
476 | } | ||
477 | sci_out(port, SCSCR, ctrl); | 362 | sci_out(port, SCSCR, ctrl); |
478 | return; | 363 | return; |
479 | } | 364 | } |
@@ -521,11 +406,11 @@ static void sci_transmit_chars(struct uart_port *port) | |||
521 | } | 406 | } |
522 | 407 | ||
523 | /* On SH3, SCIF may read end-of-break as a space->mark char */ | 408 | /* On SH3, SCIF may read end-of-break as a space->mark char */ |
524 | #define STEPFN(c) ({int __c=(c); (((__c-1)|(__c)) == -1); }) | 409 | #define STEPFN(c) ({int __c = (c); (((__c-1)|(__c)) == -1); }) |
525 | 410 | ||
526 | static inline void sci_receive_chars(struct uart_port *port) | 411 | static inline void sci_receive_chars(struct uart_port *port) |
527 | { | 412 | { |
528 | struct sci_port *sci_port = (struct sci_port *)port; | 413 | struct sci_port *sci_port = to_sci_port(port); |
529 | struct tty_struct *tty = port->info->port.tty; | 414 | struct tty_struct *tty = port->info->port.tty; |
530 | int i, count, copied = 0; | 415 | int i, count, copied = 0; |
531 | unsigned short status; | 416 | unsigned short status; |
@@ -550,13 +435,13 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
550 | 435 | ||
551 | if (port->type == PORT_SCI) { | 436 | if (port->type == PORT_SCI) { |
552 | char c = sci_in(port, SCxRDR); | 437 | char c = sci_in(port, SCxRDR); |
553 | if (uart_handle_sysrq_char(port, c) || sci_port->break_flag) | 438 | if (uart_handle_sysrq_char(port, c) || |
439 | sci_port->break_flag) | ||
554 | count = 0; | 440 | count = 0; |
555 | else { | 441 | else |
556 | tty_insert_flip_char(tty, c, TTY_NORMAL); | 442 | tty_insert_flip_char(tty, c, TTY_NORMAL); |
557 | } | ||
558 | } else { | 443 | } else { |
559 | for (i=0; i<count; i++) { | 444 | for (i = 0; i < count; i++) { |
560 | char c = sci_in(port, SCxRDR); | 445 | char c = sci_in(port, SCxRDR); |
561 | status = sci_in(port, SCxSR); | 446 | status = sci_in(port, SCxSR); |
562 | #if defined(CONFIG_CPU_SH3) | 447 | #if defined(CONFIG_CPU_SH3) |
@@ -569,7 +454,7 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
569 | } | 454 | } |
570 | 455 | ||
571 | /* Nonzero => end-of-break */ | 456 | /* Nonzero => end-of-break */ |
572 | pr_debug("scif: debounce<%02x>\n", c); | 457 | dev_dbg(port->dev, "debounce<%02x>\n", c); |
573 | sci_port->break_flag = 0; | 458 | sci_port->break_flag = 0; |
574 | 459 | ||
575 | if (STEPFN(c)) { | 460 | if (STEPFN(c)) { |
@@ -586,12 +471,13 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
586 | /* Store data and status */ | 471 | /* Store data and status */ |
587 | if (status&SCxSR_FER(port)) { | 472 | if (status&SCxSR_FER(port)) { |
588 | flag = TTY_FRAME; | 473 | flag = TTY_FRAME; |
589 | pr_debug("sci: frame error\n"); | 474 | dev_notice(port->dev, "frame error\n"); |
590 | } else if (status&SCxSR_PER(port)) { | 475 | } else if (status&SCxSR_PER(port)) { |
591 | flag = TTY_PARITY; | 476 | flag = TTY_PARITY; |
592 | pr_debug("sci: parity error\n"); | 477 | dev_notice(port->dev, "parity error\n"); |
593 | } else | 478 | } else |
594 | flag = TTY_NORMAL; | 479 | flag = TTY_NORMAL; |
480 | |||
595 | tty_insert_flip_char(tty, c, flag); | 481 | tty_insert_flip_char(tty, c, flag); |
596 | } | 482 | } |
597 | } | 483 | } |
@@ -651,13 +537,14 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
651 | /* overrun error */ | 537 | /* overrun error */ |
652 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) | 538 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) |
653 | copied++; | 539 | copied++; |
654 | pr_debug("sci: overrun error\n"); | 540 | |
541 | dev_notice(port->dev, "overrun error"); | ||
655 | } | 542 | } |
656 | 543 | ||
657 | if (status & SCxSR_FER(port)) { | 544 | if (status & SCxSR_FER(port)) { |
658 | if (sci_rxd_in(port) == 0) { | 545 | if (sci_rxd_in(port) == 0) { |
659 | /* Notify of BREAK */ | 546 | /* Notify of BREAK */ |
660 | struct sci_port *sci_port = (struct sci_port *)port; | 547 | struct sci_port *sci_port = to_sci_port(port); |
661 | 548 | ||
662 | if (!sci_port->break_flag) { | 549 | if (!sci_port->break_flag) { |
663 | sci_port->break_flag = 1; | 550 | sci_port->break_flag = 1; |
@@ -666,15 +553,19 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
666 | /* Do sysrq handling. */ | 553 | /* Do sysrq handling. */ |
667 | if (uart_handle_break(port)) | 554 | if (uart_handle_break(port)) |
668 | return 0; | 555 | return 0; |
669 | pr_debug("sci: BREAK detected\n"); | 556 | |
557 | dev_dbg(port->dev, "BREAK detected\n"); | ||
558 | |||
670 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) | 559 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) |
671 | copied++; | 560 | copied++; |
672 | } | 561 | } |
562 | |||
673 | } else { | 563 | } else { |
674 | /* frame error */ | 564 | /* frame error */ |
675 | if (tty_insert_flip_char(tty, 0, TTY_FRAME)) | 565 | if (tty_insert_flip_char(tty, 0, TTY_FRAME)) |
676 | copied++; | 566 | copied++; |
677 | pr_debug("sci: frame error\n"); | 567 | |
568 | dev_notice(port->dev, "frame error\n"); | ||
678 | } | 569 | } |
679 | } | 570 | } |
680 | 571 | ||
@@ -682,7 +573,8 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
682 | /* parity error */ | 573 | /* parity error */ |
683 | if (tty_insert_flip_char(tty, 0, TTY_PARITY)) | 574 | if (tty_insert_flip_char(tty, 0, TTY_PARITY)) |
684 | copied++; | 575 | copied++; |
685 | pr_debug("sci: parity error\n"); | 576 | |
577 | dev_notice(port->dev, "parity error"); | ||
686 | } | 578 | } |
687 | 579 | ||
688 | if (copied) | 580 | if (copied) |
@@ -691,6 +583,27 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
691 | return copied; | 583 | return copied; |
692 | } | 584 | } |
693 | 585 | ||
586 | static inline int sci_handle_fifo_overrun(struct uart_port *port) | ||
587 | { | ||
588 | struct tty_struct *tty = port->info->port.tty; | ||
589 | int copied = 0; | ||
590 | |||
591 | if (port->type != PORT_SCIF) | ||
592 | return 0; | ||
593 | |||
594 | if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { | ||
595 | sci_out(port, SCLSR, 0); | ||
596 | |||
597 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
598 | tty_flip_buffer_push(tty); | ||
599 | |||
600 | dev_notice(port->dev, "overrun error\n"); | ||
601 | copied++; | ||
602 | } | ||
603 | |||
604 | return copied; | ||
605 | } | ||
606 | |||
694 | static inline int sci_handle_breaks(struct uart_port *port) | 607 | static inline int sci_handle_breaks(struct uart_port *port) |
695 | { | 608 | { |
696 | int copied = 0; | 609 | int copied = 0; |
@@ -709,23 +622,15 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
709 | /* Notify of BREAK */ | 622 | /* Notify of BREAK */ |
710 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) | 623 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) |
711 | copied++; | 624 | copied++; |
712 | pr_debug("sci: BREAK detected\n"); | ||
713 | } | ||
714 | 625 | ||
715 | #if defined(SCIF_ORER) | 626 | dev_dbg(port->dev, "BREAK detected\n"); |
716 | /* XXX: Handle SCIF overrun error */ | ||
717 | if (port->type != PORT_SCI && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { | ||
718 | sci_out(port, SCLSR, 0); | ||
719 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { | ||
720 | copied++; | ||
721 | pr_debug("sci: overrun error\n"); | ||
722 | } | ||
723 | } | 627 | } |
724 | #endif | ||
725 | 628 | ||
726 | if (copied) | 629 | if (copied) |
727 | tty_flip_buffer_push(tty); | 630 | tty_flip_buffer_push(tty); |
728 | 631 | ||
632 | copied += sci_handle_fifo_overrun(port); | ||
633 | |||
729 | return copied; | 634 | return copied; |
730 | } | 635 | } |
731 | 636 | ||
@@ -763,16 +668,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) | |||
763 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); | 668 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); |
764 | } | 669 | } |
765 | } else { | 670 | } else { |
766 | #if defined(SCIF_ORER) | 671 | sci_handle_fifo_overrun(port); |
767 | if((sci_in(port, SCLSR) & SCIF_ORER) != 0) { | ||
768 | struct tty_struct *tty = port->info->port.tty; | ||
769 | |||
770 | sci_out(port, SCLSR, 0); | ||
771 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
772 | tty_flip_buffer_push(tty); | ||
773 | pr_debug("scif: overrun error\n"); | ||
774 | } | ||
775 | #endif | ||
776 | sci_rx_interrupt(irq, ptr); | 672 | sci_rx_interrupt(irq, ptr); |
777 | } | 673 | } |
778 | 674 | ||
@@ -801,8 +697,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
801 | struct uart_port *port = ptr; | 697 | struct uart_port *port = ptr; |
802 | irqreturn_t ret = IRQ_NONE; | 698 | irqreturn_t ret = IRQ_NONE; |
803 | 699 | ||
804 | ssr_status = sci_in(port,SCxSR); | 700 | ssr_status = sci_in(port, SCxSR); |
805 | scr_status = sci_in(port,SCSCR); | 701 | scr_status = sci_in(port, SCSCR); |
806 | 702 | ||
807 | /* Tx Interrupt */ | 703 | /* Tx Interrupt */ |
808 | if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE)) | 704 | if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE)) |
@@ -820,7 +716,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
820 | return ret; | 716 | return ret; |
821 | } | 717 | } |
822 | 718 | ||
823 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) | 719 | #ifdef CONFIG_HAVE_CLK |
824 | /* | 720 | /* |
825 | * Here we define a transistion notifier so that we can update all of our | 721 | * Here we define a transistion notifier so that we can update all of our |
826 | * ports' baud rate when the peripheral clock changes. | 722 | * ports' baud rate when the peripheral clock changes. |
@@ -828,41 +724,20 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
828 | static int sci_notifier(struct notifier_block *self, | 724 | static int sci_notifier(struct notifier_block *self, |
829 | unsigned long phase, void *p) | 725 | unsigned long phase, void *p) |
830 | { | 726 | { |
831 | struct cpufreq_freqs *freqs = p; | ||
832 | int i; | 727 | int i; |
833 | 728 | ||
834 | if ((phase == CPUFREQ_POSTCHANGE) || | 729 | if ((phase == CPUFREQ_POSTCHANGE) || |
835 | (phase == CPUFREQ_RESUMECHANGE)){ | 730 | (phase == CPUFREQ_RESUMECHANGE)) |
836 | for (i = 0; i < SCI_NPORTS; i++) { | 731 | for (i = 0; i < SCI_NPORTS; i++) { |
837 | struct uart_port *port = &sci_ports[i].port; | 732 | struct sci_port *s = &sci_ports[i]; |
838 | struct clk *clk; | 733 | s->port.uartclk = clk_get_rate(s->clk); |
839 | |||
840 | /* | ||
841 | * Update the uartclk per-port if frequency has | ||
842 | * changed, since it will no longer necessarily be | ||
843 | * consistent with the old frequency. | ||
844 | * | ||
845 | * Really we want to be able to do something like | ||
846 | * uart_change_speed() or something along those lines | ||
847 | * here to implicitly reset the per-port baud rate.. | ||
848 | * | ||
849 | * Clean this up later.. | ||
850 | */ | ||
851 | clk = clk_get(NULL, "module_clk"); | ||
852 | port->uartclk = clk_get_rate(clk); | ||
853 | clk_put(clk); | ||
854 | } | 734 | } |
855 | 735 | ||
856 | printk(KERN_INFO "%s: got a postchange notification " | ||
857 | "for cpu %d (old %d, new %d)\n", | ||
858 | __func__, freqs->cpu, freqs->old, freqs->new); | ||
859 | } | ||
860 | |||
861 | return NOTIFY_OK; | 736 | return NOTIFY_OK; |
862 | } | 737 | } |
863 | 738 | ||
864 | static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; | 739 | static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; |
865 | #endif /* CONFIG_CPU_FREQ && CONFIG_HAVE_CLK */ | 740 | #endif |
866 | 741 | ||
867 | static int sci_request_irq(struct sci_port *port) | 742 | static int sci_request_irq(struct sci_port *port) |
868 | { | 743 | { |
@@ -875,23 +750,22 @@ static int sci_request_irq(struct sci_port *port) | |||
875 | "SCI Transmit Data Empty", "SCI Break" }; | 750 | "SCI Transmit Data Empty", "SCI Break" }; |
876 | 751 | ||
877 | if (port->irqs[0] == port->irqs[1]) { | 752 | if (port->irqs[0] == port->irqs[1]) { |
878 | if (!port->irqs[0]) { | 753 | if (unlikely(!port->irqs[0])) |
879 | printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n"); | ||
880 | return -ENODEV; | 754 | return -ENODEV; |
881 | } | ||
882 | 755 | ||
883 | if (request_irq(port->irqs[0], sci_mpxed_interrupt, | 756 | if (request_irq(port->irqs[0], sci_mpxed_interrupt, |
884 | IRQF_DISABLED, "sci", port)) { | 757 | IRQF_DISABLED, "sci", port)) { |
885 | printk(KERN_ERR "sci: Cannot allocate irq.\n"); | 758 | dev_err(port->port.dev, "Can't allocate IRQ\n"); |
886 | return -ENODEV; | 759 | return -ENODEV; |
887 | } | 760 | } |
888 | } else { | 761 | } else { |
889 | for (i = 0; i < ARRAY_SIZE(handlers); i++) { | 762 | for (i = 0; i < ARRAY_SIZE(handlers); i++) { |
890 | if (!port->irqs[i]) | 763 | if (unlikely(!port->irqs[i])) |
891 | continue; | 764 | continue; |
765 | |||
892 | if (request_irq(port->irqs[i], handlers[i], | 766 | if (request_irq(port->irqs[i], handlers[i], |
893 | IRQF_DISABLED, desc[i], port)) { | 767 | IRQF_DISABLED, desc[i], port)) { |
894 | printk(KERN_ERR "sci: Cannot allocate irq.\n"); | 768 | dev_err(port->port.dev, "Can't allocate IRQ\n"); |
895 | return -ENODEV; | 769 | return -ENODEV; |
896 | } | 770 | } |
897 | } | 771 | } |
@@ -904,12 +778,9 @@ static void sci_free_irq(struct sci_port *port) | |||
904 | { | 778 | { |
905 | int i; | 779 | int i; |
906 | 780 | ||
907 | if (port->irqs[0] == port->irqs[1]) { | 781 | if (port->irqs[0] == port->irqs[1]) |
908 | if (!port->irqs[0]) | 782 | free_irq(port->irqs[0], port); |
909 | printk("sci: sci_free_irq error\n"); | 783 | else { |
910 | else | ||
911 | free_irq(port->irqs[0], port); | ||
912 | } else { | ||
913 | for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { | 784 | for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { |
914 | if (!port->irqs[i]) | 785 | if (!port->irqs[i]) |
915 | continue; | 786 | continue; |
@@ -1028,7 +899,6 @@ static void sci_shutdown(struct uart_port *port) | |||
1028 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 899 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
1029 | struct ktermios *old) | 900 | struct ktermios *old) |
1030 | { | 901 | { |
1031 | struct sci_port *s = &sci_ports[port->line]; | ||
1032 | unsigned int status, baud, smr_val; | 902 | unsigned int status, baud, smr_val; |
1033 | int t = -1; | 903 | int t = -1; |
1034 | 904 | ||
@@ -1060,32 +930,36 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1060 | sci_out(port, SCSMR, smr_val); | 930 | sci_out(port, SCSMR, smr_val); |
1061 | 931 | ||
1062 | if (t > 0) { | 932 | if (t > 0) { |
1063 | if(t >= 256) { | 933 | if (t >= 256) { |
1064 | sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); | 934 | sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); |
1065 | t >>= 2; | 935 | t >>= 2; |
1066 | } else { | 936 | } else |
1067 | sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3); | 937 | sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3); |
1068 | } | 938 | |
1069 | sci_out(port, SCBRR, t); | 939 | sci_out(port, SCBRR, t); |
1070 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ | 940 | udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ |
1071 | } | 941 | } |
1072 | 942 | ||
1073 | if (likely(s->init_pins)) | 943 | sci_init_pins(port, termios->c_cflag); |
1074 | s->init_pins(port, termios->c_cflag); | 944 | sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); |
1075 | 945 | ||
1076 | sci_out(port, SCSCR, SCSCR_INIT(port)); | 946 | sci_out(port, SCSCR, SCSCR_INIT(port)); |
1077 | 947 | ||
1078 | if ((termios->c_cflag & CREAD) != 0) | 948 | if ((termios->c_cflag & CREAD) != 0) |
1079 | sci_start_rx(port,0); | 949 | sci_start_rx(port, 0); |
1080 | } | 950 | } |
1081 | 951 | ||
1082 | static const char *sci_type(struct uart_port *port) | 952 | static const char *sci_type(struct uart_port *port) |
1083 | { | 953 | { |
1084 | switch (port->type) { | 954 | switch (port->type) { |
1085 | case PORT_SCI: return "sci"; | 955 | case PORT_IRDA: |
1086 | case PORT_SCIF: return "scif"; | 956 | return "irda"; |
1087 | case PORT_IRDA: return "irda"; | 957 | case PORT_SCI: |
1088 | case PORT_SCIFA: return "scifa"; | 958 | return "sci"; |
959 | case PORT_SCIF: | ||
960 | return "scif"; | ||
961 | case PORT_SCIFA: | ||
962 | return "scifa"; | ||
1089 | } | 963 | } |
1090 | 964 | ||
1091 | return NULL; | 965 | return NULL; |
@@ -1108,19 +982,6 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
1108 | 982 | ||
1109 | port->type = s->type; | 983 | port->type = s->type; |
1110 | 984 | ||
1111 | switch (port->type) { | ||
1112 | case PORT_SCI: | ||
1113 | s->init_pins = sci_init_pins_sci; | ||
1114 | break; | ||
1115 | case PORT_SCIF: | ||
1116 | case PORT_SCIFA: | ||
1117 | s->init_pins = sci_init_pins_scif; | ||
1118 | break; | ||
1119 | case PORT_IRDA: | ||
1120 | s->init_pins = sci_init_pins_irda; | ||
1121 | break; | ||
1122 | } | ||
1123 | |||
1124 | if (port->flags & UPF_IOREMAP && !port->membase) { | 985 | if (port->flags & UPF_IOREMAP && !port->membase) { |
1125 | #if defined(CONFIG_SUPERH64) | 986 | #if defined(CONFIG_SUPERH64) |
1126 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); | 987 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); |
@@ -1129,7 +990,7 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
1129 | port->membase = ioremap_nocache(port->mapbase, 0x40); | 990 | port->membase = ioremap_nocache(port->mapbase, 0x40); |
1130 | #endif | 991 | #endif |
1131 | 992 | ||
1132 | printk(KERN_ERR "sci: can't remap port#%d\n", port->line); | 993 | dev_err(port->dev, "can't remap port#%d\n", port->line); |
1133 | } | 994 | } |
1134 | } | 995 | } |
1135 | 996 | ||
@@ -1163,6 +1024,10 @@ static struct uart_ops sci_uart_ops = { | |||
1163 | .request_port = sci_request_port, | 1024 | .request_port = sci_request_port, |
1164 | .config_port = sci_config_port, | 1025 | .config_port = sci_config_port, |
1165 | .verify_port = sci_verify_port, | 1026 | .verify_port = sci_verify_port, |
1027 | #ifdef CONFIG_CONSOLE_POLL | ||
1028 | .poll_get_char = sci_poll_get_char, | ||
1029 | .poll_put_char = sci_poll_put_char, | ||
1030 | #endif | ||
1166 | }; | 1031 | }; |
1167 | 1032 | ||
1168 | static void __init sci_init_ports(void) | 1033 | static void __init sci_init_ports(void) |
@@ -1229,7 +1094,15 @@ int __init early_sci_setup(struct uart_port *port) | |||
1229 | static void serial_console_write(struct console *co, const char *s, | 1094 | static void serial_console_write(struct console *co, const char *s, |
1230 | unsigned count) | 1095 | unsigned count) |
1231 | { | 1096 | { |
1232 | put_string(serial_console_port, s, count); | 1097 | struct uart_port *port = &serial_console_port->port; |
1098 | int i; | ||
1099 | |||
1100 | for (i = 0; i < count; i++) { | ||
1101 | if (*s == 10) | ||
1102 | sci_poll_put_char(port, '\r'); | ||
1103 | |||
1104 | sci_poll_put_char(port, *s++); | ||
1105 | } | ||
1233 | } | 1106 | } |
1234 | 1107 | ||
1235 | static int __init serial_console_setup(struct console *co, char *options) | 1108 | static int __init serial_console_setup(struct console *co, char *options) |
@@ -1307,89 +1180,8 @@ static int __init sci_console_init(void) | |||
1307 | console_initcall(sci_console_init); | 1180 | console_initcall(sci_console_init); |
1308 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 1181 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
1309 | 1182 | ||
1310 | #ifdef CONFIG_SH_KGDB_CONSOLE | 1183 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) |
1311 | /* | 1184 | #define SCI_CONSOLE (&serial_console) |
1312 | * FIXME: Most of this can go away.. at the moment, we rely on | ||
1313 | * arch/sh/kernel/setup.c to do the command line parsing for kgdb, though | ||
1314 | * most of that can easily be done here instead. | ||
1315 | * | ||
1316 | * For the time being, just accept the values that were parsed earlier.. | ||
1317 | */ | ||
1318 | static void __init kgdb_console_get_options(struct uart_port *port, int *baud, | ||
1319 | int *parity, int *bits) | ||
1320 | { | ||
1321 | *baud = kgdb_baud; | ||
1322 | *parity = tolower(kgdb_parity); | ||
1323 | *bits = kgdb_bits - '0'; | ||
1324 | } | ||
1325 | |||
1326 | /* | ||
1327 | * The naming here is somewhat misleading, since kgdb_console_setup() takes | ||
1328 | * care of the early-on initialization for kgdb, regardless of whether we | ||
1329 | * actually use kgdb as a console or not. | ||
1330 | * | ||
1331 | * On the plus side, this lets us kill off the old kgdb_sci_setup() nonsense. | ||
1332 | */ | ||
1333 | int __init kgdb_console_setup(struct console *co, char *options) | ||
1334 | { | ||
1335 | struct uart_port *port = &sci_ports[kgdb_portnum].port; | ||
1336 | int baud = 38400; | ||
1337 | int bits = 8; | ||
1338 | int parity = 'n'; | ||
1339 | int flow = 'n'; | ||
1340 | |||
1341 | if (co->index != kgdb_portnum) | ||
1342 | co->index = kgdb_portnum; | ||
1343 | |||
1344 | kgdb_sci_port = &sci_ports[co->index]; | ||
1345 | port = &kgdb_sci_port->port; | ||
1346 | |||
1347 | /* | ||
1348 | * Also need to check port->type, we don't actually have any | ||
1349 | * UPIO_PORT ports, but uart_report_port() handily misreports | ||
1350 | * it anyways if we don't have a port available by the time this is | ||
1351 | * called. | ||
1352 | */ | ||
1353 | if (!port->type) | ||
1354 | return -ENODEV; | ||
1355 | if (!port->membase || !port->mapbase) | ||
1356 | return -ENODEV; | ||
1357 | |||
1358 | if (options) | ||
1359 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
1360 | else | ||
1361 | kgdb_console_get_options(port, &baud, &parity, &bits); | ||
1362 | |||
1363 | kgdb_getchar = kgdb_sci_getchar; | ||
1364 | kgdb_putchar = kgdb_sci_putchar; | ||
1365 | |||
1366 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
1367 | } | ||
1368 | |||
1369 | static struct console kgdb_console = { | ||
1370 | .name = "ttySC", | ||
1371 | .device = uart_console_device, | ||
1372 | .write = kgdb_console_write, | ||
1373 | .setup = kgdb_console_setup, | ||
1374 | .flags = CON_PRINTBUFFER, | ||
1375 | .index = -1, | ||
1376 | .data = &sci_uart_driver, | ||
1377 | }; | ||
1378 | |||
1379 | /* Register the KGDB console so we get messages (d'oh!) */ | ||
1380 | static int __init kgdb_console_init(void) | ||
1381 | { | ||
1382 | sci_init_ports(); | ||
1383 | register_console(&kgdb_console); | ||
1384 | return 0; | ||
1385 | } | ||
1386 | console_initcall(kgdb_console_init); | ||
1387 | #endif /* CONFIG_SH_KGDB_CONSOLE */ | ||
1388 | |||
1389 | #if defined(CONFIG_SH_KGDB_CONSOLE) | ||
1390 | #define SCI_CONSOLE &kgdb_console | ||
1391 | #elif defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | ||
1392 | #define SCI_CONSOLE &serial_console | ||
1393 | #else | 1185 | #else |
1394 | #define SCI_CONSOLE 0 | 1186 | #define SCI_CONSOLE 0 |
1395 | #endif | 1187 | #endif |
@@ -1463,15 +1255,8 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1463 | uart_add_one_port(&sci_uart_driver, &sciport->port); | 1255 | uart_add_one_port(&sci_uart_driver, &sciport->port); |
1464 | } | 1256 | } |
1465 | 1257 | ||
1466 | #if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE) | 1258 | #ifdef CONFIG_HAVE_CLK |
1467 | kgdb_sci_port = &sci_ports[kgdb_portnum]; | ||
1468 | kgdb_getchar = kgdb_sci_getchar; | ||
1469 | kgdb_putchar = kgdb_sci_putchar; | ||
1470 | #endif | ||
1471 | |||
1472 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) | ||
1473 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1259 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1474 | dev_info(&dev->dev, "CPU frequency notifier registered\n"); | ||
1475 | #endif | 1260 | #endif |
1476 | 1261 | ||
1477 | #ifdef CONFIG_SH_STANDARD_BIOS | 1262 | #ifdef CONFIG_SH_STANDARD_BIOS |
@@ -1491,6 +1276,10 @@ static int __devexit sci_remove(struct platform_device *dev) | |||
1491 | { | 1276 | { |
1492 | int i; | 1277 | int i; |
1493 | 1278 | ||
1279 | #ifdef CONFIG_HAVE_CLK | ||
1280 | cpufreq_unregister_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); | ||
1281 | #endif | ||
1282 | |||
1494 | for (i = 0; i < SCI_NPORTS; i++) | 1283 | for (i = 0; i < SCI_NPORTS; i++) |
1495 | uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); | 1284 | uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); |
1496 | 1285 | ||