diff options
Diffstat (limited to 'drivers/serial')
26 files changed, 1891 insertions, 305 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 2b1ea3d4c4f4..891e1dd65f24 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -1891,8 +1891,8 @@ static int serial8250_get_poll_char(struct uart_port *port) | |||
1891 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1891 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
1892 | unsigned char lsr = serial_inp(up, UART_LSR); | 1892 | unsigned char lsr = serial_inp(up, UART_LSR); |
1893 | 1893 | ||
1894 | while (!(lsr & UART_LSR_DR)) | 1894 | if (!(lsr & UART_LSR_DR)) |
1895 | lsr = serial_inp(up, UART_LSR); | 1895 | return NO_POLL_CHAR; |
1896 | 1896 | ||
1897 | return serial_inp(up, UART_RX); | 1897 | return serial_inp(up, UART_RX); |
1898 | } | 1898 | } |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index f55c49475a8c..8b23165bc5dc 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -518,12 +518,13 @@ config SERIAL_S3C2412 | |||
518 | Serial port support for the Samsung S3C2412 and S3C2413 SoC | 518 | Serial port support for the Samsung S3C2412 and S3C2413 SoC |
519 | 519 | ||
520 | config SERIAL_S3C2440 | 520 | config SERIAL_S3C2440 |
521 | tristate "Samsung S3C2440/S3C2442 Serial port support" | 521 | tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support" |
522 | depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442) | 522 | depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416) |
523 | default y if CPU_S3C2440 | 523 | default y if CPU_S3C2440 |
524 | default y if CPU_S3C2442 | 524 | default y if CPU_S3C2442 |
525 | select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416 | ||
525 | help | 526 | help |
526 | Serial port support for the Samsung S3C2440 and S3C2442 SoC | 527 | Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC |
527 | 528 | ||
528 | config SERIAL_S3C24A0 | 529 | config SERIAL_S3C24A0 |
529 | tristate "Samsung S3C24A0 Serial port support" | 530 | tristate "Samsung S3C24A0 Serial port support" |
@@ -533,21 +534,13 @@ config SERIAL_S3C24A0 | |||
533 | Serial port support for the Samsung S3C24A0 SoC | 534 | Serial port support for the Samsung S3C24A0 SoC |
534 | 535 | ||
535 | config SERIAL_S3C6400 | 536 | config SERIAL_S3C6400 |
536 | tristate "Samsung S3C6400/S3C6410/S5P6440 Seria port support" | 537 | tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support" |
537 | depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440) | 538 | depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100) |
538 | select SERIAL_SAMSUNG_UARTS_4 | 539 | select SERIAL_SAMSUNG_UARTS_4 |
539 | default y | 540 | default y |
540 | help | 541 | help |
541 | Serial port support for the Samsung S3C6400, S3C6410 and S5P6440 | 542 | Serial port support for the Samsung S3C6400, S3C6410, S5P6440 |
542 | SoCs | 543 | and S5PC100 SoCs |
543 | |||
544 | config SERIAL_S5PC100 | ||
545 | tristate "Samsung S5PC100 Serial port support" | ||
546 | depends on SERIAL_SAMSUNG && CPU_S5PC100 | ||
547 | select SERIAL_SAMSUNG_UARTS_4 | ||
548 | default y | ||
549 | help | ||
550 | Serial port support for the Samsung S5PC100 SoCs | ||
551 | 544 | ||
552 | config SERIAL_S5PV210 | 545 | config SERIAL_S5PV210 |
553 | tristate "Samsung S5PV210 Serial port support" | 546 | tristate "Samsung S5PV210 Serial port support" |
@@ -1430,8 +1423,8 @@ config SERIAL_SC26XX_CONSOLE | |||
1430 | Support for Console on SC2681/SC2692 serial ports. | 1423 | Support for Console on SC2681/SC2692 serial ports. |
1431 | 1424 | ||
1432 | config SERIAL_BFIN_SPORT | 1425 | config SERIAL_BFIN_SPORT |
1433 | tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)" | 1426 | tristate "Blackfin SPORT emulate UART" |
1434 | depends on BLACKFIN && EXPERIMENTAL | 1427 | depends on BLACKFIN |
1435 | select SERIAL_CORE | 1428 | select SERIAL_CORE |
1436 | help | 1429 | help |
1437 | Enable SPORT emulate UART on Blackfin series. | 1430 | Enable SPORT emulate UART on Blackfin series. |
@@ -1446,28 +1439,52 @@ config SERIAL_BFIN_SPORT_CONSOLE | |||
1446 | 1439 | ||
1447 | config SERIAL_BFIN_SPORT0_UART | 1440 | config SERIAL_BFIN_SPORT0_UART |
1448 | bool "Enable UART over SPORT0" | 1441 | bool "Enable UART over SPORT0" |
1449 | depends on SERIAL_BFIN_SPORT && !(BF542 || BF542M || BF544 || BF544M) | 1442 | depends on SERIAL_BFIN_SPORT && !(BF542 || BF544) |
1450 | help | 1443 | help |
1451 | Enable UART over SPORT0 | 1444 | Enable UART over SPORT0 |
1452 | 1445 | ||
1446 | config SERIAL_BFIN_SPORT0_UART_CTSRTS | ||
1447 | bool "Enable UART over SPORT0 hardware flow control" | ||
1448 | depends on SERIAL_BFIN_SPORT0_UART | ||
1449 | help | ||
1450 | Enable hardware flow control in the driver. | ||
1451 | |||
1453 | config SERIAL_BFIN_SPORT1_UART | 1452 | config SERIAL_BFIN_SPORT1_UART |
1454 | bool "Enable UART over SPORT1" | 1453 | bool "Enable UART over SPORT1" |
1455 | depends on SERIAL_BFIN_SPORT | 1454 | depends on SERIAL_BFIN_SPORT |
1456 | help | 1455 | help |
1457 | Enable UART over SPORT1 | 1456 | Enable UART over SPORT1 |
1458 | 1457 | ||
1458 | config SERIAL_BFIN_SPORT1_UART_CTSRTS | ||
1459 | bool "Enable UART over SPORT1 hardware flow control" | ||
1460 | depends on SERIAL_BFIN_SPORT1_UART | ||
1461 | help | ||
1462 | Enable hardware flow control in the driver. | ||
1463 | |||
1459 | config SERIAL_BFIN_SPORT2_UART | 1464 | config SERIAL_BFIN_SPORT2_UART |
1460 | bool "Enable UART over SPORT2" | 1465 | bool "Enable UART over SPORT2" |
1461 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) | 1466 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1462 | help | 1467 | help |
1463 | Enable UART over SPORT2 | 1468 | Enable UART over SPORT2 |
1464 | 1469 | ||
1470 | config SERIAL_BFIN_SPORT2_UART_CTSRTS | ||
1471 | bool "Enable UART over SPORT2 hardware flow control" | ||
1472 | depends on SERIAL_BFIN_SPORT2_UART | ||
1473 | help | ||
1474 | Enable hardware flow control in the driver. | ||
1475 | |||
1465 | config SERIAL_BFIN_SPORT3_UART | 1476 | config SERIAL_BFIN_SPORT3_UART |
1466 | bool "Enable UART over SPORT3" | 1477 | bool "Enable UART over SPORT3" |
1467 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) | 1478 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1468 | help | 1479 | help |
1469 | Enable UART over SPORT3 | 1480 | Enable UART over SPORT3 |
1470 | 1481 | ||
1482 | config SERIAL_BFIN_SPORT3_UART_CTSRTS | ||
1483 | bool "Enable UART over SPORT3 hardware flow control" | ||
1484 | depends on SERIAL_BFIN_SPORT3_UART | ||
1485 | help | ||
1486 | Enable hardware flow control in the driver. | ||
1487 | |||
1471 | config SERIAL_TIMBERDALE | 1488 | config SERIAL_TIMBERDALE |
1472 | tristate "Support for timberdale UART" | 1489 | tristate "Support for timberdale UART" |
1473 | select SERIAL_CORE | 1490 | select SERIAL_CORE |
@@ -1506,4 +1523,56 @@ config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE | |||
1506 | help | 1523 | help |
1507 | Support for running a console on the GRLIB APBUART | 1524 | Support for running a console on the GRLIB APBUART |
1508 | 1525 | ||
1526 | config SERIAL_ALTERA_JTAGUART | ||
1527 | tristate "Altera JTAG UART support" | ||
1528 | select SERIAL_CORE | ||
1529 | help | ||
1530 | This driver supports the Altera JTAG UART port. | ||
1531 | |||
1532 | config SERIAL_ALTERA_JTAGUART_CONSOLE | ||
1533 | bool "Altera JTAG UART console support" | ||
1534 | depends on SERIAL_ALTERA_JTAGUART=y | ||
1535 | select SERIAL_CORE_CONSOLE | ||
1536 | help | ||
1537 | Enable a Altera JTAG UART port to be the system console. | ||
1538 | |||
1539 | config SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS | ||
1540 | bool "Bypass output when no connection" | ||
1541 | depends on SERIAL_ALTERA_JTAGUART_CONSOLE | ||
1542 | select SERIAL_CORE_CONSOLE | ||
1543 | help | ||
1544 | Bypass console output and keep going even if there is no | ||
1545 | JTAG terminal connection with the host. | ||
1546 | |||
1547 | config SERIAL_ALTERA_UART | ||
1548 | tristate "Altera UART support" | ||
1549 | select SERIAL_CORE | ||
1550 | help | ||
1551 | This driver supports the Altera softcore UART port. | ||
1552 | |||
1553 | config SERIAL_ALTERA_UART_MAXPORTS | ||
1554 | int "Maximum number of Altera UART ports" | ||
1555 | depends on SERIAL_ALTERA_UART | ||
1556 | default 4 | ||
1557 | help | ||
1558 | This setting lets you define the maximum number of the Altera | ||
1559 | UART ports. The usual default varies from board to board, and | ||
1560 | this setting is a way of catering for that. | ||
1561 | |||
1562 | config SERIAL_ALTERA_UART_BAUDRATE | ||
1563 | int "Default baudrate for Altera UART ports" | ||
1564 | depends on SERIAL_ALTERA_UART | ||
1565 | default 115200 | ||
1566 | help | ||
1567 | This setting lets you define what the default baudrate is for the | ||
1568 | Altera UART ports. The usual default varies from board to board, | ||
1569 | and this setting is a way of catering for that. | ||
1570 | |||
1571 | config SERIAL_ALTERA_UART_CONSOLE | ||
1572 | bool "Altera UART console support" | ||
1573 | depends on SERIAL_ALTERA_UART=y | ||
1574 | select SERIAL_CORE_CONSOLE | ||
1575 | help | ||
1576 | Enable a Altera UART port to be the system console. | ||
1577 | |||
1509 | endmenu | 1578 | endmenu |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 6aa4723b74ee..208a85572c32 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -44,7 +44,6 @@ obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o | |||
44 | obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o | 44 | obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o |
45 | obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o | 45 | obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o |
46 | obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o | 46 | obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o |
47 | obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o | ||
48 | obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o | 47 | obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o |
49 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o | 48 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o |
50 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 49 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
@@ -83,3 +82,5 @@ obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o | |||
83 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o | 82 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o |
84 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o | 83 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o |
85 | obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o | 84 | obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o |
85 | obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o | ||
86 | obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o | ||
diff --git a/drivers/serial/altera_jtaguart.c b/drivers/serial/altera_jtaguart.c new file mode 100644 index 000000000000..f9b49b5ff5e1 --- /dev/null +++ b/drivers/serial/altera_jtaguart.c | |||
@@ -0,0 +1,504 @@ | |||
1 | /* | ||
2 | * altera_jtaguart.c -- Altera JTAG UART driver | ||
3 | * | ||
4 | * Based on mcf.c -- Freescale ColdFire UART driver | ||
5 | * | ||
6 | * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com> | ||
7 | * (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw> | ||
8 | * (C) Copyright 2010, Tobias Klauser <tklauser@distanz.ch> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/console.h> | ||
21 | #include <linux/tty.h> | ||
22 | #include <linux/tty_flip.h> | ||
23 | #include <linux/serial.h> | ||
24 | #include <linux/serial_core.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/altera_jtaguart.h> | ||
28 | |||
29 | #define DRV_NAME "altera_jtaguart" | ||
30 | |||
31 | /* | ||
32 | * Altera JTAG UART register definitions according to the Altera JTAG UART | ||
33 | * datasheet: http://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf | ||
34 | */ | ||
35 | |||
36 | #define ALTERA_JTAGUART_SIZE 8 | ||
37 | |||
38 | #define ALTERA_JTAGUART_DATA_REG 0 | ||
39 | |||
40 | #define ALTERA_JTAGUART_DATA_DATA_MSK 0x000000FF | ||
41 | #define ALTERA_JTAGUART_DATA_RVALID_MSK 0x00008000 | ||
42 | #define ALTERA_JTAGUART_DATA_RAVAIL_MSK 0xFFFF0000 | ||
43 | #define ALTERA_JTAGUART_DATA_RAVAIL_OFF 16 | ||
44 | |||
45 | #define ALTERA_JTAGUART_CONTROL_REG 4 | ||
46 | |||
47 | #define ALTERA_JTAGUART_CONTROL_RE_MSK 0x00000001 | ||
48 | #define ALTERA_JTAGUART_CONTROL_WE_MSK 0x00000002 | ||
49 | #define ALTERA_JTAGUART_CONTROL_RI_MSK 0x00000100 | ||
50 | #define ALTERA_JTAGUART_CONTROL_RI_OFF 8 | ||
51 | #define ALTERA_JTAGUART_CONTROL_WI_MSK 0x00000200 | ||
52 | #define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400 | ||
53 | #define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000 | ||
54 | #define ALTERA_JTAGUART_CONTROL_WSPACE_OFF 16 | ||
55 | |||
56 | /* | ||
57 | * Local per-uart structure. | ||
58 | */ | ||
59 | struct altera_jtaguart { | ||
60 | struct uart_port port; | ||
61 | unsigned int sigs; /* Local copy of line sigs */ | ||
62 | unsigned long imr; /* Local IMR mirror */ | ||
63 | }; | ||
64 | |||
65 | static unsigned int altera_jtaguart_tx_empty(struct uart_port *port) | ||
66 | { | ||
67 | return (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & | ||
68 | ALTERA_JTAGUART_CONTROL_WSPACE_MSK) ? TIOCSER_TEMT : 0; | ||
69 | } | ||
70 | |||
71 | static unsigned int altera_jtaguart_get_mctrl(struct uart_port *port) | ||
72 | { | ||
73 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
74 | } | ||
75 | |||
76 | static void altera_jtaguart_set_mctrl(struct uart_port *port, unsigned int sigs) | ||
77 | { | ||
78 | } | ||
79 | |||
80 | static void altera_jtaguart_start_tx(struct uart_port *port) | ||
81 | { | ||
82 | struct altera_jtaguart *pp = | ||
83 | container_of(port, struct altera_jtaguart, port); | ||
84 | |||
85 | pp->imr |= ALTERA_JTAGUART_CONTROL_WE_MSK; | ||
86 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
87 | } | ||
88 | |||
89 | static void altera_jtaguart_stop_tx(struct uart_port *port) | ||
90 | { | ||
91 | struct altera_jtaguart *pp = | ||
92 | container_of(port, struct altera_jtaguart, port); | ||
93 | |||
94 | pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK; | ||
95 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
96 | } | ||
97 | |||
98 | static void altera_jtaguart_stop_rx(struct uart_port *port) | ||
99 | { | ||
100 | struct altera_jtaguart *pp = | ||
101 | container_of(port, struct altera_jtaguart, port); | ||
102 | |||
103 | pp->imr &= ~ALTERA_JTAGUART_CONTROL_RE_MSK; | ||
104 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
105 | } | ||
106 | |||
107 | static void altera_jtaguart_break_ctl(struct uart_port *port, int break_state) | ||
108 | { | ||
109 | } | ||
110 | |||
111 | static void altera_jtaguart_enable_ms(struct uart_port *port) | ||
112 | { | ||
113 | } | ||
114 | |||
115 | static void altera_jtaguart_set_termios(struct uart_port *port, | ||
116 | struct ktermios *termios, | ||
117 | struct ktermios *old) | ||
118 | { | ||
119 | /* Just copy the old termios settings back */ | ||
120 | if (old) | ||
121 | tty_termios_copy_hw(termios, old); | ||
122 | } | ||
123 | |||
124 | static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) | ||
125 | { | ||
126 | struct uart_port *port = &pp->port; | ||
127 | unsigned char ch, flag; | ||
128 | unsigned long status; | ||
129 | |||
130 | while ((status = readl(port->membase + ALTERA_JTAGUART_DATA_REG)) & | ||
131 | ALTERA_JTAGUART_DATA_RVALID_MSK) { | ||
132 | ch = status & ALTERA_JTAGUART_DATA_DATA_MSK; | ||
133 | flag = TTY_NORMAL; | ||
134 | port->icount.rx++; | ||
135 | |||
136 | if (uart_handle_sysrq_char(port, ch)) | ||
137 | continue; | ||
138 | uart_insert_char(port, 0, 0, ch, flag); | ||
139 | } | ||
140 | |||
141 | tty_flip_buffer_push(port->state->port.tty); | ||
142 | } | ||
143 | |||
144 | static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) | ||
145 | { | ||
146 | struct uart_port *port = &pp->port; | ||
147 | struct circ_buf *xmit = &port->state->xmit; | ||
148 | unsigned int pending, count; | ||
149 | |||
150 | if (port->x_char) { | ||
151 | /* Send special char - probably flow control */ | ||
152 | writel(port->x_char, port->membase + ALTERA_JTAGUART_DATA_REG); | ||
153 | port->x_char = 0; | ||
154 | port->icount.tx++; | ||
155 | return; | ||
156 | } | ||
157 | |||
158 | pending = uart_circ_chars_pending(xmit); | ||
159 | if (pending > 0) { | ||
160 | count = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & | ||
161 | ALTERA_JTAGUART_CONTROL_WSPACE_MSK) >> | ||
162 | ALTERA_JTAGUART_CONTROL_WSPACE_OFF; | ||
163 | if (count > pending) | ||
164 | count = pending; | ||
165 | if (count > 0) { | ||
166 | pending -= count; | ||
167 | while (count--) { | ||
168 | writel(xmit->buf[xmit->tail], | ||
169 | port->membase + ALTERA_JTAGUART_DATA_REG); | ||
170 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
171 | port->icount.tx++; | ||
172 | } | ||
173 | if (pending < WAKEUP_CHARS) | ||
174 | uart_write_wakeup(port); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | if (pending == 0) { | ||
179 | pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK; | ||
180 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) | ||
185 | { | ||
186 | struct uart_port *port = data; | ||
187 | struct altera_jtaguart *pp = | ||
188 | container_of(port, struct altera_jtaguart, port); | ||
189 | unsigned int isr; | ||
190 | |||
191 | isr = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) >> | ||
192 | ALTERA_JTAGUART_CONTROL_RI_OFF) & pp->imr; | ||
193 | |||
194 | spin_lock(&port->lock); | ||
195 | |||
196 | if (isr & ALTERA_JTAGUART_CONTROL_RE_MSK) | ||
197 | altera_jtaguart_rx_chars(pp); | ||
198 | if (isr & ALTERA_JTAGUART_CONTROL_WE_MSK) | ||
199 | altera_jtaguart_tx_chars(pp); | ||
200 | |||
201 | spin_unlock(&port->lock); | ||
202 | |||
203 | return IRQ_RETVAL(isr); | ||
204 | } | ||
205 | |||
206 | static void altera_jtaguart_config_port(struct uart_port *port, int flags) | ||
207 | { | ||
208 | port->type = PORT_ALTERA_JTAGUART; | ||
209 | |||
210 | /* Clear mask, so no surprise interrupts. */ | ||
211 | writel(0, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
212 | } | ||
213 | |||
214 | static int altera_jtaguart_startup(struct uart_port *port) | ||
215 | { | ||
216 | struct altera_jtaguart *pp = | ||
217 | container_of(port, struct altera_jtaguart, port); | ||
218 | unsigned long flags; | ||
219 | int ret; | ||
220 | |||
221 | ret = request_irq(port->irq, altera_jtaguart_interrupt, IRQF_DISABLED, | ||
222 | DRV_NAME, port); | ||
223 | if (ret) { | ||
224 | pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d " | ||
225 | "interrupt vector=%d\n", port->line, port->irq); | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | spin_lock_irqsave(&port->lock, flags); | ||
230 | |||
231 | /* Enable RX interrupts now */ | ||
232 | pp->imr = ALTERA_JTAGUART_CONTROL_RE_MSK; | ||
233 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
234 | |||
235 | spin_unlock_irqrestore(&port->lock, flags); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static void altera_jtaguart_shutdown(struct uart_port *port) | ||
241 | { | ||
242 | struct altera_jtaguart *pp = | ||
243 | container_of(port, struct altera_jtaguart, port); | ||
244 | unsigned long flags; | ||
245 | |||
246 | spin_lock_irqsave(&port->lock, flags); | ||
247 | |||
248 | /* Disable all interrupts now */ | ||
249 | pp->imr = 0; | ||
250 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
251 | |||
252 | spin_unlock_irqrestore(&port->lock, flags); | ||
253 | |||
254 | free_irq(port->irq, port); | ||
255 | } | ||
256 | |||
257 | static const char *altera_jtaguart_type(struct uart_port *port) | ||
258 | { | ||
259 | return (port->type == PORT_ALTERA_JTAGUART) ? "Altera JTAG UART" : NULL; | ||
260 | } | ||
261 | |||
262 | static int altera_jtaguart_request_port(struct uart_port *port) | ||
263 | { | ||
264 | /* UARTs always present */ | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static void altera_jtaguart_release_port(struct uart_port *port) | ||
269 | { | ||
270 | /* Nothing to release... */ | ||
271 | } | ||
272 | |||
273 | static int altera_jtaguart_verify_port(struct uart_port *port, | ||
274 | struct serial_struct *ser) | ||
275 | { | ||
276 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_ALTERA_JTAGUART) | ||
277 | return -EINVAL; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Define the basic serial functions we support. | ||
283 | */ | ||
284 | static struct uart_ops altera_jtaguart_ops = { | ||
285 | .tx_empty = altera_jtaguart_tx_empty, | ||
286 | .get_mctrl = altera_jtaguart_get_mctrl, | ||
287 | .set_mctrl = altera_jtaguart_set_mctrl, | ||
288 | .start_tx = altera_jtaguart_start_tx, | ||
289 | .stop_tx = altera_jtaguart_stop_tx, | ||
290 | .stop_rx = altera_jtaguart_stop_rx, | ||
291 | .enable_ms = altera_jtaguart_enable_ms, | ||
292 | .break_ctl = altera_jtaguart_break_ctl, | ||
293 | .startup = altera_jtaguart_startup, | ||
294 | .shutdown = altera_jtaguart_shutdown, | ||
295 | .set_termios = altera_jtaguart_set_termios, | ||
296 | .type = altera_jtaguart_type, | ||
297 | .request_port = altera_jtaguart_request_port, | ||
298 | .release_port = altera_jtaguart_release_port, | ||
299 | .config_port = altera_jtaguart_config_port, | ||
300 | .verify_port = altera_jtaguart_verify_port, | ||
301 | }; | ||
302 | |||
303 | #define ALTERA_JTAGUART_MAXPORTS 1 | ||
304 | static struct altera_jtaguart altera_jtaguart_ports[ALTERA_JTAGUART_MAXPORTS]; | ||
305 | |||
306 | #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) | ||
307 | |||
308 | int __init early_altera_jtaguart_setup(struct altera_jtaguart_platform_uart | ||
309 | *platp) | ||
310 | { | ||
311 | struct uart_port *port; | ||
312 | int i; | ||
313 | |||
314 | for (i = 0; i < ALTERA_JTAGUART_MAXPORTS && platp[i].mapbase; i++) { | ||
315 | port = &altera_jtaguart_ports[i].port; | ||
316 | |||
317 | port->line = i; | ||
318 | port->type = PORT_ALTERA_JTAGUART; | ||
319 | port->mapbase = platp[i].mapbase; | ||
320 | port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE); | ||
321 | port->iotype = SERIAL_IO_MEM; | ||
322 | port->irq = platp[i].irq; | ||
323 | port->flags = ASYNC_BOOT_AUTOCONF; | ||
324 | port->ops = &altera_jtaguart_ops; | ||
325 | } | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS) | ||
331 | static void altera_jtaguart_console_putc(struct console *co, const char c) | ||
332 | { | ||
333 | struct uart_port *port = &(altera_jtaguart_ports + co->index)->port; | ||
334 | unsigned long status; | ||
335 | unsigned long flags; | ||
336 | |||
337 | spin_lock_irqsave(&port->lock, flags); | ||
338 | while (((status = readl(port->membase + ALTERA_JTAGUART_CONTROL_REG)) & | ||
339 | ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) { | ||
340 | if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0) { | ||
341 | spin_unlock_irqrestore(&port->lock, flags); | ||
342 | return; /* no connection activity */ | ||
343 | } | ||
344 | spin_unlock_irqrestore(&port->lock, flags); | ||
345 | cpu_relax(); | ||
346 | spin_lock_irqsave(&port->lock, flags); | ||
347 | } | ||
348 | writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); | ||
349 | spin_unlock_irqrestore(&port->lock, flags); | ||
350 | } | ||
351 | #else | ||
352 | static void altera_jtaguart_console_putc(struct console *co, const char c) | ||
353 | { | ||
354 | struct uart_port *port = &(altera_jtaguart_ports + co->index)->port; | ||
355 | unsigned long flags; | ||
356 | |||
357 | spin_lock_irqsave(&port->lock, flags); | ||
358 | while ((readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & | ||
359 | ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) { | ||
360 | spin_unlock_irqrestore(&port->lock, flags); | ||
361 | cpu_relax(); | ||
362 | spin_lock_irqsave(&port->lock, flags); | ||
363 | } | ||
364 | writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); | ||
365 | spin_unlock_irqrestore(&port->lock, flags); | ||
366 | } | ||
367 | #endif | ||
368 | |||
369 | static void altera_jtaguart_console_write(struct console *co, const char *s, | ||
370 | unsigned int count) | ||
371 | { | ||
372 | for (; count; count--, s++) { | ||
373 | altera_jtaguart_console_putc(co, *s); | ||
374 | if (*s == '\n') | ||
375 | altera_jtaguart_console_putc(co, '\r'); | ||
376 | } | ||
377 | } | ||
378 | |||
379 | static int __init altera_jtaguart_console_setup(struct console *co, | ||
380 | char *options) | ||
381 | { | ||
382 | struct uart_port *port; | ||
383 | |||
384 | if (co->index < 0 || co->index >= ALTERA_JTAGUART_MAXPORTS) | ||
385 | return -EINVAL; | ||
386 | port = &altera_jtaguart_ports[co->index].port; | ||
387 | if (port->membase == 0) | ||
388 | return -ENODEV; | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static struct uart_driver altera_jtaguart_driver; | ||
393 | |||
394 | static struct console altera_jtaguart_console = { | ||
395 | .name = "ttyJ", | ||
396 | .write = altera_jtaguart_console_write, | ||
397 | .device = uart_console_device, | ||
398 | .setup = altera_jtaguart_console_setup, | ||
399 | .flags = CON_PRINTBUFFER, | ||
400 | .index = -1, | ||
401 | .data = &altera_jtaguart_driver, | ||
402 | }; | ||
403 | |||
404 | static int __init altera_jtaguart_console_init(void) | ||
405 | { | ||
406 | register_console(&altera_jtaguart_console); | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | console_initcall(altera_jtaguart_console_init); | ||
411 | |||
412 | #define ALTERA_JTAGUART_CONSOLE (&altera_jtaguart_console) | ||
413 | |||
414 | #else | ||
415 | |||
416 | #define ALTERA_JTAGUART_CONSOLE NULL | ||
417 | |||
418 | #endif /* CONFIG_ALTERA_JTAGUART_CONSOLE */ | ||
419 | |||
420 | static struct uart_driver altera_jtaguart_driver = { | ||
421 | .owner = THIS_MODULE, | ||
422 | .driver_name = "altera_jtaguart", | ||
423 | .dev_name = "ttyJ", | ||
424 | .major = ALTERA_JTAGUART_MAJOR, | ||
425 | .minor = ALTERA_JTAGUART_MINOR, | ||
426 | .nr = ALTERA_JTAGUART_MAXPORTS, | ||
427 | .cons = ALTERA_JTAGUART_CONSOLE, | ||
428 | }; | ||
429 | |||
430 | static int __devinit altera_jtaguart_probe(struct platform_device *pdev) | ||
431 | { | ||
432 | struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data; | ||
433 | struct uart_port *port; | ||
434 | int i; | ||
435 | |||
436 | for (i = 0; i < ALTERA_JTAGUART_MAXPORTS && platp[i].mapbase; i++) { | ||
437 | port = &altera_jtaguart_ports[i].port; | ||
438 | |||
439 | port->line = i; | ||
440 | port->type = PORT_ALTERA_JTAGUART; | ||
441 | port->mapbase = platp[i].mapbase; | ||
442 | port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE); | ||
443 | port->iotype = SERIAL_IO_MEM; | ||
444 | port->irq = platp[i].irq; | ||
445 | port->ops = &altera_jtaguart_ops; | ||
446 | port->flags = ASYNC_BOOT_AUTOCONF; | ||
447 | |||
448 | uart_add_one_port(&altera_jtaguart_driver, port); | ||
449 | } | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static int __devexit altera_jtaguart_remove(struct platform_device *pdev) | ||
455 | { | ||
456 | struct uart_port *port; | ||
457 | int i; | ||
458 | |||
459 | for (i = 0; i < ALTERA_JTAGUART_MAXPORTS; i++) { | ||
460 | port = &altera_jtaguart_ports[i].port; | ||
461 | if (port) | ||
462 | uart_remove_one_port(&altera_jtaguart_driver, port); | ||
463 | } | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static struct platform_driver altera_jtaguart_platform_driver = { | ||
469 | .probe = altera_jtaguart_probe, | ||
470 | .remove = __devexit_p(altera_jtaguart_remove), | ||
471 | .driver = { | ||
472 | .name = DRV_NAME, | ||
473 | .owner = THIS_MODULE, | ||
474 | }, | ||
475 | }; | ||
476 | |||
477 | static int __init altera_jtaguart_init(void) | ||
478 | { | ||
479 | int rc; | ||
480 | |||
481 | rc = uart_register_driver(&altera_jtaguart_driver); | ||
482 | if (rc) | ||
483 | return rc; | ||
484 | rc = platform_driver_register(&altera_jtaguart_platform_driver); | ||
485 | if (rc) { | ||
486 | uart_unregister_driver(&altera_jtaguart_driver); | ||
487 | return rc; | ||
488 | } | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static void __exit altera_jtaguart_exit(void) | ||
493 | { | ||
494 | platform_driver_unregister(&altera_jtaguart_platform_driver); | ||
495 | uart_unregister_driver(&altera_jtaguart_driver); | ||
496 | } | ||
497 | |||
498 | module_init(altera_jtaguart_init); | ||
499 | module_exit(altera_jtaguart_exit); | ||
500 | |||
501 | MODULE_DESCRIPTION("Altera JTAG UART driver"); | ||
502 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | ||
503 | MODULE_LICENSE("GPL"); | ||
504 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c new file mode 100644 index 000000000000..bcee156d2f2e --- /dev/null +++ b/drivers/serial/altera_uart.c | |||
@@ -0,0 +1,570 @@ | |||
1 | /* | ||
2 | * altera_uart.c -- Altera UART driver | ||
3 | * | ||
4 | * Based on mcf.c -- Freescale ColdFire UART driver | ||
5 | * | ||
6 | * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com> | ||
7 | * (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw> | ||
8 | * (C) Copyright 2010, Tobias Klauser <tklauser@distanz.ch> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/console.h> | ||
21 | #include <linux/tty.h> | ||
22 | #include <linux/tty_flip.h> | ||
23 | #include <linux/serial.h> | ||
24 | #include <linux/serial_core.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/altera_uart.h> | ||
28 | |||
29 | #define DRV_NAME "altera_uart" | ||
30 | |||
31 | /* | ||
32 | * Altera UART register definitions according to the Nios UART datasheet: | ||
33 | * http://www.altera.com/literature/ds/ds_nios_uart.pdf | ||
34 | */ | ||
35 | |||
36 | #define ALTERA_UART_SIZE 32 | ||
37 | |||
38 | #define ALTERA_UART_RXDATA_REG 0 | ||
39 | #define ALTERA_UART_TXDATA_REG 4 | ||
40 | #define ALTERA_UART_STATUS_REG 8 | ||
41 | #define ALTERA_UART_CONTROL_REG 12 | ||
42 | #define ALTERA_UART_DIVISOR_REG 16 | ||
43 | #define ALTERA_UART_EOP_REG 20 | ||
44 | |||
45 | #define ALTERA_UART_STATUS_PE_MSK 0x0001 /* parity error */ | ||
46 | #define ALTERA_UART_STATUS_FE_MSK 0x0002 /* framing error */ | ||
47 | #define ALTERA_UART_STATUS_BRK_MSK 0x0004 /* break */ | ||
48 | #define ALTERA_UART_STATUS_ROE_MSK 0x0008 /* RX overrun error */ | ||
49 | #define ALTERA_UART_STATUS_TOE_MSK 0x0010 /* TX overrun error */ | ||
50 | #define ALTERA_UART_STATUS_TMT_MSK 0x0020 /* TX shift register state */ | ||
51 | #define ALTERA_UART_STATUS_TRDY_MSK 0x0040 /* TX ready */ | ||
52 | #define ALTERA_UART_STATUS_RRDY_MSK 0x0080 /* RX ready */ | ||
53 | #define ALTERA_UART_STATUS_E_MSK 0x0100 /* exception condition */ | ||
54 | #define ALTERA_UART_STATUS_DCTS_MSK 0x0400 /* CTS logic-level change */ | ||
55 | #define ALTERA_UART_STATUS_CTS_MSK 0x0800 /* CTS logic state */ | ||
56 | #define ALTERA_UART_STATUS_EOP_MSK 0x1000 /* EOP written/read */ | ||
57 | |||
58 | /* Enable interrupt on... */ | ||
59 | #define ALTERA_UART_CONTROL_PE_MSK 0x0001 /* ...parity error */ | ||
60 | #define ALTERA_UART_CONTROL_FE_MSK 0x0002 /* ...framing error */ | ||
61 | #define ALTERA_UART_CONTROL_BRK_MSK 0x0004 /* ...break */ | ||
62 | #define ALTERA_UART_CONTROL_ROE_MSK 0x0008 /* ...RX overrun */ | ||
63 | #define ALTERA_UART_CONTROL_TOE_MSK 0x0010 /* ...TX overrun */ | ||
64 | #define ALTERA_UART_CONTROL_TMT_MSK 0x0020 /* ...TX shift register empty */ | ||
65 | #define ALTERA_UART_CONTROL_TRDY_MSK 0x0040 /* ...TX ready */ | ||
66 | #define ALTERA_UART_CONTROL_RRDY_MSK 0x0080 /* ...RX ready */ | ||
67 | #define ALTERA_UART_CONTROL_E_MSK 0x0100 /* ...exception*/ | ||
68 | |||
69 | #define ALTERA_UART_CONTROL_TRBK_MSK 0x0200 /* TX break */ | ||
70 | #define ALTERA_UART_CONTROL_DCTS_MSK 0x0400 /* Interrupt on CTS change */ | ||
71 | #define ALTERA_UART_CONTROL_RTS_MSK 0x0800 /* RTS signal */ | ||
72 | #define ALTERA_UART_CONTROL_EOP_MSK 0x1000 /* Interrupt on EOP */ | ||
73 | |||
74 | /* | ||
75 | * Local per-uart structure. | ||
76 | */ | ||
77 | struct altera_uart { | ||
78 | struct uart_port port; | ||
79 | unsigned int sigs; /* Local copy of line sigs */ | ||
80 | unsigned short imr; /* Local IMR mirror */ | ||
81 | }; | ||
82 | |||
83 | static unsigned int altera_uart_tx_empty(struct uart_port *port) | ||
84 | { | ||
85 | return (readl(port->membase + ALTERA_UART_STATUS_REG) & | ||
86 | ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0; | ||
87 | } | ||
88 | |||
89 | static unsigned int altera_uart_get_mctrl(struct uart_port *port) | ||
90 | { | ||
91 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
92 | unsigned long flags; | ||
93 | unsigned int sigs; | ||
94 | |||
95 | spin_lock_irqsave(&port->lock, flags); | ||
96 | sigs = | ||
97 | (readl(port->membase + ALTERA_UART_STATUS_REG) & | ||
98 | ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; | ||
99 | sigs |= (pp->sigs & TIOCM_RTS); | ||
100 | spin_unlock_irqrestore(&port->lock, flags); | ||
101 | |||
102 | return sigs; | ||
103 | } | ||
104 | |||
105 | static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs) | ||
106 | { | ||
107 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
108 | unsigned long flags; | ||
109 | |||
110 | spin_lock_irqsave(&port->lock, flags); | ||
111 | pp->sigs = sigs; | ||
112 | if (sigs & TIOCM_RTS) | ||
113 | pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; | ||
114 | else | ||
115 | pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; | ||
116 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
117 | spin_unlock_irqrestore(&port->lock, flags); | ||
118 | } | ||
119 | |||
120 | static void altera_uart_start_tx(struct uart_port *port) | ||
121 | { | ||
122 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
123 | unsigned long flags; | ||
124 | |||
125 | spin_lock_irqsave(&port->lock, flags); | ||
126 | pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; | ||
127 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
128 | spin_unlock_irqrestore(&port->lock, flags); | ||
129 | } | ||
130 | |||
131 | static void altera_uart_stop_tx(struct uart_port *port) | ||
132 | { | ||
133 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
134 | unsigned long flags; | ||
135 | |||
136 | spin_lock_irqsave(&port->lock, flags); | ||
137 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; | ||
138 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
139 | spin_unlock_irqrestore(&port->lock, flags); | ||
140 | } | ||
141 | |||
142 | static void altera_uart_stop_rx(struct uart_port *port) | ||
143 | { | ||
144 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
145 | unsigned long flags; | ||
146 | |||
147 | spin_lock_irqsave(&port->lock, flags); | ||
148 | pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; | ||
149 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
150 | spin_unlock_irqrestore(&port->lock, flags); | ||
151 | } | ||
152 | |||
153 | static void altera_uart_break_ctl(struct uart_port *port, int break_state) | ||
154 | { | ||
155 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
156 | unsigned long flags; | ||
157 | |||
158 | spin_lock_irqsave(&port->lock, flags); | ||
159 | if (break_state == -1) | ||
160 | pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK; | ||
161 | else | ||
162 | pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK; | ||
163 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
164 | spin_unlock_irqrestore(&port->lock, flags); | ||
165 | } | ||
166 | |||
167 | static void altera_uart_enable_ms(struct uart_port *port) | ||
168 | { | ||
169 | } | ||
170 | |||
171 | static void altera_uart_set_termios(struct uart_port *port, | ||
172 | struct ktermios *termios, | ||
173 | struct ktermios *old) | ||
174 | { | ||
175 | unsigned long flags; | ||
176 | unsigned int baud, baudclk; | ||
177 | |||
178 | baud = uart_get_baud_rate(port, termios, old, 0, 4000000); | ||
179 | baudclk = port->uartclk / baud; | ||
180 | |||
181 | if (old) | ||
182 | tty_termios_copy_hw(termios, old); | ||
183 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
184 | |||
185 | spin_lock_irqsave(&port->lock, flags); | ||
186 | writel(baudclk, port->membase + ALTERA_UART_DIVISOR_REG); | ||
187 | spin_unlock_irqrestore(&port->lock, flags); | ||
188 | } | ||
189 | |||
190 | static void altera_uart_rx_chars(struct altera_uart *pp) | ||
191 | { | ||
192 | struct uart_port *port = &pp->port; | ||
193 | unsigned char ch, flag; | ||
194 | unsigned short status; | ||
195 | |||
196 | while ((status = readl(port->membase + ALTERA_UART_STATUS_REG)) & | ||
197 | ALTERA_UART_STATUS_RRDY_MSK) { | ||
198 | ch = readl(port->membase + ALTERA_UART_RXDATA_REG); | ||
199 | flag = TTY_NORMAL; | ||
200 | port->icount.rx++; | ||
201 | |||
202 | if (status & ALTERA_UART_STATUS_E_MSK) { | ||
203 | writel(status, port->membase + ALTERA_UART_STATUS_REG); | ||
204 | |||
205 | if (status & ALTERA_UART_STATUS_BRK_MSK) { | ||
206 | port->icount.brk++; | ||
207 | if (uart_handle_break(port)) | ||
208 | continue; | ||
209 | } else if (status & ALTERA_UART_STATUS_PE_MSK) { | ||
210 | port->icount.parity++; | ||
211 | } else if (status & ALTERA_UART_STATUS_ROE_MSK) { | ||
212 | port->icount.overrun++; | ||
213 | } else if (status & ALTERA_UART_STATUS_FE_MSK) { | ||
214 | port->icount.frame++; | ||
215 | } | ||
216 | |||
217 | status &= port->read_status_mask; | ||
218 | |||
219 | if (status & ALTERA_UART_STATUS_BRK_MSK) | ||
220 | flag = TTY_BREAK; | ||
221 | else if (status & ALTERA_UART_STATUS_PE_MSK) | ||
222 | flag = TTY_PARITY; | ||
223 | else if (status & ALTERA_UART_STATUS_FE_MSK) | ||
224 | flag = TTY_FRAME; | ||
225 | } | ||
226 | |||
227 | if (uart_handle_sysrq_char(port, ch)) | ||
228 | continue; | ||
229 | uart_insert_char(port, status, ALTERA_UART_STATUS_ROE_MSK, ch, | ||
230 | flag); | ||
231 | } | ||
232 | |||
233 | tty_flip_buffer_push(port->state->port.tty); | ||
234 | } | ||
235 | |||
236 | static void altera_uart_tx_chars(struct altera_uart *pp) | ||
237 | { | ||
238 | struct uart_port *port = &pp->port; | ||
239 | struct circ_buf *xmit = &port->state->xmit; | ||
240 | |||
241 | if (port->x_char) { | ||
242 | /* Send special char - probably flow control */ | ||
243 | writel(port->x_char, port->membase + ALTERA_UART_TXDATA_REG); | ||
244 | port->x_char = 0; | ||
245 | port->icount.tx++; | ||
246 | return; | ||
247 | } | ||
248 | |||
249 | while (readl(port->membase + ALTERA_UART_STATUS_REG) & | ||
250 | ALTERA_UART_STATUS_TRDY_MSK) { | ||
251 | if (xmit->head == xmit->tail) | ||
252 | break; | ||
253 | writel(xmit->buf[xmit->tail], | ||
254 | port->membase + ALTERA_UART_TXDATA_REG); | ||
255 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
256 | port->icount.tx++; | ||
257 | } | ||
258 | |||
259 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
260 | uart_write_wakeup(port); | ||
261 | |||
262 | if (xmit->head == xmit->tail) { | ||
263 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; | ||
264 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | static irqreturn_t altera_uart_interrupt(int irq, void *data) | ||
269 | { | ||
270 | struct uart_port *port = data; | ||
271 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
272 | unsigned int isr; | ||
273 | |||
274 | isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr; | ||
275 | if (isr & ALTERA_UART_STATUS_RRDY_MSK) | ||
276 | altera_uart_rx_chars(pp); | ||
277 | if (isr & ALTERA_UART_STATUS_TRDY_MSK) | ||
278 | altera_uart_tx_chars(pp); | ||
279 | return IRQ_RETVAL(isr); | ||
280 | } | ||
281 | |||
282 | static void altera_uart_config_port(struct uart_port *port, int flags) | ||
283 | { | ||
284 | port->type = PORT_ALTERA_UART; | ||
285 | |||
286 | /* Clear mask, so no surprise interrupts. */ | ||
287 | writel(0, port->membase + ALTERA_UART_CONTROL_REG); | ||
288 | /* Clear status register */ | ||
289 | writel(0, port->membase + ALTERA_UART_STATUS_REG); | ||
290 | } | ||
291 | |||
292 | static int altera_uart_startup(struct uart_port *port) | ||
293 | { | ||
294 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
295 | unsigned long flags; | ||
296 | int ret; | ||
297 | |||
298 | ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED, | ||
299 | DRV_NAME, port); | ||
300 | if (ret) { | ||
301 | pr_err(DRV_NAME ": unable to attach Altera UART %d " | ||
302 | "interrupt vector=%d\n", port->line, port->irq); | ||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | spin_lock_irqsave(&port->lock, flags); | ||
307 | |||
308 | /* Enable RX interrupts now */ | ||
309 | pp->imr = ALTERA_UART_CONTROL_RRDY_MSK; | ||
310 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
311 | |||
312 | spin_unlock_irqrestore(&port->lock, flags); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static void altera_uart_shutdown(struct uart_port *port) | ||
318 | { | ||
319 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
320 | unsigned long flags; | ||
321 | |||
322 | spin_lock_irqsave(&port->lock, flags); | ||
323 | |||
324 | /* Disable all interrupts now */ | ||
325 | pp->imr = 0; | ||
326 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
327 | |||
328 | spin_unlock_irqrestore(&port->lock, flags); | ||
329 | |||
330 | free_irq(port->irq, port); | ||
331 | } | ||
332 | |||
333 | static const char *altera_uart_type(struct uart_port *port) | ||
334 | { | ||
335 | return (port->type == PORT_ALTERA_UART) ? "Altera UART" : NULL; | ||
336 | } | ||
337 | |||
338 | static int altera_uart_request_port(struct uart_port *port) | ||
339 | { | ||
340 | /* UARTs always present */ | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static void altera_uart_release_port(struct uart_port *port) | ||
345 | { | ||
346 | /* Nothing to release... */ | ||
347 | } | ||
348 | |||
349 | static int altera_uart_verify_port(struct uart_port *port, | ||
350 | struct serial_struct *ser) | ||
351 | { | ||
352 | if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_ALTERA_UART)) | ||
353 | return -EINVAL; | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | /* | ||
358 | * Define the basic serial functions we support. | ||
359 | */ | ||
360 | static struct uart_ops altera_uart_ops = { | ||
361 | .tx_empty = altera_uart_tx_empty, | ||
362 | .get_mctrl = altera_uart_get_mctrl, | ||
363 | .set_mctrl = altera_uart_set_mctrl, | ||
364 | .start_tx = altera_uart_start_tx, | ||
365 | .stop_tx = altera_uart_stop_tx, | ||
366 | .stop_rx = altera_uart_stop_rx, | ||
367 | .enable_ms = altera_uart_enable_ms, | ||
368 | .break_ctl = altera_uart_break_ctl, | ||
369 | .startup = altera_uart_startup, | ||
370 | .shutdown = altera_uart_shutdown, | ||
371 | .set_termios = altera_uart_set_termios, | ||
372 | .type = altera_uart_type, | ||
373 | .request_port = altera_uart_request_port, | ||
374 | .release_port = altera_uart_release_port, | ||
375 | .config_port = altera_uart_config_port, | ||
376 | .verify_port = altera_uart_verify_port, | ||
377 | }; | ||
378 | |||
379 | static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS]; | ||
380 | |||
381 | #if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) | ||
382 | |||
383 | int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) | ||
384 | { | ||
385 | struct uart_port *port; | ||
386 | int i; | ||
387 | |||
388 | for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) { | ||
389 | port = &altera_uart_ports[i].port; | ||
390 | |||
391 | port->line = i; | ||
392 | port->type = PORT_ALTERA_UART; | ||
393 | port->mapbase = platp[i].mapbase; | ||
394 | port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); | ||
395 | port->iotype = SERIAL_IO_MEM; | ||
396 | port->irq = platp[i].irq; | ||
397 | port->uartclk = platp[i].uartclk; | ||
398 | port->flags = ASYNC_BOOT_AUTOCONF; | ||
399 | port->ops = &altera_uart_ops; | ||
400 | } | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static void altera_uart_console_putc(struct console *co, const char c) | ||
406 | { | ||
407 | struct uart_port *port = &(altera_uart_ports + co->index)->port; | ||
408 | int i; | ||
409 | |||
410 | for (i = 0; i < 0x10000; i++) { | ||
411 | if (readl(port->membase + ALTERA_UART_STATUS_REG) & | ||
412 | ALTERA_UART_STATUS_TRDY_MSK) | ||
413 | break; | ||
414 | } | ||
415 | writel(c, port->membase + ALTERA_UART_TXDATA_REG); | ||
416 | for (i = 0; i < 0x10000; i++) { | ||
417 | if (readl(port->membase + ALTERA_UART_STATUS_REG) & | ||
418 | ALTERA_UART_STATUS_TRDY_MSK) | ||
419 | break; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | static void altera_uart_console_write(struct console *co, const char *s, | ||
424 | unsigned int count) | ||
425 | { | ||
426 | for (; count; count--, s++) { | ||
427 | altera_uart_console_putc(co, *s); | ||
428 | if (*s == '\n') | ||
429 | altera_uart_console_putc(co, '\r'); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | static int __init altera_uart_console_setup(struct console *co, char *options) | ||
434 | { | ||
435 | struct uart_port *port; | ||
436 | int baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE; | ||
437 | int bits = 8; | ||
438 | int parity = 'n'; | ||
439 | int flow = 'n'; | ||
440 | |||
441 | if (co->index < 0 || co->index >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS) | ||
442 | return -EINVAL; | ||
443 | port = &altera_uart_ports[co->index].port; | ||
444 | if (port->membase == 0) | ||
445 | return -ENODEV; | ||
446 | |||
447 | if (options) | ||
448 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
449 | |||
450 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
451 | } | ||
452 | |||
453 | static struct uart_driver altera_uart_driver; | ||
454 | |||
455 | static struct console altera_uart_console = { | ||
456 | .name = "ttyS", | ||
457 | .write = altera_uart_console_write, | ||
458 | .device = uart_console_device, | ||
459 | .setup = altera_uart_console_setup, | ||
460 | .flags = CON_PRINTBUFFER, | ||
461 | .index = -1, | ||
462 | .data = &altera_uart_driver, | ||
463 | }; | ||
464 | |||
465 | static int __init altera_uart_console_init(void) | ||
466 | { | ||
467 | register_console(&altera_uart_console); | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | console_initcall(altera_uart_console_init); | ||
472 | |||
473 | #define ALTERA_UART_CONSOLE (&altera_uart_console) | ||
474 | |||
475 | #else | ||
476 | |||
477 | #define ALTERA_UART_CONSOLE NULL | ||
478 | |||
479 | #endif /* CONFIG_ALTERA_UART_CONSOLE */ | ||
480 | |||
481 | /* | ||
482 | * Define the altera_uart UART driver structure. | ||
483 | */ | ||
484 | static struct uart_driver altera_uart_driver = { | ||
485 | .owner = THIS_MODULE, | ||
486 | .driver_name = DRV_NAME, | ||
487 | .dev_name = "ttyS", | ||
488 | .major = TTY_MAJOR, | ||
489 | .minor = 64, | ||
490 | .nr = CONFIG_SERIAL_ALTERA_UART_MAXPORTS, | ||
491 | .cons = ALTERA_UART_CONSOLE, | ||
492 | }; | ||
493 | |||
494 | static int __devinit altera_uart_probe(struct platform_device *pdev) | ||
495 | { | ||
496 | struct altera_uart_platform_uart *platp = pdev->dev.platform_data; | ||
497 | struct uart_port *port; | ||
498 | int i; | ||
499 | |||
500 | for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) { | ||
501 | port = &altera_uart_ports[i].port; | ||
502 | |||
503 | port->line = i; | ||
504 | port->type = PORT_ALTERA_UART; | ||
505 | port->mapbase = platp[i].mapbase; | ||
506 | port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); | ||
507 | port->iotype = SERIAL_IO_MEM; | ||
508 | port->irq = platp[i].irq; | ||
509 | port->uartclk = platp[i].uartclk; | ||
510 | port->ops = &altera_uart_ops; | ||
511 | port->flags = ASYNC_BOOT_AUTOCONF; | ||
512 | |||
513 | uart_add_one_port(&altera_uart_driver, port); | ||
514 | } | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static int altera_uart_remove(struct platform_device *pdev) | ||
520 | { | ||
521 | struct uart_port *port; | ||
522 | int i; | ||
523 | |||
524 | for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++) { | ||
525 | port = &altera_uart_ports[i].port; | ||
526 | if (port) | ||
527 | uart_remove_one_port(&altera_uart_driver, port); | ||
528 | } | ||
529 | |||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static struct platform_driver altera_uart_platform_driver = { | ||
534 | .probe = altera_uart_probe, | ||
535 | .remove = __devexit_p(altera_uart_remove), | ||
536 | .driver = { | ||
537 | .name = DRV_NAME, | ||
538 | .owner = THIS_MODULE, | ||
539 | .pm = NULL, | ||
540 | }, | ||
541 | }; | ||
542 | |||
543 | static int __init altera_uart_init(void) | ||
544 | { | ||
545 | int rc; | ||
546 | |||
547 | rc = uart_register_driver(&altera_uart_driver); | ||
548 | if (rc) | ||
549 | return rc; | ||
550 | rc = platform_driver_register(&altera_uart_platform_driver); | ||
551 | if (rc) { | ||
552 | uart_unregister_driver(&altera_uart_driver); | ||
553 | return rc; | ||
554 | } | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static void __exit altera_uart_exit(void) | ||
559 | { | ||
560 | platform_driver_unregister(&altera_uart_platform_driver); | ||
561 | uart_unregister_driver(&altera_uart_driver); | ||
562 | } | ||
563 | |||
564 | module_init(altera_uart_init); | ||
565 | module_exit(altera_uart_exit); | ||
566 | |||
567 | MODULE_DESCRIPTION("Altera UART driver"); | ||
568 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | ||
569 | MODULE_LICENSE("GPL"); | ||
570 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 743ebf5f16da..eb4cb480b93e 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -342,9 +342,9 @@ static int pl010_get_poll_char(struct uart_port *port) | |||
342 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 342 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
343 | unsigned int status; | 343 | unsigned int status; |
344 | 344 | ||
345 | do { | 345 | status = readw(uap->port.membase + UART01x_FR); |
346 | status = readw(uap->port.membase + UART01x_FR); | 346 | if (status & UART01x_FR_RXFE) |
347 | } while (status & UART01x_FR_RXFE); | 347 | return NO_POLL_CHAR; |
348 | 348 | ||
349 | return readw(uap->port.membase + UART01x_DR); | 349 | return readw(uap->port.membase + UART01x_DR); |
350 | } | 350 | } |
diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c index fe91319b5f65..0099b8692b60 100644 --- a/drivers/serial/apbuart.c +++ b/drivers/serial/apbuart.c | |||
@@ -559,7 +559,7 @@ static int __devinit apbuart_probe(struct of_device *op, | |||
559 | 559 | ||
560 | i = 0; | 560 | i = 0; |
561 | for (i = 0; i < grlib_apbuart_port_nr; i++) { | 561 | for (i = 0; i < grlib_apbuart_port_nr; i++) { |
562 | if (op->node == grlib_apbuart_nodes[i]) | 562 | if (op->dev.of_node == grlib_apbuart_nodes[i]) |
563 | break; | 563 | break; |
564 | } | 564 | } |
565 | 565 | ||
@@ -584,12 +584,12 @@ static struct of_device_id __initdata apbuart_match[] = { | |||
584 | }; | 584 | }; |
585 | 585 | ||
586 | static struct of_platform_driver grlib_apbuart_of_driver = { | 586 | static struct of_platform_driver grlib_apbuart_of_driver = { |
587 | .match_table = apbuart_match, | ||
588 | .probe = apbuart_probe, | 587 | .probe = apbuart_probe, |
589 | .driver = { | 588 | .driver = { |
590 | .owner = THIS_MODULE, | 589 | .owner = THIS_MODULE, |
591 | .name = "grlib-apbuart", | 590 | .name = "grlib-apbuart", |
592 | }, | 591 | .of_match_table = apbuart_match, |
592 | }, | ||
593 | }; | 593 | }; |
594 | 594 | ||
595 | 595 | ||
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 2c9bf9b68327..eed3c2d8dd1c 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/dma-mapping.h> | 38 | #include <linux/dma-mapping.h> |
39 | #include <linux/atmel_pdc.h> | 39 | #include <linux/atmel_pdc.h> |
40 | #include <linux/atmel_serial.h> | 40 | #include <linux/atmel_serial.h> |
41 | #include <linux/uaccess.h> | ||
41 | 42 | ||
42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
43 | 44 | ||
@@ -59,6 +60,9 @@ | |||
59 | 60 | ||
60 | #include <linux/serial_core.h> | 61 | #include <linux/serial_core.h> |
61 | 62 | ||
63 | static void atmel_start_rx(struct uart_port *port); | ||
64 | static void atmel_stop_rx(struct uart_port *port); | ||
65 | |||
62 | #ifdef CONFIG_SERIAL_ATMEL_TTYAT | 66 | #ifdef CONFIG_SERIAL_ATMEL_TTYAT |
63 | 67 | ||
64 | /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we | 68 | /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we |
@@ -93,6 +97,7 @@ | |||
93 | #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR) | 97 | #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR) |
94 | #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) | 98 | #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) |
95 | #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) | 99 | #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) |
100 | #define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR) | ||
96 | 101 | ||
97 | /* PDC registers */ | 102 | /* PDC registers */ |
98 | #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) | 103 | #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) |
@@ -147,6 +152,9 @@ struct atmel_uart_port { | |||
147 | unsigned int irq_status_prev; | 152 | unsigned int irq_status_prev; |
148 | 153 | ||
149 | struct circ_buf rx_ring; | 154 | struct circ_buf rx_ring; |
155 | |||
156 | struct serial_rs485 rs485; /* rs485 settings */ | ||
157 | unsigned int tx_done_mask; | ||
150 | }; | 158 | }; |
151 | 159 | ||
152 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; | 160 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; |
@@ -187,6 +195,46 @@ static bool atmel_use_dma_tx(struct uart_port *port) | |||
187 | } | 195 | } |
188 | #endif | 196 | #endif |
189 | 197 | ||
198 | /* Enable or disable the rs485 support */ | ||
199 | void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | ||
200 | { | ||
201 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
202 | unsigned int mode; | ||
203 | |||
204 | spin_lock(&port->lock); | ||
205 | |||
206 | /* Disable interrupts */ | ||
207 | UART_PUT_IDR(port, atmel_port->tx_done_mask); | ||
208 | |||
209 | mode = UART_GET_MR(port); | ||
210 | |||
211 | /* Resetting serial mode to RS232 (0x0) */ | ||
212 | mode &= ~ATMEL_US_USMODE; | ||
213 | |||
214 | atmel_port->rs485 = *rs485conf; | ||
215 | |||
216 | if (rs485conf->flags & SER_RS485_ENABLED) { | ||
217 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
218 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | ||
219 | UART_PUT_TTGR(port, rs485conf->delay_rts_before_send); | ||
220 | mode |= ATMEL_US_USMODE_RS485; | ||
221 | } else { | ||
222 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
223 | if (atmel_use_dma_tx(port)) | ||
224 | atmel_port->tx_done_mask = ATMEL_US_ENDTX | | ||
225 | ATMEL_US_TXBUFE; | ||
226 | else | ||
227 | atmel_port->tx_done_mask = ATMEL_US_TXRDY; | ||
228 | } | ||
229 | UART_PUT_MR(port, mode); | ||
230 | |||
231 | /* Enable interrupts */ | ||
232 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
233 | |||
234 | spin_unlock(&port->lock); | ||
235 | |||
236 | } | ||
237 | |||
190 | /* | 238 | /* |
191 | * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty. | 239 | * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty. |
192 | */ | 240 | */ |
@@ -202,6 +250,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
202 | { | 250 | { |
203 | unsigned int control = 0; | 251 | unsigned int control = 0; |
204 | unsigned int mode; | 252 | unsigned int mode; |
253 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
205 | 254 | ||
206 | #ifdef CONFIG_ARCH_AT91RM9200 | 255 | #ifdef CONFIG_ARCH_AT91RM9200 |
207 | if (cpu_is_at91rm9200()) { | 256 | if (cpu_is_at91rm9200()) { |
@@ -236,6 +285,17 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
236 | mode |= ATMEL_US_CHMODE_LOC_LOOP; | 285 | mode |= ATMEL_US_CHMODE_LOC_LOOP; |
237 | else | 286 | else |
238 | mode |= ATMEL_US_CHMODE_NORMAL; | 287 | mode |= ATMEL_US_CHMODE_NORMAL; |
288 | |||
289 | /* Resetting serial mode to RS232 (0x0) */ | ||
290 | mode &= ~ATMEL_US_USMODE; | ||
291 | |||
292 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
293 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
294 | UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); | ||
295 | mode |= ATMEL_US_USMODE_RS485; | ||
296 | } else { | ||
297 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
298 | } | ||
239 | UART_PUT_MR(port, mode); | 299 | UART_PUT_MR(port, mode); |
240 | } | 300 | } |
241 | 301 | ||
@@ -268,12 +328,17 @@ static u_int atmel_get_mctrl(struct uart_port *port) | |||
268 | */ | 328 | */ |
269 | static void atmel_stop_tx(struct uart_port *port) | 329 | static void atmel_stop_tx(struct uart_port *port) |
270 | { | 330 | { |
331 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
332 | |||
271 | if (atmel_use_dma_tx(port)) { | 333 | if (atmel_use_dma_tx(port)) { |
272 | /* disable PDC transmit */ | 334 | /* disable PDC transmit */ |
273 | UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); | 335 | UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); |
274 | UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 336 | } |
275 | } else | 337 | /* Disable interrupts */ |
276 | UART_PUT_IDR(port, ATMEL_US_TXRDY); | 338 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
339 | |||
340 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | ||
341 | atmel_start_rx(port); | ||
277 | } | 342 | } |
278 | 343 | ||
279 | /* | 344 | /* |
@@ -281,17 +346,39 @@ static void atmel_stop_tx(struct uart_port *port) | |||
281 | */ | 346 | */ |
282 | static void atmel_start_tx(struct uart_port *port) | 347 | static void atmel_start_tx(struct uart_port *port) |
283 | { | 348 | { |
349 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
350 | |||
284 | if (atmel_use_dma_tx(port)) { | 351 | if (atmel_use_dma_tx(port)) { |
285 | if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) | 352 | if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) |
286 | /* The transmitter is already running. Yes, we | 353 | /* The transmitter is already running. Yes, we |
287 | really need this.*/ | 354 | really need this.*/ |
288 | return; | 355 | return; |
289 | 356 | ||
290 | UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 357 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) |
358 | atmel_stop_rx(port); | ||
359 | |||
291 | /* re-enable PDC transmit */ | 360 | /* re-enable PDC transmit */ |
292 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); | 361 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); |
293 | } else | 362 | } |
294 | UART_PUT_IER(port, ATMEL_US_TXRDY); | 363 | /* Enable interrupts */ |
364 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * start receiving - port is in process of being opened. | ||
369 | */ | ||
370 | static void atmel_start_rx(struct uart_port *port) | ||
371 | { | ||
372 | UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */ | ||
373 | |||
374 | if (atmel_use_dma_rx(port)) { | ||
375 | /* enable PDC controller */ | ||
376 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | | ||
377 | port->read_status_mask); | ||
378 | UART_PUT_PTCR(port, ATMEL_PDC_RXTEN); | ||
379 | } else { | ||
380 | UART_PUT_IER(port, ATMEL_US_RXRDY); | ||
381 | } | ||
295 | } | 382 | } |
296 | 383 | ||
297 | /* | 384 | /* |
@@ -302,9 +389,11 @@ static void atmel_stop_rx(struct uart_port *port) | |||
302 | if (atmel_use_dma_rx(port)) { | 389 | if (atmel_use_dma_rx(port)) { |
303 | /* disable PDC receive */ | 390 | /* disable PDC receive */ |
304 | UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); | 391 | UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); |
305 | UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); | 392 | UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | |
306 | } else | 393 | port->read_status_mask); |
394 | } else { | ||
307 | UART_PUT_IDR(port, ATMEL_US_RXRDY); | 395 | UART_PUT_IDR(port, ATMEL_US_RXRDY); |
396 | } | ||
308 | } | 397 | } |
309 | 398 | ||
310 | /* | 399 | /* |
@@ -428,8 +517,9 @@ static void atmel_rx_chars(struct uart_port *port) | |||
428 | static void atmel_tx_chars(struct uart_port *port) | 517 | static void atmel_tx_chars(struct uart_port *port) |
429 | { | 518 | { |
430 | struct circ_buf *xmit = &port->state->xmit; | 519 | struct circ_buf *xmit = &port->state->xmit; |
520 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
431 | 521 | ||
432 | if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) { | 522 | if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) { |
433 | UART_PUT_CHAR(port, port->x_char); | 523 | UART_PUT_CHAR(port, port->x_char); |
434 | port->icount.tx++; | 524 | port->icount.tx++; |
435 | port->x_char = 0; | 525 | port->x_char = 0; |
@@ -437,7 +527,7 @@ static void atmel_tx_chars(struct uart_port *port) | |||
437 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 527 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
438 | return; | 528 | return; |
439 | 529 | ||
440 | while (UART_GET_CSR(port) & ATMEL_US_TXRDY) { | 530 | while (UART_GET_CSR(port) & atmel_port->tx_done_mask) { |
441 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); | 531 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); |
442 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 532 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
443 | port->icount.tx++; | 533 | port->icount.tx++; |
@@ -449,7 +539,8 @@ static void atmel_tx_chars(struct uart_port *port) | |||
449 | uart_write_wakeup(port); | 539 | uart_write_wakeup(port); |
450 | 540 | ||
451 | if (!uart_circ_empty(xmit)) | 541 | if (!uart_circ_empty(xmit)) |
452 | UART_PUT_IER(port, ATMEL_US_TXRDY); | 542 | /* Enable interrupts */ |
543 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
453 | } | 544 | } |
454 | 545 | ||
455 | /* | 546 | /* |
@@ -501,18 +592,10 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending) | |||
501 | { | 592 | { |
502 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 593 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
503 | 594 | ||
504 | if (atmel_use_dma_tx(port)) { | 595 | if (pending & atmel_port->tx_done_mask) { |
505 | /* PDC transmit */ | 596 | /* Either PDC or interrupt transmission */ |
506 | if (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) { | 597 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
507 | UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 598 | tasklet_schedule(&atmel_port->tasklet); |
508 | tasklet_schedule(&atmel_port->tasklet); | ||
509 | } | ||
510 | } else { | ||
511 | /* Interrupt transmit */ | ||
512 | if (pending & ATMEL_US_TXRDY) { | ||
513 | UART_PUT_IDR(port, ATMEL_US_TXRDY); | ||
514 | tasklet_schedule(&atmel_port->tasklet); | ||
515 | } | ||
516 | } | 599 | } |
517 | } | 600 | } |
518 | 601 | ||
@@ -590,9 +673,15 @@ static void atmel_tx_dma(struct uart_port *port) | |||
590 | 673 | ||
591 | UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); | 674 | UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); |
592 | UART_PUT_TCR(port, count); | 675 | UART_PUT_TCR(port, count); |
593 | /* re-enable PDC transmit and interrupts */ | 676 | /* re-enable PDC transmit */ |
594 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); | 677 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); |
595 | UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 678 | /* Enable interrupts */ |
679 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
680 | } else { | ||
681 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
682 | /* DMA done, stop TX, start RX for RS485 */ | ||
683 | atmel_start_rx(port); | ||
684 | } | ||
596 | } | 685 | } |
597 | 686 | ||
598 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 687 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -1017,6 +1106,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1017 | { | 1106 | { |
1018 | unsigned long flags; | 1107 | unsigned long flags; |
1019 | unsigned int mode, imr, quot, baud; | 1108 | unsigned int mode, imr, quot, baud; |
1109 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
1020 | 1110 | ||
1021 | /* Get current mode register */ | 1111 | /* Get current mode register */ |
1022 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | 1112 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL |
@@ -1115,6 +1205,17 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1115 | /* disable receiver and transmitter */ | 1205 | /* disable receiver and transmitter */ |
1116 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); | 1206 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); |
1117 | 1207 | ||
1208 | /* Resetting serial mode to RS232 (0x0) */ | ||
1209 | mode &= ~ATMEL_US_USMODE; | ||
1210 | |||
1211 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
1212 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
1213 | UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); | ||
1214 | mode |= ATMEL_US_USMODE_RS485; | ||
1215 | } else { | ||
1216 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
1217 | } | ||
1218 | |||
1118 | /* set the parity, stop bits and data size */ | 1219 | /* set the parity, stop bits and data size */ |
1119 | UART_PUT_MR(port, mode); | 1220 | UART_PUT_MR(port, mode); |
1120 | 1221 | ||
@@ -1231,6 +1332,35 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) | |||
1231 | } | 1332 | } |
1232 | #endif | 1333 | #endif |
1233 | 1334 | ||
1335 | static int | ||
1336 | atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) | ||
1337 | { | ||
1338 | struct serial_rs485 rs485conf; | ||
1339 | |||
1340 | switch (cmd) { | ||
1341 | case TIOCSRS485: | ||
1342 | if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg, | ||
1343 | sizeof(rs485conf))) | ||
1344 | return -EFAULT; | ||
1345 | |||
1346 | atmel_config_rs485(port, &rs485conf); | ||
1347 | break; | ||
1348 | |||
1349 | case TIOCGRS485: | ||
1350 | if (copy_to_user((struct serial_rs485 *) arg, | ||
1351 | &(to_atmel_uart_port(port)->rs485), | ||
1352 | sizeof(rs485conf))) | ||
1353 | return -EFAULT; | ||
1354 | break; | ||
1355 | |||
1356 | default: | ||
1357 | return -ENOIOCTLCMD; | ||
1358 | } | ||
1359 | return 0; | ||
1360 | } | ||
1361 | |||
1362 | |||
1363 | |||
1234 | static struct uart_ops atmel_pops = { | 1364 | static struct uart_ops atmel_pops = { |
1235 | .tx_empty = atmel_tx_empty, | 1365 | .tx_empty = atmel_tx_empty, |
1236 | .set_mctrl = atmel_set_mctrl, | 1366 | .set_mctrl = atmel_set_mctrl, |
@@ -1250,6 +1380,7 @@ static struct uart_ops atmel_pops = { | |||
1250 | .config_port = atmel_config_port, | 1380 | .config_port = atmel_config_port, |
1251 | .verify_port = atmel_verify_port, | 1381 | .verify_port = atmel_verify_port, |
1252 | .pm = atmel_serial_pm, | 1382 | .pm = atmel_serial_pm, |
1383 | .ioctl = atmel_ioctl, | ||
1253 | #ifdef CONFIG_CONSOLE_POLL | 1384 | #ifdef CONFIG_CONSOLE_POLL |
1254 | .poll_get_char = atmel_poll_get_char, | 1385 | .poll_get_char = atmel_poll_get_char, |
1255 | .poll_put_char = atmel_poll_put_char, | 1386 | .poll_put_char = atmel_poll_put_char, |
@@ -1265,13 +1396,12 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
1265 | struct uart_port *port = &atmel_port->uart; | 1396 | struct uart_port *port = &atmel_port->uart; |
1266 | struct atmel_uart_data *data = pdev->dev.platform_data; | 1397 | struct atmel_uart_data *data = pdev->dev.platform_data; |
1267 | 1398 | ||
1268 | port->iotype = UPIO_MEM; | 1399 | port->iotype = UPIO_MEM; |
1269 | port->flags = UPF_BOOT_AUTOCONF; | 1400 | port->flags = UPF_BOOT_AUTOCONF; |
1270 | port->ops = &atmel_pops; | 1401 | port->ops = &atmel_pops; |
1271 | port->fifosize = 1; | 1402 | port->fifosize = 1; |
1272 | port->line = pdev->id; | 1403 | port->line = pdev->id; |
1273 | port->dev = &pdev->dev; | 1404 | port->dev = &pdev->dev; |
1274 | |||
1275 | port->mapbase = pdev->resource[0].start; | 1405 | port->mapbase = pdev->resource[0].start; |
1276 | port->irq = pdev->resource[1].start; | 1406 | port->irq = pdev->resource[1].start; |
1277 | 1407 | ||
@@ -1299,8 +1429,16 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
1299 | 1429 | ||
1300 | atmel_port->use_dma_rx = data->use_dma_rx; | 1430 | atmel_port->use_dma_rx = data->use_dma_rx; |
1301 | atmel_port->use_dma_tx = data->use_dma_tx; | 1431 | atmel_port->use_dma_tx = data->use_dma_tx; |
1302 | if (atmel_use_dma_tx(port)) | 1432 | atmel_port->rs485 = data->rs485; |
1433 | /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ | ||
1434 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | ||
1435 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | ||
1436 | else if (atmel_use_dma_tx(port)) { | ||
1303 | port->fifosize = PDC_BUFFER_SIZE; | 1437 | port->fifosize = PDC_BUFFER_SIZE; |
1438 | atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE; | ||
1439 | } else { | ||
1440 | atmel_port->tx_done_mask = ATMEL_US_TXRDY; | ||
1441 | } | ||
1304 | } | 1442 | } |
1305 | 1443 | ||
1306 | /* | 1444 | /* |
@@ -1334,6 +1472,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch) | |||
1334 | static void atmel_console_write(struct console *co, const char *s, u_int count) | 1472 | static void atmel_console_write(struct console *co, const char *s, u_int count) |
1335 | { | 1473 | { |
1336 | struct uart_port *port = &atmel_ports[co->index].uart; | 1474 | struct uart_port *port = &atmel_ports[co->index].uart; |
1475 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
1337 | unsigned int status, imr; | 1476 | unsigned int status, imr; |
1338 | unsigned int pdc_tx; | 1477 | unsigned int pdc_tx; |
1339 | 1478 | ||
@@ -1341,7 +1480,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count) | |||
1341 | * First, save IMR and then disable interrupts | 1480 | * First, save IMR and then disable interrupts |
1342 | */ | 1481 | */ |
1343 | imr = UART_GET_IMR(port); | 1482 | imr = UART_GET_IMR(port); |
1344 | UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY); | 1483 | UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask); |
1345 | 1484 | ||
1346 | /* Store PDC transmit status and disable it */ | 1485 | /* Store PDC transmit status and disable it */ |
1347 | pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; | 1486 | pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; |
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index c88f8ad3ff82..e57fb3d228e2 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -34,32 +34,12 @@ | |||
34 | #include <linux/tty_flip.h> | 34 | #include <linux/tty_flip.h> |
35 | #include <linux/serial_core.h> | 35 | #include <linux/serial_core.h> |
36 | 36 | ||
37 | #include <asm/bfin_sport.h> | ||
37 | #include <asm/delay.h> | 38 | #include <asm/delay.h> |
38 | #include <asm/portmux.h> | 39 | #include <asm/portmux.h> |
39 | 40 | ||
40 | #include "bfin_sport_uart.h" | 41 | #include "bfin_sport_uart.h" |
41 | 42 | ||
42 | #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART | ||
43 | unsigned short bfin_uart_pin_req_sport0[] = | ||
44 | {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \ | ||
45 | P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0}; | ||
46 | #endif | ||
47 | #ifdef CONFIG_SERIAL_BFIN_SPORT1_UART | ||
48 | unsigned short bfin_uart_pin_req_sport1[] = | ||
49 | {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \ | ||
50 | P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0}; | ||
51 | #endif | ||
52 | #ifdef CONFIG_SERIAL_BFIN_SPORT2_UART | ||
53 | unsigned short bfin_uart_pin_req_sport2[] = | ||
54 | {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, \ | ||
55 | P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0}; | ||
56 | #endif | ||
57 | #ifdef CONFIG_SERIAL_BFIN_SPORT3_UART | ||
58 | unsigned short bfin_uart_pin_req_sport3[] = | ||
59 | {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, \ | ||
60 | P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0}; | ||
61 | #endif | ||
62 | |||
63 | struct sport_uart_port { | 43 | struct sport_uart_port { |
64 | struct uart_port port; | 44 | struct uart_port port; |
65 | int err_irq; | 45 | int err_irq; |
@@ -69,9 +49,13 @@ struct sport_uart_port { | |||
69 | unsigned short txmask2; | 49 | unsigned short txmask2; |
70 | unsigned char stopb; | 50 | unsigned char stopb; |
71 | /* unsigned char parib; */ | 51 | /* unsigned char parib; */ |
52 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
53 | int cts_pin; | ||
54 | int rts_pin; | ||
55 | #endif | ||
72 | }; | 56 | }; |
73 | 57 | ||
74 | static void sport_uart_tx_chars(struct sport_uart_port *up); | 58 | static int sport_uart_tx_chars(struct sport_uart_port *up); |
75 | static void sport_stop_tx(struct uart_port *port); | 59 | static void sport_stop_tx(struct uart_port *port); |
76 | 60 | ||
77 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) | 61 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) |
@@ -219,6 +203,59 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
219 | return IRQ_HANDLED; | 203 | return IRQ_HANDLED; |
220 | } | 204 | } |
221 | 205 | ||
206 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
207 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
208 | { | ||
209 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
210 | if (up->cts_pin < 0) | ||
211 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
212 | |||
213 | /* CTS PIN is negative assertive. */ | ||
214 | if (SPORT_UART_GET_CTS(up)) | ||
215 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
216 | else | ||
217 | return TIOCM_DSR | TIOCM_CAR; | ||
218 | } | ||
219 | |||
220 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
221 | { | ||
222 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
223 | if (up->rts_pin < 0) | ||
224 | return; | ||
225 | |||
226 | /* RTS PIN is negative assertive. */ | ||
227 | if (mctrl & TIOCM_RTS) | ||
228 | SPORT_UART_ENABLE_RTS(up); | ||
229 | else | ||
230 | SPORT_UART_DISABLE_RTS(up); | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Handle any change of modem status signal. | ||
235 | */ | ||
236 | static irqreturn_t sport_mctrl_cts_int(int irq, void *dev_id) | ||
237 | { | ||
238 | struct sport_uart_port *up = (struct sport_uart_port *)dev_id; | ||
239 | unsigned int status; | ||
240 | |||
241 | status = sport_get_mctrl(&up->port); | ||
242 | uart_handle_cts_change(&up->port, status & TIOCM_CTS); | ||
243 | |||
244 | return IRQ_HANDLED; | ||
245 | } | ||
246 | #else | ||
247 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
248 | { | ||
249 | pr_debug("%s enter\n", __func__); | ||
250 | return TIOCM_CTS | TIOCM_CD | TIOCM_DSR; | ||
251 | } | ||
252 | |||
253 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
254 | { | ||
255 | pr_debug("%s enter\n", __func__); | ||
256 | } | ||
257 | #endif | ||
258 | |||
222 | /* Reqeust IRQ, Setup clock */ | 259 | /* Reqeust IRQ, Setup clock */ |
223 | static int sport_startup(struct uart_port *port) | 260 | static int sport_startup(struct uart_port *port) |
224 | { | 261 | { |
@@ -247,6 +284,21 @@ static int sport_startup(struct uart_port *port) | |||
247 | goto fail2; | 284 | goto fail2; |
248 | } | 285 | } |
249 | 286 | ||
287 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
288 | if (up->cts_pin >= 0) { | ||
289 | if (request_irq(gpio_to_irq(up->cts_pin), | ||
290 | sport_mctrl_cts_int, | ||
291 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | | ||
292 | IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) { | ||
293 | up->cts_pin = -1; | ||
294 | dev_info(port->dev, "Unable to attach BlackFin UART \ | ||
295 | over SPORT CTS interrupt. So, disable it.\n"); | ||
296 | } | ||
297 | } | ||
298 | if (up->rts_pin >= 0) | ||
299 | gpio_direction_output(up->rts_pin, 0); | ||
300 | #endif | ||
301 | |||
250 | return 0; | 302 | return 0; |
251 | fail2: | 303 | fail2: |
252 | free_irq(up->port.irq+1, up); | 304 | free_irq(up->port.irq+1, up); |
@@ -256,23 +308,35 @@ static int sport_startup(struct uart_port *port) | |||
256 | return ret; | 308 | return ret; |
257 | } | 309 | } |
258 | 310 | ||
259 | static void sport_uart_tx_chars(struct sport_uart_port *up) | 311 | /* |
312 | * sport_uart_tx_chars | ||
313 | * | ||
314 | * ret 1 means need to enable sport. | ||
315 | * ret 0 means do nothing. | ||
316 | */ | ||
317 | static int sport_uart_tx_chars(struct sport_uart_port *up) | ||
260 | { | 318 | { |
261 | struct circ_buf *xmit = &up->port.state->xmit; | 319 | struct circ_buf *xmit = &up->port.state->xmit; |
262 | 320 | ||
263 | if (SPORT_GET_STAT(up) & TXF) | 321 | if (SPORT_GET_STAT(up) & TXF) |
264 | return; | 322 | return 0; |
265 | 323 | ||
266 | if (up->port.x_char) { | 324 | if (up->port.x_char) { |
267 | tx_one_byte(up, up->port.x_char); | 325 | tx_one_byte(up, up->port.x_char); |
268 | up->port.icount.tx++; | 326 | up->port.icount.tx++; |
269 | up->port.x_char = 0; | 327 | up->port.x_char = 0; |
270 | return; | 328 | return 1; |
271 | } | 329 | } |
272 | 330 | ||
273 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | 331 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { |
274 | sport_stop_tx(&up->port); | 332 | /* The waiting loop to stop SPORT TX from TX interrupt is |
275 | return; | 333 | * too long. This may block SPORT RX interrupts and cause |
334 | * RX FIFO overflow. So, do stop sport TX only after the last | ||
335 | * char in TX FIFO is moved into the shift register. | ||
336 | */ | ||
337 | if (SPORT_GET_STAT(up) & TXHRE) | ||
338 | sport_stop_tx(&up->port); | ||
339 | return 0; | ||
276 | } | 340 | } |
277 | 341 | ||
278 | while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) { | 342 | while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) { |
@@ -283,6 +347,8 @@ static void sport_uart_tx_chars(struct sport_uart_port *up) | |||
283 | 347 | ||
284 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 348 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
285 | uart_write_wakeup(&up->port); | 349 | uart_write_wakeup(&up->port); |
350 | |||
351 | return 1; | ||
286 | } | 352 | } |
287 | 353 | ||
288 | static unsigned int sport_tx_empty(struct uart_port *port) | 354 | static unsigned int sport_tx_empty(struct uart_port *port) |
@@ -298,23 +364,15 @@ static unsigned int sport_tx_empty(struct uart_port *port) | |||
298 | return 0; | 364 | return 0; |
299 | } | 365 | } |
300 | 366 | ||
301 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
302 | { | ||
303 | pr_debug("%s enter\n", __func__); | ||
304 | return (TIOCM_CTS | TIOCM_CD | TIOCM_DSR); | ||
305 | } | ||
306 | |||
307 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
308 | { | ||
309 | pr_debug("%s enter\n", __func__); | ||
310 | } | ||
311 | |||
312 | static void sport_stop_tx(struct uart_port *port) | 367 | static void sport_stop_tx(struct uart_port *port) |
313 | { | 368 | { |
314 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 369 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
315 | 370 | ||
316 | pr_debug("%s enter\n", __func__); | 371 | pr_debug("%s enter\n", __func__); |
317 | 372 | ||
373 | if (!(SPORT_GET_TCR1(up) & TSPEN)) | ||
374 | return; | ||
375 | |||
318 | /* Although the hold register is empty, last byte is still in shift | 376 | /* Although the hold register is empty, last byte is still in shift |
319 | * register and not sent out yet. So, put a dummy data into TX FIFO. | 377 | * register and not sent out yet. So, put a dummy data into TX FIFO. |
320 | * Then, sport tx stops when last byte is shift out and the dummy | 378 | * Then, sport tx stops when last byte is shift out and the dummy |
@@ -337,11 +395,12 @@ static void sport_start_tx(struct uart_port *port) | |||
337 | pr_debug("%s enter\n", __func__); | 395 | pr_debug("%s enter\n", __func__); |
338 | 396 | ||
339 | /* Write data into SPORT FIFO before enable SPROT to transmit */ | 397 | /* Write data into SPORT FIFO before enable SPROT to transmit */ |
340 | sport_uart_tx_chars(up); | 398 | if (sport_uart_tx_chars(up)) { |
399 | /* Enable transmit, then an interrupt will generated */ | ||
400 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
401 | SSYNC(); | ||
402 | } | ||
341 | 403 | ||
342 | /* Enable transmit, then an interrupt will generated */ | ||
343 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
344 | SSYNC(); | ||
345 | pr_debug("%s exit\n", __func__); | 404 | pr_debug("%s exit\n", __func__); |
346 | } | 405 | } |
347 | 406 | ||
@@ -379,6 +438,10 @@ static void sport_shutdown(struct uart_port *port) | |||
379 | free_irq(up->port.irq, up); | 438 | free_irq(up->port.irq, up); |
380 | free_irq(up->port.irq+1, up); | 439 | free_irq(up->port.irq+1, up); |
381 | free_irq(up->err_irq, up); | 440 | free_irq(up->err_irq, up); |
441 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
442 | if (up->cts_pin >= 0) | ||
443 | free_irq(gpio_to_irq(up->cts_pin), up); | ||
444 | #endif | ||
382 | } | 445 | } |
383 | 446 | ||
384 | static const char *sport_type(struct uart_port *port) | 447 | static const char *sport_type(struct uart_port *port) |
@@ -448,27 +511,14 @@ static void sport_set_termios(struct uart_port *port, | |||
448 | /* up->parib = 1; */ | 511 | /* up->parib = 1; */ |
449 | } | 512 | } |
450 | 513 | ||
451 | port->read_status_mask = OE; | 514 | spin_lock_irqsave(&up->port.lock, flags); |
452 | if (termios->c_iflag & INPCK) | 515 | |
453 | port->read_status_mask |= (FE | PE); | 516 | port->read_status_mask = 0; |
454 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
455 | port->read_status_mask |= BI; | ||
456 | 517 | ||
457 | /* | 518 | /* |
458 | * Characters to ignore | 519 | * Characters to ignore |
459 | */ | 520 | */ |
460 | port->ignore_status_mask = 0; | 521 | port->ignore_status_mask = 0; |
461 | if (termios->c_iflag & IGNPAR) | ||
462 | port->ignore_status_mask |= FE | PE; | ||
463 | if (termios->c_iflag & IGNBRK) { | ||
464 | port->ignore_status_mask |= BI; | ||
465 | /* | ||
466 | * If we're ignoring parity and break indicators, | ||
467 | * ignore overruns too (for real raw support). | ||
468 | */ | ||
469 | if (termios->c_iflag & IGNPAR) | ||
470 | port->ignore_status_mask |= OE; | ||
471 | } | ||
472 | 522 | ||
473 | /* RX extract mask */ | 523 | /* RX extract mask */ |
474 | up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8); | 524 | up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8); |
@@ -488,8 +538,6 @@ static void sport_set_termios(struct uart_port *port, | |||
488 | /* uart baud rate */ | 538 | /* uart baud rate */ |
489 | port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16); | 539 | port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16); |
490 | 540 | ||
491 | spin_lock_irqsave(&up->port.lock, flags); | ||
492 | |||
493 | /* Disable UART */ | 541 | /* Disable UART */ |
494 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | 542 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); |
495 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); | 543 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); |
@@ -542,6 +590,8 @@ struct uart_ops sport_uart_ops = { | |||
542 | static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS]; | 590 | static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS]; |
543 | 591 | ||
544 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | 592 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE |
593 | #define CLASS_BFIN_SPORT_CONSOLE "bfin-sport-console" | ||
594 | |||
545 | static int __init | 595 | static int __init |
546 | sport_uart_console_setup(struct console *co, char *options) | 596 | sport_uart_console_setup(struct console *co, char *options) |
547 | { | 597 | { |
@@ -549,7 +599,11 @@ sport_uart_console_setup(struct console *co, char *options) | |||
549 | int baud = 57600; | 599 | int baud = 57600; |
550 | int bits = 8; | 600 | int bits = 8; |
551 | int parity = 'n'; | 601 | int parity = 'n'; |
602 | # ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
603 | int flow = 'r'; | ||
604 | # else | ||
552 | int flow = 'n'; | 605 | int flow = 'n'; |
606 | # endif | ||
553 | 607 | ||
554 | /* Check whether an invalid uart number has been specified */ | 608 | /* Check whether an invalid uart number has been specified */ |
555 | if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS) | 609 | if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS) |
@@ -690,11 +744,11 @@ static int __devinit sport_uart_probe(struct platform_device *pdev) | |||
690 | 744 | ||
691 | if (bfin_sport_uart_ports[pdev->id] == NULL) { | 745 | if (bfin_sport_uart_ports[pdev->id] == NULL) { |
692 | bfin_sport_uart_ports[pdev->id] = | 746 | bfin_sport_uart_ports[pdev->id] = |
693 | kmalloc(sizeof(struct sport_uart_port), GFP_KERNEL); | 747 | kzalloc(sizeof(struct sport_uart_port), GFP_KERNEL); |
694 | sport = bfin_sport_uart_ports[pdev->id]; | 748 | sport = bfin_sport_uart_ports[pdev->id]; |
695 | if (!sport) { | 749 | if (!sport) { |
696 | dev_err(&pdev->dev, | 750 | dev_err(&pdev->dev, |
697 | "Fail to kmalloc sport_uart_port\n"); | 751 | "Fail to malloc sport_uart_port\n"); |
698 | return -ENOMEM; | 752 | return -ENOMEM; |
699 | } | 753 | } |
700 | 754 | ||
@@ -720,13 +774,13 @@ static int __devinit sport_uart_probe(struct platform_device *pdev) | |||
720 | goto out_error_free_peripherals; | 774 | goto out_error_free_peripherals; |
721 | } | 775 | } |
722 | 776 | ||
723 | sport->port.membase = ioremap(res->start, | 777 | sport->port.membase = ioremap(res->start, resource_size(res)); |
724 | res->end - res->start); | ||
725 | if (!sport->port.membase) { | 778 | if (!sport->port.membase) { |
726 | dev_err(&pdev->dev, "Cannot map sport IO\n"); | 779 | dev_err(&pdev->dev, "Cannot map sport IO\n"); |
727 | ret = -ENXIO; | 780 | ret = -ENXIO; |
728 | goto out_error_free_peripherals; | 781 | goto out_error_free_peripherals; |
729 | } | 782 | } |
783 | sport->port.mapbase = res->start; | ||
730 | 784 | ||
731 | sport->port.irq = platform_get_irq(pdev, 0); | 785 | sport->port.irq = platform_get_irq(pdev, 0); |
732 | if (sport->port.irq < 0) { | 786 | if (sport->port.irq < 0) { |
@@ -741,6 +795,22 @@ static int __devinit sport_uart_probe(struct platform_device *pdev) | |||
741 | ret = -ENOENT; | 795 | ret = -ENOENT; |
742 | goto out_error_unmap; | 796 | goto out_error_unmap; |
743 | } | 797 | } |
798 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
799 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
800 | if (res == NULL) | ||
801 | sport->cts_pin = -1; | ||
802 | else | ||
803 | sport->cts_pin = res->start; | ||
804 | |||
805 | res = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
806 | if (res == NULL) | ||
807 | sport->rts_pin = -1; | ||
808 | else | ||
809 | sport->rts_pin = res->start; | ||
810 | |||
811 | if (sport->rts_pin >= 0) | ||
812 | gpio_request(sport->rts_pin, DRV_NAME); | ||
813 | #endif | ||
744 | } | 814 | } |
745 | 815 | ||
746 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | 816 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE |
@@ -779,6 +849,10 @@ static int __devexit sport_uart_remove(struct platform_device *pdev) | |||
779 | 849 | ||
780 | if (sport) { | 850 | if (sport) { |
781 | uart_remove_one_port(&sport_uart_reg, &sport->port); | 851 | uart_remove_one_port(&sport_uart_reg, &sport->port); |
852 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
853 | if (sport->rts_pin >= 0) | ||
854 | gpio_free(sport->rts_pin); | ||
855 | #endif | ||
782 | iounmap(sport->port.membase); | 856 | iounmap(sport->port.membase); |
783 | peripheral_free_list( | 857 | peripheral_free_list( |
784 | (unsigned short *)pdev->dev.platform_data); | 858 | (unsigned short *)pdev->dev.platform_data); |
@@ -802,7 +876,7 @@ static struct platform_driver sport_uart_driver = { | |||
802 | 876 | ||
803 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | 877 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE |
804 | static __initdata struct early_platform_driver early_sport_uart_driver = { | 878 | static __initdata struct early_platform_driver early_sport_uart_driver = { |
805 | .class_str = DRV_NAME, | 879 | .class_str = CLASS_BFIN_SPORT_CONSOLE, |
806 | .pdrv = &sport_uart_driver, | 880 | .pdrv = &sport_uart_driver, |
807 | .requested_id = EARLY_PLATFORM_ID_UNSET, | 881 | .requested_id = EARLY_PLATFORM_ID_UNSET, |
808 | }; | 882 | }; |
@@ -811,7 +885,8 @@ static int __init sport_uart_rs_console_init(void) | |||
811 | { | 885 | { |
812 | early_platform_driver_register(&early_sport_uart_driver, DRV_NAME); | 886 | early_platform_driver_register(&early_sport_uart_driver, DRV_NAME); |
813 | 887 | ||
814 | early_platform_driver_probe(DRV_NAME, BFIN_SPORT_UART_MAX_PORTS, 0); | 888 | early_platform_driver_probe(CLASS_BFIN_SPORT_CONSOLE, |
889 | BFIN_SPORT_UART_MAX_PORTS, 0); | ||
815 | 890 | ||
816 | register_console(&sport_uart_console); | 891 | register_console(&sport_uart_console); |
817 | 892 | ||
@@ -824,7 +899,7 @@ static int __init sport_uart_init(void) | |||
824 | { | 899 | { |
825 | int ret; | 900 | int ret; |
826 | 901 | ||
827 | pr_info("Serial: Blackfin uart over sport driver\n"); | 902 | pr_info("Blackfin uart over sport driver\n"); |
828 | 903 | ||
829 | ret = uart_register_driver(&sport_uart_reg); | 904 | ret = uart_register_driver(&sport_uart_reg); |
830 | if (ret) { | 905 | if (ret) { |
diff --git a/drivers/serial/bfin_sport_uart.h b/drivers/serial/bfin_sport_uart.h index abe03614e4df..9ce253e381d2 100644 --- a/drivers/serial/bfin_sport_uart.h +++ b/drivers/serial/bfin_sport_uart.h | |||
@@ -37,7 +37,21 @@ | |||
37 | #define SPORT_GET_TFSDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_TFSDIV)) | 37 | #define SPORT_GET_TFSDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_TFSDIV)) |
38 | #define SPORT_GET_TX(sport) bfin_read16(((sport)->port.membase + OFFSET_TX)) | 38 | #define SPORT_GET_TX(sport) bfin_read16(((sport)->port.membase + OFFSET_TX)) |
39 | #define SPORT_GET_RX(sport) bfin_read16(((sport)->port.membase + OFFSET_RX)) | 39 | #define SPORT_GET_RX(sport) bfin_read16(((sport)->port.membase + OFFSET_RX)) |
40 | #define SPORT_GET_RX32(sport) bfin_read32(((sport)->port.membase + OFFSET_RX)) | 40 | /* |
41 | * If another interrupt fires while doing a 32-bit read from RX FIFO, | ||
42 | * a fake RX underflow error will be generated. So disable interrupts | ||
43 | * to prevent interruption while reading the FIFO. | ||
44 | */ | ||
45 | #define SPORT_GET_RX32(sport) \ | ||
46 | ({ \ | ||
47 | unsigned int __ret; \ | ||
48 | if (ANOMALY_05000473) \ | ||
49 | local_irq_disable(); \ | ||
50 | __ret = bfin_read32((sport)->port.membase + OFFSET_RX); \ | ||
51 | if (ANOMALY_05000473) \ | ||
52 | local_irq_enable(); \ | ||
53 | __ret; \ | ||
54 | }) | ||
41 | #define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1)) | 55 | #define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1)) |
42 | #define SPORT_GET_RCR2(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR2)) | 56 | #define SPORT_GET_RCR2(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR2)) |
43 | #define SPORT_GET_RCLKDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_RCLKDIV)) | 57 | #define SPORT_GET_RCLKDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_RCLKDIV)) |
@@ -58,4 +72,15 @@ | |||
58 | 72 | ||
59 | #define SPORT_TX_FIFO_SIZE 8 | 73 | #define SPORT_TX_FIFO_SIZE 8 |
60 | 74 | ||
75 | #define SPORT_UART_GET_CTS(x) gpio_get_value(x->cts_pin) | ||
76 | #define SPORT_UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) | ||
77 | #define SPORT_UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) | ||
78 | |||
79 | #if defined(CONFIG_SERIAL_BFIN_SPORT0_UART_CTSRTS) \ | ||
80 | || defined(CONFIG_SERIAL_BFIN_SPORT1_UART_CTSRTS) \ | ||
81 | || defined(CONFIG_SERIAL_BFIN_SPORT2_UART_CTSRTS) \ | ||
82 | || defined(CONFIG_SERIAL_BFIN_SPORT3_UART_CTSRTS) | ||
83 | # define CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
84 | #endif | ||
85 | |||
61 | #endif /* _BFIN_SPORT_UART_H */ | 86 | #endif /* _BFIN_SPORT_UART_H */ |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 300cea768d74..9eb62a256e9a 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -1342,7 +1342,7 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev, | |||
1342 | /* initialize the device pointer for the port */ | 1342 | /* initialize the device pointer for the port */ |
1343 | pinfo->port.dev = &ofdev->dev; | 1343 | pinfo->port.dev = &ofdev->dev; |
1344 | 1344 | ||
1345 | ret = cpm_uart_init_port(ofdev->node, pinfo); | 1345 | ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo); |
1346 | if (ret) | 1346 | if (ret) |
1347 | return ret; | 1347 | return ret; |
1348 | 1348 | ||
@@ -1372,8 +1372,11 @@ static struct of_device_id cpm_uart_match[] = { | |||
1372 | }; | 1372 | }; |
1373 | 1373 | ||
1374 | static struct of_platform_driver cpm_uart_driver = { | 1374 | static struct of_platform_driver cpm_uart_driver = { |
1375 | .name = "cpm_uart", | 1375 | .driver = { |
1376 | .match_table = cpm_uart_match, | 1376 | .name = "cpm_uart", |
1377 | .owner = THIS_MODULE, | ||
1378 | .of_match_table = cpm_uart_match, | ||
1379 | }, | ||
1377 | .probe = cpm_uart_probe, | 1380 | .probe = cpm_uart_probe, |
1378 | .remove = cpm_uart_remove, | 1381 | .remove = cpm_uart_remove, |
1379 | }; | 1382 | }; |
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index eadc1ab6bbce..a9a94ae72349 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
@@ -14,7 +14,9 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/kgdb.h> | 16 | #include <linux/kgdb.h> |
17 | #include <linux/kdb.h> | ||
17 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/console.h> | ||
18 | 20 | ||
19 | #define MAX_CONFIG_LEN 40 | 21 | #define MAX_CONFIG_LEN 40 |
20 | 22 | ||
@@ -32,6 +34,40 @@ static struct kparam_string kps = { | |||
32 | static struct tty_driver *kgdb_tty_driver; | 34 | static struct tty_driver *kgdb_tty_driver; |
33 | static int kgdb_tty_line; | 35 | static int kgdb_tty_line; |
34 | 36 | ||
37 | #ifdef CONFIG_KDB_KEYBOARD | ||
38 | static int kgdboc_register_kbd(char **cptr) | ||
39 | { | ||
40 | if (strncmp(*cptr, "kbd", 3) == 0) { | ||
41 | if (kdb_poll_idx < KDB_POLL_FUNC_MAX) { | ||
42 | kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char; | ||
43 | kdb_poll_idx++; | ||
44 | if (cptr[0][3] == ',') | ||
45 | *cptr += 4; | ||
46 | else | ||
47 | return 1; | ||
48 | } | ||
49 | } | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static void kgdboc_unregister_kbd(void) | ||
54 | { | ||
55 | int i; | ||
56 | |||
57 | for (i = 0; i < kdb_poll_idx; i++) { | ||
58 | if (kdb_poll_funcs[i] == kdb_get_kbd_char) { | ||
59 | kdb_poll_idx--; | ||
60 | kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx]; | ||
61 | kdb_poll_funcs[kdb_poll_idx] = NULL; | ||
62 | i--; | ||
63 | } | ||
64 | } | ||
65 | } | ||
66 | #else /* ! CONFIG_KDB_KEYBOARD */ | ||
67 | #define kgdboc_register_kbd(x) 0 | ||
68 | #define kgdboc_unregister_kbd() | ||
69 | #endif /* ! CONFIG_KDB_KEYBOARD */ | ||
70 | |||
35 | static int kgdboc_option_setup(char *opt) | 71 | static int kgdboc_option_setup(char *opt) |
36 | { | 72 | { |
37 | if (strlen(opt) > MAX_CONFIG_LEN) { | 73 | if (strlen(opt) > MAX_CONFIG_LEN) { |
@@ -45,25 +81,51 @@ static int kgdboc_option_setup(char *opt) | |||
45 | 81 | ||
46 | __setup("kgdboc=", kgdboc_option_setup); | 82 | __setup("kgdboc=", kgdboc_option_setup); |
47 | 83 | ||
84 | static void cleanup_kgdboc(void) | ||
85 | { | ||
86 | kgdboc_unregister_kbd(); | ||
87 | if (configured == 1) | ||
88 | kgdb_unregister_io_module(&kgdboc_io_ops); | ||
89 | } | ||
90 | |||
48 | static int configure_kgdboc(void) | 91 | static int configure_kgdboc(void) |
49 | { | 92 | { |
50 | struct tty_driver *p; | 93 | struct tty_driver *p; |
51 | int tty_line = 0; | 94 | int tty_line = 0; |
52 | int err; | 95 | int err; |
96 | char *cptr = config; | ||
97 | struct console *cons; | ||
53 | 98 | ||
54 | err = kgdboc_option_setup(config); | 99 | err = kgdboc_option_setup(config); |
55 | if (err || !strlen(config) || isspace(config[0])) | 100 | if (err || !strlen(config) || isspace(config[0])) |
56 | goto noconfig; | 101 | goto noconfig; |
57 | 102 | ||
58 | err = -ENODEV; | 103 | err = -ENODEV; |
104 | kgdboc_io_ops.is_console = 0; | ||
105 | kgdb_tty_driver = NULL; | ||
59 | 106 | ||
60 | p = tty_find_polling_driver(config, &tty_line); | 107 | if (kgdboc_register_kbd(&cptr)) |
108 | goto do_register; | ||
109 | |||
110 | p = tty_find_polling_driver(cptr, &tty_line); | ||
61 | if (!p) | 111 | if (!p) |
62 | goto noconfig; | 112 | goto noconfig; |
63 | 113 | ||
114 | cons = console_drivers; | ||
115 | while (cons) { | ||
116 | int idx; | ||
117 | if (cons->device && cons->device(cons, &idx) == p && | ||
118 | idx == tty_line) { | ||
119 | kgdboc_io_ops.is_console = 1; | ||
120 | break; | ||
121 | } | ||
122 | cons = cons->next; | ||
123 | } | ||
124 | |||
64 | kgdb_tty_driver = p; | 125 | kgdb_tty_driver = p; |
65 | kgdb_tty_line = tty_line; | 126 | kgdb_tty_line = tty_line; |
66 | 127 | ||
128 | do_register: | ||
67 | err = kgdb_register_io_module(&kgdboc_io_ops); | 129 | err = kgdb_register_io_module(&kgdboc_io_ops); |
68 | if (err) | 130 | if (err) |
69 | goto noconfig; | 131 | goto noconfig; |
@@ -75,6 +137,7 @@ static int configure_kgdboc(void) | |||
75 | noconfig: | 137 | noconfig: |
76 | config[0] = 0; | 138 | config[0] = 0; |
77 | configured = 0; | 139 | configured = 0; |
140 | cleanup_kgdboc(); | ||
78 | 141 | ||
79 | return err; | 142 | return err; |
80 | } | 143 | } |
@@ -88,20 +151,18 @@ static int __init init_kgdboc(void) | |||
88 | return configure_kgdboc(); | 151 | return configure_kgdboc(); |
89 | } | 152 | } |
90 | 153 | ||
91 | static void cleanup_kgdboc(void) | ||
92 | { | ||
93 | if (configured == 1) | ||
94 | kgdb_unregister_io_module(&kgdboc_io_ops); | ||
95 | } | ||
96 | |||
97 | static int kgdboc_get_char(void) | 154 | static int kgdboc_get_char(void) |
98 | { | 155 | { |
156 | if (!kgdb_tty_driver) | ||
157 | return -1; | ||
99 | return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver, | 158 | return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver, |
100 | kgdb_tty_line); | 159 | kgdb_tty_line); |
101 | } | 160 | } |
102 | 161 | ||
103 | static void kgdboc_put_char(u8 chr) | 162 | static void kgdboc_put_char(u8 chr) |
104 | { | 163 | { |
164 | if (!kgdb_tty_driver) | ||
165 | return; | ||
105 | kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver, | 166 | kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver, |
106 | kgdb_tty_line, chr); | 167 | kgdb_tty_line, chr); |
107 | } | 168 | } |
@@ -162,6 +223,25 @@ static struct kgdb_io kgdboc_io_ops = { | |||
162 | .post_exception = kgdboc_post_exp_handler, | 223 | .post_exception = kgdboc_post_exp_handler, |
163 | }; | 224 | }; |
164 | 225 | ||
226 | #ifdef CONFIG_KGDB_SERIAL_CONSOLE | ||
227 | /* This is only available if kgdboc is a built in for early debugging */ | ||
228 | int __init kgdboc_early_init(char *opt) | ||
229 | { | ||
230 | /* save the first character of the config string because the | ||
231 | * init routine can destroy it. | ||
232 | */ | ||
233 | char save_ch; | ||
234 | |||
235 | kgdboc_option_setup(opt); | ||
236 | save_ch = config[0]; | ||
237 | init_kgdboc(); | ||
238 | config[0] = save_ch; | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | early_param("ekgdboc", kgdboc_early_init); | ||
243 | #endif /* CONFIG_KGDB_SERIAL_CONSOLE */ | ||
244 | |||
165 | module_init(init_kgdboc); | 245 | module_init(init_kgdboc); |
166 | module_exit(cleanup_kgdboc); | 246 | module_exit(cleanup_kgdboc); |
167 | module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); | 247 | module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index f0ca448a1ebf..84a35f699016 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -1226,14 +1226,14 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1226 | 1226 | ||
1227 | /* Check validity & presence */ | 1227 | /* Check validity & presence */ |
1228 | for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) | 1228 | for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) |
1229 | if (mpc52xx_uart_nodes[idx] == op->node) | 1229 | if (mpc52xx_uart_nodes[idx] == op->dev.of_node) |
1230 | break; | 1230 | break; |
1231 | if (idx >= MPC52xx_PSC_MAXNUM) | 1231 | if (idx >= MPC52xx_PSC_MAXNUM) |
1232 | return -EINVAL; | 1232 | return -EINVAL; |
1233 | pr_debug("Found %s assigned to ttyPSC%x\n", | 1233 | pr_debug("Found %s assigned to ttyPSC%x\n", |
1234 | mpc52xx_uart_nodes[idx]->full_name, idx); | 1234 | mpc52xx_uart_nodes[idx]->full_name, idx); |
1235 | 1235 | ||
1236 | uartclk = psc_ops->getuartclk(op->node); | 1236 | uartclk = psc_ops->getuartclk(op->dev.of_node); |
1237 | if (uartclk == 0) { | 1237 | if (uartclk == 0) { |
1238 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); | 1238 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); |
1239 | return -EINVAL; | 1239 | return -EINVAL; |
@@ -1253,7 +1253,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1253 | port->dev = &op->dev; | 1253 | port->dev = &op->dev; |
1254 | 1254 | ||
1255 | /* Search for IRQ and mapbase */ | 1255 | /* Search for IRQ and mapbase */ |
1256 | ret = of_address_to_resource(op->node, 0, &res); | 1256 | ret = of_address_to_resource(op->dev.of_node, 0, &res); |
1257 | if (ret) | 1257 | if (ret) |
1258 | return ret; | 1258 | return ret; |
1259 | 1259 | ||
@@ -1263,7 +1263,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1263 | return -EINVAL; | 1263 | return -EINVAL; |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | psc_ops->get_irq(port, op->node); | 1266 | psc_ops->get_irq(port, op->dev.of_node); |
1267 | if (port->irq == NO_IRQ) { | 1267 | if (port->irq == NO_IRQ) { |
1268 | dev_dbg(&op->dev, "Could not get irq\n"); | 1268 | dev_dbg(&op->dev, "Could not get irq\n"); |
1269 | return -EINVAL; | 1269 | return -EINVAL; |
@@ -1362,15 +1362,16 @@ mpc52xx_uart_of_enumerate(void) | |||
1362 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); | 1362 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); |
1363 | 1363 | ||
1364 | static struct of_platform_driver mpc52xx_uart_of_driver = { | 1364 | static struct of_platform_driver mpc52xx_uart_of_driver = { |
1365 | .match_table = mpc52xx_uart_of_match, | ||
1366 | .probe = mpc52xx_uart_of_probe, | 1365 | .probe = mpc52xx_uart_of_probe, |
1367 | .remove = mpc52xx_uart_of_remove, | 1366 | .remove = mpc52xx_uart_of_remove, |
1368 | #ifdef CONFIG_PM | 1367 | #ifdef CONFIG_PM |
1369 | .suspend = mpc52xx_uart_of_suspend, | 1368 | .suspend = mpc52xx_uart_of_suspend, |
1370 | .resume = mpc52xx_uart_of_resume, | 1369 | .resume = mpc52xx_uart_of_resume, |
1371 | #endif | 1370 | #endif |
1372 | .driver = { | 1371 | .driver = { |
1373 | .name = "mpc52xx-psc-uart", | 1372 | .name = "mpc52xx-psc-uart", |
1373 | .owner = THIS_MODULE, | ||
1374 | .of_match_table = mpc52xx_uart_of_match, | ||
1374 | }, | 1375 | }, |
1375 | }; | 1376 | }; |
1376 | 1377 | ||
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index 55e113a0be03..6a9c6605666a 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -2071,6 +2071,7 @@ static int mpsc_drv_probe(struct platform_device *dev) | |||
2071 | 2071 | ||
2072 | if (!(rc = mpsc_drv_map_regs(pi, dev))) { | 2072 | if (!(rc = mpsc_drv_map_regs(pi, dev))) { |
2073 | mpsc_drv_get_platform_data(pi, dev, dev->id); | 2073 | mpsc_drv_get_platform_data(pi, dev, dev->id); |
2074 | pi->port.dev = &dev->dev; | ||
2074 | 2075 | ||
2075 | if (!(rc = mpsc_make_ready(pi))) { | 2076 | if (!(rc = mpsc_make_ready(pi))) { |
2076 | spin_lock_init(&pi->tx_lock); | 2077 | spin_lock_init(&pi->tx_lock); |
diff --git a/drivers/serial/nwpserial.c b/drivers/serial/nwpserial.c index e1ab8ec0a4a6..3c02fa96f282 100644 --- a/drivers/serial/nwpserial.c +++ b/drivers/serial/nwpserial.c | |||
@@ -344,7 +344,7 @@ int nwpserial_register_port(struct uart_port *port) | |||
344 | 344 | ||
345 | mutex_lock(&nwpserial_mutex); | 345 | mutex_lock(&nwpserial_mutex); |
346 | 346 | ||
347 | dn = to_of_device(port->dev)->node; | 347 | dn = to_of_device(port->dev)->dev.of_node; |
348 | if (dn == NULL) | 348 | if (dn == NULL) |
349 | goto out; | 349 | goto out; |
350 | 350 | ||
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 4abfebdb0fcc..a48d9080f552 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c | |||
@@ -31,7 +31,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, | |||
31 | int type, struct uart_port *port) | 31 | int type, struct uart_port *port) |
32 | { | 32 | { |
33 | struct resource resource; | 33 | struct resource resource; |
34 | struct device_node *np = ofdev->node; | 34 | struct device_node *np = ofdev->dev.of_node; |
35 | const unsigned int *clk, *spd; | 35 | const unsigned int *clk, *spd; |
36 | const u32 *prop; | 36 | const u32 *prop; |
37 | int ret, prop_size; | 37 | int ret, prop_size; |
@@ -88,7 +88,7 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev, | |||
88 | int port_type; | 88 | int port_type; |
89 | int ret; | 89 | int ret; |
90 | 90 | ||
91 | if (of_find_property(ofdev->node, "used-by-rtas", NULL)) | 91 | if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) |
92 | return -EBUSY; | 92 | return -EBUSY; |
93 | 93 | ||
94 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 94 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
@@ -175,11 +175,13 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { | |||
175 | }; | 175 | }; |
176 | 176 | ||
177 | static struct of_platform_driver of_platform_serial_driver = { | 177 | static struct of_platform_driver of_platform_serial_driver = { |
178 | .owner = THIS_MODULE, | 178 | .driver = { |
179 | .name = "of_serial", | 179 | .name = "of_serial", |
180 | .owner = THIS_MODULE, | ||
181 | .of_match_table = of_platform_serial_table, | ||
182 | }, | ||
180 | .probe = of_platform_serial_probe, | 183 | .probe = of_platform_serial_probe, |
181 | .remove = of_platform_serial_remove, | 184 | .remove = of_platform_serial_remove, |
182 | .match_table = of_platform_serial_table, | ||
183 | }; | 185 | }; |
184 | 186 | ||
185 | static int __init of_platform_serial_init(void) | 187 | static int __init of_platform_serial_init(void) |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 700e10833bf9..cabbdc7ba583 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -1611,7 +1611,7 @@ static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1611 | /* Iterate the pmz_ports array to find a matching entry | 1611 | /* Iterate the pmz_ports array to find a matching entry |
1612 | */ | 1612 | */ |
1613 | for (i = 0; i < MAX_ZS_PORTS; i++) | 1613 | for (i = 0; i < MAX_ZS_PORTS; i++) |
1614 | if (pmz_ports[i].node == mdev->ofdev.node) { | 1614 | if (pmz_ports[i].node == mdev->ofdev.dev.of_node) { |
1615 | struct uart_pmac_port *uap = &pmz_ports[i]; | 1615 | struct uart_pmac_port *uap = &pmz_ports[i]; |
1616 | 1616 | ||
1617 | uap->dev = mdev; | 1617 | uap->dev = mdev; |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 8cfa5b12ea7a..dadd686c9801 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -89,7 +89,6 @@ struct serial_info { | |||
89 | int manfid; | 89 | int manfid; |
90 | int prodid; | 90 | int prodid; |
91 | int c950ctrl; | 91 | int c950ctrl; |
92 | dev_node_t node[4]; | ||
93 | int line[4]; | 92 | int line[4]; |
94 | const struct serial_quirk *quirk; | 93 | const struct serial_quirk *quirk; |
95 | }; | 94 | }; |
@@ -289,8 +288,6 @@ static void serial_remove(struct pcmcia_device *link) | |||
289 | for (i = 0; i < info->ndev; i++) | 288 | for (i = 0; i < info->ndev; i++) |
290 | serial8250_unregister_port(info->line[i]); | 289 | serial8250_unregister_port(info->line[i]); |
291 | 290 | ||
292 | info->p_dev->dev_node = NULL; | ||
293 | |||
294 | if (!info->slave) | 291 | if (!info->slave) |
295 | pcmcia_disable_device(link); | 292 | pcmcia_disable_device(link); |
296 | } | 293 | } |
@@ -343,7 +340,6 @@ static int serial_probe(struct pcmcia_device *link) | |||
343 | 340 | ||
344 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 341 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
345 | link->io.NumPorts1 = 8; | 342 | link->io.NumPorts1 = 8; |
346 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | ||
347 | link->conf.Attributes = CONF_ENABLE_IRQ; | 343 | link->conf.Attributes = CONF_ENABLE_IRQ; |
348 | if (do_sound) { | 344 | if (do_sound) { |
349 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 345 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
@@ -411,11 +407,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | |||
411 | } | 407 | } |
412 | 408 | ||
413 | info->line[info->ndev] = line; | 409 | info->line[info->ndev] = line; |
414 | sprintf(info->node[info->ndev].dev_name, "ttyS%d", line); | ||
415 | info->node[info->ndev].major = TTY_MAJOR; | ||
416 | info->node[info->ndev].minor = 0x40 + line; | ||
417 | if (info->ndev > 0) | ||
418 | info->node[info->ndev - 1].next = &info->node[info->ndev]; | ||
419 | info->ndev++; | 410 | info->ndev++; |
420 | 411 | ||
421 | return 0; | 412 | return 0; |
@@ -486,7 +477,7 @@ static int simple_config(struct pcmcia_device *link) | |||
486 | } | 477 | } |
487 | if (info->slave) { | 478 | if (info->slave) { |
488 | return setup_serial(link, info, port, | 479 | return setup_serial(link, info, port, |
489 | link->irq.AssignedIRQ); | 480 | link->irq); |
490 | } | 481 | } |
491 | } | 482 | } |
492 | 483 | ||
@@ -507,10 +498,6 @@ static int simple_config(struct pcmcia_device *link) | |||
507 | return -1; | 498 | return -1; |
508 | 499 | ||
509 | found_port: | 500 | found_port: |
510 | i = pcmcia_request_irq(link, &link->irq); | ||
511 | if (i != 0) | ||
512 | link->irq.AssignedIRQ = 0; | ||
513 | |||
514 | if (info->multi && (info->manfid == MANFID_3COM)) | 501 | if (info->multi && (info->manfid == MANFID_3COM)) |
515 | link->conf.ConfigIndex &= ~(0x08); | 502 | link->conf.ConfigIndex &= ~(0x08); |
516 | 503 | ||
@@ -523,7 +510,7 @@ found_port: | |||
523 | i = pcmcia_request_configuration(link, &link->conf); | 510 | i = pcmcia_request_configuration(link, &link->conf); |
524 | if (i != 0) | 511 | if (i != 0) |
525 | return -1; | 512 | return -1; |
526 | return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); | 513 | return setup_serial(link, info, link->io.BasePort1, link->irq); |
527 | } | 514 | } |
528 | 515 | ||
529 | static int multi_config_check(struct pcmcia_device *p_dev, | 516 | static int multi_config_check(struct pcmcia_device *p_dev, |
@@ -586,13 +573,9 @@ static int multi_config(struct pcmcia_device *link) | |||
586 | } | 573 | } |
587 | } | 574 | } |
588 | 575 | ||
589 | i = pcmcia_request_irq(link, &link->irq); | 576 | if (!link->irq) |
590 | if (i != 0) { | 577 | dev_warn(&link->dev, |
591 | /* FIXME: comment does not fit, error handling does not fit */ | 578 | "serial_cs: no usable IRQ found, continuing...\n"); |
592 | printk(KERN_NOTICE | ||
593 | "serial_cs: no usable port range found, giving up\n"); | ||
594 | link->irq.AssignedIRQ = 0; | ||
595 | } | ||
596 | 579 | ||
597 | /* | 580 | /* |
598 | * Apply any configuration quirks. | 581 | * Apply any configuration quirks. |
@@ -615,11 +598,11 @@ static int multi_config(struct pcmcia_device *link) | |||
615 | if (link->conf.ConfigIndex == 1 || | 598 | if (link->conf.ConfigIndex == 1 || |
616 | link->conf.ConfigIndex == 3) { | 599 | link->conf.ConfigIndex == 3) { |
617 | err = setup_serial(link, info, base2, | 600 | err = setup_serial(link, info, base2, |
618 | link->irq.AssignedIRQ); | 601 | link->irq); |
619 | base2 = link->io.BasePort1; | 602 | base2 = link->io.BasePort1; |
620 | } else { | 603 | } else { |
621 | err = setup_serial(link, info, link->io.BasePort1, | 604 | err = setup_serial(link, info, link->io.BasePort1, |
622 | link->irq.AssignedIRQ); | 605 | link->irq); |
623 | } | 606 | } |
624 | info->c950ctrl = base2; | 607 | info->c950ctrl = base2; |
625 | 608 | ||
@@ -633,10 +616,10 @@ static int multi_config(struct pcmcia_device *link) | |||
633 | return 0; | 616 | return 0; |
634 | } | 617 | } |
635 | 618 | ||
636 | setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); | 619 | setup_serial(link, info, link->io.BasePort1, link->irq); |
637 | for (i = 0; i < info->multi - 1; i++) | 620 | for (i = 0; i < info->multi - 1; i++) |
638 | setup_serial(link, info, base2 + (8 * i), | 621 | setup_serial(link, info, base2 + (8 * i), |
639 | link->irq.AssignedIRQ); | 622 | link->irq); |
640 | return 0; | 623 | return 0; |
641 | } | 624 | } |
642 | 625 | ||
@@ -720,7 +703,6 @@ static int serial_config(struct pcmcia_device * link) | |||
720 | if (info->quirk->post(link)) | 703 | if (info->quirk->post(link)) |
721 | goto failed; | 704 | goto failed; |
722 | 705 | ||
723 | link->dev_node = &info->node[0]; | ||
724 | return 0; | 706 | return 0; |
725 | 707 | ||
726 | failed: | 708 | failed: |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 8eb094c1f61b..5f90fcd7d107 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -83,16 +83,16 @@ struct sci_port { | |||
83 | 83 | ||
84 | /* Interface clock */ | 84 | /* Interface clock */ |
85 | struct clk *iclk; | 85 | struct clk *iclk; |
86 | /* Data clock */ | 86 | /* Function clock */ |
87 | struct clk *dclk; | 87 | struct clk *fclk; |
88 | 88 | ||
89 | struct list_head node; | 89 | struct list_head node; |
90 | struct dma_chan *chan_tx; | 90 | struct dma_chan *chan_tx; |
91 | struct dma_chan *chan_rx; | 91 | struct dma_chan *chan_rx; |
92 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 92 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
93 | struct device *dma_dev; | 93 | struct device *dma_dev; |
94 | enum sh_dmae_slave_chan_id slave_tx; | 94 | unsigned int slave_tx; |
95 | enum sh_dmae_slave_chan_id slave_rx; | 95 | unsigned int slave_rx; |
96 | struct dma_async_tx_descriptor *desc_tx; | 96 | struct dma_async_tx_descriptor *desc_tx; |
97 | struct dma_async_tx_descriptor *desc_rx[2]; | 97 | struct dma_async_tx_descriptor *desc_rx[2]; |
98 | dma_cookie_t cookie_tx; | 98 | dma_cookie_t cookie_tx; |
@@ -107,6 +107,7 @@ struct sci_port { | |||
107 | struct work_struct work_tx; | 107 | struct work_struct work_tx; |
108 | struct work_struct work_rx; | 108 | struct work_struct work_rx; |
109 | struct timer_list rx_timer; | 109 | struct timer_list rx_timer; |
110 | unsigned int rx_timeout; | ||
110 | #endif | 111 | #endif |
111 | }; | 112 | }; |
112 | 113 | ||
@@ -150,7 +151,11 @@ static int sci_poll_get_char(struct uart_port *port) | |||
150 | handle_error(port); | 151 | handle_error(port); |
151 | continue; | 152 | continue; |
152 | } | 153 | } |
153 | } while (!(status & SCxSR_RDxF(port))); | 154 | break; |
155 | } while (1); | ||
156 | |||
157 | if (!(status & SCxSR_RDxF(port))) | ||
158 | return NO_POLL_CHAR; | ||
154 | 159 | ||
155 | c = sci_in(port, SCxRDR); | 160 | c = sci_in(port, SCxRDR); |
156 | 161 | ||
@@ -674,22 +679,22 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) | |||
674 | struct sci_port *s = to_sci_port(port); | 679 | struct sci_port *s = to_sci_port(port); |
675 | 680 | ||
676 | if (s->chan_rx) { | 681 | if (s->chan_rx) { |
677 | unsigned long tout; | ||
678 | u16 scr = sci_in(port, SCSCR); | 682 | u16 scr = sci_in(port, SCSCR); |
679 | u16 ssr = sci_in(port, SCxSR); | 683 | u16 ssr = sci_in(port, SCxSR); |
680 | 684 | ||
681 | /* Disable future Rx interrupts */ | 685 | /* Disable future Rx interrupts */ |
682 | sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE); | 686 | if (port->type == PORT_SCIFA) { |
687 | disable_irq_nosync(irq); | ||
688 | scr |= 0x4000; | ||
689 | } else { | ||
690 | scr &= ~SCI_CTRL_FLAGS_RIE; | ||
691 | } | ||
692 | sci_out(port, SCSCR, scr); | ||
683 | /* Clear current interrupt */ | 693 | /* Clear current interrupt */ |
684 | sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); | 694 | sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); |
685 | /* Calculate delay for 1.5 DMA buffers */ | 695 | dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n", |
686 | tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / | 696 | jiffies, s->rx_timeout); |
687 | port->fifosize / 2; | 697 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); |
688 | dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n", | ||
689 | tout * 1000 / HZ); | ||
690 | if (tout < 2) | ||
691 | tout = 2; | ||
692 | mod_timer(&s->rx_timer, jiffies + tout); | ||
693 | 698 | ||
694 | return IRQ_HANDLED; | 699 | return IRQ_HANDLED; |
695 | } | 700 | } |
@@ -799,7 +804,7 @@ static int sci_notifier(struct notifier_block *self, | |||
799 | (phase == CPUFREQ_RESUMECHANGE)) { | 804 | (phase == CPUFREQ_RESUMECHANGE)) { |
800 | spin_lock_irqsave(&priv->lock, flags); | 805 | spin_lock_irqsave(&priv->lock, flags); |
801 | list_for_each_entry(sci_port, &priv->ports, node) | 806 | list_for_each_entry(sci_port, &priv->ports, node) |
802 | sci_port->port.uartclk = clk_get_rate(sci_port->dclk); | 807 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
803 | spin_unlock_irqrestore(&priv->lock, flags); | 808 | spin_unlock_irqrestore(&priv->lock, flags); |
804 | } | 809 | } |
805 | 810 | ||
@@ -810,21 +815,17 @@ static void sci_clk_enable(struct uart_port *port) | |||
810 | { | 815 | { |
811 | struct sci_port *sci_port = to_sci_port(port); | 816 | struct sci_port *sci_port = to_sci_port(port); |
812 | 817 | ||
813 | clk_enable(sci_port->dclk); | 818 | clk_enable(sci_port->iclk); |
814 | sci_port->port.uartclk = clk_get_rate(sci_port->dclk); | 819 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
815 | 820 | clk_enable(sci_port->fclk); | |
816 | if (sci_port->iclk) | ||
817 | clk_enable(sci_port->iclk); | ||
818 | } | 821 | } |
819 | 822 | ||
820 | static void sci_clk_disable(struct uart_port *port) | 823 | static void sci_clk_disable(struct uart_port *port) |
821 | { | 824 | { |
822 | struct sci_port *sci_port = to_sci_port(port); | 825 | struct sci_port *sci_port = to_sci_port(port); |
823 | 826 | ||
824 | if (sci_port->iclk) | 827 | clk_disable(sci_port->fclk); |
825 | clk_disable(sci_port->iclk); | 828 | clk_disable(sci_port->iclk); |
826 | |||
827 | clk_disable(sci_port->dclk); | ||
828 | } | 829 | } |
829 | 830 | ||
830 | static int sci_request_irq(struct sci_port *port) | 831 | static int sci_request_irq(struct sci_port *port) |
@@ -913,22 +914,26 @@ static void sci_dma_tx_complete(void *arg) | |||
913 | 914 | ||
914 | spin_lock_irqsave(&port->lock, flags); | 915 | spin_lock_irqsave(&port->lock, flags); |
915 | 916 | ||
916 | xmit->tail += s->sg_tx.length; | 917 | xmit->tail += sg_dma_len(&s->sg_tx); |
917 | xmit->tail &= UART_XMIT_SIZE - 1; | 918 | xmit->tail &= UART_XMIT_SIZE - 1; |
918 | 919 | ||
919 | port->icount.tx += s->sg_tx.length; | 920 | port->icount.tx += sg_dma_len(&s->sg_tx); |
920 | 921 | ||
921 | async_tx_ack(s->desc_tx); | 922 | async_tx_ack(s->desc_tx); |
922 | s->cookie_tx = -EINVAL; | 923 | s->cookie_tx = -EINVAL; |
923 | s->desc_tx = NULL; | 924 | s->desc_tx = NULL; |
924 | 925 | ||
925 | spin_unlock_irqrestore(&port->lock, flags); | ||
926 | |||
927 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 926 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
928 | uart_write_wakeup(port); | 927 | uart_write_wakeup(port); |
929 | 928 | ||
930 | if (uart_circ_chars_pending(xmit)) | 929 | if (!uart_circ_empty(xmit)) { |
931 | schedule_work(&s->work_tx); | 930 | schedule_work(&s->work_tx); |
931 | } else if (port->type == PORT_SCIFA) { | ||
932 | u16 ctrl = sci_in(port, SCSCR); | ||
933 | sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE); | ||
934 | } | ||
935 | |||
936 | spin_unlock_irqrestore(&port->lock, flags); | ||
932 | } | 937 | } |
933 | 938 | ||
934 | /* Locking: called with port lock held */ | 939 | /* Locking: called with port lock held */ |
@@ -972,13 +977,13 @@ static void sci_dma_rx_complete(void *arg) | |||
972 | unsigned long flags; | 977 | unsigned long flags; |
973 | int count; | 978 | int count; |
974 | 979 | ||
975 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 980 | dev_dbg(port->dev, "%s(%d) active #%d\n", __func__, port->line, s->active_rx); |
976 | 981 | ||
977 | spin_lock_irqsave(&port->lock, flags); | 982 | spin_lock_irqsave(&port->lock, flags); |
978 | 983 | ||
979 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); | 984 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); |
980 | 985 | ||
981 | mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5)); | 986 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); |
982 | 987 | ||
983 | spin_unlock_irqrestore(&port->lock, flags); | 988 | spin_unlock_irqrestore(&port->lock, flags); |
984 | 989 | ||
@@ -999,8 +1004,9 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) | |||
999 | s->chan_rx = NULL; | 1004 | s->chan_rx = NULL; |
1000 | s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; | 1005 | s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; |
1001 | dma_release_channel(chan); | 1006 | dma_release_channel(chan); |
1002 | dma_free_coherent(port->dev, s->buf_len_rx * 2, | 1007 | if (sg_dma_address(&s->sg_rx[0])) |
1003 | sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); | 1008 | dma_free_coherent(port->dev, s->buf_len_rx * 2, |
1009 | sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); | ||
1004 | if (enable_pio) | 1010 | if (enable_pio) |
1005 | sci_start_rx(port); | 1011 | sci_start_rx(port); |
1006 | } | 1012 | } |
@@ -1050,6 +1056,8 @@ static void sci_submit_rx(struct sci_port *s) | |||
1050 | sci_rx_dma_release(s, true); | 1056 | sci_rx_dma_release(s, true); |
1051 | return; | 1057 | return; |
1052 | } | 1058 | } |
1059 | dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__, | ||
1060 | s->cookie_rx[i], i); | ||
1053 | } | 1061 | } |
1054 | 1062 | ||
1055 | s->active_rx = s->cookie_rx[0]; | 1063 | s->active_rx = s->cookie_rx[0]; |
@@ -1084,7 +1092,7 @@ static void work_fn_rx(struct work_struct *work) | |||
1084 | unsigned long flags; | 1092 | unsigned long flags; |
1085 | int count; | 1093 | int count; |
1086 | 1094 | ||
1087 | chan->device->device_terminate_all(chan); | 1095 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); |
1088 | dev_dbg(port->dev, "Read %u bytes with cookie %d\n", | 1096 | dev_dbg(port->dev, "Read %u bytes with cookie %d\n", |
1089 | sh_desc->partial, sh_desc->cookie); | 1097 | sh_desc->partial, sh_desc->cookie); |
1090 | 1098 | ||
@@ -1107,10 +1115,10 @@ static void work_fn_rx(struct work_struct *work) | |||
1107 | return; | 1115 | return; |
1108 | } | 1116 | } |
1109 | 1117 | ||
1110 | dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__, | ||
1111 | s->cookie_rx[new], new); | ||
1112 | |||
1113 | s->active_rx = s->cookie_rx[!new]; | 1118 | s->active_rx = s->cookie_rx[!new]; |
1119 | |||
1120 | dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n", __func__, | ||
1121 | s->cookie_rx[new], new, s->active_rx); | ||
1114 | } | 1122 | } |
1115 | 1123 | ||
1116 | static void work_fn_tx(struct work_struct *work) | 1124 | static void work_fn_tx(struct work_struct *work) |
@@ -1131,14 +1139,13 @@ static void work_fn_tx(struct work_struct *work) | |||
1131 | */ | 1139 | */ |
1132 | spin_lock_irq(&port->lock); | 1140 | spin_lock_irq(&port->lock); |
1133 | sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); | 1141 | sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); |
1134 | sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + | 1142 | sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + |
1135 | sg->offset; | 1143 | sg->offset; |
1136 | sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), | 1144 | sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), |
1137 | CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); | 1145 | CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); |
1138 | sg->dma_length = sg->length; | ||
1139 | spin_unlock_irq(&port->lock); | 1146 | spin_unlock_irq(&port->lock); |
1140 | 1147 | ||
1141 | BUG_ON(!sg->length); | 1148 | BUG_ON(!sg_dma_len(sg)); |
1142 | 1149 | ||
1143 | desc = chan->device->device_prep_slave_sg(chan, | 1150 | desc = chan->device->device_prep_slave_sg(chan, |
1144 | sg, s->sg_len_tx, DMA_TO_DEVICE, | 1151 | sg, s->sg_len_tx, DMA_TO_DEVICE, |
@@ -1173,23 +1180,28 @@ static void work_fn_tx(struct work_struct *work) | |||
1173 | 1180 | ||
1174 | static void sci_start_tx(struct uart_port *port) | 1181 | static void sci_start_tx(struct uart_port *port) |
1175 | { | 1182 | { |
1183 | struct sci_port *s = to_sci_port(port); | ||
1176 | unsigned short ctrl; | 1184 | unsigned short ctrl; |
1177 | 1185 | ||
1178 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1186 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
1179 | struct sci_port *s = to_sci_port(port); | 1187 | if (port->type == PORT_SCIFA) { |
1180 | 1188 | u16 new, scr = sci_in(port, SCSCR); | |
1181 | if (s->chan_tx) { | 1189 | if (s->chan_tx) |
1182 | if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0) | 1190 | new = scr | 0x8000; |
1183 | schedule_work(&s->work_tx); | 1191 | else |
1184 | 1192 | new = scr & ~0x8000; | |
1185 | return; | 1193 | if (new != scr) |
1194 | sci_out(port, SCSCR, new); | ||
1186 | } | 1195 | } |
1196 | if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && | ||
1197 | s->cookie_tx < 0) | ||
1198 | schedule_work(&s->work_tx); | ||
1187 | #endif | 1199 | #endif |
1188 | 1200 | if (!s->chan_tx || port->type == PORT_SCIFA) { | |
1189 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1201 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ |
1190 | ctrl = sci_in(port, SCSCR); | 1202 | ctrl = sci_in(port, SCSCR); |
1191 | ctrl |= SCI_CTRL_FLAGS_TIE; | 1203 | sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE); |
1192 | sci_out(port, SCSCR, ctrl); | 1204 | } |
1193 | } | 1205 | } |
1194 | 1206 | ||
1195 | static void sci_stop_tx(struct uart_port *port) | 1207 | static void sci_stop_tx(struct uart_port *port) |
@@ -1198,6 +1210,8 @@ static void sci_stop_tx(struct uart_port *port) | |||
1198 | 1210 | ||
1199 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1211 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ |
1200 | ctrl = sci_in(port, SCSCR); | 1212 | ctrl = sci_in(port, SCSCR); |
1213 | if (port->type == PORT_SCIFA) | ||
1214 | ctrl &= ~0x8000; | ||
1201 | ctrl &= ~SCI_CTRL_FLAGS_TIE; | 1215 | ctrl &= ~SCI_CTRL_FLAGS_TIE; |
1202 | sci_out(port, SCSCR, ctrl); | 1216 | sci_out(port, SCSCR, ctrl); |
1203 | } | 1217 | } |
@@ -1208,6 +1222,8 @@ static void sci_start_rx(struct uart_port *port) | |||
1208 | 1222 | ||
1209 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ | 1223 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ |
1210 | ctrl |= sci_in(port, SCSCR); | 1224 | ctrl |= sci_in(port, SCSCR); |
1225 | if (port->type == PORT_SCIFA) | ||
1226 | ctrl &= ~0x4000; | ||
1211 | sci_out(port, SCSCR, ctrl); | 1227 | sci_out(port, SCSCR, ctrl); |
1212 | } | 1228 | } |
1213 | 1229 | ||
@@ -1217,6 +1233,8 @@ static void sci_stop_rx(struct uart_port *port) | |||
1217 | 1233 | ||
1218 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ | 1234 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ |
1219 | ctrl = sci_in(port, SCSCR); | 1235 | ctrl = sci_in(port, SCSCR); |
1236 | if (port->type == PORT_SCIFA) | ||
1237 | ctrl &= ~0x4000; | ||
1220 | ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); | 1238 | ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); |
1221 | sci_out(port, SCSCR, ctrl); | 1239 | sci_out(port, SCSCR, ctrl); |
1222 | } | 1240 | } |
@@ -1251,8 +1269,12 @@ static void rx_timer_fn(unsigned long arg) | |||
1251 | { | 1269 | { |
1252 | struct sci_port *s = (struct sci_port *)arg; | 1270 | struct sci_port *s = (struct sci_port *)arg; |
1253 | struct uart_port *port = &s->port; | 1271 | struct uart_port *port = &s->port; |
1254 | |||
1255 | u16 scr = sci_in(port, SCSCR); | 1272 | u16 scr = sci_in(port, SCSCR); |
1273 | |||
1274 | if (port->type == PORT_SCIFA) { | ||
1275 | scr &= ~0x4000; | ||
1276 | enable_irq(s->irqs[1]); | ||
1277 | } | ||
1256 | sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE); | 1278 | sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE); |
1257 | dev_dbg(port->dev, "DMA Rx timed out\n"); | 1279 | dev_dbg(port->dev, "DMA Rx timed out\n"); |
1258 | schedule_work(&s->work_rx); | 1280 | schedule_work(&s->work_rx); |
@@ -1339,8 +1361,7 @@ static void sci_request_dma(struct uart_port *port) | |||
1339 | sg_init_table(sg, 1); | 1361 | sg_init_table(sg, 1); |
1340 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, | 1362 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, |
1341 | (int)buf[i] & ~PAGE_MASK); | 1363 | (int)buf[i] & ~PAGE_MASK); |
1342 | sg->dma_address = dma[i]; | 1364 | sg_dma_address(sg) = dma[i]; |
1343 | sg->dma_length = sg->length; | ||
1344 | } | 1365 | } |
1345 | 1366 | ||
1346 | INIT_WORK(&s->work_rx, work_fn_rx); | 1367 | INIT_WORK(&s->work_rx, work_fn_rx); |
@@ -1403,8 +1424,12 @@ static void sci_shutdown(struct uart_port *port) | |||
1403 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 1424 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
1404 | struct ktermios *old) | 1425 | struct ktermios *old) |
1405 | { | 1426 | { |
1427 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1428 | struct sci_port *s = to_sci_port(port); | ||
1429 | #endif | ||
1406 | unsigned int status, baud, smr_val, max_baud; | 1430 | unsigned int status, baud, smr_val, max_baud; |
1407 | int t = -1; | 1431 | int t = -1; |
1432 | u16 scfcr = 0; | ||
1408 | 1433 | ||
1409 | /* | 1434 | /* |
1410 | * earlyprintk comes here early on with port->uartclk set to zero. | 1435 | * earlyprintk comes here early on with port->uartclk set to zero. |
@@ -1427,7 +1452,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1427 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ | 1452 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ |
1428 | 1453 | ||
1429 | if (port->type != PORT_SCI) | 1454 | if (port->type != PORT_SCI) |
1430 | sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); | 1455 | sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); |
1431 | 1456 | ||
1432 | smr_val = sci_in(port, SCSMR) & 3; | 1457 | smr_val = sci_in(port, SCSMR) & 3; |
1433 | if ((termios->c_cflag & CSIZE) == CS7) | 1458 | if ((termios->c_cflag & CSIZE) == CS7) |
@@ -1458,10 +1483,32 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1458 | } | 1483 | } |
1459 | 1484 | ||
1460 | sci_init_pins(port, termios->c_cflag); | 1485 | sci_init_pins(port, termios->c_cflag); |
1461 | sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); | 1486 | sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0)); |
1462 | 1487 | ||
1463 | sci_out(port, SCSCR, SCSCR_INIT(port)); | 1488 | sci_out(port, SCSCR, SCSCR_INIT(port)); |
1464 | 1489 | ||
1490 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1491 | /* | ||
1492 | * Calculate delay for 1.5 DMA buffers: see | ||
1493 | * drivers/serial/serial_core.c::uart_update_timeout(). With 10 bits | ||
1494 | * (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function | ||
1495 | * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)." | ||
1496 | * Then below we calculate 3 jiffies (12ms) for 1.5 DMA buffers (3 FIFO | ||
1497 | * sizes), but it has been found out experimentally, that this is not | ||
1498 | * enough: the driver too often needlessly runs on a DMA timeout. 20ms | ||
1499 | * as a minimum seem to work perfectly. | ||
1500 | */ | ||
1501 | if (s->chan_rx) { | ||
1502 | s->rx_timeout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / | ||
1503 | port->fifosize / 2; | ||
1504 | dev_dbg(port->dev, | ||
1505 | "DMA Rx t-out %ums, tty t-out %u jiffies\n", | ||
1506 | s->rx_timeout * 1000 / HZ, port->timeout); | ||
1507 | if (s->rx_timeout < msecs_to_jiffies(20)) | ||
1508 | s->rx_timeout = msecs_to_jiffies(20); | ||
1509 | } | ||
1510 | #endif | ||
1511 | |||
1465 | if ((termios->c_cflag & CREAD) != 0) | 1512 | if ((termios->c_cflag & CREAD) != 0) |
1466 | sci_start_rx(port); | 1513 | sci_start_rx(port); |
1467 | } | 1514 | } |
@@ -1553,10 +1600,10 @@ static struct uart_ops sci_uart_ops = { | |||
1553 | #endif | 1600 | #endif |
1554 | }; | 1601 | }; |
1555 | 1602 | ||
1556 | static void __devinit sci_init_single(struct platform_device *dev, | 1603 | static int __devinit sci_init_single(struct platform_device *dev, |
1557 | struct sci_port *sci_port, | 1604 | struct sci_port *sci_port, |
1558 | unsigned int index, | 1605 | unsigned int index, |
1559 | struct plat_sci_port *p) | 1606 | struct plat_sci_port *p) |
1560 | { | 1607 | { |
1561 | struct uart_port *port = &sci_port->port; | 1608 | struct uart_port *port = &sci_port->port; |
1562 | 1609 | ||
@@ -1577,8 +1624,23 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1577 | } | 1624 | } |
1578 | 1625 | ||
1579 | if (dev) { | 1626 | if (dev) { |
1580 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; | 1627 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); |
1581 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); | 1628 | if (IS_ERR(sci_port->iclk)) { |
1629 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); | ||
1630 | if (IS_ERR(sci_port->iclk)) { | ||
1631 | dev_err(&dev->dev, "can't get iclk\n"); | ||
1632 | return PTR_ERR(sci_port->iclk); | ||
1633 | } | ||
1634 | } | ||
1635 | |||
1636 | /* | ||
1637 | * The function clock is optional, ignore it if we can't | ||
1638 | * find it. | ||
1639 | */ | ||
1640 | sci_port->fclk = clk_get(&dev->dev, "sci_fck"); | ||
1641 | if (IS_ERR(sci_port->fclk)) | ||
1642 | sci_port->fclk = NULL; | ||
1643 | |||
1582 | sci_port->enable = sci_clk_enable; | 1644 | sci_port->enable = sci_clk_enable; |
1583 | sci_port->disable = sci_clk_disable; | 1645 | sci_port->disable = sci_clk_disable; |
1584 | port->dev = &dev->dev; | 1646 | port->dev = &dev->dev; |
@@ -1605,6 +1667,7 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1605 | #endif | 1667 | #endif |
1606 | 1668 | ||
1607 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | 1669 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); |
1670 | return 0; | ||
1608 | } | 1671 | } |
1609 | 1672 | ||
1610 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 1673 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE |
@@ -1754,8 +1817,11 @@ static int sci_remove(struct platform_device *dev) | |||
1754 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1817 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1755 | 1818 | ||
1756 | spin_lock_irqsave(&priv->lock, flags); | 1819 | spin_lock_irqsave(&priv->lock, flags); |
1757 | list_for_each_entry(p, &priv->ports, node) | 1820 | list_for_each_entry(p, &priv->ports, node) { |
1758 | uart_remove_one_port(&sci_uart_driver, &p->port); | 1821 | uart_remove_one_port(&sci_uart_driver, &p->port); |
1822 | clk_put(p->iclk); | ||
1823 | clk_put(p->fclk); | ||
1824 | } | ||
1759 | spin_unlock_irqrestore(&priv->lock, flags); | 1825 | spin_unlock_irqrestore(&priv->lock, flags); |
1760 | 1826 | ||
1761 | kfree(priv); | 1827 | kfree(priv); |
@@ -1781,7 +1847,9 @@ static int __devinit sci_probe_single(struct platform_device *dev, | |||
1781 | return 0; | 1847 | return 0; |
1782 | } | 1848 | } |
1783 | 1849 | ||
1784 | sci_init_single(dev, sciport, index, p); | 1850 | ret = sci_init_single(dev, sciport, index, p); |
1851 | if (ret) | ||
1852 | return ret; | ||
1785 | 1853 | ||
1786 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); | 1854 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); |
1787 | if (ret) | 1855 | if (ret) |
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d14cca7fb88d..890f91742962 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
@@ -565,7 +565,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m | |||
565 | if (err) | 565 | if (err) |
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->dev.of_node, |
569 | &sunhv_reg, port->line, false); | 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); |
@@ -630,8 +630,11 @@ static const struct of_device_id hv_match[] = { | |||
630 | MODULE_DEVICE_TABLE(of, hv_match); | 630 | MODULE_DEVICE_TABLE(of, hv_match); |
631 | 631 | ||
632 | static struct of_platform_driver hv_driver = { | 632 | static struct of_platform_driver hv_driver = { |
633 | .name = "hv", | 633 | .driver = { |
634 | .match_table = hv_match, | 634 | .name = "hv", |
635 | .owner = THIS_MODULE, | ||
636 | .of_match_table = hv_match, | ||
637 | }, | ||
635 | .probe = hv_probe, | 638 | .probe = hv_probe, |
636 | .remove = __devexit_p(hv_remove), | 639 | .remove = __devexit_p(hv_remove), |
637 | }; | 640 | }; |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index d2e0321049e2..5e81bc6b48b0 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, to_of_device(up->port.dev)->node); | 886 | sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_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; |
@@ -1026,11 +1026,11 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * | |||
1026 | if (err) | 1026 | if (err) |
1027 | goto out1; | 1027 | goto out1; |
1028 | 1028 | ||
1029 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | 1029 | sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, |
1030 | &sunsab_reg, up[0].port.line, | 1030 | &sunsab_reg, up[0].port.line, |
1031 | false); | 1031 | false); |
1032 | 1032 | ||
1033 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | 1033 | sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, |
1034 | &sunsab_reg, up[1].port.line, | 1034 | &sunsab_reg, up[1].port.line, |
1035 | false); | 1035 | false); |
1036 | 1036 | ||
@@ -1093,8 +1093,11 @@ static const struct of_device_id sab_match[] = { | |||
1093 | MODULE_DEVICE_TABLE(of, sab_match); | 1093 | MODULE_DEVICE_TABLE(of, sab_match); |
1094 | 1094 | ||
1095 | static struct of_platform_driver sab_driver = { | 1095 | static struct of_platform_driver sab_driver = { |
1096 | .name = "sab", | 1096 | .driver = { |
1097 | .match_table = sab_match, | 1097 | .name = "sab", |
1098 | .owner = THIS_MODULE, | ||
1099 | .of_match_table = sab_match, | ||
1100 | }, | ||
1098 | .probe = sab_probe, | 1101 | .probe = sab_probe, |
1099 | .remove = __devexit_p(sab_remove), | 1102 | .remove = __devexit_p(sab_remove), |
1100 | }; | 1103 | }; |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 01f7731e59b8..234459c2f012 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1200,7 +1200,7 @@ static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up) | |||
1200 | return -ENODEV; | 1200 | return -ENODEV; |
1201 | 1201 | ||
1202 | printk("%s: %s port at %llx, irq %u\n", | 1202 | printk("%s: %s port at %llx, irq %u\n", |
1203 | to_of_device(up->port.dev)->node->full_name, | 1203 | to_of_device(up->port.dev)->dev.of_node->full_name, |
1204 | (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", | 1204 | (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", |
1205 | (unsigned long long) up->port.mapbase, | 1205 | (unsigned long long) up->port.mapbase, |
1206 | up->port.irq); | 1206 | up->port.irq); |
@@ -1352,7 +1352,7 @@ static int __init sunsu_console_setup(struct console *co, char *options) | |||
1352 | spin_lock_init(&port->lock); | 1352 | spin_lock_init(&port->lock); |
1353 | 1353 | ||
1354 | /* Get firmware console settings. */ | 1354 | /* Get firmware console settings. */ |
1355 | sunserial_console_termios(co, to_of_device(port->dev)->node); | 1355 | sunserial_console_termios(co, to_of_device(port->dev)->dev.of_node); |
1356 | 1356 | ||
1357 | memset(&termios, 0, sizeof(struct ktermios)); | 1357 | memset(&termios, 0, sizeof(struct ktermios)); |
1358 | termios.c_cflag = co->cflag; | 1358 | termios.c_cflag = co->cflag; |
@@ -1409,7 +1409,7 @@ static enum su_type __devinit su_get_type(struct device_node *dp) | |||
1409 | static int __devinit su_probe(struct of_device *op, const struct of_device_id *match) | 1409 | static int __devinit su_probe(struct of_device *op, const struct of_device_id *match) |
1410 | { | 1410 | { |
1411 | static int inst; | 1411 | static int inst; |
1412 | struct device_node *dp = op->node; | 1412 | struct device_node *dp = op->dev.of_node; |
1413 | struct uart_sunsu_port *up; | 1413 | struct uart_sunsu_port *up; |
1414 | struct resource *rp; | 1414 | struct resource *rp; |
1415 | enum su_type type; | 1415 | enum su_type type; |
@@ -1539,8 +1539,11 @@ static const struct of_device_id su_match[] = { | |||
1539 | MODULE_DEVICE_TABLE(of, su_match); | 1539 | MODULE_DEVICE_TABLE(of, su_match); |
1540 | 1540 | ||
1541 | static struct of_platform_driver su_driver = { | 1541 | static struct of_platform_driver su_driver = { |
1542 | .name = "su", | 1542 | .driver = { |
1543 | .match_table = su_match, | 1543 | .name = "su", |
1544 | .owner = THIS_MODULE, | ||
1545 | .of_match_table = su_match, | ||
1546 | }, | ||
1544 | .probe = su_probe, | 1547 | .probe = su_probe, |
1545 | .remove = __devexit_p(su_remove), | 1548 | .remove = __devexit_p(su_remove), |
1546 | }; | 1549 | }; |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 2c7a66af4f52..f9a24f4ebb34 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -102,6 +102,8 @@ struct uart_sunzilog_port { | |||
102 | #endif | 102 | #endif |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static void sunzilog_putchar(struct uart_port *port, int ch); | ||
106 | |||
105 | #define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase)) | 107 | #define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase)) |
106 | #define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT)) | 108 | #define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT)) |
107 | 109 | ||
@@ -996,6 +998,50 @@ static int sunzilog_verify_port(struct uart_port *port, struct serial_struct *se | |||
996 | return -EINVAL; | 998 | return -EINVAL; |
997 | } | 999 | } |
998 | 1000 | ||
1001 | #ifdef CONFIG_CONSOLE_POLL | ||
1002 | static int sunzilog_get_poll_char(struct uart_port *port) | ||
1003 | { | ||
1004 | unsigned char ch, r1; | ||
1005 | struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | ||
1006 | struct zilog_channel __iomem *channel | ||
1007 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | ||
1008 | |||
1009 | |||
1010 | r1 = read_zsreg(channel, R1); | ||
1011 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { | ||
1012 | writeb(ERR_RES, &channel->control); | ||
1013 | ZSDELAY(); | ||
1014 | ZS_WSYNC(channel); | ||
1015 | } | ||
1016 | |||
1017 | ch = readb(&channel->control); | ||
1018 | ZSDELAY(); | ||
1019 | |||
1020 | /* This funny hack depends upon BRK_ABRT not interfering | ||
1021 | * with the other bits we care about in R1. | ||
1022 | */ | ||
1023 | if (ch & BRK_ABRT) | ||
1024 | r1 |= BRK_ABRT; | ||
1025 | |||
1026 | if (!(ch & Rx_CH_AV)) | ||
1027 | return NO_POLL_CHAR; | ||
1028 | |||
1029 | ch = readb(&channel->data); | ||
1030 | ZSDELAY(); | ||
1031 | |||
1032 | ch &= up->parity_mask; | ||
1033 | return ch; | ||
1034 | } | ||
1035 | |||
1036 | static void sunzilog_put_poll_char(struct uart_port *port, | ||
1037 | unsigned char ch) | ||
1038 | { | ||
1039 | struct uart_sunzilog_port *up = (struct uart_sunzilog_port *)port; | ||
1040 | |||
1041 | sunzilog_putchar(&up->port, ch); | ||
1042 | } | ||
1043 | #endif /* CONFIG_CONSOLE_POLL */ | ||
1044 | |||
999 | static struct uart_ops sunzilog_pops = { | 1045 | static struct uart_ops sunzilog_pops = { |
1000 | .tx_empty = sunzilog_tx_empty, | 1046 | .tx_empty = sunzilog_tx_empty, |
1001 | .set_mctrl = sunzilog_set_mctrl, | 1047 | .set_mctrl = sunzilog_set_mctrl, |
@@ -1013,6 +1059,10 @@ static struct uart_ops sunzilog_pops = { | |||
1013 | .request_port = sunzilog_request_port, | 1059 | .request_port = sunzilog_request_port, |
1014 | .config_port = sunzilog_config_port, | 1060 | .config_port = sunzilog_config_port, |
1015 | .verify_port = sunzilog_verify_port, | 1061 | .verify_port = sunzilog_verify_port, |
1062 | #ifdef CONFIG_CONSOLE_POLL | ||
1063 | .poll_get_char = sunzilog_get_poll_char, | ||
1064 | .poll_put_char = sunzilog_put_poll_char, | ||
1065 | #endif | ||
1016 | }; | 1066 | }; |
1017 | 1067 | ||
1018 | static int uart_chip_count; | 1068 | static int uart_chip_count; |
@@ -1180,7 +1230,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) | |||
1180 | (sunzilog_reg.minor - 64) + con->index, con->index); | 1230 | (sunzilog_reg.minor - 64) + con->index, con->index); |
1181 | 1231 | ||
1182 | /* Get firmware console settings. */ | 1232 | /* Get firmware console settings. */ |
1183 | sunserial_console_termios(con, to_of_device(up->port.dev)->node); | 1233 | sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node); |
1184 | 1234 | ||
1185 | /* Firmware console speed is limited to 150-->38400 baud so | 1235 | /* Firmware console speed is limited to 150-->38400 baud so |
1186 | * this hackish cflag thing is OK. | 1236 | * this hackish cflag thing is OK. |
@@ -1358,7 +1408,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1358 | int keyboard_mouse = 0; | 1408 | int keyboard_mouse = 0; |
1359 | int err; | 1409 | int err; |
1360 | 1410 | ||
1361 | if (of_find_property(op->node, "keyboard", NULL)) | 1411 | if (of_find_property(op->dev.of_node, "keyboard", NULL)) |
1362 | keyboard_mouse = 1; | 1412 | keyboard_mouse = 1; |
1363 | 1413 | ||
1364 | /* uarts must come before keyboards/mice */ | 1414 | /* uarts must come before keyboards/mice */ |
@@ -1415,7 +1465,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1415 | sunzilog_init_hw(&up[1]); | 1465 | sunzilog_init_hw(&up[1]); |
1416 | 1466 | ||
1417 | if (!keyboard_mouse) { | 1467 | if (!keyboard_mouse) { |
1418 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | 1468 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, |
1419 | &sunzilog_reg, up[0].port.line, | 1469 | &sunzilog_reg, up[0].port.line, |
1420 | false)) | 1470 | false)) |
1421 | up->flags |= SUNZILOG_FLAG_IS_CONS; | 1471 | up->flags |= SUNZILOG_FLAG_IS_CONS; |
@@ -1425,7 +1475,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1425 | rp, sizeof(struct zilog_layout)); | 1475 | rp, sizeof(struct zilog_layout)); |
1426 | return err; | 1476 | return err; |
1427 | } | 1477 | } |
1428 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | 1478 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, |
1429 | &sunzilog_reg, up[1].port.line, | 1479 | &sunzilog_reg, up[1].port.line, |
1430 | false)) | 1480 | false)) |
1431 | up->flags |= SUNZILOG_FLAG_IS_CONS; | 1481 | up->flags |= SUNZILOG_FLAG_IS_CONS; |
@@ -1491,8 +1541,11 @@ static const struct of_device_id zs_match[] = { | |||
1491 | MODULE_DEVICE_TABLE(of, zs_match); | 1541 | MODULE_DEVICE_TABLE(of, zs_match); |
1492 | 1542 | ||
1493 | static struct of_platform_driver zs_driver = { | 1543 | static struct of_platform_driver zs_driver = { |
1494 | .name = "zs", | 1544 | .driver = { |
1495 | .match_table = zs_match, | 1545 | .name = "zs", |
1546 | .owner = THIS_MODULE, | ||
1547 | .of_match_table = zs_match, | ||
1548 | }, | ||
1496 | .probe = zs_probe, | 1549 | .probe = zs_probe, |
1497 | .remove = __devexit_p(zs_remove), | 1550 | .remove = __devexit_p(zs_remove), |
1498 | }; | 1551 | }; |
diff --git a/drivers/serial/timbuart.c b/drivers/serial/timbuart.c index 786ba85c170b..67ca642713b8 100644 --- a/drivers/serial/timbuart.c +++ b/drivers/serial/timbuart.c | |||
@@ -68,12 +68,22 @@ static void timbuart_start_tx(struct uart_port *port) | |||
68 | tasklet_schedule(&uart->tasklet); | 68 | tasklet_schedule(&uart->tasklet); |
69 | } | 69 | } |
70 | 70 | ||
71 | static unsigned int timbuart_tx_empty(struct uart_port *port) | ||
72 | { | ||
73 | u32 isr = ioread32(port->membase + TIMBUART_ISR); | ||
74 | |||
75 | return (isr & TXBE) ? TIOCSER_TEMT : 0; | ||
76 | } | ||
77 | |||
71 | static void timbuart_flush_buffer(struct uart_port *port) | 78 | static void timbuart_flush_buffer(struct uart_port *port) |
72 | { | 79 | { |
73 | u8 ctl = ioread8(port->membase + TIMBUART_CTRL) | TIMBUART_CTRL_FLSHTX; | 80 | if (!timbuart_tx_empty(port)) { |
81 | u8 ctl = ioread8(port->membase + TIMBUART_CTRL) | | ||
82 | TIMBUART_CTRL_FLSHTX; | ||
74 | 83 | ||
75 | iowrite8(ctl, port->membase + TIMBUART_CTRL); | 84 | iowrite8(ctl, port->membase + TIMBUART_CTRL); |
76 | iowrite32(TXBF, port->membase + TIMBUART_ISR); | 85 | iowrite32(TXBF, port->membase + TIMBUART_ISR); |
86 | } | ||
77 | } | 87 | } |
78 | 88 | ||
79 | static void timbuart_rx_chars(struct uart_port *port) | 89 | static void timbuart_rx_chars(struct uart_port *port) |
@@ -195,13 +205,6 @@ void timbuart_tasklet(unsigned long arg) | |||
195 | dev_dbg(uart->port.dev, "%s leaving\n", __func__); | 205 | dev_dbg(uart->port.dev, "%s leaving\n", __func__); |
196 | } | 206 | } |
197 | 207 | ||
198 | static unsigned int timbuart_tx_empty(struct uart_port *port) | ||
199 | { | ||
200 | u32 isr = ioread32(port->membase + TIMBUART_ISR); | ||
201 | |||
202 | return (isr & TXBE) ? TIOCSER_TEMT : 0; | ||
203 | } | ||
204 | |||
205 | static unsigned int timbuart_get_mctrl(struct uart_port *port) | 208 | static unsigned int timbuart_get_mctrl(struct uart_port *port) |
206 | { | 209 | { |
207 | u8 cts = ioread8(port->membase + TIMBUART_CTRL); | 210 | u8 cts = ioread8(port->membase + TIMBUART_CTRL); |
@@ -220,7 +223,7 @@ static void timbuart_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
220 | if (mctrl & TIOCM_RTS) | 223 | if (mctrl & TIOCM_RTS) |
221 | iowrite8(TIMBUART_CTRL_RTS, port->membase + TIMBUART_CTRL); | 224 | iowrite8(TIMBUART_CTRL_RTS, port->membase + TIMBUART_CTRL); |
222 | else | 225 | else |
223 | iowrite8(TIMBUART_CTRL_RTS, port->membase + TIMBUART_CTRL); | 226 | iowrite8(0, port->membase + TIMBUART_CTRL); |
224 | } | 227 | } |
225 | 228 | ||
226 | static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier) | 229 | static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier) |
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index f0a6c61b17f7..8acccd564378 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c | |||
@@ -86,7 +86,7 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
86 | /* stats */ | 86 | /* stats */ |
87 | if (stat & ULITE_STATUS_RXVALID) { | 87 | if (stat & ULITE_STATUS_RXVALID) { |
88 | port->icount.rx++; | 88 | port->icount.rx++; |
89 | ch = readb(port->membase + ULITE_RX); | 89 | ch = ioread32be(port->membase + ULITE_RX); |
90 | 90 | ||
91 | if (stat & ULITE_STATUS_PARITY) | 91 | if (stat & ULITE_STATUS_PARITY) |
92 | port->icount.parity++; | 92 | port->icount.parity++; |
@@ -131,7 +131,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
131 | return 0; | 131 | return 0; |
132 | 132 | ||
133 | if (port->x_char) { | 133 | if (port->x_char) { |
134 | writeb(port->x_char, port->membase + ULITE_TX); | 134 | iowrite32be(port->x_char, port->membase + ULITE_TX); |
135 | port->x_char = 0; | 135 | port->x_char = 0; |
136 | port->icount.tx++; | 136 | port->icount.tx++; |
137 | return 1; | 137 | return 1; |
@@ -140,7 +140,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
140 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 140 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
141 | return 0; | 141 | return 0; |
142 | 142 | ||
143 | writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX); | 143 | iowrite32be(xmit->buf[xmit->tail], port->membase + ULITE_TX); |
144 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); | 144 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); |
145 | port->icount.tx++; | 145 | port->icount.tx++; |
146 | 146 | ||
@@ -157,7 +157,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) | |||
157 | int busy, n = 0; | 157 | int busy, n = 0; |
158 | 158 | ||
159 | do { | 159 | do { |
160 | int stat = readb(port->membase + ULITE_STATUS); | 160 | int stat = ioread32be(port->membase + ULITE_STATUS); |
161 | busy = ulite_receive(port, stat); | 161 | busy = ulite_receive(port, stat); |
162 | busy |= ulite_transmit(port, stat); | 162 | busy |= ulite_transmit(port, stat); |
163 | n++; | 163 | n++; |
@@ -178,7 +178,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port) | |||
178 | unsigned int ret; | 178 | unsigned int ret; |
179 | 179 | ||
180 | spin_lock_irqsave(&port->lock, flags); | 180 | spin_lock_irqsave(&port->lock, flags); |
181 | ret = readb(port->membase + ULITE_STATUS); | 181 | ret = ioread32be(port->membase + ULITE_STATUS); |
182 | spin_unlock_irqrestore(&port->lock, flags); | 182 | spin_unlock_irqrestore(&port->lock, flags); |
183 | 183 | ||
184 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; | 184 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; |
@@ -201,7 +201,7 @@ static void ulite_stop_tx(struct uart_port *port) | |||
201 | 201 | ||
202 | static void ulite_start_tx(struct uart_port *port) | 202 | static void ulite_start_tx(struct uart_port *port) |
203 | { | 203 | { |
204 | ulite_transmit(port, readb(port->membase + ULITE_STATUS)); | 204 | ulite_transmit(port, ioread32be(port->membase + ULITE_STATUS)); |
205 | } | 205 | } |
206 | 206 | ||
207 | static void ulite_stop_rx(struct uart_port *port) | 207 | static void ulite_stop_rx(struct uart_port *port) |
@@ -230,17 +230,17 @@ static int ulite_startup(struct uart_port *port) | |||
230 | if (ret) | 230 | if (ret) |
231 | return ret; | 231 | return ret; |
232 | 232 | ||
233 | writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, | 233 | iowrite32be(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, |
234 | port->membase + ULITE_CONTROL); | 234 | port->membase + ULITE_CONTROL); |
235 | writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 235 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); |
236 | 236 | ||
237 | return 0; | 237 | return 0; |
238 | } | 238 | } |
239 | 239 | ||
240 | static void ulite_shutdown(struct uart_port *port) | 240 | static void ulite_shutdown(struct uart_port *port) |
241 | { | 241 | { |
242 | writeb(0, port->membase + ULITE_CONTROL); | 242 | iowrite32be(0, port->membase + ULITE_CONTROL); |
243 | readb(port->membase + ULITE_CONTROL); /* dummy */ | 243 | ioread32be(port->membase + ULITE_CONTROL); /* dummy */ |
244 | free_irq(port->irq, port); | 244 | free_irq(port->irq, port); |
245 | } | 245 | } |
246 | 246 | ||
@@ -352,7 +352,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
352 | 352 | ||
353 | /* Spin waiting for TX fifo to have space available */ | 353 | /* Spin waiting for TX fifo to have space available */ |
354 | for (i = 0; i < 100000; i++) { | 354 | for (i = 0; i < 100000; i++) { |
355 | val = readb(port->membase + ULITE_STATUS); | 355 | val = ioread32be(port->membase + ULITE_STATUS); |
356 | if ((val & ULITE_STATUS_TXFULL) == 0) | 356 | if ((val & ULITE_STATUS_TXFULL) == 0) |
357 | break; | 357 | break; |
358 | cpu_relax(); | 358 | cpu_relax(); |
@@ -362,7 +362,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
362 | static void ulite_console_putchar(struct uart_port *port, int ch) | 362 | static void ulite_console_putchar(struct uart_port *port, int ch) |
363 | { | 363 | { |
364 | ulite_console_wait_tx(port); | 364 | ulite_console_wait_tx(port); |
365 | writeb(ch, port->membase + ULITE_TX); | 365 | iowrite32be(ch, port->membase + ULITE_TX); |
366 | } | 366 | } |
367 | 367 | ||
368 | static void ulite_console_write(struct console *co, const char *s, | 368 | static void ulite_console_write(struct console *co, const char *s, |
@@ -379,8 +379,8 @@ static void ulite_console_write(struct console *co, const char *s, | |||
379 | spin_lock_irqsave(&port->lock, flags); | 379 | spin_lock_irqsave(&port->lock, flags); |
380 | 380 | ||
381 | /* save and disable interrupt */ | 381 | /* save and disable interrupt */ |
382 | ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; | 382 | ier = ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; |
383 | writeb(0, port->membase + ULITE_CONTROL); | 383 | iowrite32be(0, port->membase + ULITE_CONTROL); |
384 | 384 | ||
385 | uart_console_write(port, s, count, ulite_console_putchar); | 385 | uart_console_write(port, s, count, ulite_console_putchar); |
386 | 386 | ||
@@ -388,7 +388,7 @@ static void ulite_console_write(struct console *co, const char *s, | |||
388 | 388 | ||
389 | /* restore interrupt state */ | 389 | /* restore interrupt state */ |
390 | if (ier) | 390 | if (ier) |
391 | writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 391 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); |
392 | 392 | ||
393 | if (locked) | 393 | if (locked) |
394 | spin_unlock_irqrestore(&port->lock, flags); | 394 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -591,17 +591,17 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match) | |||
591 | 591 | ||
592 | dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match); | 592 | dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match); |
593 | 593 | ||
594 | rc = of_address_to_resource(op->node, 0, &res); | 594 | rc = of_address_to_resource(op->dev.of_node, 0, &res); |
595 | if (rc) { | 595 | if (rc) { |
596 | dev_err(&op->dev, "invalid address\n"); | 596 | dev_err(&op->dev, "invalid address\n"); |
597 | return rc; | 597 | return rc; |
598 | } | 598 | } |
599 | 599 | ||
600 | irq = irq_of_parse_and_map(op->node, 0); | 600 | irq = irq_of_parse_and_map(op->dev.of_node, 0); |
601 | 601 | ||
602 | id = of_get_property(op->node, "port-number", NULL); | 602 | id = of_get_property(op->dev.of_node, "port-number", NULL); |
603 | 603 | ||
604 | return ulite_assign(&op->dev, id ? *id : -1, res.start+3, irq); | 604 | return ulite_assign(&op->dev, id ? *id : -1, res.start, irq); |
605 | } | 605 | } |
606 | 606 | ||
607 | static int __devexit ulite_of_remove(struct of_device *op) | 607 | static int __devexit ulite_of_remove(struct of_device *op) |
@@ -610,13 +610,12 @@ static int __devexit ulite_of_remove(struct of_device *op) | |||
610 | } | 610 | } |
611 | 611 | ||
612 | static struct of_platform_driver ulite_of_driver = { | 612 | static struct of_platform_driver ulite_of_driver = { |
613 | .owner = THIS_MODULE, | ||
614 | .name = "uartlite", | ||
615 | .match_table = ulite_of_match, | ||
616 | .probe = ulite_of_probe, | 613 | .probe = ulite_of_probe, |
617 | .remove = __devexit_p(ulite_of_remove), | 614 | .remove = __devexit_p(ulite_of_remove), |
618 | .driver = { | 615 | .driver = { |
619 | .name = "uartlite", | 616 | .name = "uartlite", |
617 | .owner = THIS_MODULE, | ||
618 | .of_match_table = ulite_of_match, | ||
620 | }, | 619 | }, |
621 | }; | 620 | }; |
622 | 621 | ||
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 074904912f64..907b06f5c447 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c | |||
@@ -1197,7 +1197,7 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) | |||
1197 | static int ucc_uart_probe(struct of_device *ofdev, | 1197 | static int ucc_uart_probe(struct of_device *ofdev, |
1198 | const struct of_device_id *match) | 1198 | const struct of_device_id *match) |
1199 | { | 1199 | { |
1200 | struct device_node *np = ofdev->node; | 1200 | struct device_node *np = ofdev->dev.of_node; |
1201 | const unsigned int *iprop; /* Integer OF properties */ | 1201 | const unsigned int *iprop; /* Integer OF properties */ |
1202 | const char *sprop; /* String OF properties */ | 1202 | const char *sprop; /* String OF properties */ |
1203 | struct uart_qe_port *qe_port = NULL; | 1203 | struct uart_qe_port *qe_port = NULL; |
@@ -1486,9 +1486,11 @@ static struct of_device_id ucc_uart_match[] = { | |||
1486 | MODULE_DEVICE_TABLE(of, ucc_uart_match); | 1486 | MODULE_DEVICE_TABLE(of, ucc_uart_match); |
1487 | 1487 | ||
1488 | static struct of_platform_driver ucc_uart_of_driver = { | 1488 | static struct of_platform_driver ucc_uart_of_driver = { |
1489 | .owner = THIS_MODULE, | 1489 | .driver = { |
1490 | .name = "ucc_uart", | 1490 | .name = "ucc_uart", |
1491 | .match_table = ucc_uart_match, | 1491 | .owner = THIS_MODULE, |
1492 | .of_match_table = ucc_uart_match, | ||
1493 | }, | ||
1492 | .probe = ucc_uart_probe, | 1494 | .probe = ucc_uart_probe, |
1493 | .remove = ucc_uart_remove, | 1495 | .remove = ucc_uart_remove, |
1494 | }; | 1496 | }; |