aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-12-09 01:14:38 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-12-09 01:14:38 -0500
commitbcd6acd51f3d4d1ada201e9bc5c40a31d6d80c71 (patch)
tree2f6dffd2d3e4dd67355a224de7e7a960335a92fd /drivers/serial
parent11c34c7deaeeebcee342cbc35e1bb2a6711b2431 (diff)
parent3ff6a468b45b5dfeb0e903e56f4eb27d34b2437c (diff)
Merge commit 'origin/master' into next
Conflicts: include/linux/kvm.h
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Kconfig13
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/apbuart.c710
-rw-r--r--drivers/serial/apbuart.h64
-rw-r--r--drivers/serial/bcm63xx_uart.c4
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/s3c2412.c2
-rw-r--r--drivers/serial/s3c2440.c2
-rw-r--r--drivers/serial/s3c24a0.c2
-rw-r--r--drivers/serial/samsung.c2
-rw-r--r--drivers/serial/samsung.h2
-rw-r--r--drivers/serial/serial_cs.c143
-rw-r--r--drivers/serial/suncore.c37
-rw-r--r--drivers/serial/suncore.h5
-rw-r--r--drivers/serial/sunhv.c2
-rw-r--r--drivers/serial/sunsab.c9
-rw-r--r--drivers/serial/sunsu.c36
-rw-r--r--drivers/serial/sunzilog.c8
18 files changed, 899 insertions, 145 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e52257257279..50943ff78f4b 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1477,4 +1477,17 @@ config SERIAL_BCM63XX_CONSOLE
1477 If you have enabled the serial port on the bcm63xx CPU 1477 If you have enabled the serial port on the bcm63xx CPU
1478 you can make it the console by answering Y to this option. 1478 you can make it the console by answering Y to this option.
1479 1479
1480config SERIAL_GRLIB_GAISLER_APBUART
1481 tristate "GRLIB APBUART serial support"
1482 depends on OF
1483 ---help---
1484 Add support for the GRLIB APBUART serial port.
1485
1486config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
1487 bool "Console on GRLIB APBUART serial port"
1488 depends on SERIAL_GRLIB_GAISLER_APBUART=y
1489 select SERIAL_CORE_CONSOLE
1490 help
1491 Support for running a console on the GRLIB APBUART
1492
1480endmenu 1493endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index d21d5dd5d048..5548fe7df61d 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -81,3 +81,4 @@ obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
81obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o 81obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
82obj-$(CONFIG_SERIAL_QE) += ucc_uart.o 82obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
83obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o 83obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
84obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c
new file mode 100644
index 000000000000..fe91319b5f65
--- /dev/null
+++ b/drivers/serial/apbuart.c
@@ -0,0 +1,710 @@
1/*
2 * Driver for GRLIB serial ports (APBUART)
3 *
4 * Based on linux/drivers/serial/amba.c
5 *
6 * Copyright (C) 2000 Deep Blue Solutions Ltd.
7 * Copyright (C) 2003 Konrad Eisele <eiselekd@web.de>
8 * Copyright (C) 2006 Daniel Hellstrom <daniel@gaisler.com>, Aeroflex Gaisler AB
9 * Copyright (C) 2008 Gilead Kutnick <kutnickg@zin-tech.com>
10 * Copyright (C) 2009 Kristoffer Glembo <kristoffer@gaisler.com>, Aeroflex Gaisler AB
11 */
12
13#if defined(CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
14#define SUPPORT_SYSRQ
15#endif
16
17#include <linux/module.h>
18#include <linux/tty.h>
19#include <linux/ioport.h>
20#include <linux/init.h>
21#include <linux/serial.h>
22#include <linux/console.h>
23#include <linux/sysrq.h>
24#include <linux/kthread.h>
25#include <linux/device.h>
26#include <linux/of.h>
27#include <linux/of_device.h>
28#include <linux/of_platform.h>
29#include <linux/platform_device.h>
30#include <linux/io.h>
31#include <linux/serial_core.h>
32#include <asm/irq.h>
33
34#include "apbuart.h"
35
36#define SERIAL_APBUART_MAJOR TTY_MAJOR
37#define SERIAL_APBUART_MINOR 64
38#define UART_DUMMY_RSR_RX 0x8000 /* for ignore all read */
39
40static void apbuart_tx_chars(struct uart_port *port);
41
42static void apbuart_stop_tx(struct uart_port *port)
43{
44 unsigned int cr;
45
46 cr = UART_GET_CTRL(port);
47 cr &= ~UART_CTRL_TI;
48 UART_PUT_CTRL(port, cr);
49}
50
51static void apbuart_start_tx(struct uart_port *port)
52{
53 unsigned int cr;
54
55 cr = UART_GET_CTRL(port);
56 cr |= UART_CTRL_TI;
57 UART_PUT_CTRL(port, cr);
58
59 if (UART_GET_STATUS(port) & UART_STATUS_THE)
60 apbuart_tx_chars(port);
61}
62
63static void apbuart_stop_rx(struct uart_port *port)
64{
65 unsigned int cr;
66
67 cr = UART_GET_CTRL(port);
68 cr &= ~(UART_CTRL_RI);
69 UART_PUT_CTRL(port, cr);
70}
71
72static void apbuart_enable_ms(struct uart_port *port)
73{
74 /* No modem status change interrupts for APBUART */
75}
76
77static void apbuart_rx_chars(struct uart_port *port)
78{
79 struct tty_struct *tty = port->state->port.tty;
80 unsigned int status, ch, rsr, flag;
81 unsigned int max_chars = port->fifosize;
82
83 status = UART_GET_STATUS(port);
84
85 while (UART_RX_DATA(status) && (max_chars--)) {
86
87 ch = UART_GET_CHAR(port);
88 flag = TTY_NORMAL;
89
90 port->icount.rx++;
91
92 rsr = UART_GET_STATUS(port) | UART_DUMMY_RSR_RX;
93 UART_PUT_STATUS(port, 0);
94 if (rsr & UART_STATUS_ERR) {
95
96 if (rsr & UART_STATUS_BR) {
97 rsr &= ~(UART_STATUS_FE | UART_STATUS_PE);
98 port->icount.brk++;
99 if (uart_handle_break(port))
100 goto ignore_char;
101 } else if (rsr & UART_STATUS_PE) {
102 port->icount.parity++;
103 } else if (rsr & UART_STATUS_FE) {
104 port->icount.frame++;
105 }
106 if (rsr & UART_STATUS_OE)
107 port->icount.overrun++;
108
109 rsr &= port->read_status_mask;
110
111 if (rsr & UART_STATUS_PE)
112 flag = TTY_PARITY;
113 else if (rsr & UART_STATUS_FE)
114 flag = TTY_FRAME;
115 }
116
117 if (uart_handle_sysrq_char(port, ch))
118 goto ignore_char;
119
120 uart_insert_char(port, rsr, UART_STATUS_OE, ch, flag);
121
122
123 ignore_char:
124 status = UART_GET_STATUS(port);
125 }
126
127 tty_flip_buffer_push(tty);
128}
129
130static void apbuart_tx_chars(struct uart_port *port)
131{
132 struct circ_buf *xmit = &port->state->xmit;
133 int count;
134
135 if (port->x_char) {
136 UART_PUT_CHAR(port, port->x_char);
137 port->icount.tx++;
138 port->x_char = 0;
139 return;
140 }
141
142 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
143 apbuart_stop_tx(port);
144 return;
145 }
146
147 /* amba: fill FIFO */
148 count = port->fifosize >> 1;
149 do {
150 UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
151 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
152 port->icount.tx++;
153 if (uart_circ_empty(xmit))
154 break;
155 } while (--count > 0);
156
157 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
158 uart_write_wakeup(port);
159
160 if (uart_circ_empty(xmit))
161 apbuart_stop_tx(port);
162}
163
164static irqreturn_t apbuart_int(int irq, void *dev_id)
165{
166 struct uart_port *port = dev_id;
167 unsigned int status;
168
169 spin_lock(&port->lock);
170
171 status = UART_GET_STATUS(port);
172 if (status & UART_STATUS_DR)
173 apbuart_rx_chars(port);
174 if (status & UART_STATUS_THE)
175 apbuart_tx_chars(port);
176
177 spin_unlock(&port->lock);
178
179 return IRQ_HANDLED;
180}
181
182static unsigned int apbuart_tx_empty(struct uart_port *port)
183{
184 unsigned int status = UART_GET_STATUS(port);
185 return status & UART_STATUS_THE ? TIOCSER_TEMT : 0;
186}
187
188static unsigned int apbuart_get_mctrl(struct uart_port *port)
189{
190 /* The GRLIB APBUART handles flow control in hardware */
191 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
192}
193
194static void apbuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
195{
196 /* The GRLIB APBUART handles flow control in hardware */
197}
198
199static void apbuart_break_ctl(struct uart_port *port, int break_state)
200{
201 /* We don't support sending break */
202}
203
204static int apbuart_startup(struct uart_port *port)
205{
206 int retval;
207 unsigned int cr;
208
209 /* Allocate the IRQ */
210 retval = request_irq(port->irq, apbuart_int, 0, "apbuart", port);
211 if (retval)
212 return retval;
213
214 /* Finally, enable interrupts */
215 cr = UART_GET_CTRL(port);
216 UART_PUT_CTRL(port,
217 cr | UART_CTRL_RE | UART_CTRL_TE |
218 UART_CTRL_RI | UART_CTRL_TI);
219
220 return 0;
221}
222
223static void apbuart_shutdown(struct uart_port *port)
224{
225 unsigned int cr;
226
227 /* disable all interrupts, disable the port */
228 cr = UART_GET_CTRL(port);
229 UART_PUT_CTRL(port,
230 cr & ~(UART_CTRL_RE | UART_CTRL_TE |
231 UART_CTRL_RI | UART_CTRL_TI));
232
233 /* Free the interrupt */
234 free_irq(port->irq, port);
235}
236
237static void apbuart_set_termios(struct uart_port *port,
238 struct ktermios *termios, struct ktermios *old)
239{
240 unsigned int cr;
241 unsigned long flags;
242 unsigned int baud, quot;
243
244 /* Ask the core to calculate the divisor for us. */
245 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
246 if (baud == 0)
247 panic("invalid baudrate %i\n", port->uartclk / 16);
248
249 /* uart_get_divisor calc a *16 uart freq, apbuart is *8 */
250 quot = (uart_get_divisor(port, baud)) * 2;
251 cr = UART_GET_CTRL(port);
252 cr &= ~(UART_CTRL_PE | UART_CTRL_PS);
253
254 if (termios->c_cflag & PARENB) {
255 cr |= UART_CTRL_PE;
256 if ((termios->c_cflag & PARODD))
257 cr |= UART_CTRL_PS;
258 }
259
260 /* Enable flow control. */
261 if (termios->c_cflag & CRTSCTS)
262 cr |= UART_CTRL_FL;
263
264 spin_lock_irqsave(&port->lock, flags);
265
266 /* Update the per-port timeout. */
267 uart_update_timeout(port, termios->c_cflag, baud);
268
269 port->read_status_mask = UART_STATUS_OE;
270 if (termios->c_iflag & INPCK)
271 port->read_status_mask |= UART_STATUS_FE | UART_STATUS_PE;
272
273 /* Characters to ignore */
274 port->ignore_status_mask = 0;
275 if (termios->c_iflag & IGNPAR)
276 port->ignore_status_mask |= UART_STATUS_FE | UART_STATUS_PE;
277
278 /* Ignore all characters if CREAD is not set. */
279 if ((termios->c_cflag & CREAD) == 0)
280 port->ignore_status_mask |= UART_DUMMY_RSR_RX;
281
282 /* Set baud rate */
283 quot -= 1;
284 UART_PUT_SCAL(port, quot);
285 UART_PUT_CTRL(port, cr);
286
287 spin_unlock_irqrestore(&port->lock, flags);
288}
289
290static const char *apbuart_type(struct uart_port *port)
291{
292 return port->type == PORT_APBUART ? "GRLIB/APBUART" : NULL;
293}
294
295static void apbuart_release_port(struct uart_port *port)
296{
297 release_mem_region(port->mapbase, 0x100);
298}
299
300static int apbuart_request_port(struct uart_port *port)
301{
302 return request_mem_region(port->mapbase, 0x100, "grlib-apbuart")
303 != NULL ? 0 : -EBUSY;
304 return 0;
305}
306
307/* Configure/autoconfigure the port */
308static void apbuart_config_port(struct uart_port *port, int flags)
309{
310 if (flags & UART_CONFIG_TYPE) {
311 port->type = PORT_APBUART;
312 apbuart_request_port(port);
313 }
314}
315
316/* Verify the new serial_struct (for TIOCSSERIAL) */
317static int apbuart_verify_port(struct uart_port *port,
318 struct serial_struct *ser)
319{
320 int ret = 0;
321 if (ser->type != PORT_UNKNOWN && ser->type != PORT_APBUART)
322 ret = -EINVAL;
323 if (ser->irq < 0 || ser->irq >= NR_IRQS)
324 ret = -EINVAL;
325 if (ser->baud_base < 9600)
326 ret = -EINVAL;
327 return ret;
328}
329
330static struct uart_ops grlib_apbuart_ops = {
331 .tx_empty = apbuart_tx_empty,
332 .set_mctrl = apbuart_set_mctrl,
333 .get_mctrl = apbuart_get_mctrl,
334 .stop_tx = apbuart_stop_tx,
335 .start_tx = apbuart_start_tx,
336 .stop_rx = apbuart_stop_rx,
337 .enable_ms = apbuart_enable_ms,
338 .break_ctl = apbuart_break_ctl,
339 .startup = apbuart_startup,
340 .shutdown = apbuart_shutdown,
341 .set_termios = apbuart_set_termios,
342 .type = apbuart_type,
343 .release_port = apbuart_release_port,
344 .request_port = apbuart_request_port,
345 .config_port = apbuart_config_port,
346 .verify_port = apbuart_verify_port,
347};
348
349static struct uart_port grlib_apbuart_ports[UART_NR];
350static struct device_node *grlib_apbuart_nodes[UART_NR];
351
352static int apbuart_scan_fifo_size(struct uart_port *port, int portnumber)
353{
354 int ctrl, loop = 0;
355 int status;
356 int fifosize;
357 unsigned long flags;
358
359 ctrl = UART_GET_CTRL(port);
360
361 /*
362 * Enable the transceiver and wait for it to be ready to send data.
363 * Clear interrupts so that this process will not be externally
364 * interrupted in the middle (which can cause the transceiver to
365 * drain prematurely).
366 */
367
368 local_irq_save(flags);
369
370 UART_PUT_CTRL(port, ctrl | UART_CTRL_TE);
371
372 while (!UART_TX_READY(UART_GET_STATUS(port)))
373 loop++;
374
375 /*
376 * Disable the transceiver so data isn't actually sent during the
377 * actual test.
378 */
379
380 UART_PUT_CTRL(port, ctrl & ~(UART_CTRL_TE));
381
382 fifosize = 1;
383 UART_PUT_CHAR(port, 0);
384
385 /*
386 * So long as transmitting a character increments the tranceivier FIFO
387 * length the FIFO must be at least that big. These bytes will
388 * automatically drain off of the FIFO.
389 */
390
391 status = UART_GET_STATUS(port);
392 while (((status >> 20) & 0x3F) == fifosize) {
393 fifosize++;
394 UART_PUT_CHAR(port, 0);
395 status = UART_GET_STATUS(port);
396 }
397
398 fifosize--;
399
400 UART_PUT_CTRL(port, ctrl);
401 local_irq_restore(flags);
402
403 if (fifosize == 0)
404 fifosize = 1;
405
406 return fifosize;
407}
408
409static void apbuart_flush_fifo(struct uart_port *port)
410{
411 int i;
412
413 for (i = 0; i < port->fifosize; i++)
414 UART_GET_CHAR(port);
415}
416
417
418/* ======================================================================== */
419/* Console driver, if enabled */
420/* ======================================================================== */
421
422#ifdef CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
423
424static void apbuart_console_putchar(struct uart_port *port, int ch)
425{
426 unsigned int status;
427 do {
428 status = UART_GET_STATUS(port);
429 } while (!UART_TX_READY(status));
430 UART_PUT_CHAR(port, ch);
431}
432
433static void
434apbuart_console_write(struct console *co, const char *s, unsigned int count)
435{
436 struct uart_port *port = &grlib_apbuart_ports[co->index];
437 unsigned int status, old_cr, new_cr;
438
439 /* First save the CR then disable the interrupts */
440 old_cr = UART_GET_CTRL(port);
441 new_cr = old_cr & ~(UART_CTRL_RI | UART_CTRL_TI);
442 UART_PUT_CTRL(port, new_cr);
443
444 uart_console_write(port, s, count, apbuart_console_putchar);
445
446 /*
447 * Finally, wait for transmitter to become empty
448 * and restore the TCR
449 */
450 do {
451 status = UART_GET_STATUS(port);
452 } while (!UART_TX_READY(status));
453 UART_PUT_CTRL(port, old_cr);
454}
455
456static void __init
457apbuart_console_get_options(struct uart_port *port, int *baud,
458 int *parity, int *bits)
459{
460 if (UART_GET_CTRL(port) & (UART_CTRL_RE | UART_CTRL_TE)) {
461
462 unsigned int quot, status;
463 status = UART_GET_STATUS(port);
464
465 *parity = 'n';
466 if (status & UART_CTRL_PE) {
467 if ((status & UART_CTRL_PS) == 0)
468 *parity = 'e';
469 else
470 *parity = 'o';
471 }
472
473 *bits = 8;
474 quot = UART_GET_SCAL(port) / 8;
475 *baud = port->uartclk / (16 * (quot + 1));
476 }
477}
478
479static int __init apbuart_console_setup(struct console *co, char *options)
480{
481 struct uart_port *port;
482 int baud = 38400;
483 int bits = 8;
484 int parity = 'n';
485 int flow = 'n';
486
487 pr_debug("apbuart_console_setup co=%p, co->index=%i, options=%s\n",
488 co, co->index, options);
489
490 /*
491 * Check whether an invalid uart number has been specified, and
492 * if so, search for the first available port that does have
493 * console support.
494 */
495 if (co->index >= grlib_apbuart_port_nr)
496 co->index = 0;
497
498 port = &grlib_apbuart_ports[co->index];
499
500 spin_lock_init(&port->lock);
501
502 if (options)
503 uart_parse_options(options, &baud, &parity, &bits, &flow);
504 else
505 apbuart_console_get_options(port, &baud, &parity, &bits);
506
507 return uart_set_options(port, co, baud, parity, bits, flow);
508}
509
510static struct uart_driver grlib_apbuart_driver;
511
512static struct console grlib_apbuart_console = {
513 .name = "ttyS",
514 .write = apbuart_console_write,
515 .device = uart_console_device,
516 .setup = apbuart_console_setup,
517 .flags = CON_PRINTBUFFER,
518 .index = -1,
519 .data = &grlib_apbuart_driver,
520};
521
522
523static void grlib_apbuart_configure(void);
524
525static int __init apbuart_console_init(void)
526{
527 grlib_apbuart_configure();
528 register_console(&grlib_apbuart_console);
529 return 0;
530}
531
532console_initcall(apbuart_console_init);
533
534#define APBUART_CONSOLE (&grlib_apbuart_console)
535#else
536#define APBUART_CONSOLE NULL
537#endif
538
539static struct uart_driver grlib_apbuart_driver = {
540 .owner = THIS_MODULE,
541 .driver_name = "serial",
542 .dev_name = "ttyS",
543 .major = SERIAL_APBUART_MAJOR,
544 .minor = SERIAL_APBUART_MINOR,
545 .nr = UART_NR,
546 .cons = APBUART_CONSOLE,
547};
548
549
550/* ======================================================================== */
551/* OF Platform Driver */
552/* ======================================================================== */
553
554static int __devinit apbuart_probe(struct of_device *op,
555 const struct of_device_id *match)
556{
557 int i = -1;
558 struct uart_port *port = NULL;
559
560 i = 0;
561 for (i = 0; i < grlib_apbuart_port_nr; i++) {
562 if (op->node == grlib_apbuart_nodes[i])
563 break;
564 }
565
566 port = &grlib_apbuart_ports[i];
567 port->dev = &op->dev;
568
569 uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port);
570
571 apbuart_flush_fifo((struct uart_port *) port);
572
573 printk(KERN_INFO "grlib-apbuart at 0x%llx, irq %d\n",
574 (unsigned long long) port->mapbase, port->irq);
575 return 0;
576
577}
578
579static struct of_device_id __initdata apbuart_match[] = {
580 {
581 .name = "GAISLER_APBUART",
582 },
583 {},
584};
585
586static struct of_platform_driver grlib_apbuart_of_driver = {
587 .match_table = apbuart_match,
588 .probe = apbuart_probe,
589 .driver = {
590 .owner = THIS_MODULE,
591 .name = "grlib-apbuart",
592 },
593};
594
595
596static void grlib_apbuart_configure(void)
597{
598 static int enum_done;
599 struct device_node *np, *rp;
600 struct uart_port *port = NULL;
601 const u32 *prop;
602 int freq_khz;
603 int v = 0, d = 0;
604 unsigned int addr;
605 int irq, line;
606 struct amba_prom_registers *regs;
607
608 if (enum_done)
609 return;
610
611 /* Get bus frequency */
612 rp = of_find_node_by_path("/");
613 rp = of_get_next_child(rp, NULL);
614 prop = of_get_property(rp, "clock-frequency", NULL);
615 freq_khz = *prop;
616
617 line = 0;
618 for_each_matching_node(np, apbuart_match) {
619
620 int *vendor = (int *) of_get_property(np, "vendor", NULL);
621 int *device = (int *) of_get_property(np, "device", NULL);
622 int *irqs = (int *) of_get_property(np, "interrupts", NULL);
623 regs = (struct amba_prom_registers *)
624 of_get_property(np, "reg", NULL);
625
626 if (vendor)
627 v = *vendor;
628 if (device)
629 d = *device;
630
631 if (!irqs || !regs)
632 return;
633
634 grlib_apbuart_nodes[line] = np;
635
636 addr = regs->phys_addr;
637 irq = *irqs;
638
639 port = &grlib_apbuart_ports[line];
640
641 port->mapbase = addr;
642 port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map));
643 port->irq = irq;
644 port->iotype = UPIO_MEM;
645 port->ops = &grlib_apbuart_ops;
646 port->flags = UPF_BOOT_AUTOCONF;
647 port->line = line;
648 port->uartclk = freq_khz * 1000;
649 port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line);
650 line++;
651
652 /* We support maximum UART_NR uarts ... */
653 if (line == UART_NR)
654 break;
655
656 }
657
658 enum_done = 1;
659
660 grlib_apbuart_driver.nr = grlib_apbuart_port_nr = line;
661}
662
663static int __init grlib_apbuart_init(void)
664{
665 int ret;
666
667 /* Find all APBUARTS in device the tree and initialize their ports */
668 grlib_apbuart_configure();
669
670 printk(KERN_INFO "Serial: GRLIB APBUART driver\n");
671
672 ret = uart_register_driver(&grlib_apbuart_driver);
673
674 if (ret) {
675 printk(KERN_ERR "%s: uart_register_driver failed (%i)\n",
676 __FILE__, ret);
677 return ret;
678 }
679
680 ret = of_register_platform_driver(&grlib_apbuart_of_driver);
681 if (ret) {
682 printk(KERN_ERR
683 "%s: of_register_platform_driver failed (%i)\n",
684 __FILE__, ret);
685 uart_unregister_driver(&grlib_apbuart_driver);
686 return ret;
687 }
688
689 return ret;
690}
691
692static void __exit grlib_apbuart_exit(void)
693{
694 int i;
695
696 for (i = 0; i < grlib_apbuart_port_nr; i++)
697 uart_remove_one_port(&grlib_apbuart_driver,
698 &grlib_apbuart_ports[i]);
699
700 uart_unregister_driver(&grlib_apbuart_driver);
701 of_unregister_platform_driver(&grlib_apbuart_of_driver);
702}
703
704module_init(grlib_apbuart_init);
705module_exit(grlib_apbuart_exit);
706
707MODULE_AUTHOR("Aeroflex Gaisler AB");
708MODULE_DESCRIPTION("GRLIB APBUART serial driver");
709MODULE_VERSION("2.1");
710MODULE_LICENSE("GPL");
diff --git a/drivers/serial/apbuart.h b/drivers/serial/apbuart.h
new file mode 100644
index 000000000000..5faf87c8d2bc
--- /dev/null
+++ b/drivers/serial/apbuart.h
@@ -0,0 +1,64 @@
1#ifndef __GRLIB_APBUART_H__
2#define __GRLIB_APBUART_H__
3
4#include <asm/io.h>
5
6#define UART_NR 8
7static int grlib_apbuart_port_nr;
8
9struct grlib_apbuart_regs_map {
10 u32 data;
11 u32 status;
12 u32 ctrl;
13 u32 scaler;
14};
15
16struct amba_prom_registers {
17 unsigned int phys_addr;
18 unsigned int reg_size;
19};
20
21/*
22 * The following defines the bits in the APBUART Status Registers.
23 */
24#define UART_STATUS_DR 0x00000001 /* Data Ready */
25#define UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */
26#define UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */
27#define UART_STATUS_BR 0x00000008 /* Break Error */
28#define UART_STATUS_OE 0x00000010 /* RX Overrun Error */
29#define UART_STATUS_PE 0x00000020 /* RX Parity Error */
30#define UART_STATUS_FE 0x00000040 /* RX Framing Error */
31#define UART_STATUS_ERR 0x00000078 /* Error Mask */
32
33/*
34 * The following defines the bits in the APBUART Ctrl Registers.
35 */
36#define UART_CTRL_RE 0x00000001 /* Receiver enable */
37#define UART_CTRL_TE 0x00000002 /* Transmitter enable */
38#define UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */
39#define UART_CTRL_TI 0x00000008 /* Transmitter irq */
40#define UART_CTRL_PS 0x00000010 /* Parity select */
41#define UART_CTRL_PE 0x00000020 /* Parity enable */
42#define UART_CTRL_FL 0x00000040 /* Flow control enable */
43#define UART_CTRL_LB 0x00000080 /* Loopback enable */
44
45#define APBBASE(port) ((struct grlib_apbuart_regs_map *)((port)->membase))
46
47#define APBBASE_DATA_P(port) (&(APBBASE(port)->data))
48#define APBBASE_STATUS_P(port) (&(APBBASE(port)->status))
49#define APBBASE_CTRL_P(port) (&(APBBASE(port)->ctrl))
50#define APBBASE_SCALAR_P(port) (&(APBBASE(port)->scaler))
51
52#define UART_GET_CHAR(port) (__raw_readl(APBBASE_DATA_P(port)))
53#define UART_PUT_CHAR(port, v) (__raw_writel(v, APBBASE_DATA_P(port)))
54#define UART_GET_STATUS(port) (__raw_readl(APBBASE_STATUS_P(port)))
55#define UART_PUT_STATUS(port, v)(__raw_writel(v, APBBASE_STATUS_P(port)))
56#define UART_GET_CTRL(port) (__raw_readl(APBBASE_CTRL_P(port)))
57#define UART_PUT_CTRL(port, v) (__raw_writel(v, APBBASE_CTRL_P(port)))
58#define UART_GET_SCAL(port) (__raw_readl(APBBASE_SCALAR_P(port)))
59#define UART_PUT_SCAL(port, v) (__raw_writel(v, APBBASE_SCALAR_P(port)))
60
61#define UART_RX_DATA(s) (((s) & UART_STATUS_DR) != 0)
62#define UART_TX_READY(s) (((s) & UART_STATUS_THE) != 0)
63
64#endif /* __GRLIB_APBUART_H__ */
diff --git a/drivers/serial/bcm63xx_uart.c b/drivers/serial/bcm63xx_uart.c
index beddaa6e9069..37ad0c449937 100644
--- a/drivers/serial/bcm63xx_uart.c
+++ b/drivers/serial/bcm63xx_uart.c
@@ -242,7 +242,7 @@ static void bcm_uart_do_rx(struct uart_port *port)
242 * higher than fifo size anyway since we're much faster than 242 * higher than fifo size anyway since we're much faster than
243 * serial port */ 243 * serial port */
244 max_count = 32; 244 max_count = 32;
245 tty = port->info->port.tty; 245 tty = port->state->port.tty;
246 do { 246 do {
247 unsigned int iestat, c, cstat; 247 unsigned int iestat, c, cstat;
248 char flag; 248 char flag;
@@ -318,7 +318,7 @@ static void bcm_uart_do_tx(struct uart_port *port)
318 return; 318 return;
319 } 319 }
320 320
321 xmit = &port->info->xmit; 321 xmit = &port->state->xmit;
322 if (uart_circ_empty(xmit)) 322 if (uart_circ_empty(xmit))
323 goto txq_empty; 323 goto txq_empty;
324 324
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index c99f0821cae3..73f089d3efd6 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * Driver for Samsung S3C2410 SoC onboard UARTs. 3 * Driver for Samsung S3C2410 SoC onboard UARTs.
4 * 4 *
5 * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics 5 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
6 * http://armlinux.simtec.co.uk/ 6 * http://armlinux.simtec.co.uk/
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c
index 6e057d8809d3..ce75e28e36ef 100644
--- a/drivers/serial/s3c2412.c
+++ b/drivers/serial/s3c2412.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs. 3 * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
4 * 4 *
5 * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics 5 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
6 * http://armlinux.simtec.co.uk/ 6 * http://armlinux.simtec.co.uk/
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c
index 69ff5d340f04..094cc3904b13 100644
--- a/drivers/serial/s3c2440.c
+++ b/drivers/serial/s3c2440.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs. 3 * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
4 * 4 *
5 * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics 5 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
6 * http://armlinux.simtec.co.uk/ 6 * http://armlinux.simtec.co.uk/
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/serial/s3c24a0.c b/drivers/serial/s3c24a0.c
index 26c49e18bdd1..fad6083ca427 100644
--- a/drivers/serial/s3c24a0.c
+++ b/drivers/serial/s3c24a0.c
@@ -6,7 +6,7 @@
6 * 6 *
7 * Author: Sandeep Patil <sandeep.patil@azingo.com> 7 * Author: Sandeep Patil <sandeep.patil@azingo.com>
8 * 8 *
9 * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics 9 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
10 * http://armlinux.simtec.co.uk/ 10 * http://armlinux.simtec.co.uk/
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 1523e8d9ae77..52e3df113ec0 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * Driver core for Samsung SoC onboard UARTs. 3 * Driver core for Samsung SoC onboard UARTs.
4 * 4 *
5 * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics 5 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
6 * http://armlinux.simtec.co.uk/ 6 * http://armlinux.simtec.co.uk/
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/serial/samsung.h b/drivers/serial/samsung.h
index d3fe315969f6..1fb22343df42 100644
--- a/drivers/serial/samsung.h
+++ b/drivers/serial/samsung.h
@@ -2,7 +2,7 @@
2 * 2 *
3 * Driver for Samsung SoC onboard UARTs. 3 * Driver for Samsung SoC onboard UARTs.
4 * 4 *
5 * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics 5 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
6 * http://armlinux.simtec.co.uk/ 6 * http://armlinux.simtec.co.uk/
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 7c7914f5fa02..fc413f0f8dd2 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -54,14 +54,6 @@
54 54
55#include "8250.h" 55#include "8250.h"
56 56
57#ifdef PCMCIA_DEBUG
58static int pc_debug = PCMCIA_DEBUG;
59module_param(pc_debug, int, 0644);
60#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
61static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)";
62#else
63#define DEBUG(n, args...)
64#endif
65 57
66/*====================================================================*/ 58/*====================================================================*/
67 59
@@ -121,24 +113,20 @@ static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_
121static int quirk_post_ibm(struct pcmcia_device *link) 113static int quirk_post_ibm(struct pcmcia_device *link)
122{ 114{
123 conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; 115 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
124 int last_ret, last_fn; 116 int ret;
117
118 ret = pcmcia_access_configuration_register(link, &reg);
119 if (ret)
120 goto failed;
125 121
126 last_ret = pcmcia_access_configuration_register(link, &reg);
127 if (last_ret) {
128 last_fn = AccessConfigurationRegister;
129 goto cs_failed;
130 }
131 reg.Action = CS_WRITE; 122 reg.Action = CS_WRITE;
132 reg.Value = reg.Value | 1; 123 reg.Value = reg.Value | 1;
133 last_ret = pcmcia_access_configuration_register(link, &reg); 124 ret = pcmcia_access_configuration_register(link, &reg);
134 if (last_ret) { 125 if (ret)
135 last_fn = AccessConfigurationRegister; 126 goto failed;
136 goto cs_failed;
137 }
138 return 0; 127 return 0;
139 128
140 cs_failed: 129 failed:
141 cs_error(link, last_fn, last_ret);
142 return -ENODEV; 130 return -ENODEV;
143} 131}
144 132
@@ -283,7 +271,7 @@ static void serial_remove(struct pcmcia_device *link)
283 struct serial_info *info = link->priv; 271 struct serial_info *info = link->priv;
284 int i; 272 int i;
285 273
286 DEBUG(0, "serial_release(0x%p)\n", link); 274 dev_dbg(&link->dev, "serial_release\n");
287 275
288 /* 276 /*
289 * Recheck to see if the device is still configured. 277 * Recheck to see if the device is still configured.
@@ -334,7 +322,7 @@ static int serial_probe(struct pcmcia_device *link)
334{ 322{
335 struct serial_info *info; 323 struct serial_info *info;
336 324
337 DEBUG(0, "serial_attach()\n"); 325 dev_dbg(&link->dev, "serial_attach()\n");
338 326
339 /* Create new serial device */ 327 /* Create new serial device */
340 info = kzalloc(sizeof (*info), GFP_KERNEL); 328 info = kzalloc(sizeof (*info), GFP_KERNEL);
@@ -346,7 +334,6 @@ static int serial_probe(struct pcmcia_device *link)
346 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 334 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
347 link->io.NumPorts1 = 8; 335 link->io.NumPorts1 = 8;
348 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; 336 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
349 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
350 link->conf.Attributes = CONF_ENABLE_IRQ; 337 link->conf.Attributes = CONF_ENABLE_IRQ;
351 if (do_sound) { 338 if (do_sound) {
352 link->conf.Attributes |= CONF_ENABLE_SPKR; 339 link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -370,7 +357,7 @@ static void serial_detach(struct pcmcia_device *link)
370{ 357{
371 struct serial_info *info = link->priv; 358 struct serial_info *info = link->priv;
372 359
373 DEBUG(0, "serial_detach(0x%p)\n", link); 360 dev_dbg(&link->dev, "serial_detach\n");
374 361
375 /* 362 /*
376 * Ensure any outstanding scheduled tasks are completed. 363 * Ensure any outstanding scheduled tasks are completed.
@@ -399,7 +386,7 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
399 port.irq = irq; 386 port.irq = irq;
400 port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; 387 port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
401 port.uartclk = 1843200; 388 port.uartclk = 1843200;
402 port.dev = &handle_to_dev(handle); 389 port.dev = &handle->dev;
403 if (buggy_uart) 390 if (buggy_uart)
404 port.flags |= UPF_BUGGY_UART; 391 port.flags |= UPF_BUGGY_UART;
405 392
@@ -426,21 +413,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
426 413
427/*====================================================================*/ 414/*====================================================================*/
428 415
429static int
430first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
431{
432 int i;
433 i = pcmcia_get_first_tuple(handle, tuple);
434 if (i != 0)
435 return i;
436 i = pcmcia_get_tuple_data(handle, tuple);
437 if (i != 0)
438 return i;
439 return pcmcia_parse_tuple(tuple, parse);
440}
441
442/*====================================================================*/
443
444static int simple_config_check(struct pcmcia_device *p_dev, 416static int simple_config_check(struct pcmcia_device *p_dev,
445 cistpl_cftable_entry_t *cf, 417 cistpl_cftable_entry_t *cf,
446 cistpl_cftable_entry_t *dflt, 418 cistpl_cftable_entry_t *dflt,
@@ -522,15 +494,13 @@ static int simple_config(struct pcmcia_device *link)
522 494
523 printk(KERN_NOTICE 495 printk(KERN_NOTICE
524 "serial_cs: no usable port range found, giving up\n"); 496 "serial_cs: no usable port range found, giving up\n");
525 cs_error(link, RequestIO, i);
526 return -1; 497 return -1;
527 498
528found_port: 499found_port:
529 i = pcmcia_request_irq(link, &link->irq); 500 i = pcmcia_request_irq(link, &link->irq);
530 if (i != 0) { 501 if (i != 0)
531 cs_error(link, RequestIRQ, i);
532 link->irq.AssignedIRQ = 0; 502 link->irq.AssignedIRQ = 0;
533 } 503
534 if (info->multi && (info->manfid == MANFID_3COM)) 504 if (info->multi && (info->manfid == MANFID_3COM))
535 link->conf.ConfigIndex &= ~(0x08); 505 link->conf.ConfigIndex &= ~(0x08);
536 506
@@ -541,10 +511,8 @@ found_port:
541 info->quirk->config(link); 511 info->quirk->config(link);
542 512
543 i = pcmcia_request_configuration(link, &link->conf); 513 i = pcmcia_request_configuration(link, &link->conf);
544 if (i != 0) { 514 if (i != 0)
545 cs_error(link, RequestConfiguration, i);
546 return -1; 515 return -1;
547 }
548 return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); 516 return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
549} 517}
550 518
@@ -613,7 +581,6 @@ static int multi_config(struct pcmcia_device *link)
613 /* FIXME: comment does not fit, error handling does not fit */ 581 /* FIXME: comment does not fit, error handling does not fit */
614 printk(KERN_NOTICE 582 printk(KERN_NOTICE
615 "serial_cs: no usable port range found, giving up\n"); 583 "serial_cs: no usable port range found, giving up\n");
616 cs_error(link, RequestIRQ, i);
617 link->irq.AssignedIRQ = 0; 584 link->irq.AssignedIRQ = 0;
618 } 585 }
619 586
@@ -624,10 +591,8 @@ static int multi_config(struct pcmcia_device *link)
624 info->quirk->config(link); 591 info->quirk->config(link);
625 592
626 i = pcmcia_request_configuration(link, &link->conf); 593 i = pcmcia_request_configuration(link, &link->conf);
627 if (i != 0) { 594 if (i != 0)
628 cs_error(link, RequestConfiguration, i);
629 return -ENODEV; 595 return -ENODEV;
630 }
631 596
632 /* The Oxford Semiconductor OXCF950 cards are in fact single-port: 597 /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
633 * 8 registers are for the UART, the others are extra registers. 598 * 8 registers are for the UART, the others are extra registers.
@@ -665,6 +630,25 @@ static int multi_config(struct pcmcia_device *link)
665 return 0; 630 return 0;
666} 631}
667 632
633static int serial_check_for_multi(struct pcmcia_device *p_dev,
634 cistpl_cftable_entry_t *cf,
635 cistpl_cftable_entry_t *dflt,
636 unsigned int vcc,
637 void *priv_data)
638{
639 struct serial_info *info = p_dev->priv;
640
641 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
642 info->multi = cf->io.win[0].len >> 3;
643
644 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
645 (cf->io.win[1].len == 8))
646 info->multi = 2;
647
648 return 0; /* break */
649}
650
651
668/*====================================================================== 652/*======================================================================
669 653
670 serial_config() is scheduled to run after a CARD_INSERTION event 654 serial_config() is scheduled to run after a CARD_INSERTION event
@@ -676,46 +660,14 @@ static int multi_config(struct pcmcia_device *link)
676static int serial_config(struct pcmcia_device * link) 660static int serial_config(struct pcmcia_device * link)
677{ 661{
678 struct serial_info *info = link->priv; 662 struct serial_info *info = link->priv;
679 struct serial_cfg_mem *cfg_mem; 663 int i;
680 tuple_t *tuple;
681 u_char *buf;
682 cisparse_t *parse;
683 cistpl_cftable_entry_t *cf;
684 int i, last_ret, last_fn;
685
686 DEBUG(0, "serial_config(0x%p)\n", link);
687
688 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
689 if (!cfg_mem)
690 goto failed;
691 664
692 tuple = &cfg_mem->tuple; 665 dev_dbg(&link->dev, "serial_config\n");
693 parse = &cfg_mem->parse;
694 cf = &parse->cftable_entry;
695 buf = cfg_mem->buf;
696
697 tuple->TupleData = (cisdata_t *) buf;
698 tuple->TupleOffset = 0;
699 tuple->TupleDataMax = 255;
700 tuple->Attributes = 0;
701
702 /* Get configuration register information */
703 tuple->DesiredTuple = CISTPL_CONFIG;
704 last_ret = first_tuple(link, tuple, parse);
705 if (last_ret != 0) {
706 last_fn = ParseTuple;
707 goto cs_failed;
708 }
709 link->conf.ConfigBase = parse->config.base;
710 link->conf.Present = parse->config.rmask[0];
711 666
712 /* Is this a compliant multifunction card? */ 667 /* Is this a compliant multifunction card? */
713 tuple->DesiredTuple = CISTPL_LONGLINK_MFC; 668 info->multi = (link->socket->functions > 1);
714 tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
715 info->multi = (first_tuple(link, tuple, parse) == 0);
716 669
717 /* Is this a multiport card? */ 670 /* Is this a multiport card? */
718 tuple->DesiredTuple = CISTPL_MANFID;
719 info->manfid = link->manf_id; 671 info->manfid = link->manf_id;
720 info->prodid = link->card_id; 672 info->prodid = link->card_id;
721 673
@@ -730,20 +682,11 @@ static int serial_config(struct pcmcia_device * link)
730 682
731 /* Another check for dual-serial cards: look for either serial or 683 /* Another check for dual-serial cards: look for either serial or
732 multifunction cards that ask for appropriate IO port ranges */ 684 multifunction cards that ask for appropriate IO port ranges */
733 tuple->DesiredTuple = CISTPL_FUNCID;
734 if ((info->multi == 0) && 685 if ((info->multi == 0) &&
735 (link->has_func_id) && 686 (link->has_func_id) &&
736 ((link->func_id == CISTPL_FUNCID_MULTI) || 687 ((link->func_id == CISTPL_FUNCID_MULTI) ||
737 (link->func_id == CISTPL_FUNCID_SERIAL))) { 688 (link->func_id == CISTPL_FUNCID_SERIAL)))
738 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; 689 pcmcia_loop_config(link, serial_check_for_multi, info);
739 if (first_tuple(link, tuple, parse) == 0) {
740 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
741 info->multi = cf->io.win[0].len >> 3;
742 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
743 (cf->io.win[1].len == 8))
744 info->multi = 2;
745 }
746 }
747 690
748 /* 691 /*
749 * Apply any multi-port quirk. 692 * Apply any multi-port quirk.
@@ -768,14 +711,10 @@ static int serial_config(struct pcmcia_device * link)
768 goto failed; 711 goto failed;
769 712
770 link->dev_node = &info->node[0]; 713 link->dev_node = &info->node[0];
771 kfree(cfg_mem);
772 return 0; 714 return 0;
773 715
774cs_failed:
775 cs_error(link, last_fn, last_ret);
776failed: 716failed:
777 serial_remove(link); 717 serial_remove(link);
778 kfree(cfg_mem);
779 return -ENODEV; 718 return -ENODEV;
780} 719}
781 720
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index a2d4a19550ab..ed7d958b0a01 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -53,20 +53,21 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count)
53EXPORT_SYMBOL(sunserial_unregister_minors); 53EXPORT_SYMBOL(sunserial_unregister_minors);
54 54
55int sunserial_console_match(struct console *con, struct device_node *dp, 55int sunserial_console_match(struct console *con, struct device_node *dp,
56 struct uart_driver *drv, int line) 56 struct uart_driver *drv, int line, bool ignore_line)
57{ 57{
58 int off;
59
60 if (!con || of_console_device != dp) 58 if (!con || of_console_device != dp)
61 return 0; 59 return 0;
62 60
63 off = 0; 61 if (!ignore_line) {
64 if (of_console_options && 62 int off = 0;
65 *of_console_options == 'b')
66 off = 1;
67 63
68 if ((line & 1) != off) 64 if (of_console_options &&
69 return 0; 65 *of_console_options == 'b')
66 off = 1;
67
68 if ((line & 1) != off)
69 return 0;
70 }
70 71
71 con->index = line; 72 con->index = line;
72 drv->cons = con; 73 drv->cons = con;
@@ -76,23 +77,24 @@ int sunserial_console_match(struct console *con, struct device_node *dp,
76} 77}
77EXPORT_SYMBOL(sunserial_console_match); 78EXPORT_SYMBOL(sunserial_console_match);
78 79
79void 80void sunserial_console_termios(struct console *con, struct device_node *uart_dp)
80sunserial_console_termios(struct console *con)
81{ 81{
82 struct device_node *dp; 82 const char *mode, *s;
83 const char *od, *mode, *s;
84 char mode_prop[] = "ttyX-mode"; 83 char mode_prop[] = "ttyX-mode";
85 int baud, bits, stop, cflag; 84 int baud, bits, stop, cflag;
86 char parity; 85 char parity;
87 86
88 dp = of_find_node_by_path("/options"); 87 if (!strcmp(uart_dp->name, "rsc") ||
89 od = of_get_property(dp, "output-device", NULL); 88 !strcmp(uart_dp->name, "rsc-console") ||
90 if (!strcmp(od, "rsc")) { 89 !strcmp(uart_dp->name, "rsc-control")) {
91 mode = of_get_property(of_console_device, 90 mode = of_get_property(uart_dp,
92 "ssp-console-modes", NULL); 91 "ssp-console-modes", NULL);
93 if (!mode) 92 if (!mode)
94 mode = "115200,8,n,1,-"; 93 mode = "115200,8,n,1,-";
94 } else if (!strcmp(uart_dp->name, "lom-console")) {
95 mode = "9600,8,n,1,-";
95 } else { 96 } else {
97 struct device_node *dp;
96 char c; 98 char c;
97 99
98 c = 'a'; 100 c = 'a';
@@ -101,6 +103,7 @@ sunserial_console_termios(struct console *con)
101 103
102 mode_prop[3] = c; 104 mode_prop[3] = c;
103 105
106 dp = of_find_node_by_path("/options");
104 mode = of_get_property(dp, mode_prop, NULL); 107 mode = of_get_property(dp, mode_prop, NULL);
105 if (!mode) 108 if (!mode)
106 mode = "9600,8,n,1,-"; 109 mode = "9600,8,n,1,-";
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h
index 042668aa602e..db2057936c31 100644
--- a/drivers/serial/suncore.h
+++ b/drivers/serial/suncore.h
@@ -26,7 +26,8 @@ extern int sunserial_register_minors(struct uart_driver *, int);
26extern void sunserial_unregister_minors(struct uart_driver *, int); 26extern void sunserial_unregister_minors(struct uart_driver *, int);
27 27
28extern int sunserial_console_match(struct console *, struct device_node *, 28extern int sunserial_console_match(struct console *, struct device_node *,
29 struct uart_driver *, int); 29 struct uart_driver *, int, bool);
30extern void sunserial_console_termios(struct console *); 30extern void sunserial_console_termios(struct console *,
31 struct device_node *);
31 32
32#endif /* !(_SERIAL_SUN_H) */ 33#endif /* !(_SERIAL_SUN_H) */
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index d548652dee50..d14cca7fb88d 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -566,7 +566,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
566 goto out_free_con_read_page; 566 goto out_free_con_read_page;
567 567
568 sunserial_console_match(&sunhv_console, op->node, 568 sunserial_console_match(&sunhv_console, op->node,
569 &sunhv_reg, port->line); 569 &sunhv_reg, port->line, false);
570 570
571 err = uart_add_one_port(&sunhv_reg, port); 571 err = uart_add_one_port(&sunhv_reg, port);
572 if (err) 572 if (err)
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index d1ad34128635..d514e28d0755 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options)
883 printk("Console: ttyS%d (SAB82532)\n", 883 printk("Console: ttyS%d (SAB82532)\n",
884 (sunsab_reg.minor - 64) + con->index); 884 (sunsab_reg.minor - 64) + con->index);
885 885
886 sunserial_console_termios(con); 886 sunserial_console_termios(con, to_of_device(up->port.dev)->node);
887 887
888 switch (con->cflag & CBAUD) { 888 switch (con->cflag & CBAUD) {
889 case B150: baud = 150; break; 889 case B150: baud = 150; break;
@@ -1027,10 +1027,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
1027 goto out1; 1027 goto out1;
1028 1028
1029 sunserial_console_match(SUNSAB_CONSOLE(), op->node, 1029 sunserial_console_match(SUNSAB_CONSOLE(), op->node,
1030 &sunsab_reg, up[0].port.line); 1030 &sunsab_reg, up[0].port.line,
1031 false);
1031 1032
1032 sunserial_console_match(SUNSAB_CONSOLE(), op->node, 1033 sunserial_console_match(SUNSAB_CONSOLE(), op->node,
1033 &sunsab_reg, up[1].port.line); 1034 &sunsab_reg, up[1].port.line,
1035 false);
1034 1036
1035 err = uart_add_one_port(&sunsab_reg, &up[0].port); 1037 err = uart_add_one_port(&sunsab_reg, &up[0].port);
1036 if (err) 1038 if (err)
@@ -1116,7 +1118,6 @@ static int __init sunsab_init(void)
1116 if (!sunsab_ports) 1118 if (!sunsab_ports)
1117 return -ENOMEM; 1119 return -ENOMEM;
1118 1120
1119 sunsab_reg.cons = SUNSAB_CONSOLE();
1120 err = sunserial_register_minors(&sunsab_reg, num_channels); 1121 err = sunserial_register_minors(&sunsab_reg, num_channels);
1121 if (err) { 1122 if (err) {
1122 kfree(sunsab_ports); 1123 kfree(sunsab_ports);
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 68d262b15749..170d3d68c8f0 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1329,11 +1329,9 @@ static void sunsu_console_write(struct console *co, const char *s,
1329 */ 1329 */
1330static int __init sunsu_console_setup(struct console *co, char *options) 1330static int __init sunsu_console_setup(struct console *co, char *options)
1331{ 1331{
1332 static struct ktermios dummy;
1333 struct ktermios termios;
1332 struct uart_port *port; 1334 struct uart_port *port;
1333 int baud = 9600;
1334 int bits = 8;
1335 int parity = 'n';
1336 int flow = 'n';
1337 1335
1338 printk("Console: ttyS%d (SU)\n", 1336 printk("Console: ttyS%d (SU)\n",
1339 (sunsu_reg.minor - 64) + co->index); 1337 (sunsu_reg.minor - 64) + co->index);
@@ -1352,10 +1350,15 @@ static int __init sunsu_console_setup(struct console *co, char *options)
1352 */ 1350 */
1353 spin_lock_init(&port->lock); 1351 spin_lock_init(&port->lock);
1354 1352
1355 if (options) 1353 /* Get firmware console settings. */
1356 uart_parse_options(options, &baud, &parity, &bits, &flow); 1354 sunserial_console_termios(co, to_of_device(port->dev)->node);
1357 1355
1358 return uart_set_options(port, co, baud, parity, bits, flow); 1356 memset(&termios, 0, sizeof(struct ktermios));
1357 termios.c_cflag = co->cflag;
1358 port->mctrl |= TIOCM_DTR;
1359 port->ops->set_termios(port, &termios, &dummy);
1360
1361 return 0;
1359} 1362}
1360 1363
1361static struct console sunsu_console = { 1364static struct console sunsu_console = {
@@ -1409,6 +1412,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
1409 struct uart_sunsu_port *up; 1412 struct uart_sunsu_port *up;
1410 struct resource *rp; 1413 struct resource *rp;
1411 enum su_type type; 1414 enum su_type type;
1415 bool ignore_line;
1412 int err; 1416 int err;
1413 1417
1414 type = su_get_type(dp); 1418 type = su_get_type(dp);
@@ -1467,8 +1471,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
1467 1471
1468 up->port.ops = &sunsu_pops; 1472 up->port.ops = &sunsu_pops;
1469 1473
1474 ignore_line = false;
1475 if (!strcmp(dp->name, "rsc-console") ||
1476 !strcmp(dp->name, "lom-console"))
1477 ignore_line = true;
1478
1470 sunserial_console_match(SUNSU_CONSOLE(), dp, 1479 sunserial_console_match(SUNSU_CONSOLE(), dp,
1471 &sunsu_reg, up->port.line); 1480 &sunsu_reg, up->port.line,
1481 ignore_line);
1472 err = uart_add_one_port(&sunsu_reg, &up->port); 1482 err = uart_add_one_port(&sunsu_reg, &up->port);
1473 if (err) 1483 if (err)
1474 goto out_unmap; 1484 goto out_unmap;
@@ -1517,6 +1527,10 @@ static const struct of_device_id su_match[] = {
1517 .name = "serial", 1527 .name = "serial",
1518 .compatible = "su", 1528 .compatible = "su",
1519 }, 1529 },
1530 {
1531 .type = "serial",
1532 .compatible = "su",
1533 },
1520 {}, 1534 {},
1521}; 1535};
1522MODULE_DEVICE_TABLE(of, su_match); 1536MODULE_DEVICE_TABLE(of, su_match);
@@ -1548,6 +1562,12 @@ static int __init sunsu_init(void)
1548 num_uart++; 1562 num_uart++;
1549 } 1563 }
1550 } 1564 }
1565 for_each_node_by_type(dp, "serial") {
1566 if (of_device_is_compatible(dp, "su")) {
1567 if (su_get_type(dp) == SU_PORT_PORT)
1568 num_uart++;
1569 }
1570 }
1551 1571
1552 if (num_uart) { 1572 if (num_uart) {
1553 err = sunserial_register_minors(&sunsu_reg, num_uart); 1573 err = sunserial_register_minors(&sunsu_reg, num_uart);
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index ef693ae22e7f..2c7a66af4f52 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
1180 (sunzilog_reg.minor - 64) + con->index, con->index); 1180 (sunzilog_reg.minor - 64) + con->index, con->index);
1181 1181
1182 /* Get firmware console settings. */ 1182 /* Get firmware console settings. */
1183 sunserial_console_termios(con); 1183 sunserial_console_termios(con, to_of_device(up->port.dev)->node);
1184 1184
1185 /* Firmware console speed is limited to 150-->38400 baud so 1185 /* Firmware console speed is limited to 150-->38400 baud so
1186 * this hackish cflag thing is OK. 1186 * this hackish cflag thing is OK.
@@ -1416,7 +1416,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1416 1416
1417 if (!keyboard_mouse) { 1417 if (!keyboard_mouse) {
1418 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, 1418 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
1419 &sunzilog_reg, up[0].port.line)) 1419 &sunzilog_reg, up[0].port.line,
1420 false))
1420 up->flags |= SUNZILOG_FLAG_IS_CONS; 1421 up->flags |= SUNZILOG_FLAG_IS_CONS;
1421 err = uart_add_one_port(&sunzilog_reg, &up[0].port); 1422 err = uart_add_one_port(&sunzilog_reg, &up[0].port);
1422 if (err) { 1423 if (err) {
@@ -1425,7 +1426,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1425 return err; 1426 return err;
1426 } 1427 }
1427 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, 1428 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
1428 &sunzilog_reg, up[1].port.line)) 1429 &sunzilog_reg, up[1].port.line,
1430 false))
1429 up->flags |= SUNZILOG_FLAG_IS_CONS; 1431 up->flags |= SUNZILOG_FLAG_IS_CONS;
1430 err = uart_add_one_port(&sunzilog_reg, &up[1].port); 1432 err = uart_add_one_port(&sunzilog_reg, &up[1].port);
1431 if (err) { 1433 if (err) {