2 * linux/drivers/serial/altera_juart.c
4 * Driver for Altera JTAG UART core with Avalon interface
6 * Copyright 2004 Microtronix Datacom Ltd
8 * Based on linux/drivers/serial/amba.c, which is
9 * Copyright 1999 ARM Limited
10 * Copyright (C) 2000 Deep Blue Solutions Ltd.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * Written by Wentao Xu <wentao@microtronix.com>
27 * Jun/20/2005 DGT Microtronix Datacom - support for
28 * arch/kernel/start.c - boot time error
32 #include <linux/module.h>
33 #include <linux/tty.h>
34 #include <linux/ioport.h>
35 #include <linux/init.h>
36 #include <linux/serial.h>
37 #include <linux/console.h>
38 #include <linux/sysrq.h>
39 #include <linux/device.h>
40 #include <linux/irq.h>
44 #if defined(CONFIG_SERIAL_AJUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
48 #include <linux/serial_core.h>
50 #include <asm/altera_juart.h> //;dgt;
54 #define SERIAL_JUART_MAJOR 232
55 #define SERIAL_JUART_MINOR 16
56 #define SERIAL_JUART_NR UART_NR
58 #define JUART_ISR_PASS_LIMIT 16
67 * Control Register bit definition
69 #define JTAG_UARTCR_RIE 1
70 #define JTAG_UARTCR_TIE 2
71 #define JTAG_UARTCR_RIS (1<<8)
72 #define JTAG_UARTCR_TIS (1<<9)
73 #define JTAG_UARTCR_AC (1<<10)
78 #define JTAG_UARTDR_RVALID (1<<15)
79 #define JTAG_UARTDR_DATA 255
81 * Access macros for the JTAG UARTs
83 #define UART_GET_DR(p) readl((p)->membase + JTAG_UARTDR)
84 #define UART_PUT_DR(p, c) writel((c), (p)->membase + JTAG_UARTDR)
85 #define UART_GET_CR(p) readl((p)->membase + JTAG_UARTCR)
86 #define UART_PUT_CR(p,c) writel((c), (p)->membase + JTAG_UARTCR)
88 #define UART_PORT_SIZE 8
92 * We wrap our port structure around the generic uart_port.
95 struct uart_port port
;
98 static void jtaguart_stop_tx(struct uart_port
*port
)
102 cr
= UART_GET_CR(port
);
103 cr
&= ~JTAG_UARTCR_TIE
;
104 UART_PUT_CR(port
, cr
);
107 static void jtaguart_start_tx(struct uart_port
*port
)
111 cr
= UART_GET_CR(port
);
112 cr
|= JTAG_UARTCR_TIE
;
113 UART_PUT_CR(port
, cr
);
116 static void jtaguart_stop_rx(struct uart_port
*port
)
120 cr
= UART_GET_CR(port
);
121 cr
&= ~(JTAG_UARTCR_RIE
);
122 UART_PUT_CR(port
, cr
);
125 static void jtaguart_enable_ms(struct uart_port
*port
)
131 jtaguart_rx_chars(struct uart_port
*port
)
133 jtaguart_rx_chars(struct uart_port
*port
)
136 struct tty_struct
*tty
= port
->info
->tty
;
137 unsigned int data
, max_count
= 256;
141 data
= UART_GET_DR(port
);
142 if (!(data
& JTAG_UARTDR_RVALID
))
152 if (!uart_handle_sysrq_char(port
, data
& JTAG_UARTDR_DATA
)) {
153 tty_insert_flip_char(tty
, data
& JTAG_UARTDR_DATA
, flag
);
156 } while ((data
>> 16) && (max_count
--));
159 tty_schedule_flip(tty
);
165 static void jtaguart_tx_chars(struct uart_port
*port
)
167 struct circ_buf
*xmit
= &port
->info
->xmit
;
170 UART_PUT_DR(port
, port
->x_char
);
175 if (uart_circ_empty(xmit
) || uart_tx_stopped(port
)) {
176 jtaguart_stop_tx(port
);
181 UART_PUT_DR(port
, xmit
->buf
[xmit
->tail
]);
182 xmit
->tail
= (xmit
->tail
+ 1) & (UART_XMIT_SIZE
- 1);
184 if (uart_circ_empty(xmit
))
186 } while (UART_GET_CR(port
) >> 16);
188 if (uart_circ_chars_pending(xmit
) < WAKEUP_CHARS
)
189 uart_write_wakeup(port
);
191 if (uart_circ_empty(xmit
))
192 jtaguart_stop_tx(port
);
195 static irqreturn_t
jtaguart_int(int irq
, void *dev_id
)
197 struct uart_port
*port
= dev_id
;
198 unsigned int status
, pass_counter
= JUART_ISR_PASS_LIMIT
;
200 status
= UART_GET_CR(port
);
202 if (status
& JTAG_UARTCR_RIS
)
204 jtaguart_rx_chars(port
, regs
);
206 jtaguart_rx_chars(port
);
208 if (status
& JTAG_UARTCR_TIS
)
209 jtaguart_tx_chars(port
);
211 if (pass_counter
-- == 0)
214 status
= UART_GET_CR(port
);
215 } while ((status
& JTAG_UARTCR_RIS
) ||
216 ((status
& JTAG_UARTCR_TIS
) && (status
& JTAG_UARTCR_TIE
)));
221 static unsigned int jtaguart_tx_empty(struct uart_port
*port
)
223 return ((UART_GET_CR(port
)>>16) > 0 ) ? TIOCSER_TEMT
: 0;
226 static unsigned int jtaguart_get_mctrl(struct uart_port
*port
)
228 return (TIOCM_CAR
| TIOCM_DSR
| TIOCM_CTS
);
231 static void jtaguart_set_mctrl(struct uart_port
*port
, unsigned int mctrl
)
235 static void jtaguart_break_ctl(struct uart_port
*port
, int break_state
)
239 static int jtaguart_startup(struct uart_port
*port
)
241 //struct juart_port *uap = (struct juart_port *)port;
247 retval
= request_irq(port
->irq
, jtaguart_int
, 0, "jtag_uart", port
);
252 * Finally, enable reception interrupts
254 UART_PUT_CR(port
, JTAG_UARTCR_RIE
);
259 static void jtaguart_shutdown(struct uart_port
*port
)
264 free_irq(port
->irq
, port
);
267 * disable all interrupts, disable the port
269 UART_PUT_CR(port
, 0);
273 jtaguart_set_termios(struct uart_port
*port
, struct termios
*termios
,
276 port
->read_status_mask
= 0;
277 port
->ignore_status_mask
= 0;
280 static const char *jtaguart_type(struct uart_port
*port
)
282 return port
->type
== PORT_JTAG_UART
? "jtag_uart" : NULL
;
286 * Release the memory region(s) being used by 'port'
288 static void jtaguart_release_port(struct uart_port
*port
)
290 release_mem_region(port
->mapbase
, UART_PORT_SIZE
);
294 * Request the memory region(s) being used by 'port'
296 static int jtaguart_request_port(struct uart_port
*port
)
298 return request_mem_region(port
->mapbase
, UART_PORT_SIZE
, "jtag_uart")
299 != NULL
? 0 : -EBUSY
;
303 * Configure/autoconfigure the port.
305 static void jtaguart_config_port(struct uart_port
*port
, int flags
)
307 if (flags
& UART_CONFIG_TYPE
) {
308 port
->type
= PORT_JTAG_UART
;
309 jtaguart_request_port(port
);
314 * verify the new serial_struct (for TIOCSSERIAL).
316 static int jtaguart_verify_port(struct uart_port
*port
, struct serial_struct
*ser
)
319 if (ser
->type
!= PORT_UNKNOWN
&& ser
->type
!= PORT_JTAG_UART
)
321 if (ser
->irq
< 0 || ser
->irq
>= NR_IRQS
)
323 if (ser
->baud_base
< 9600)
328 static struct uart_ops juart_pops
= {
329 .tx_empty
= jtaguart_tx_empty
,
330 .set_mctrl
= jtaguart_set_mctrl
,
331 .get_mctrl
= jtaguart_get_mctrl
,
332 .stop_tx
= jtaguart_stop_tx
,
333 .start_tx
= jtaguart_start_tx
,
334 .stop_rx
= jtaguart_stop_rx
,
335 .enable_ms
= jtaguart_enable_ms
,
336 .break_ctl
= jtaguart_break_ctl
,
337 .startup
= jtaguart_startup
,
338 .shutdown
= jtaguart_shutdown
,
339 .set_termios
= jtaguart_set_termios
,
340 .type
= jtaguart_type
,
341 .release_port
= jtaguart_release_port
,
342 .request_port
= jtaguart_request_port
,
343 .config_port
= jtaguart_config_port
,
344 .verify_port
= jtaguart_verify_port
,
347 static struct juart_port juart_ports
[UART_NR
] = {
350 .membase
= (char*)na_jtag_uart
,
351 .mapbase
= na_jtag_uart
,
352 .iotype
= SERIAL_IO_MEM
,
353 .irq
= na_jtag_uart_irq
,
357 .flags
= ASYNC_BOOT_AUTOCONF
,
363 #ifdef CONFIG_SERIAL_AJUART_CONSOLE
367 jtaguart_console_write(struct console
*co
, const char *s
, unsigned int count
)
369 struct uart_port
*port
= &juart_ports
[co
->index
].port
;
370 unsigned int status
, old_cr
;
374 * First save the CR then disable the interrupts
376 old_cr
= UART_GET_CR(port
);
377 UART_PUT_CR(port
, 0);
380 * Now, do each character
382 for (i
= 0; i
< count
; i
++) {
384 status
= UART_GET_CR(port
);
385 } while (!(status
>>16));
386 UART_PUT_DR(port
, s
[i
]);
389 status
= UART_GET_CR(port
);
390 } while (!(status
>>16));
391 UART_PUT_DR(port
, '\r');
396 * Finally, wait for transmitter to become empty
398 * We don't have to wait until fifo is empty since
399 * the operation is irrevocable: all the chars can
400 * be deemed as "done"
403 status = UART_GET_CR(port);
404 } while ((status>>16)<port->fifosize);*/
405 UART_PUT_CR(port
, old_cr
);
409 jtaguart_console_get_options(struct uart_port
*port
, int *baud
,
410 int *parity
, int *bits
)
414 *baud
= port
->uartclk
/ 16;
417 static int __init
jtaguart_console_setup(struct console
*co
, char *options
)
419 struct uart_port
*port
;
426 * Check whether an invalid uart number has been specified, and
427 * if so, search for the first available port that does have
430 if (co
->index
>= UART_NR
)
432 port
= &juart_ports
[co
->index
].port
;
434 jtaguart_console_get_options(port
, &baud
, &parity
, &bits
);
436 return uart_set_options(port
, co
, baud
, parity
, bits
, flow
);
439 extern struct uart_driver juart_reg
;
441 struct console juart_console
= {
443 .write
= jtaguart_console_write
,
444 .device
= uart_console_device
,
445 .setup
= jtaguart_console_setup
,
446 .flags
= CON_PRINTBUFFER
,
451 static int __init
jtaguart_console_init(void)
453 register_console(&juart_console
);
456 console_initcall(jtaguart_console_init
);
458 #define JTAG_CONSOLE &juart_console
460 #define JTAG_CONSOLE NULL
463 static struct uart_driver juart_reg
= {
464 .owner
= THIS_MODULE
,
465 .driver_name
= "ttyJ",
467 .major
= SERIAL_JUART_MAJOR
,
468 .minor
= SERIAL_JUART_MINOR
,
469 .nr
= SERIAL_JUART_NR
,
470 .cons
= JTAG_CONSOLE
,
473 static int __init
jtaguart_init(void)
477 printk(KERN_INFO
"Serial: JTAG UART driver $Revision: 1.3 $\n");
479 ret
= uart_register_driver(&juart_reg
);
483 for (i
= 0; i
< UART_NR
; i
++)
484 uart_add_one_port(&juart_reg
, &juart_ports
[i
].port
);
489 static void __exit
jtaguart_exit(void)
493 for (i
= 0; i
< UART_NR
; i
++)
494 uart_remove_one_port(&juart_reg
, &juart_ports
[i
].port
);
496 uart_unregister_driver(&juart_reg
);
499 module_init(jtaguart_init
);
500 module_exit(jtaguart_exit
);
502 MODULE_AUTHOR("Microtronix Datacom");
503 MODULE_DESCRIPTION("Driver for Altera JTAG UART $Revision 1.0");
504 MODULE_LICENSE("GPL");
505 MODULE_ALIAS_CHARDEV(SERIAL_JUART_MAJOR
, SERIAL_JUART_MINOR
);