diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/Kconfig | 82 | ||||
-rw-r--r-- | drivers/serial/Makefile | 2 | ||||
-rw-r--r-- | drivers/serial/altera_jtaguart.c | 504 | ||||
-rw-r--r-- | drivers/serial/altera_uart.c | 570 | ||||
-rw-r--r-- | drivers/serial/bfin_sport_uart.c | 209 | ||||
-rw-r--r-- | drivers/serial/bfin_sport_uart.h | 27 | ||||
-rw-r--r-- | drivers/serial/timbuart.c | 25 | ||||
-rw-r--r-- | drivers/serial/uartlite.c | 32 |
8 files changed, 1353 insertions, 98 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 302836a80693..8b23165bc5dc 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -1423,8 +1423,8 @@ config SERIAL_SC26XX_CONSOLE | |||
1423 | Support for Console on SC2681/SC2692 serial ports. | 1423 | Support for Console on SC2681/SC2692 serial ports. |
1424 | 1424 | ||
1425 | config SERIAL_BFIN_SPORT | 1425 | config SERIAL_BFIN_SPORT |
1426 | tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)" | 1426 | tristate "Blackfin SPORT emulate UART" |
1427 | depends on BLACKFIN && EXPERIMENTAL | 1427 | depends on BLACKFIN |
1428 | select SERIAL_CORE | 1428 | select SERIAL_CORE |
1429 | help | 1429 | help |
1430 | Enable SPORT emulate UART on Blackfin series. | 1430 | Enable SPORT emulate UART on Blackfin series. |
@@ -1439,28 +1439,52 @@ config SERIAL_BFIN_SPORT_CONSOLE | |||
1439 | 1439 | ||
1440 | config SERIAL_BFIN_SPORT0_UART | 1440 | config SERIAL_BFIN_SPORT0_UART |
1441 | bool "Enable UART over SPORT0" | 1441 | bool "Enable UART over SPORT0" |
1442 | depends on SERIAL_BFIN_SPORT && !(BF542 || BF542M || BF544 || BF544M) | 1442 | depends on SERIAL_BFIN_SPORT && !(BF542 || BF544) |
1443 | help | 1443 | help |
1444 | Enable UART over SPORT0 | 1444 | Enable UART over SPORT0 |
1445 | 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 | |||
1446 | config SERIAL_BFIN_SPORT1_UART | 1452 | config SERIAL_BFIN_SPORT1_UART |
1447 | bool "Enable UART over SPORT1" | 1453 | bool "Enable UART over SPORT1" |
1448 | depends on SERIAL_BFIN_SPORT | 1454 | depends on SERIAL_BFIN_SPORT |
1449 | help | 1455 | help |
1450 | Enable UART over SPORT1 | 1456 | Enable UART over SPORT1 |
1451 | 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 | |||
1452 | config SERIAL_BFIN_SPORT2_UART | 1464 | config SERIAL_BFIN_SPORT2_UART |
1453 | bool "Enable UART over SPORT2" | 1465 | bool "Enable UART over SPORT2" |
1454 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) | 1466 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1455 | help | 1467 | help |
1456 | Enable UART over SPORT2 | 1468 | Enable UART over SPORT2 |
1457 | 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 | |||
1458 | config SERIAL_BFIN_SPORT3_UART | 1476 | config SERIAL_BFIN_SPORT3_UART |
1459 | bool "Enable UART over SPORT3" | 1477 | bool "Enable UART over SPORT3" |
1460 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) | 1478 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1461 | help | 1479 | help |
1462 | Enable UART over SPORT3 | 1480 | Enable UART over SPORT3 |
1463 | 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 | |||
1464 | config SERIAL_TIMBERDALE | 1488 | config SERIAL_TIMBERDALE |
1465 | tristate "Support for timberdale UART" | 1489 | tristate "Support for timberdale UART" |
1466 | select SERIAL_CORE | 1490 | select SERIAL_CORE |
@@ -1499,4 +1523,56 @@ config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE | |||
1499 | help | 1523 | help |
1500 | Support for running a console on the GRLIB APBUART | 1524 | Support for running a console on the GRLIB APBUART |
1501 | 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 | |||
1502 | endmenu | 1578 | endmenu |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 328f107346c4..208a85572c32 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -82,3 +82,5 @@ obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o | |||
82 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o | 82 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o |
83 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o | 83 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o |
84 | 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/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/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..e6639a95d276 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); |
@@ -601,7 +601,7 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match) | |||
601 | 601 | ||
602 | id = of_get_property(op->node, "port-number", NULL); | 602 | id = of_get_property(op->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) |