aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/8250_exar_st16c554.c52
-rw-r--r--drivers/serial/8250_pnp.c29
-rw-r--r--drivers/serial/Kconfig30
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/amba-pl010.c2
-rw-r--r--drivers/serial/dz.c371
-rw-r--r--drivers/serial/dz.h32
-rw-r--r--drivers/serial/mpsc.c22
-rw-r--r--drivers/serial/uartlite.c505
9 files changed, 839 insertions, 206 deletions
diff --git a/drivers/serial/8250_exar_st16c554.c b/drivers/serial/8250_exar_st16c554.c
new file mode 100644
index 000000000000..567143ace159
--- /dev/null
+++ b/drivers/serial/8250_exar_st16c554.c
@@ -0,0 +1,52 @@
1/*
2 * linux/drivers/serial/8250_exar.c
3 *
4 * Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com >
5 * Based on 8250_boca.
6 *
7 * Copyright (C) 2005 Russell King.
8 * Data taken from include/asm-i386/serial.h
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 version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/serial_8250.h>
17
18#define PORT(_base,_irq) \
19 { \
20 .iobase = _base, \
21 .irq = _irq, \
22 .uartclk = 1843200, \
23 .iotype = UPIO_PORT, \
24 .flags = UPF_BOOT_AUTOCONF, \
25 }
26
27static struct plat_serial8250_port exar_data[] = {
28 PORT(0x100, 5),
29 PORT(0x108, 5),
30 PORT(0x110, 5),
31 PORT(0x118, 5),
32 { },
33};
34
35static struct platform_device exar_device = {
36 .name = "serial8250",
37 .id = PLAT8250_DEV_EXAR_ST16C554,
38 .dev = {
39 .platform_data = exar_data,
40 },
41};
42
43static int __init exar_init(void)
44{
45 return platform_device_register(&exar_device);
46}
47
48module_init(exar_init);
49
50MODULE_AUTHOR("Paul B Schroeder");
51MODULE_DESCRIPTION("8250 serial probe module for Exar cards");
52MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 71d907c8288b..d3d6b82706b5 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -464,11 +464,38 @@ static void __devexit serial_pnp_remove(struct pnp_dev *dev)
464 serial8250_unregister_port(line - 1); 464 serial8250_unregister_port(line - 1);
465} 465}
466 466
467#ifdef CONFIG_PM
468static int serial_pnp_suspend(struct pnp_dev *dev, pm_message_t state)
469{
470 long line = (long)pnp_get_drvdata(dev);
471
472 if (!line)
473 return -ENODEV;
474 serial8250_suspend_port(line - 1);
475 return 0;
476}
477
478static int serial_pnp_resume(struct pnp_dev *dev)
479{
480 long line = (long)pnp_get_drvdata(dev);
481
482 if (!line)
483 return -ENODEV;
484 serial8250_resume_port(line - 1);
485 return 0;
486}
487#else
488#define serial_pnp_suspend NULL
489#define serial_pnp_resume NULL
490#endif /* CONFIG_PM */
491
467static struct pnp_driver serial_pnp_driver = { 492static struct pnp_driver serial_pnp_driver = {
468 .name = "serial", 493 .name = "serial",
469 .id_table = pnp_dev_table,
470 .probe = serial_pnp_probe, 494 .probe = serial_pnp_probe,
471 .remove = __devexit_p(serial_pnp_remove), 495 .remove = __devexit_p(serial_pnp_remove),
496 .suspend = serial_pnp_suspend,
497 .resume = serial_pnp_resume,
498 .id_table = pnp_dev_table,
472}; 499};
473 500
474static int __init serial8250_pnp_init(void) 501static int __init serial8250_pnp_init(void)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 0b71e7d18903..fc12d5df10e2 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -210,6 +210,17 @@ config SERIAL_8250_BOCA
210 To compile this driver as a module, choose M here: the module 210 To compile this driver as a module, choose M here: the module
211 will be called 8250_boca. 211 will be called 8250_boca.
212 212
213config SERIAL_8250_EXAR_ST16C554
214 tristate "Support Exar ST16C554/554D Quad UART"
215 depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
216 help
217 The Uplogix Envoy TU301 uses this Exar Quad UART. If you are
218 tinkering with your Envoy TU301, or have a machine with this UART,
219 say Y here.
220
221 To compile this driver as a module, choose M here: the module
222 will be called 8250_exar_st16c554.
223
213config SERIAL_8250_HUB6 224config SERIAL_8250_HUB6
214 tristate "Support Hub6 cards" 225 tristate "Support Hub6 cards"
215 depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS 226 depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
@@ -511,6 +522,25 @@ config SERIAL_IMX_CONSOLE
511 your boot loader (lilo or loadlin) about how to pass options to the 522 your boot loader (lilo or loadlin) about how to pass options to the
512 kernel at boot time.) 523 kernel at boot time.)
513 524
525config SERIAL_UARTLITE
526 tristate "Xilinx uartlite serial port support"
527 depends on PPC32
528 select SERIAL_CORE
529 help
530 Say Y here if you want to use the Xilinx uartlite serial controller.
531
532 To compile this driver as a module, choose M here: the
533 module will be called uartlite.ko.
534
535config SERIAL_UARTLITE_CONSOLE
536 bool "Support for console on Xilinx uartlite serial port"
537 depends on SERIAL_UARTLITE=y
538 select SERIAL_CORE_CONSOLE
539 help
540 Say Y here if you wish to use a Xilinx uartlite as the system
541 console (the system console is the device which receives all kernel
542 messages and warnings and which allows logins in single user mode).
543
514config SERIAL_SUNCORE 544config SERIAL_SUNCORE
515 bool 545 bool
516 depends on SPARC 546 depends on SPARC
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index b4d8a7c182e3..df3632cd7df9 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
17obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o 17obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
18obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o 18obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
19obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o 19obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
20obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
20obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o 21obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
21obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o 22obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
22obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o 23obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
@@ -55,4 +56,5 @@ obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
55obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o 56obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
56obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o 57obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
57obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o 58obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
59obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
58obj-$(CONFIG_SERIAL_NETX) += netx-serial.o 60obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 4213fabc62bf..4d3626ef4643 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -129,6 +129,8 @@ static void pl010_rx_chars(struct uart_port *port)
129 */ 129 */
130 rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX; 130 rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
131 if (unlikely(rsr & UART01x_RSR_ANY)) { 131 if (unlikely(rsr & UART01x_RSR_ANY)) {
132 writel(0, port->membase + UART01x_ECR);
133
132 if (rsr & UART01x_RSR_BE) { 134 if (rsr & UART01x_RSR_BE) {
133 rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); 135 rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
134 port->icount.brk++; 136 port->icount.brk++;
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index 53662b33b841..af1544f3356f 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -1,11 +1,13 @@
1/* 1/*
2 * dz.c: Serial port driver for DECStations equiped 2 * dz.c: Serial port driver for DECstations equipped
3 * with the DZ chipset. 3 * with the DZ chipset.
4 * 4 *
5 * Copyright (C) 1998 Olivier A. D. Lebaillif 5 * Copyright (C) 1998 Olivier A. D. Lebaillif
6 * 6 *
7 * Email: olivier.lebaillif@ifrsys.com 7 * Email: olivier.lebaillif@ifrsys.com
8 * 8 *
9 * Copyright (C) 2004, 2006 Maciej W. Rozycki
10 *
9 * [31-AUG-98] triemer 11 * [31-AUG-98] triemer
10 * Changed IRQ to use Harald's dec internals interrupts.h 12 * Changed IRQ to use Harald's dec internals interrupts.h
11 * removed base_addr code - moving address assignment to setup.c 13 * removed base_addr code - moving address assignment to setup.c
@@ -26,10 +28,16 @@
26 28
27#undef DEBUG_DZ 29#undef DEBUG_DZ
28 30
31#if defined(CONFIG_SERIAL_DZ_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
32#define SUPPORT_SYSRQ
33#endif
34
35#include <linux/delay.h>
29#include <linux/module.h> 36#include <linux/module.h>
30#include <linux/interrupt.h> 37#include <linux/interrupt.h>
31#include <linux/init.h> 38#include <linux/init.h>
32#include <linux/console.h> 39#include <linux/console.h>
40#include <linux/sysrq.h>
33#include <linux/tty.h> 41#include <linux/tty.h>
34#include <linux/tty_flip.h> 42#include <linux/tty_flip.h>
35#include <linux/serial_core.h> 43#include <linux/serial_core.h>
@@ -45,14 +53,10 @@
45#include <asm/system.h> 53#include <asm/system.h>
46#include <asm/uaccess.h> 54#include <asm/uaccess.h>
47 55
48#define CONSOLE_LINE (3) /* for definition of struct console */
49
50#include "dz.h" 56#include "dz.h"
51 57
52#define DZ_INTR_DEBUG 1
53
54static char *dz_name = "DECstation DZ serial driver version "; 58static char *dz_name = "DECstation DZ serial driver version ";
55static char *dz_version = "1.02"; 59static char *dz_version = "1.03";
56 60
57struct dz_port { 61struct dz_port {
58 struct uart_port port; 62 struct uart_port port;
@@ -61,22 +65,6 @@ struct dz_port {
61 65
62static struct dz_port dz_ports[DZ_NB_PORT]; 66static struct dz_port dz_ports[DZ_NB_PORT];
63 67
64#ifdef DEBUG_DZ
65/*
66 * debugging code to send out chars via prom
67 */
68static void debug_console(const char *s, int count)
69{
70 unsigned i;
71
72 for (i = 0; i < count; i++) {
73 if (*s == 10)
74 prom_printf("%c", 13);
75 prom_printf("%c", *s++);
76 }
77}
78#endif
79
80/* 68/*
81 * ------------------------------------------------------------ 69 * ------------------------------------------------------------
82 * dz_in () and dz_out () 70 * dz_in () and dz_out ()
@@ -90,6 +78,7 @@ static inline unsigned short dz_in(struct dz_port *dport, unsigned offset)
90{ 78{
91 volatile unsigned short *addr = 79 volatile unsigned short *addr =
92 (volatile unsigned short *) (dport->port.membase + offset); 80 (volatile unsigned short *) (dport->port.membase + offset);
81
93 return *addr; 82 return *addr;
94} 83}
95 84
@@ -98,6 +87,7 @@ static inline void dz_out(struct dz_port *dport, unsigned offset,
98{ 87{
99 volatile unsigned short *addr = 88 volatile unsigned short *addr =
100 (volatile unsigned short *) (dport->port.membase + offset); 89 (volatile unsigned short *) (dport->port.membase + offset);
90
101 *addr = value; 91 *addr = value;
102} 92}
103 93
@@ -144,7 +134,7 @@ static void dz_stop_rx(struct uart_port *uport)
144 134
145 spin_lock_irqsave(&dport->port.lock, flags); 135 spin_lock_irqsave(&dport->port.lock, flags);
146 dport->cflag &= ~DZ_CREAD; 136 dport->cflag &= ~DZ_CREAD;
147 dz_out(dport, DZ_LPR, dport->cflag); 137 dz_out(dport, DZ_LPR, dport->cflag | dport->port.line);
148 spin_unlock_irqrestore(&dport->port.lock, flags); 138 spin_unlock_irqrestore(&dport->port.lock, flags);
149} 139}
150 140
@@ -155,14 +145,14 @@ static void dz_enable_ms(struct uart_port *port)
155 145
156/* 146/*
157 * ------------------------------------------------------------ 147 * ------------------------------------------------------------
158 * Here starts the interrupt handling routines. All of the
159 * following subroutines are declared as inline and are folded
160 * into dz_interrupt. They were separated out for readability's
161 * sake.
162 * 148 *
163 * Note: rs_interrupt() is a "fast" interrupt, which means that it 149 * Here start the interrupt handling routines. All of the following
150 * subroutines are declared as inline and are folded into
151 * dz_interrupt. They were separated out for readability's sake.
152 *
153 * Note: dz_interrupt() is a "fast" interrupt, which means that it
164 * runs with interrupts turned off. People who may want to modify 154 * runs with interrupts turned off. People who may want to modify
165 * rs_interrupt() should try to keep the interrupt handler as fast as 155 * dz_interrupt() should try to keep the interrupt handler as fast as
166 * possible. After you are done making modifications, it is not a bad 156 * possible. After you are done making modifications, it is not a bad
167 * idea to do: 157 * idea to do:
168 * 158 *
@@ -180,92 +170,74 @@ static void dz_enable_ms(struct uart_port *port)
180 * This routine deals with inputs from any lines. 170 * This routine deals with inputs from any lines.
181 * ------------------------------------------------------------ 171 * ------------------------------------------------------------
182 */ 172 */
183static inline void dz_receive_chars(struct dz_port *dport) 173static inline void dz_receive_chars(struct dz_port *dport_in,
174 struct pt_regs *regs)
184{ 175{
176 struct dz_port *dport;
185 struct tty_struct *tty = NULL; 177 struct tty_struct *tty = NULL;
186 struct uart_icount *icount; 178 struct uart_icount *icount;
187 int ignore = 0; 179 int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 };
188 unsigned short status, tmp; 180 unsigned short status;
189 unsigned char ch, flag; 181 unsigned char ch, flag;
182 int i;
190 183
191 /* this code is going to be a problem... 184 while ((status = dz_in(dport_in, DZ_RBUF)) & DZ_DVAL) {
192 the call to tty_flip_buffer is going to need 185 dport = &dz_ports[LINE(status)];
193 to be rethought... 186 tty = dport->port.info->tty; /* point to the proper dev */
194 */
195 do {
196 status = dz_in(dport, DZ_RBUF);
197
198 /* punt so we don't get duplicate characters */
199 if (!(status & DZ_DVAL))
200 goto ignore_char;
201
202
203 ch = UCHAR(status); /* grab the char */
204 flag = TTY_NORMAL;
205 187
206#if 0 188 ch = UCHAR(status); /* grab the char */
207 if (info->is_console) {
208 if (ch == 0)
209 return; /* it's a break ... */
210 }
211#endif
212 189
213 tty = dport->port.info->tty;/* now tty points to the proper dev */
214 icount = &dport->port.icount; 190 icount = &dport->port.icount;
215
216 if (!tty)
217 break;
218
219 icount->rx++; 191 icount->rx++;
220 192
221 /* keep track of the statistics */ 193 flag = TTY_NORMAL;
222 if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) { 194 if (status & DZ_FERR) { /* frame error */
223 if (status & DZ_PERR) /* parity error */ 195 /*
224 icount->parity++; 196 * There is no separate BREAK status bit, so
225 else if (status & DZ_FERR) /* frame error */ 197 * treat framing errors as BREAKs for Magic SysRq
226 icount->frame++; 198 * and SAK; normally, otherwise.
227 if (status & DZ_OERR) /* overrun error */
228 icount->overrun++;
229
230 /* check to see if we should ignore the character
231 and mask off conditions that should be ignored
232 */ 199 */
233 200 if (uart_handle_break(&dport->port))
234 if (status & dport->port.ignore_status_mask) { 201 continue;
235 if (++ignore > 100) 202 if (dport->port.flags & UPF_SAK)
236 break; 203 flag = TTY_BREAK;
237 goto ignore_char; 204 else
238 }
239 /* mask off the error conditions we want to ignore */
240 tmp = status & dport->port.read_status_mask;
241
242 if (tmp & DZ_PERR) {
243 flag = TTY_PARITY;
244#ifdef DEBUG_DZ
245 debug_console("PERR\n", 5);
246#endif
247 } else if (tmp & DZ_FERR) {
248 flag = TTY_FRAME; 205 flag = TTY_FRAME;
249#ifdef DEBUG_DZ 206 } else if (status & DZ_OERR) /* overrun error */
250 debug_console("FERR\n", 5); 207 flag = TTY_OVERRUN;
251#endif 208 else if (status & DZ_PERR) /* parity error */
252 } 209 flag = TTY_PARITY;
253 if (tmp & DZ_OERR) { 210
254#ifdef DEBUG_DZ 211 /* keep track of the statistics */
255 debug_console("OERR\n", 5); 212 switch (flag) {
256#endif 213 case TTY_FRAME:
257 tty_insert_flip_char(tty, ch, flag); 214 icount->frame++;
258 ch = 0; 215 break;
259 flag = TTY_OVERRUN; 216 case TTY_PARITY:
260 } 217 icount->parity++;
218 break;
219 case TTY_OVERRUN:
220 icount->overrun++;
221 break;
222 case TTY_BREAK:
223 icount->brk++;
224 break;
225 default:
226 break;
261 } 227 }
262 tty_insert_flip_char(tty, ch, flag);
263 ignore_char:
264 ;
265 } while (status & DZ_DVAL);
266 228
267 if (tty) 229 if (uart_handle_sysrq_char(&dport->port, ch, regs))
268 tty_flip_buffer_push(tty); 230 continue;
231
232 if ((status & dport->port.ignore_status_mask) == 0) {
233 uart_insert_char(&dport->port,
234 status, DZ_OERR, ch, flag);
235 lines_rx[LINE(status)] = 1;
236 }
237 }
238 for (i = 0; i < DZ_NB_PORT; i++)
239 if (lines_rx[i])
240 tty_flip_buffer_push(dz_ports[i].port.info->tty);
269} 241}
270 242
271/* 243/*
@@ -275,26 +247,32 @@ static inline void dz_receive_chars(struct dz_port *dport)
275 * This routine deals with outputs to any lines. 247 * This routine deals with outputs to any lines.
276 * ------------------------------------------------------------ 248 * ------------------------------------------------------------
277 */ 249 */
278static inline void dz_transmit_chars(struct dz_port *dport) 250static inline void dz_transmit_chars(struct dz_port *dport_in)
279{ 251{
280 struct circ_buf *xmit = &dport->port.info->xmit; 252 struct dz_port *dport;
253 struct circ_buf *xmit;
254 unsigned short status;
281 unsigned char tmp; 255 unsigned char tmp;
282 256
283 if (dport->port.x_char) { /* XON/XOFF chars */ 257 status = dz_in(dport_in, DZ_CSR);
258 dport = &dz_ports[LINE(status)];
259 xmit = &dport->port.info->xmit;
260
261 if (dport->port.x_char) { /* XON/XOFF chars */
284 dz_out(dport, DZ_TDR, dport->port.x_char); 262 dz_out(dport, DZ_TDR, dport->port.x_char);
285 dport->port.icount.tx++; 263 dport->port.icount.tx++;
286 dport->port.x_char = 0; 264 dport->port.x_char = 0;
287 return; 265 return;
288 } 266 }
289 /* if nothing to do or stopped or hardware stopped */ 267 /* If nothing to do or stopped or hardware stopped. */
290 if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) { 268 if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
291 dz_stop_tx(&dport->port); 269 dz_stop_tx(&dport->port);
292 return; 270 return;
293 } 271 }
294 272
295 /* 273 /*
296 * if something to do ... (rember the dz has no output fifo so we go 274 * If something to do... (remember the dz has no output fifo,
297 * one char at a time :-< 275 * so we go one char at a time) :-<
298 */ 276 */
299 tmp = xmit->buf[xmit->tail]; 277 tmp = xmit->buf[xmit->tail];
300 xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1); 278 xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1);
@@ -304,23 +282,29 @@ static inline void dz_transmit_chars(struct dz_port *dport)
304 if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS) 282 if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
305 uart_write_wakeup(&dport->port); 283 uart_write_wakeup(&dport->port);
306 284
307 /* Are we done */ 285 /* Are we are done. */
308 if (uart_circ_empty(xmit)) 286 if (uart_circ_empty(xmit))
309 dz_stop_tx(&dport->port); 287 dz_stop_tx(&dport->port);
310} 288}
311 289
312/* 290/*
313 * ------------------------------------------------------------ 291 * ------------------------------------------------------------
314 * check_modem_status () 292 * check_modem_status()
315 * 293 *
316 * Only valid for the MODEM line duh ! 294 * DS 3100 & 5100: Only valid for the MODEM line, duh!
295 * DS 5000/200: Valid for the MODEM and PRINTER line.
317 * ------------------------------------------------------------ 296 * ------------------------------------------------------------
318 */ 297 */
319static inline void check_modem_status(struct dz_port *dport) 298static inline void check_modem_status(struct dz_port *dport)
320{ 299{
300 /*
301 * FIXME:
302 * 1. No status change interrupt; use a timer.
303 * 2. Handle the 3100/5000 as appropriate. --macro
304 */
321 unsigned short status; 305 unsigned short status;
322 306
323 /* if not ne modem line just return */ 307 /* If not the modem line just return. */
324 if (dport->port.line != DZ_MODEM) 308 if (dport->port.line != DZ_MODEM)
325 return; 309 return;
326 310
@@ -341,21 +325,18 @@ static inline void check_modem_status(struct dz_port *dport)
341 */ 325 */
342static irqreturn_t dz_interrupt(int irq, void *dev) 326static irqreturn_t dz_interrupt(int irq, void *dev)
343{ 327{
344 struct dz_port *dport; 328 struct dz_port *dport = (struct dz_port *)dev;
345 unsigned short status; 329 unsigned short status;
346 330
347 /* get the reason why we just got an irq */ 331 /* get the reason why we just got an irq */
348 status = dz_in((struct dz_port *)dev, DZ_CSR); 332 status = dz_in(dport, DZ_CSR);
349 dport = &dz_ports[LINE(status)];
350 333
351 if (status & DZ_RDONE) 334 if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE))
352 dz_receive_chars(dport); 335 dz_receive_chars(dport, regs);
353 336
354 if (status & DZ_TRDY) 337 if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE))
355 dz_transmit_chars(dport); 338 dz_transmit_chars(dport);
356 339
357 /* FIXME: what about check modem status??? --rmk */
358
359 return IRQ_HANDLED; 340 return IRQ_HANDLED;
360} 341}
361 342
@@ -367,13 +348,13 @@ static irqreturn_t dz_interrupt(int irq, void *dev)
367 348
368static unsigned int dz_get_mctrl(struct uart_port *uport) 349static unsigned int dz_get_mctrl(struct uart_port *uport)
369{ 350{
351 /*
352 * FIXME: Handle the 3100/5000 as appropriate. --macro
353 */
370 struct dz_port *dport = (struct dz_port *)uport; 354 struct dz_port *dport = (struct dz_port *)uport;
371 unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 355 unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
372 356
373 if (dport->port.line == DZ_MODEM) { 357 if (dport->port.line == DZ_MODEM) {
374 /*
375 * CHECKME: This is a guess from the other code... --rmk
376 */
377 if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR) 358 if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR)
378 mctrl &= ~TIOCM_DSR; 359 mctrl &= ~TIOCM_DSR;
379 } 360 }
@@ -383,6 +364,9 @@ static unsigned int dz_get_mctrl(struct uart_port *uport)
383 364
384static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl) 365static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
385{ 366{
367 /*
368 * FIXME: Handle the 3100/5000 as appropriate. --macro
369 */
386 struct dz_port *dport = (struct dz_port *)uport; 370 struct dz_port *dport = (struct dz_port *)uport;
387 unsigned short tmp; 371 unsigned short tmp;
388 372
@@ -409,13 +393,6 @@ static int dz_startup(struct uart_port *uport)
409 unsigned long flags; 393 unsigned long flags;
410 unsigned short tmp; 394 unsigned short tmp;
411 395
412 /* The dz lines for the mouse/keyboard must be
413 * opened using their respective drivers.
414 */
415 if ((dport->port.line == DZ_KEYBOARD) ||
416 (dport->port.line == DZ_MOUSE))
417 return -ENODEV;
418
419 spin_lock_irqsave(&dport->port.lock, flags); 396 spin_lock_irqsave(&dport->port.lock, flags);
420 397
421 /* enable the interrupt and the scanning */ 398 /* enable the interrupt and the scanning */
@@ -442,7 +419,8 @@ static void dz_shutdown(struct uart_port *uport)
442} 419}
443 420
444/* 421/*
445 * get_lsr_info - get line status register info 422 * -------------------------------------------------------------------
423 * dz_tx_empty() -- get the transmitter empty status
446 * 424 *
447 * Purpose: Let user call ioctl() to get info when the UART physically 425 * Purpose: Let user call ioctl() to get info when the UART physically
448 * is emptied. On bus types like RS485, the transmitter must 426 * is emptied. On bus types like RS485, the transmitter must
@@ -450,21 +428,28 @@ static void dz_shutdown(struct uart_port *uport)
450 * the transmit shift register is empty, not be done when the 428 * the transmit shift register is empty, not be done when the
451 * transmit holding register is empty. This functionality 429 * transmit holding register is empty. This functionality
452 * allows an RS485 driver to be written in user space. 430 * allows an RS485 driver to be written in user space.
431 * -------------------------------------------------------------------
453 */ 432 */
454static unsigned int dz_tx_empty(struct uart_port *uport) 433static unsigned int dz_tx_empty(struct uart_port *uport)
455{ 434{
456 struct dz_port *dport = (struct dz_port *)uport; 435 struct dz_port *dport = (struct dz_port *)uport;
457 unsigned short status = dz_in(dport, DZ_LPR); 436 unsigned short tmp, mask = 1 << dport->port.line;
458 437
459 /* FIXME: this appears to be obviously broken --rmk. */ 438 tmp = dz_in(dport, DZ_TCR);
460 return status ? TIOCSER_TEMT : 0; 439 tmp &= mask;
440
441 return tmp ? 0 : TIOCSER_TEMT;
461} 442}
462 443
463static void dz_break_ctl(struct uart_port *uport, int break_state) 444static void dz_break_ctl(struct uart_port *uport, int break_state)
464{ 445{
446 /*
447 * FIXME: Can't access BREAK bits in TDR easily;
448 * reuse the code for polled TX. --macro
449 */
465 struct dz_port *dport = (struct dz_port *)uport; 450 struct dz_port *dport = (struct dz_port *)uport;
466 unsigned long flags; 451 unsigned long flags;
467 unsigned short tmp, mask = 1 << uport->line; 452 unsigned short tmp, mask = 1 << dport->port.line;
468 453
469 spin_lock_irqsave(&uport->lock, flags); 454 spin_lock_irqsave(&uport->lock, flags);
470 tmp = dz_in(dport, DZ_TCR); 455 tmp = dz_in(dport, DZ_TCR);
@@ -561,7 +546,7 @@ static void dz_set_termios(struct uart_port *uport, struct termios *termios,
561 546
562 spin_lock_irqsave(&dport->port.lock, flags); 547 spin_lock_irqsave(&dport->port.lock, flags);
563 548
564 dz_out(dport, DZ_LPR, cflag); 549 dz_out(dport, DZ_LPR, cflag | dport->port.line);
565 dport->cflag = cflag; 550 dport->cflag = cflag;
566 551
567 /* setup accept flag */ 552 /* setup accept flag */
@@ -650,7 +635,7 @@ static void __init dz_init_ports(void)
650 for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { 635 for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
651 spin_lock_init(&dport->port.lock); 636 spin_lock_init(&dport->port.lock);
652 dport->port.membase = (char *) base; 637 dport->port.membase = (char *) base;
653 dport->port.iotype = UPIO_PORT; 638 dport->port.iotype = UPIO_MEM;
654 dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; 639 dport->port.irq = dec_interrupt[DEC_IRQ_DZ11];
655 dport->port.line = i; 640 dport->port.line = i;
656 dport->port.fifosize = 1; 641 dport->port.fifosize = 1;
@@ -662,10 +647,7 @@ static void __init dz_init_ports(void)
662static void dz_reset(struct dz_port *dport) 647static void dz_reset(struct dz_port *dport)
663{ 648{
664 dz_out(dport, DZ_CSR, DZ_CLR); 649 dz_out(dport, DZ_CSR, DZ_CLR);
665
666 while (dz_in(dport, DZ_CSR) & DZ_CLR); 650 while (dz_in(dport, DZ_CSR) & DZ_CLR);
667 /* FIXME: cpu_relax? */
668
669 iob(); 651 iob();
670 652
671 /* enable scanning */ 653 /* enable scanning */
@@ -673,26 +655,55 @@ static void dz_reset(struct dz_port *dport)
673} 655}
674 656
675#ifdef CONFIG_SERIAL_DZ_CONSOLE 657#ifdef CONFIG_SERIAL_DZ_CONSOLE
658/*
659 * -------------------------------------------------------------------
660 * dz_console_putchar() -- transmit a character
661 *
662 * Polled transmission. This is tricky. We need to mask transmit
663 * interrupts so that they do not interfere, enable the transmitter
664 * for the line requested and then wait till the transmit scanner
665 * requests data for this line. But it may request data for another
666 * line first, in which case we have to disable its transmitter and
667 * repeat waiting till our line pops up. Only then the character may
668 * be transmitted. Finally, the state of the transmitter mask is
669 * restored. Welcome to the world of PDP-11!
670 * -------------------------------------------------------------------
671 */
676static void dz_console_putchar(struct uart_port *uport, int ch) 672static void dz_console_putchar(struct uart_port *uport, int ch)
677{ 673{
678 struct dz_port *dport = (struct dz_port *)uport; 674 struct dz_port *dport = (struct dz_port *)uport;
679 unsigned long flags; 675 unsigned long flags;
680 int loops = 2500; 676 unsigned short csr, tcr, trdy, mask;
681 unsigned short tmp = (unsigned char)ch; 677 int loops = 10000;
682 /* this code sends stuff out to serial device - spinning its
683 wheels and waiting. */
684 678
685 spin_lock_irqsave(&dport->port.lock, flags); 679 spin_lock_irqsave(&dport->port.lock, flags);
680 csr = dz_in(dport, DZ_CSR);
681 dz_out(dport, DZ_CSR, csr & ~DZ_TIE);
682 tcr = dz_in(dport, DZ_TCR);
683 tcr |= 1 << dport->port.line;
684 mask = tcr;
685 dz_out(dport, DZ_TCR, mask);
686 iob();
687 spin_unlock_irqrestore(&dport->port.lock, flags);
686 688
687 /* spin our wheels */ 689 while (loops--) {
688 while (((dz_in(dport, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--) 690 trdy = dz_in(dport, DZ_CSR);
689 /* FIXME: cpu_relax, udelay? --rmk */ 691 if (!(trdy & DZ_TRDY))
690 ; 692 continue;
693 trdy = (trdy & DZ_TLINE) >> 8;
694 if (trdy == dport->port.line)
695 break;
696 mask &= ~(1 << trdy);
697 dz_out(dport, DZ_TCR, mask);
698 iob();
699 udelay(2);
700 }
691 701
692 /* Actually transmit the character. */ 702 if (loops) /* Cannot send otherwise. */
693 dz_out(dport, DZ_TDR, tmp); 703 dz_out(dport, DZ_TDR, ch);
694 704
695 spin_unlock_irqrestore(&dport->port.lock, flags); 705 dz_out(dport, DZ_TCR, tcr);
706 dz_out(dport, DZ_CSR, csr);
696} 707}
697 708
698/* 709/*
@@ -703,11 +714,11 @@ static void dz_console_putchar(struct uart_port *uport, int ch)
703 * The console must be locked when we get here. 714 * The console must be locked when we get here.
704 * ------------------------------------------------------------------- 715 * -------------------------------------------------------------------
705 */ 716 */
706static void dz_console_print(struct console *cons, 717static void dz_console_print(struct console *co,
707 const char *str, 718 const char *str,
708 unsigned int count) 719 unsigned int count)
709{ 720{
710 struct dz_port *dport = &dz_ports[CONSOLE_LINE]; 721 struct dz_port *dport = &dz_ports[co->index];
711#ifdef DEBUG_DZ 722#ifdef DEBUG_DZ
712 prom_printf((char *) str); 723 prom_printf((char *) str);
713#endif 724#endif
@@ -716,49 +727,43 @@ static void dz_console_print(struct console *cons,
716 727
717static int __init dz_console_setup(struct console *co, char *options) 728static int __init dz_console_setup(struct console *co, char *options)
718{ 729{
719 struct dz_port *dport = &dz_ports[CONSOLE_LINE]; 730 struct dz_port *dport = &dz_ports[co->index];
720 int baud = 9600; 731 int baud = 9600;
721 int bits = 8; 732 int bits = 8;
722 int parity = 'n'; 733 int parity = 'n';
723 int flow = 'n'; 734 int flow = 'n';
724 int ret;
725 unsigned short mask, tmp;
726 735
727 if (options) 736 if (options)
728 uart_parse_options(options, &baud, &parity, &bits, &flow); 737 uart_parse_options(options, &baud, &parity, &bits, &flow);
729 738
730 dz_reset(dport); 739 dz_reset(dport);
731 740
732 ret = uart_set_options(&dport->port, co, baud, parity, bits, flow); 741 return uart_set_options(&dport->port, co, baud, parity, bits, flow);
733 if (ret == 0) {
734 mask = 1 << dport->port.line;
735 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */
736 if (!(tmp & mask)) {
737 tmp |= mask; /* set the TX flag */
738 dz_out(dport, DZ_TCR, tmp);
739 }
740 }
741
742 return ret;
743} 742}
744 743
745static struct console dz_sercons = 744static struct uart_driver dz_reg;
746{ 745static struct console dz_sercons = {
747 .name = "ttyS", 746 .name = "ttyS",
748 .write = dz_console_print, 747 .write = dz_console_print,
749 .device = uart_console_device, 748 .device = uart_console_device,
750 .setup = dz_console_setup, 749 .setup = dz_console_setup,
751 .flags = CON_CONSDEV | CON_PRINTBUFFER, 750 .flags = CON_PRINTBUFFER,
752 .index = CONSOLE_LINE, 751 .index = -1,
752 .data = &dz_reg,
753}; 753};
754 754
755void __init dz_serial_console_init(void) 755static int __init dz_serial_console_init(void)
756{ 756{
757 dz_init_ports(); 757 if (!IOASIC) {
758 758 dz_init_ports();
759 register_console(&dz_sercons); 759 register_console(&dz_sercons);
760 return 0;
761 } else
762 return -ENXIO;
760} 763}
761 764
765console_initcall(dz_serial_console_init);
766
762#define SERIAL_DZ_CONSOLE &dz_sercons 767#define SERIAL_DZ_CONSOLE &dz_sercons
763#else 768#else
764#define SERIAL_DZ_CONSOLE NULL 769#define SERIAL_DZ_CONSOLE NULL
@@ -767,35 +772,29 @@ void __init dz_serial_console_init(void)
767static struct uart_driver dz_reg = { 772static struct uart_driver dz_reg = {
768 .owner = THIS_MODULE, 773 .owner = THIS_MODULE,
769 .driver_name = "serial", 774 .driver_name = "serial",
770 .dev_name = "ttyS%d", 775 .dev_name = "ttyS",
771 .major = TTY_MAJOR, 776 .major = TTY_MAJOR,
772 .minor = 64, 777 .minor = 64,
773 .nr = DZ_NB_PORT, 778 .nr = DZ_NB_PORT,
774 .cons = SERIAL_DZ_CONSOLE, 779 .cons = SERIAL_DZ_CONSOLE,
775}; 780};
776 781
777int __init dz_init(void) 782static int __init dz_init(void)
778{ 783{
779 unsigned long flags;
780 int ret, i; 784 int ret, i;
781 785
786 if (IOASIC)
787 return -ENXIO;
788
782 printk("%s%s\n", dz_name, dz_version); 789 printk("%s%s\n", dz_name, dz_version);
783 790
784 dz_init_ports(); 791 dz_init_ports();
785 792
786 save_flags(flags);
787 cli();
788
789#ifndef CONFIG_SERIAL_DZ_CONSOLE 793#ifndef CONFIG_SERIAL_DZ_CONSOLE
790 /* reset the chip */ 794 /* reset the chip */
791 dz_reset(&dz_ports[0]); 795 dz_reset(&dz_ports[0]);
792#endif 796#endif
793 797
794 /* order matters here... the trick is that flags
795 is updated... in request_irq - to immediatedly obliterate
796 it is unwise. */
797 restore_flags(flags);
798
799 if (request_irq(dz_ports[0].port.irq, dz_interrupt, 798 if (request_irq(dz_ports[0].port.irq, dz_interrupt,
800 IRQF_DISABLED, "DZ", &dz_ports[0])) 799 IRQF_DISABLED, "DZ", &dz_ports[0]))
801 panic("Unable to register DZ interrupt"); 800 panic("Unable to register DZ interrupt");
@@ -810,5 +809,7 @@ int __init dz_init(void)
810 return ret; 809 return ret;
811} 810}
812 811
812module_init(dz_init);
813
813MODULE_DESCRIPTION("DECstation DZ serial driver"); 814MODULE_DESCRIPTION("DECstation DZ serial driver");
814MODULE_LICENSE("GPL"); 815MODULE_LICENSE("GPL");
diff --git a/drivers/serial/dz.h b/drivers/serial/dz.h
index 86ef417382bb..9674d4e49872 100644
--- a/drivers/serial/dz.h
+++ b/drivers/serial/dz.h
@@ -1,20 +1,22 @@
1/* 1/*
2 * dz.h: Serial port driver for DECStations equiped 2 * dz.h: Serial port driver for DECstations equipped
3 * with the DZ chipset. 3 * with the DZ chipset.
4 * 4 *
5 * Copyright (C) 1998 Olivier A. D. Lebaillif 5 * Copyright (C) 1998 Olivier A. D. Lebaillif
6 * 6 *
7 * Email: olivier.lebaillif@ifrsys.com 7 * Email: olivier.lebaillif@ifrsys.com
8 * 8 *
9 * Copyright (C) 2004, 2006 Maciej W. Rozycki
9 */ 10 */
10#ifndef DZ_SERIAL_H 11#ifndef DZ_SERIAL_H
11#define DZ_SERIAL_H 12#define DZ_SERIAL_H
12 13
13/* 14/*
14 * Definitions for the Control and Status Received. 15 * Definitions for the Control and Status Register.
15 */ 16 */
16#define DZ_TRDY 0x8000 /* Transmitter empty */ 17#define DZ_TRDY 0x8000 /* Transmitter empty */
17#define DZ_TIE 0x4000 /* Transmitter Interrupt Enable */ 18#define DZ_TIE 0x4000 /* Transmitter Interrupt Enbl */
19#define DZ_TLINE 0x0300 /* Transmitter Line Number */
18#define DZ_RDONE 0x0080 /* Receiver data ready */ 20#define DZ_RDONE 0x0080 /* Receiver data ready */
19#define DZ_RIE 0x0040 /* Receive Interrupt Enable */ 21#define DZ_RIE 0x0040 /* Receive Interrupt Enable */
20#define DZ_MSE 0x0020 /* Master Scan Enable */ 22#define DZ_MSE 0x0020 /* Master Scan Enable */
@@ -22,32 +24,44 @@
22#define DZ_MAINT 0x0008 /* Loop Back Mode */ 24#define DZ_MAINT 0x0008 /* Loop Back Mode */
23 25
24/* 26/*
25 * Definitions for the Received buffer. 27 * Definitions for the Receiver Buffer Register.
26 */ 28 */
27#define DZ_RBUF_MASK 0x00FF /* Data Mask in the Receive Buffer */ 29#define DZ_RBUF_MASK 0x00FF /* Data Mask */
28#define DZ_LINE_MASK 0x0300 /* Line Mask in the Receive Buffer */ 30#define DZ_LINE_MASK 0x0300 /* Line Mask */
29#define DZ_DVAL 0x8000 /* Valid Data indicator */ 31#define DZ_DVAL 0x8000 /* Valid Data indicator */
30#define DZ_OERR 0x4000 /* Overrun error indicator */ 32#define DZ_OERR 0x4000 /* Overrun error indicator */
31#define DZ_FERR 0x2000 /* Frame error indicator */ 33#define DZ_FERR 0x2000 /* Frame error indicator */
32#define DZ_PERR 0x1000 /* Parity error indicator */ 34#define DZ_PERR 0x1000 /* Parity error indicator */
33 35
34#define LINE(x) (x & DZ_LINE_MASK) >> 8 /* Get the line number from the input buffer */ 36#define LINE(x) ((x & DZ_LINE_MASK) >> 8) /* Get the line number
35#define UCHAR(x) (unsigned char)(x & DZ_RBUF_MASK) 37 from the input buffer */
38#define UCHAR(x) ((unsigned char)(x & DZ_RBUF_MASK))
36 39
37/* 40/*
38 * Definitions for the Transmit Register. 41 * Definitions for the Transmit Control Register.
39 */ 42 */
40#define DZ_LINE_KEYBOARD 0x0001 43#define DZ_LINE_KEYBOARD 0x0001
41#define DZ_LINE_MOUSE 0x0002 44#define DZ_LINE_MOUSE 0x0002
42#define DZ_LINE_MODEM 0x0004 45#define DZ_LINE_MODEM 0x0004
43#define DZ_LINE_PRINTER 0x0008 46#define DZ_LINE_PRINTER 0x0008
44 47
48#define DZ_MODEM_RTS 0x0800 /* RTS for the modem line (2) */
45#define DZ_MODEM_DTR 0x0400 /* DTR for the modem line (2) */ 49#define DZ_MODEM_DTR 0x0400 /* DTR for the modem line (2) */
50#define DZ_PRINT_RTS 0x0200 /* RTS for the prntr line (3) */
51#define DZ_PRINT_DTR 0x0100 /* DTR for the prntr line (3) */
52#define DZ_LNENB 0x000f /* Transmitter Line Enable */
46 53
47/* 54/*
48 * Definitions for the Modem Status Register. 55 * Definitions for the Modem Status Register.
49 */ 56 */
57#define DZ_MODEM_RI 0x0800 /* RI for the modem line (2) */
58#define DZ_MODEM_CD 0x0400 /* CD for the modem line (2) */
50#define DZ_MODEM_DSR 0x0200 /* DSR for the modem line (2) */ 59#define DZ_MODEM_DSR 0x0200 /* DSR for the modem line (2) */
60#define DZ_MODEM_CTS 0x0100 /* CTS for the modem line (2) */
61#define DZ_PRINT_RI 0x0008 /* RI for the printer line (3) */
62#define DZ_PRINT_CD 0x0004 /* CD for the printer line (3) */
63#define DZ_PRINT_DSR 0x0002 /* DSR for the prntr line (3) */
64#define DZ_PRINT_CTS 0x0001 /* CTS for the prntr line (3) */
51 65
52/* 66/*
53 * Definitions for the Transmit Data Register. 67 * Definitions for the Transmit Data Register.
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 8eea69f29989..29823bd60fb0 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -555,7 +555,7 @@ mpsc_sdma_start_tx(struct mpsc_port_info *pi)
555 if (!mpsc_sdma_tx_active(pi)) { 555 if (!mpsc_sdma_tx_active(pi)) {
556 txre = (struct mpsc_tx_desc *)(pi->txr + 556 txre = (struct mpsc_tx_desc *)(pi->txr +
557 (pi->txr_tail * MPSC_TXRE_SIZE)); 557 (pi->txr_tail * MPSC_TXRE_SIZE));
558 dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); 558 dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
559#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 559#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
560 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 560 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
561 invalidate_dcache_range((ulong)txre, 561 invalidate_dcache_range((ulong)txre,
@@ -931,7 +931,7 @@ mpsc_init_rings(struct mpsc_port_info *pi)
931 } 931 }
932 txre->link = cpu_to_be32(pi->txr_p); /* Wrap last back to first */ 932 txre->link = cpu_to_be32(pi->txr_p); /* Wrap last back to first */
933 933
934 dma_cache_sync((void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE, 934 dma_cache_sync(pi->port.dev, (void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE,
935 DMA_BIDIRECTIONAL); 935 DMA_BIDIRECTIONAL);
936#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 936#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
937 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 937 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
@@ -1005,7 +1005,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
1005 1005
1006 rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE)); 1006 rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE));
1007 1007
1008 dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); 1008 dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
1009#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1009#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1010 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1010 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
1011 invalidate_dcache_range((ulong)rxre, 1011 invalidate_dcache_range((ulong)rxre,
@@ -1029,7 +1029,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi)
1029 } 1029 }
1030 1030
1031 bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE); 1031 bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
1032 dma_cache_sync((void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE); 1032 dma_cache_sync(pi->port.dev, (void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
1033#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1033#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1034 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1034 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
1035 invalidate_dcache_range((ulong)bp, 1035 invalidate_dcache_range((ulong)bp,
@@ -1098,7 +1098,7 @@ next_frame:
1098 SDMA_DESC_CMDSTAT_F | 1098 SDMA_DESC_CMDSTAT_F |
1099 SDMA_DESC_CMDSTAT_L); 1099 SDMA_DESC_CMDSTAT_L);
1100 wmb(); 1100 wmb();
1101 dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL); 1101 dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
1102#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1102#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1103 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1103 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
1104 flush_dcache_range((ulong)rxre, 1104 flush_dcache_range((ulong)rxre,
@@ -1109,7 +1109,7 @@ next_frame:
1109 pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1); 1109 pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1);
1110 rxre = (struct mpsc_rx_desc *)(pi->rxr + 1110 rxre = (struct mpsc_rx_desc *)(pi->rxr +
1111 (pi->rxr_posn * MPSC_RXRE_SIZE)); 1111 (pi->rxr_posn * MPSC_RXRE_SIZE));
1112 dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); 1112 dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
1113#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1113#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1114 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1114 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
1115 invalidate_dcache_range((ulong)rxre, 1115 invalidate_dcache_range((ulong)rxre,
@@ -1143,7 +1143,7 @@ mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
1143 SDMA_DESC_CMDSTAT_EI 1143 SDMA_DESC_CMDSTAT_EI
1144 : 0)); 1144 : 0));
1145 wmb(); 1145 wmb();
1146 dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL); 1146 dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL);
1147#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1147#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1148 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1148 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
1149 flush_dcache_range((ulong)txre, 1149 flush_dcache_range((ulong)txre,
@@ -1192,7 +1192,7 @@ mpsc_copy_tx_data(struct mpsc_port_info *pi)
1192 else /* All tx data copied into ring bufs */ 1192 else /* All tx data copied into ring bufs */
1193 return; 1193 return;
1194 1194
1195 dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); 1195 dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
1196#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1196#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1197 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1197 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
1198 flush_dcache_range((ulong)bp, 1198 flush_dcache_range((ulong)bp,
@@ -1217,7 +1217,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
1217 txre = (struct mpsc_tx_desc *)(pi->txr + 1217 txre = (struct mpsc_tx_desc *)(pi->txr +
1218 (pi->txr_tail * MPSC_TXRE_SIZE)); 1218 (pi->txr_tail * MPSC_TXRE_SIZE));
1219 1219
1220 dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); 1220 dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
1221#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1221#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1222 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1222 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
1223 invalidate_dcache_range((ulong)txre, 1223 invalidate_dcache_range((ulong)txre,
@@ -1235,7 +1235,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
1235 1235
1236 txre = (struct mpsc_tx_desc *)(pi->txr + 1236 txre = (struct mpsc_tx_desc *)(pi->txr +
1237 (pi->txr_tail * MPSC_TXRE_SIZE)); 1237 (pi->txr_tail * MPSC_TXRE_SIZE));
1238 dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, 1238 dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE,
1239 DMA_FROM_DEVICE); 1239 DMA_FROM_DEVICE);
1240#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1240#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1241 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1241 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
@@ -1652,7 +1652,7 @@ mpsc_console_write(struct console *co, const char *s, uint count)
1652 count--; 1652 count--;
1653 } 1653 }
1654 1654
1655 dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); 1655 dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
1656#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 1656#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
1657 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ 1657 if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
1658 flush_dcache_range((ulong)bp, 1658 flush_dcache_range((ulong)bp,
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
new file mode 100644
index 000000000000..83690653b78b
--- /dev/null
+++ b/drivers/serial/uartlite.c
@@ -0,0 +1,505 @@
1/*
2 * uartlite.c: Serial driver for Xilinx uartlite serial controller
3 *
4 * Peter Korsgaard <jacmet@sunsite.dk>
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/module.h>
13#include <linux/console.h>
14#include <linux/serial.h>
15#include <linux/serial_core.h>
16#include <linux/tty.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19#include <asm/io.h>
20
21#define ULITE_MAJOR 204
22#define ULITE_MINOR 187
23#define ULITE_NR_UARTS 4
24
25/* For register details see datasheet:
26 http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf
27*/
28#define ULITE_RX 0x00
29#define ULITE_TX 0x04
30#define ULITE_STATUS 0x08
31#define ULITE_CONTROL 0x0c
32
33#define ULITE_REGION 16
34
35#define ULITE_STATUS_RXVALID 0x01
36#define ULITE_STATUS_RXFULL 0x02
37#define ULITE_STATUS_TXEMPTY 0x04
38#define ULITE_STATUS_TXFULL 0x08
39#define ULITE_STATUS_IE 0x10
40#define ULITE_STATUS_OVERRUN 0x20
41#define ULITE_STATUS_FRAME 0x40
42#define ULITE_STATUS_PARITY 0x80
43
44#define ULITE_CONTROL_RST_TX 0x01
45#define ULITE_CONTROL_RST_RX 0x02
46#define ULITE_CONTROL_IE 0x10
47
48
49static struct uart_port ports[ULITE_NR_UARTS];
50
51static int ulite_receive(struct uart_port *port, int stat)
52{
53 struct tty_struct *tty = port->info->tty;
54 unsigned char ch = 0;
55 char flag = TTY_NORMAL;
56
57 if ((stat & (ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
58 | ULITE_STATUS_FRAME)) == 0)
59 return 0;
60
61 /* stats */
62 if (stat & ULITE_STATUS_RXVALID) {
63 port->icount.rx++;
64 ch = readb(port->membase + ULITE_RX);
65
66 if (stat & ULITE_STATUS_PARITY)
67 port->icount.parity++;
68 }
69
70 if (stat & ULITE_STATUS_OVERRUN)
71 port->icount.overrun++;
72
73 if (stat & ULITE_STATUS_FRAME)
74 port->icount.frame++;
75
76
77 /* drop byte with parity error if IGNPAR specificed */
78 if (stat & port->ignore_status_mask & ULITE_STATUS_PARITY)
79 stat &= ~ULITE_STATUS_RXVALID;
80
81 stat &= port->read_status_mask;
82
83 if (stat & ULITE_STATUS_PARITY)
84 flag = TTY_PARITY;
85
86
87 stat &= ~port->ignore_status_mask;
88
89 if (stat & ULITE_STATUS_RXVALID)
90 tty_insert_flip_char(tty, ch, flag);
91
92 if (stat & ULITE_STATUS_FRAME)
93 tty_insert_flip_char(tty, 0, TTY_FRAME);
94
95 if (stat & ULITE_STATUS_OVERRUN)
96 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
97
98 return 1;
99}
100
101static int ulite_transmit(struct uart_port *port, int stat)
102{
103 struct circ_buf *xmit = &port->info->xmit;
104
105 if (stat & ULITE_STATUS_TXFULL)
106 return 0;
107
108 if (port->x_char) {
109 writeb(port->x_char, port->membase + ULITE_TX);
110 port->x_char = 0;
111 port->icount.tx++;
112 return 1;
113 }
114
115 if (uart_circ_empty(xmit) || uart_tx_stopped(port))
116 return 0;
117
118 writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX);
119 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
120 port->icount.tx++;
121
122 /* wake up */
123 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
124 uart_write_wakeup(port);
125
126 return 1;
127}
128
129static irqreturn_t ulite_isr(int irq, void *dev_id)
130{
131 struct uart_port *port = (struct uart_port *)dev_id;
132 int busy;
133
134 do {
135 int stat = readb(port->membase + ULITE_STATUS);
136 busy = ulite_receive(port, stat);
137 busy |= ulite_transmit(port, stat);
138 } while (busy);
139
140 tty_flip_buffer_push(port->info->tty);
141
142 return IRQ_HANDLED;
143}
144
145static unsigned int ulite_tx_empty(struct uart_port *port)
146{
147 unsigned long flags;
148 unsigned int ret;
149
150 spin_lock_irqsave(&port->lock, flags);
151 ret = readb(port->membase + ULITE_STATUS);
152 spin_unlock_irqrestore(&port->lock, flags);
153
154 return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
155}
156
157static unsigned int ulite_get_mctrl(struct uart_port *port)
158{
159 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
160}
161
162static void ulite_set_mctrl(struct uart_port *port, unsigned int mctrl)
163{
164 /* N/A */
165}
166
167static void ulite_stop_tx(struct uart_port *port)
168{
169 /* N/A */
170}
171
172static void ulite_start_tx(struct uart_port *port)
173{
174 ulite_transmit(port, readb(port->membase + ULITE_STATUS));
175}
176
177static void ulite_stop_rx(struct uart_port *port)
178{
179 /* don't forward any more data (like !CREAD) */
180 port->ignore_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY
181 | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
182}
183
184static void ulite_enable_ms(struct uart_port *port)
185{
186 /* N/A */
187}
188
189static void ulite_break_ctl(struct uart_port *port, int ctl)
190{
191 /* N/A */
192}
193
194static int ulite_startup(struct uart_port *port)
195{
196 int ret;
197
198 ret = request_irq(port->irq, ulite_isr,
199 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "uartlite", port);
200 if (ret)
201 return ret;
202
203 writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX,
204 port->membase + ULITE_CONTROL);
205 writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
206
207 return 0;
208}
209
210static void ulite_shutdown(struct uart_port *port)
211{
212 writeb(0, port->membase + ULITE_CONTROL);
213 readb(port->membase + ULITE_CONTROL); /* dummy */
214 free_irq(port->irq, port);
215}
216
217static void ulite_set_termios(struct uart_port *port, struct termios *termios,
218 struct termios *old)
219{
220 unsigned long flags;
221 unsigned int baud;
222
223 spin_lock_irqsave(&port->lock, flags);
224
225 port->read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN
226 | ULITE_STATUS_TXFULL;
227
228 if (termios->c_iflag & INPCK)
229 port->read_status_mask |=
230 ULITE_STATUS_PARITY | ULITE_STATUS_FRAME;
231
232 port->ignore_status_mask = 0;
233 if (termios->c_iflag & IGNPAR)
234 port->ignore_status_mask |= ULITE_STATUS_PARITY
235 | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
236
237 /* ignore all characters if CREAD is not set */
238 if ((termios->c_cflag & CREAD) == 0)
239 port->ignore_status_mask |=
240 ULITE_STATUS_RXVALID | ULITE_STATUS_PARITY
241 | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
242
243 /* update timeout */
244 baud = uart_get_baud_rate(port, termios, old, 0, 460800);
245 uart_update_timeout(port, termios->c_cflag, baud);
246
247 spin_unlock_irqrestore(&port->lock, flags);
248}
249
250static const char *ulite_type(struct uart_port *port)
251{
252 return port->type == PORT_UARTLITE ? "uartlite" : NULL;
253}
254
255static void ulite_release_port(struct uart_port *port)
256{
257 release_mem_region(port->mapbase, ULITE_REGION);
258 iounmap(port->membase);
259 port->membase = 0;
260}
261
262static int ulite_request_port(struct uart_port *port)
263{
264 if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) {
265 dev_err(port->dev, "Memory region busy\n");
266 return -EBUSY;
267 }
268
269 port->membase = ioremap(port->mapbase, ULITE_REGION);
270 if (!port->membase) {
271 dev_err(port->dev, "Unable to map registers\n");
272 release_mem_region(port->mapbase, ULITE_REGION);
273 return -EBUSY;
274 }
275
276 return 0;
277}
278
279static void ulite_config_port(struct uart_port *port, int flags)
280{
281 ulite_request_port(port);
282 port->type = PORT_UARTLITE;
283}
284
285static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
286{
287 /* we don't want the core code to modify any port params */
288 return -EINVAL;
289}
290
291static struct uart_ops ulite_ops = {
292 .tx_empty = ulite_tx_empty,
293 .set_mctrl = ulite_set_mctrl,
294 .get_mctrl = ulite_get_mctrl,
295 .stop_tx = ulite_stop_tx,
296 .start_tx = ulite_start_tx,
297 .stop_rx = ulite_stop_rx,
298 .enable_ms = ulite_enable_ms,
299 .break_ctl = ulite_break_ctl,
300 .startup = ulite_startup,
301 .shutdown = ulite_shutdown,
302 .set_termios = ulite_set_termios,
303 .type = ulite_type,
304 .release_port = ulite_release_port,
305 .request_port = ulite_request_port,
306 .config_port = ulite_config_port,
307 .verify_port = ulite_verify_port
308};
309
310#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
311static void ulite_console_wait_tx(struct uart_port *port)
312{
313 int i;
314
315 /* wait up to 10ms for the character(s) to be sent */
316 for (i = 0; i < 10000; i++) {
317 if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
318 break;
319 udelay(1);
320 }
321}
322
323static void ulite_console_putchar(struct uart_port *port, int ch)
324{
325 ulite_console_wait_tx(port);
326 writeb(ch, port->membase + ULITE_TX);
327}
328
329static void ulite_console_write(struct console *co, const char *s,
330 unsigned int count)
331{
332 struct uart_port *port = &ports[co->index];
333 unsigned long flags;
334 unsigned int ier;
335 int locked = 1;
336
337 if (oops_in_progress) {
338 locked = spin_trylock_irqsave(&port->lock, flags);
339 } else
340 spin_lock_irqsave(&port->lock, flags);
341
342 /* save and disable interrupt */
343 ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE;
344 writeb(0, port->membase + ULITE_CONTROL);
345
346 uart_console_write(port, s, count, ulite_console_putchar);
347
348 ulite_console_wait_tx(port);
349
350 /* restore interrupt state */
351 if (ier)
352 writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
353
354 if (locked)
355 spin_unlock_irqrestore(&port->lock, flags);
356}
357
358static int __init ulite_console_setup(struct console *co, char *options)
359{
360 struct uart_port *port;
361 int baud = 9600;
362 int bits = 8;
363 int parity = 'n';
364 int flow = 'n';
365
366 if (co->index < 0 || co->index >= ULITE_NR_UARTS)
367 return -EINVAL;
368
369 port = &ports[co->index];
370
371 /* not initialized yet? */
372 if (!port->membase)
373 return -ENODEV;
374
375 if (options)
376 uart_parse_options(options, &baud, &parity, &bits, &flow);
377
378 return uart_set_options(port, co, baud, parity, bits, flow);
379}
380
381static struct uart_driver ulite_uart_driver;
382
383static struct console ulite_console = {
384 .name = "ttyUL",
385 .write = ulite_console_write,
386 .device = uart_console_device,
387 .setup = ulite_console_setup,
388 .flags = CON_PRINTBUFFER,
389 .index = -1, /* Specified on the cmdline (e.g. console=ttyUL0 ) */
390 .data = &ulite_uart_driver,
391};
392
393static int __init ulite_console_init(void)
394{
395 register_console(&ulite_console);
396 return 0;
397}
398
399console_initcall(ulite_console_init);
400
401#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
402
403static struct uart_driver ulite_uart_driver = {
404 .owner = THIS_MODULE,
405 .driver_name = "uartlite",
406 .dev_name = "ttyUL",
407 .major = ULITE_MAJOR,
408 .minor = ULITE_MINOR,
409 .nr = ULITE_NR_UARTS,
410#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
411 .cons = &ulite_console,
412#endif
413};
414
415static int __devinit ulite_probe(struct platform_device *pdev)
416{
417 struct resource *res, *res2;
418 struct uart_port *port;
419
420 if (pdev->id < 0 || pdev->id >= ULITE_NR_UARTS)
421 return -EINVAL;
422
423 if (ports[pdev->id].membase)
424 return -EBUSY;
425
426 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
427 if (!res)
428 return -ENODEV;
429
430 res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
431 if (!res2)
432 return -ENODEV;
433
434 port = &ports[pdev->id];
435
436 port->fifosize = 16;
437 port->regshift = 2;
438 port->iotype = UPIO_MEM;
439 port->iobase = 1; /* mark port in use */
440 port->mapbase = res->start;
441 port->membase = 0;
442 port->ops = &ulite_ops;
443 port->irq = res2->start;
444 port->flags = UPF_BOOT_AUTOCONF;
445 port->dev = &pdev->dev;
446 port->type = PORT_UNKNOWN;
447 port->line = pdev->id;
448
449 uart_add_one_port(&ulite_uart_driver, port);
450 platform_set_drvdata(pdev, port);
451
452 return 0;
453}
454
455static int ulite_remove(struct platform_device *pdev)
456{
457 struct uart_port *port = platform_get_drvdata(pdev);
458
459 platform_set_drvdata(pdev, NULL);
460
461 if (port)
462 uart_remove_one_port(&ulite_uart_driver, port);
463
464 /* mark port as free */
465 port->membase = 0;
466
467 return 0;
468}
469
470static struct platform_driver ulite_platform_driver = {
471 .probe = ulite_probe,
472 .remove = ulite_remove,
473 .driver = {
474 .owner = THIS_MODULE,
475 .name = "uartlite",
476 },
477};
478
479int __init ulite_init(void)
480{
481 int ret;
482
483 ret = uart_register_driver(&ulite_uart_driver);
484 if (ret)
485 return ret;
486
487 ret = platform_driver_register(&ulite_platform_driver);
488 if (ret)
489 uart_unregister_driver(&ulite_uart_driver);
490
491 return ret;
492}
493
494void __exit ulite_exit(void)
495{
496 platform_driver_unregister(&ulite_platform_driver);
497 uart_unregister_driver(&ulite_uart_driver);
498}
499
500module_init(ulite_init);
501module_exit(ulite_exit);
502
503MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
504MODULE_DESCRIPTION("Xilinx uartlite serial driver");
505MODULE_LICENSE("GPL");