2 * linux/drivers/serial/uart00.c
4 * Driver for UART00 serial ports
6 * Based on drivers/char/serial_amba.c, by ARM Limited &
7 * Deep Blue Solutions Ltd.
8 * Copyright 2001 Altera Corporation
10 * Update for 2.6.4 by Dirk Behme <dirk.behme@de.bosch.com>
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 * $Id: uart00.c,v 1.35 2002/07/28 10:03:28 rmk Exp $
29 #include <linux/config.h>
31 #if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
35 #include <linux/module.h>
36 #include <linux/ioport.h>
37 #include <linux/init.h>
38 #include <linux/console.h>
39 #include <linux/sysrq.h>
40 #include <linux/tty.h>
41 #include <linux/tty_flip.h>
42 #include <linux/serial_core.h>
43 #include <linux/serial.h>
47 #include <asm/sizes.h>
49 #include <asm/arch/excalibur.h>
50 #define UART00_TYPE (volatile unsigned int*)
51 #include <asm/arch/uart00.h>
52 #include <asm/arch/int_ctrl00.h>
56 #define SERIAL_UART00_NAME "ttyUA"
57 #define SERIAL_UART00_MAJOR 204
58 #define SERIAL_UART00_MINOR 16 /* Temporary - will change in future */
59 #define SERIAL_UART00_NR UART_NR
60 #define UART_PORT_SIZE 0x50
62 #define UART00_ISR_PASS_LIMIT 256
65 * Access macros for the UART00 UARTs
67 #define UART_GET_INT_STATUS(p) inl(UART_ISR((p)->membase))
68 #define UART_PUT_IES(p, c) outl(c,UART_IES((p)->membase))
69 #define UART_GET_IES(p) inl(UART_IES((p)->membase))
70 #define UART_PUT_IEC(p, c) outl(c,UART_IEC((p)->membase))
71 #define UART_GET_IEC(p) inl(UART_IEC((p)->membase))
72 #define UART_PUT_CHAR(p, c) outl(c,UART_TD((p)->membase))
73 #define UART_GET_CHAR(p) inl(UART_RD((p)->membase))
74 #define UART_GET_RSR(p) inl(UART_RSR((p)->membase))
75 #define UART_GET_RDS(p) inl(UART_RDS((p)->membase))
76 #define UART_GET_MSR(p) inl(UART_MSR((p)->membase))
77 #define UART_GET_MCR(p) inl(UART_MCR((p)->membase))
78 #define UART_PUT_MCR(p, c) outl(c,UART_MCR((p)->membase))
79 #define UART_GET_MC(p) inl(UART_MC((p)->membase))
80 #define UART_PUT_MC(p, c) outl(c,UART_MC((p)->membase))
81 #define UART_GET_TSR(p) inl(UART_TSR((p)->membase))
82 #define UART_GET_DIV_HI(p) inl(UART_DIV_HI((p)->membase))
83 #define UART_PUT_DIV_HI(p,c) outl(c,UART_DIV_HI((p)->membase))
84 #define UART_GET_DIV_LO(p) inl(UART_DIV_LO((p)->membase))
85 #define UART_PUT_DIV_LO(p,c) outl(c,UART_DIV_LO((p)->membase))
86 #define UART_RX_DATA(s) ((s) & UART_RSR_RX_LEVEL_MSK)
87 #define UART_TX_READY(s) (((s) & UART_TSR_TX_LEVEL_MSK) < 15)
88 //#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0)
90 static void uart00_stop_tx(struct uart_port
*port
)
92 UART_PUT_IEC(port
, UART_IEC_TIE_MSK
);
95 static void uart00_stop_rx(struct uart_port
*port
)
97 UART_PUT_IEC(port
, UART_IEC_RE_MSK
);
100 static void uart00_enable_ms(struct uart_port
*port
)
102 UART_PUT_IES(port
, UART_IES_ME_MSK
);
106 uart00_rx_chars(struct uart_port
*port
, struct pt_regs
*regs
)
108 struct tty_struct
*tty
= port
->info
->tty
;
109 unsigned int status
, ch
, rds
, flg
, ignored
= 0;
111 status
= UART_GET_RSR(port
);
112 while (UART_RX_DATA(status
)) {
114 * We need to read rds before reading the
115 * character from the fifo
117 rds
= UART_GET_RDS(port
);
118 ch
= UART_GET_CHAR(port
);
121 if (tty
->flip
.count
>= TTY_FLIPBUF_SIZE
)
127 * Note that the error handling code is
128 * out of the main execution path
130 if (rds
& (UART_RDS_BI_MSK
|UART_RDS_FE_MSK
|
131 UART_RDS_PE_MSK
|UART_RDS_PE_MSK
))
133 if (uart_handle_sysrq_char(port
, ch
, regs
))
137 tty_insert_flip_char(tty
, ch
, flg
);
140 status
= UART_GET_RSR(port
);
143 tty_flip_buffer_push(tty
);
147 if (rds
& UART_RDS_BI_MSK
) {
148 status
&= ~(UART_RDS_FE_MSK
| UART_RDS_PE_MSK
);
150 if (uart_handle_break(port
))
152 } else if (rds
& UART_RDS_PE_MSK
)
153 port
->icount
.parity
++;
154 else if (rds
& UART_RDS_FE_MSK
)
155 port
->icount
.frame
++;
156 if (rds
& UART_RDS_OE_MSK
)
157 port
->icount
.overrun
++;
159 if (rds
& port
->ignore_status_mask
) {
164 rds
&= port
->read_status_mask
;
166 if (rds
& UART_RDS_BI_MSK
)
168 else if (rds
& UART_RDS_PE_MSK
)
170 else if (rds
& UART_RDS_FE_MSK
)
173 if (rds
& UART_RDS_OE_MSK
) {
175 * CHECK: does overrun affect the current character?
176 * ASSUMPTION: it does not.
178 tty_insert_flip_char(tty
, ch
, flg
);
188 static void uart00_tx_chars(struct uart_port
*port
)
190 struct circ_buf
*xmit
= &port
->info
->xmit
;
194 while ((UART_GET_TSR(port
) & UART_TSR_TX_LEVEL_MSK
) == 15)
196 UART_PUT_CHAR(port
, port
->x_char
);
201 if (uart_circ_empty(xmit
) || uart_tx_stopped(port
)) {
202 uart00_stop_tx(port
);
206 count
= port
->fifosize
>> 1;
208 while ((UART_GET_TSR(port
) & UART_TSR_TX_LEVEL_MSK
) == 15)
210 UART_PUT_CHAR(port
, xmit
->buf
[xmit
->tail
]);
211 xmit
->tail
= (xmit
->tail
+ 1) & (UART_XMIT_SIZE
- 1);
213 if (uart_circ_empty(xmit
))
215 } while (--count
> 0);
217 if (uart_circ_chars_pending(xmit
) < WAKEUP_CHARS
)
218 uart_write_wakeup(port
);
220 if (uart_circ_empty(xmit
))
221 uart00_stop_tx(port
);
224 static void uart00_start_tx(struct uart_port
*port
)
226 UART_PUT_IES(port
, UART_IES_TIE_MSK
);
227 uart00_tx_chars(port
);
230 static void uart00_modem_status(struct uart_port
*port
)
234 status
= UART_GET_MSR(port
);
236 if (!(status
& (UART_MSR_DCTS_MSK
| UART_MSR_DDSR_MSK
|
237 UART_MSR_TERI_MSK
| UART_MSR_DDCD_MSK
)))
240 if (status
& UART_MSR_DDCD_MSK
)
241 uart_handle_dcd_change(port
, status
& UART_MSR_DCD_MSK
);
243 if (status
& UART_MSR_DDSR_MSK
)
246 if (status
& UART_MSR_DCTS_MSK
)
247 uart_handle_cts_change(port
, status
& UART_MSR_CTS_MSK
);
249 wake_up_interruptible(&port
->info
->delta_msr_wait
);
252 static irqreturn_t
uart00_int(int irq
, void *dev_id
, struct pt_regs
*regs
)
254 struct uart_port
*port
= dev_id
;
255 unsigned int status
, pass_counter
= 0;
257 status
= UART_GET_INT_STATUS(port
);
259 if (status
& UART_ISR_RI_MSK
)
260 uart00_rx_chars(port
, regs
);
261 if (status
& UART_ISR_MI_MSK
)
262 uart00_modem_status(port
);
263 if (status
& (UART_ISR_TI_MSK
| UART_ISR_TII_MSK
))
264 uart00_tx_chars(port
);
265 if (pass_counter
++ > UART00_ISR_PASS_LIMIT
)
268 status
= UART_GET_INT_STATUS(port
);
274 static unsigned int uart00_tx_empty(struct uart_port
*port
)
276 return UART_GET_TSR(port
) & UART_TSR_TX_LEVEL_MSK
? 0 : TIOCSER_TEMT
;
279 static unsigned int uart00_get_mctrl(struct uart_port
*port
)
281 unsigned int result
= 0;
284 status
= UART_GET_MSR(port
);
285 if (status
& UART_MSR_DCD_MSK
)
287 if (status
& UART_MSR_DSR_MSK
)
289 if (status
& UART_MSR_CTS_MSK
)
291 if (status
& UART_MSR_RI_MSK
)
297 static void uart00_set_mctrl_null(struct uart_port
*port
, unsigned int mctrl
)
301 static void uart00_break_ctl(struct uart_port
*port
, int break_state
)
306 spin_lock_irqsave(&port
->lock
, flags
);
307 mcr
= UART_GET_MCR(port
);
308 if (break_state
== -1)
309 mcr
|= UART_MCR_BR_MSK
;
311 mcr
&= ~UART_MCR_BR_MSK
;
312 UART_PUT_MCR(port
, mcr
);
313 spin_unlock_irqrestore(&port
->lock
, flags
);
317 uart00_set_termios(struct uart_port
*port
, struct termios
*termios
,
320 unsigned int uart_mc
, old_ies
, baud
, quot
;
324 * We don't support CREAD (yet)
326 termios
->c_cflag
|= CREAD
;
329 * Ask the core to calculate the divisor for us.
331 baud
= uart_get_baud_rate(port
, termios
, old
, 0, port
->uartclk
/16);
332 quot
= uart_get_divisor(port
, baud
);
334 /* byte size and parity */
335 switch (termios
->c_cflag
& CSIZE
) {
337 uart_mc
= UART_MC_CLS_CHARLEN_5
;
340 uart_mc
= UART_MC_CLS_CHARLEN_6
;
343 uart_mc
= UART_MC_CLS_CHARLEN_7
;
346 uart_mc
= UART_MC_CLS_CHARLEN_8
;
349 if (termios
->c_cflag
& CSTOPB
)
350 uart_mc
|= UART_MC_ST_TWO
;
351 if (termios
->c_cflag
& PARENB
) {
352 uart_mc
|= UART_MC_PE_MSK
;
353 if (!(termios
->c_cflag
& PARODD
))
354 uart_mc
|= UART_MC_EP_MSK
;
357 spin_lock_irqsave(&port
->lock
, flags
);
360 * Update the per-port timeout.
362 uart_update_timeout(port
, termios
->c_cflag
, baud
);
364 port
->read_status_mask
= UART_RDS_OE_MSK
;
365 if (termios
->c_iflag
& INPCK
)
366 port
->read_status_mask
|= UART_RDS_FE_MSK
| UART_RDS_PE_MSK
;
367 if (termios
->c_iflag
& (BRKINT
| PARMRK
))
368 port
->read_status_mask
|= UART_RDS_BI_MSK
;
371 * Characters to ignore
373 port
->ignore_status_mask
= 0;
374 if (termios
->c_iflag
& IGNPAR
)
375 port
->ignore_status_mask
|= UART_RDS_FE_MSK
| UART_RDS_PE_MSK
;
376 if (termios
->c_iflag
& IGNBRK
) {
377 port
->ignore_status_mask
|= UART_RDS_BI_MSK
;
379 * If we're ignoring parity and break indicators,
380 * ignore overruns to (for real raw support).
382 if (termios
->c_iflag
& IGNPAR
)
383 port
->ignore_status_mask
|= UART_RDS_OE_MSK
;
386 /* first, disable everything */
387 old_ies
= UART_GET_IES(port
);
389 if (UART_ENABLE_MS(port
, termios
->c_cflag
))
390 old_ies
|= UART_IES_ME_MSK
;
393 UART_PUT_DIV_LO(port
, (quot
& 0xff));
394 UART_PUT_DIV_HI(port
, ((quot
& 0xf00) >> 8));
396 UART_PUT_MC(port
, uart_mc
);
397 UART_PUT_IES(port
, old_ies
);
399 spin_unlock_irqrestore(&port
->lock
, flags
);
402 static int uart00_startup(struct uart_port
*port
)
409 result
= request_irq(port
->irq
, uart00_int
, 0, "uart00", port
);
411 printk(KERN_ERR
"Request of irq %d failed\n", port
->irq
);
416 * Finally, enable interrupts. Use the TII interrupt to minimise
417 * the number of interrupts generated. If higher performance is
418 * needed, consider using the TI interrupt with a suitable FIFO
421 UART_PUT_IES(port
, UART_IES_RE_MSK
| UART_IES_TIE_MSK
);
426 static void uart00_shutdown(struct uart_port
*port
)
429 * disable all interrupts, disable the port
431 UART_PUT_IEC(port
, 0xff);
433 /* disable break condition and fifos */
434 UART_PUT_MCR(port
, UART_GET_MCR(port
) &~UART_MCR_BR_MSK
);
439 free_irq(port
->irq
, port
);
442 static const char *uart00_type(struct uart_port
*port
)
444 return port
->type
== PORT_UART00
? "Altera UART00" : NULL
;
448 * Release the memory region(s) being used by 'port'
450 static void uart00_release_port(struct uart_port
*port
)
452 release_mem_region(port
->mapbase
, UART_PORT_SIZE
);
454 #ifdef CONFIG_ARCH_CAMELOT
455 if (port
->membase
!= (void*)IO_ADDRESS(EXC_UART00_BASE
)) {
456 iounmap(port
->membase
);
462 * Request the memory region(s) being used by 'port'
464 static int uart00_request_port(struct uart_port
*port
)
466 return request_mem_region(port
->mapbase
, UART_PORT_SIZE
, "serial_uart00")
467 != NULL
? 0 : -EBUSY
;
471 * Configure/autoconfigure the port.
473 static void uart00_config_port(struct uart_port
*port
, int flags
)
477 * Map the io memory if this is a soft uart
480 port
->membase
= ioremap_nocache(port
->mapbase
,SZ_4K
);
483 printk(KERN_ERR
"serial00: cannot map io memory\n");
485 port
->type
= PORT_UART00
;
490 * verify the new serial_struct (for TIOCSSERIAL).
492 static int uart00_verify_port(struct uart_port
*port
, struct serial_struct
*ser
)
495 if (ser
->type
!= PORT_UNKNOWN
&& ser
->type
!= PORT_UART00
)
497 if (ser
->irq
< 0 || ser
->irq
>= NR_IRQS
)
499 if (ser
->baud_base
< 9600)
504 static struct uart_ops uart00_pops
= {
505 .tx_empty
= uart00_tx_empty
,
506 .set_mctrl
= uart00_set_mctrl_null
,
507 .get_mctrl
= uart00_get_mctrl
,
508 .stop_tx
= uart00_stop_tx
,
509 .start_tx
= uart00_start_tx
,
510 .stop_rx
= uart00_stop_rx
,
511 .enable_ms
= uart00_enable_ms
,
512 .break_ctl
= uart00_break_ctl
,
513 .startup
= uart00_startup
,
514 .shutdown
= uart00_shutdown
,
515 .set_termios
= uart00_set_termios
,
517 .release_port
= uart00_release_port
,
518 .request_port
= uart00_request_port
,
519 .config_port
= uart00_config_port
,
520 .verify_port
= uart00_verify_port
,
524 #ifdef CONFIG_ARCH_CAMELOT
525 static struct uart_port epxa10db_port
= {
526 .membase
= (void*)IO_ADDRESS(EXC_UART00_BASE
),
527 .mapbase
= EXC_UART00_BASE
,
528 .iotype
= SERIAL_IO_MEM
,
530 .uartclk
= EXC_AHB2_CLK_FREQUENCY
,
533 .flags
= ASYNC_BOOT_AUTOCONF
,
538 #ifdef CONFIG_SERIAL_UART00_CONSOLE
539 static void uart00_console_write(struct console
*co
, const char *s
, unsigned count
)
541 #ifdef CONFIG_ARCH_CAMELOT
542 struct uart_port
*port
= &epxa10db_port
;
543 unsigned int status
, old_ies
;
547 * First save the CR then disable the interrupts
549 old_ies
= UART_GET_IES(port
);
550 UART_PUT_IEC(port
,0xff);
553 * Now, do each character
555 for (i
= 0; i
< count
; i
++) {
557 status
= UART_GET_TSR(port
);
558 } while (!UART_TX_READY(status
));
559 UART_PUT_CHAR(port
, s
[i
]);
562 status
= UART_GET_TSR(port
);
563 } while (!UART_TX_READY(status
));
564 UART_PUT_CHAR(port
, '\r');
569 * Finally, wait for transmitter to become empty
570 * and restore the IES
573 status
= UART_GET_TSR(port
);
574 } while (status
& UART_TSR_TX_LEVEL_MSK
);
575 UART_PUT_IES(port
, old_ies
);
580 uart00_console_get_options(struct uart_port
*port
, int *baud
,
581 int *parity
, int *bits
)
583 unsigned int uart_mc
, quot
;
585 uart_mc
= UART_GET_MC(port
);
588 if (uart_mc
& UART_MC_PE_MSK
) {
589 if (uart_mc
& UART_MC_EP_MSK
)
595 switch (uart_mc
& UART_MC_CLS_MSK
) {
596 case UART_MC_CLS_CHARLEN_5
:
599 case UART_MC_CLS_CHARLEN_6
:
602 case UART_MC_CLS_CHARLEN_7
:
605 case UART_MC_CLS_CHARLEN_8
:
609 quot
= UART_GET_DIV_LO(port
) | (UART_GET_DIV_HI(port
) << 8);
610 *baud
= port
->uartclk
/ (16 *quot
);
613 static int __init
uart00_console_setup(struct console
*co
, char *options
)
615 struct uart_port
*port
;
621 #ifdef CONFIG_ARCH_CAMELOT
622 port
= &epxa10db_port
; ;
627 uart_parse_options(options
, &baud
, &parity
, &bits
, &flow
);
629 uart00_console_get_options(port
, &baud
, &parity
, &bits
);
631 return uart_set_options(port
, co
, baud
, parity
, bits
, flow
);
634 extern struct uart_driver uart00_reg
;
635 static struct console uart00_console
= {
636 .name
= SERIAL_UART00_NAME
,
637 .write
= uart00_console_write
,
638 .device
= uart_console_device
,
639 .setup
= uart00_console_setup
,
640 .flags
= CON_PRINTBUFFER
,
645 static int __init
uart00_console_init(void)
647 register_console(&uart00_console
);
650 console_initcall(uart00_console_init
);
652 #define UART00_CONSOLE &uart00_console
654 #define UART00_CONSOLE NULL
657 static struct uart_driver uart00_reg
= {
659 .driver_name
= SERIAL_UART00_NAME
,
660 .dev_name
= SERIAL_UART00_NAME
,
661 .major
= SERIAL_UART00_MAJOR
,
662 .minor
= SERIAL_UART00_MINOR
,
664 .cons
= UART00_CONSOLE
,
667 struct dev_port_entry
{
668 unsigned int base_addr
;
669 struct uart_port
*port
;
672 #ifdef CONFIG_PLD_HOTSWAP
674 static struct dev_port_entry dev_port_map
[UART_NR
];
677 * Keep a mapping of dev_info addresses -> port lines to use when
678 * removing ports dev==NULL indicates unused entry
681 struct uart00_ps_data
{
683 unsigned int fifosize
;
686 int uart00_add_device(struct pldhs_dev_info
* dev_info
, void* dev_ps_data
)
688 struct uart00_ps_data
* dev_ps
=dev_ps_data
;
689 struct uart_port
* port
;
693 while(dev_port_map
[i
].port
)
697 printk(KERN_WARNING
"uart00: Maximum number of ports reached\n");
701 port
=kmalloc(sizeof(struct uart_port
),GFP_KERNEL
);
705 printk("clk=%d fifo=%d\n",dev_ps
->clk
,dev_ps
->fifosize
);
707 port
->mapbase
=dev_info
->base_addr
;
708 port
->iotype
=SERIAL_IO_MEM
;
709 port
->irq
=dev_info
->irq
;
710 port
->uartclk
=dev_ps
->clk
;
711 port
->fifosize
=dev_ps
->fifosize
;
712 port
->ops
=&uart00_pops
;
714 port
->flags
=ASYNC_BOOT_AUTOCONF
;
716 result
=uart_add_one_port(&uart00_reg
, port
);
718 printk("uart_add_one_port returned %d\n",result
);
721 dev_port_map
[i
].base_addr
=dev_info
->base_addr
;
722 dev_port_map
[i
].port
=port
;
723 printk("uart00: added device at %x as ttyUA%d\n",dev_port_map
[i
].base_addr
,i
);
728 int uart00_remove_devices(void)
734 for(i
=1;i
<UART_NR
;i
++){
735 if(dev_port_map
[i
].base_addr
){
736 result
=uart_remove_one_port(&uart00_reg
, dev_port_map
[i
].port
);
740 /* port removed sucessfully, so now tidy up */
741 kfree(dev_port_map
[i
].port
);
742 dev_port_map
[i
].base_addr
=0;
743 dev_port_map
[i
].port
=NULL
;
750 struct pld_hotswap_ops uart00_pldhs_ops
={
752 .add_device
= uart00_add_device
,
753 .remove_devices
= uart00_remove_devices
,
758 static int __init
uart00_init(void)
762 printk(KERN_INFO
"Serial: UART00 driver $Revision: 1.35 $\n");
764 printk(KERN_WARNING
"serial_uart00:Using temporary major/minor pairs"
765 " - these WILL change in the future\n");
767 result
= uart_register_driver(&uart00_reg
);
770 #ifdef CONFIG_ARCH_CAMELOT
771 result
= uart_add_one_port(&uart00_reg
,&epxa10db_port
);
774 uart_unregister_driver(&uart00_reg
);
776 #ifdef CONFIG_PLD_HOTSWAP
777 pldhs_register_driver(&uart00_pldhs_ops
);
782 __initcall(uart00_init
);