diff options
Diffstat (limited to 'drivers/serial/atmel_serial.c')
-rw-r--r-- | drivers/serial/atmel_serial.c | 255 |
1 files changed, 150 insertions, 105 deletions
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 60f52904aad0..bb9c3574caa9 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -73,6 +73,7 @@ | |||
73 | 73 | ||
74 | #define ATMEL_ISR_PASS_LIMIT 256 | 74 | #define ATMEL_ISR_PASS_LIMIT 256 |
75 | 75 | ||
76 | /* UART registers. CR is write-only, hence no GET macro */ | ||
76 | #define UART_PUT_CR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_CR) | 77 | #define UART_PUT_CR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_CR) |
77 | #define UART_GET_MR(port) __raw_readl((port)->membase + ATMEL_US_MR) | 78 | #define UART_GET_MR(port) __raw_readl((port)->membase + ATMEL_US_MR) |
78 | #define UART_PUT_MR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_MR) | 79 | #define UART_PUT_MR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_MR) |
@@ -86,8 +87,6 @@ | |||
86 | #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) | 87 | #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) |
87 | #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) | 88 | #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) |
88 | 89 | ||
89 | // #define UART_GET_CR(port) __raw_readl((port)->membase + ATMEL_US_CR) // is write-only | ||
90 | |||
91 | /* PDC registers */ | 90 | /* PDC registers */ |
92 | #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) | 91 | #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) |
93 | #define UART_GET_PTSR(port) __raw_readl((port)->membase + ATMEL_PDC_PTSR) | 92 | #define UART_GET_PTSR(port) __raw_readl((port)->membase + ATMEL_PDC_PTSR) |
@@ -100,8 +99,6 @@ | |||
100 | 99 | ||
101 | #define UART_PUT_TPR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TPR) | 100 | #define UART_PUT_TPR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TPR) |
102 | #define UART_PUT_TCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TCR) | 101 | #define UART_PUT_TCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TCR) |
103 | //#define UART_PUT_TNPR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TNPR) | ||
104 | //#define UART_PUT_TNCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TNCR) | ||
105 | 102 | ||
106 | static int (*atmel_open_hook)(struct uart_port *); | 103 | static int (*atmel_open_hook)(struct uart_port *); |
107 | static void (*atmel_close_hook)(struct uart_port *); | 104 | static void (*atmel_close_hook)(struct uart_port *); |
@@ -141,8 +138,8 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
141 | #ifdef CONFIG_ARCH_AT91RM9200 | 138 | #ifdef CONFIG_ARCH_AT91RM9200 |
142 | if (cpu_is_at91rm9200()) { | 139 | if (cpu_is_at91rm9200()) { |
143 | /* | 140 | /* |
144 | * AT91RM9200 Errata #39: RTS0 is not internally connected to PA21. | 141 | * AT91RM9200 Errata #39: RTS0 is not internally connected |
145 | * We need to drive the pin manually. | 142 | * to PA21. We need to drive the pin manually. |
146 | */ | 143 | */ |
147 | if (port->mapbase == AT91RM9200_BASE_US0) { | 144 | if (port->mapbase == AT91RM9200_BASE_US0) { |
148 | if (mctrl & TIOCM_RTS) | 145 | if (mctrl & TIOCM_RTS) |
@@ -227,7 +224,8 @@ static void atmel_stop_rx(struct uart_port *port) | |||
227 | */ | 224 | */ |
228 | static void atmel_enable_ms(struct uart_port *port) | 225 | static void atmel_enable_ms(struct uart_port *port) |
229 | { | 226 | { |
230 | UART_PUT_IER(port, ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC | ATMEL_US_CTSIC); | 227 | UART_PUT_IER(port, ATMEL_US_RIIC | ATMEL_US_DSRIC |
228 | | ATMEL_US_DCDIC | ATMEL_US_CTSIC); | ||
231 | } | 229 | } |
232 | 230 | ||
233 | /* | 231 | /* |
@@ -246,7 +244,7 @@ static void atmel_break_ctl(struct uart_port *port, int break_state) | |||
246 | */ | 244 | */ |
247 | static void atmel_rx_chars(struct uart_port *port) | 245 | static void atmel_rx_chars(struct uart_port *port) |
248 | { | 246 | { |
249 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; | 247 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *)port; |
250 | struct tty_struct *tty = port->info->tty; | 248 | struct tty_struct *tty = port->info->tty; |
251 | unsigned int status, ch, flg; | 249 | unsigned int status, ch, flg; |
252 | 250 | ||
@@ -265,10 +263,12 @@ static void atmel_rx_chars(struct uart_port *port) | |||
265 | if (unlikely(status & (ATMEL_US_PARE | ATMEL_US_FRAME | 263 | if (unlikely(status & (ATMEL_US_PARE | ATMEL_US_FRAME |
266 | | ATMEL_US_OVRE | ATMEL_US_RXBRK) | 264 | | ATMEL_US_OVRE | ATMEL_US_RXBRK) |
267 | || atmel_port->break_active)) { | 265 | || atmel_port->break_active)) { |
268 | UART_PUT_CR(port, ATMEL_US_RSTSTA); /* clear error */ | 266 | /* clear error */ |
267 | UART_PUT_CR(port, ATMEL_US_RSTSTA); | ||
269 | if (status & ATMEL_US_RXBRK | 268 | if (status & ATMEL_US_RXBRK |
270 | && !atmel_port->break_active) { | 269 | && !atmel_port->break_active) { |
271 | status &= ~(ATMEL_US_PARE | ATMEL_US_FRAME); /* ignore side-effect */ | 270 | /* ignore side-effect */ |
271 | status &= ~(ATMEL_US_PARE | ATMEL_US_FRAME); | ||
272 | port->icount.brk++; | 272 | port->icount.brk++; |
273 | atmel_port->break_active = 1; | 273 | atmel_port->break_active = 1; |
274 | UART_PUT_IER(port, ATMEL_US_RXBRK); | 274 | UART_PUT_IER(port, ATMEL_US_RXBRK); |
@@ -308,7 +308,7 @@ static void atmel_rx_chars(struct uart_port *port) | |||
308 | 308 | ||
309 | uart_insert_char(port, status, ATMEL_US_OVRE, ch, flg); | 309 | uart_insert_char(port, status, ATMEL_US_OVRE, ch, flg); |
310 | 310 | ||
311 | ignore_char: | 311 | ignore_char: |
312 | status = UART_GET_CSR(port); | 312 | status = UART_GET_CSR(port); |
313 | } | 313 | } |
314 | 314 | ||
@@ -349,44 +349,73 @@ static void atmel_tx_chars(struct uart_port *port) | |||
349 | } | 349 | } |
350 | 350 | ||
351 | /* | 351 | /* |
352 | * receive interrupt handler. | ||
353 | */ | ||
354 | static void | ||
355 | atmel_handle_receive(struct uart_port *port, unsigned int pending) | ||
356 | { | ||
357 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *)port; | ||
358 | |||
359 | /* Interrupt receive */ | ||
360 | if (pending & ATMEL_US_RXRDY) | ||
361 | atmel_rx_chars(port); | ||
362 | else if (pending & ATMEL_US_RXBRK) { | ||
363 | /* | ||
364 | * End of break detected. If it came along with a | ||
365 | * character, atmel_rx_chars will handle it. | ||
366 | */ | ||
367 | UART_PUT_CR(port, ATMEL_US_RSTSTA); | ||
368 | UART_PUT_IDR(port, ATMEL_US_RXBRK); | ||
369 | atmel_port->break_active = 0; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * transmit interrupt handler. | ||
375 | */ | ||
376 | static void | ||
377 | atmel_handle_transmit(struct uart_port *port, unsigned int pending) | ||
378 | { | ||
379 | /* Interrupt transmit */ | ||
380 | if (pending & ATMEL_US_TXRDY) | ||
381 | atmel_tx_chars(port); | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * status flags interrupt handler. | ||
386 | */ | ||
387 | static void | ||
388 | atmel_handle_status(struct uart_port *port, unsigned int pending, | ||
389 | unsigned int status) | ||
390 | { | ||
391 | /* TODO: All reads to CSR will clear these interrupts! */ | ||
392 | if (pending & ATMEL_US_RIIC) | ||
393 | port->icount.rng++; | ||
394 | if (pending & ATMEL_US_DSRIC) | ||
395 | port->icount.dsr++; | ||
396 | if (pending & ATMEL_US_DCDIC) | ||
397 | uart_handle_dcd_change(port, !(status & ATMEL_US_DCD)); | ||
398 | if (pending & ATMEL_US_CTSIC) | ||
399 | uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); | ||
400 | if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC | ||
401 | | ATMEL_US_CTSIC)) | ||
402 | wake_up_interruptible(&port->info->delta_msr_wait); | ||
403 | } | ||
404 | |||
405 | /* | ||
352 | * Interrupt handler | 406 | * Interrupt handler |
353 | */ | 407 | */ |
354 | static irqreturn_t atmel_interrupt(int irq, void *dev_id) | 408 | static irqreturn_t atmel_interrupt(int irq, void *dev_id) |
355 | { | 409 | { |
356 | struct uart_port *port = dev_id; | 410 | struct uart_port *port = dev_id; |
357 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; | ||
358 | unsigned int status, pending, pass_counter = 0; | 411 | unsigned int status, pending, pass_counter = 0; |
359 | 412 | ||
360 | status = UART_GET_CSR(port); | 413 | status = UART_GET_CSR(port); |
361 | pending = status & UART_GET_IMR(port); | 414 | pending = status & UART_GET_IMR(port); |
362 | while (pending) { | 415 | while (pending) { |
363 | /* Interrupt receive */ | 416 | atmel_handle_receive(port, pending); |
364 | if (pending & ATMEL_US_RXRDY) | 417 | atmel_handle_status(port, pending, status); |
365 | atmel_rx_chars(port); | 418 | atmel_handle_transmit(port, pending); |
366 | else if (pending & ATMEL_US_RXBRK) { | ||
367 | /* | ||
368 | * End of break detected. If it came along | ||
369 | * with a character, atmel_rx_chars will | ||
370 | * handle it. | ||
371 | */ | ||
372 | UART_PUT_CR(port, ATMEL_US_RSTSTA); | ||
373 | UART_PUT_IDR(port, ATMEL_US_RXBRK); | ||
374 | atmel_port->break_active = 0; | ||
375 | } | ||
376 | |||
377 | // TODO: All reads to CSR will clear these interrupts! | ||
378 | if (pending & ATMEL_US_RIIC) port->icount.rng++; | ||
379 | if (pending & ATMEL_US_DSRIC) port->icount.dsr++; | ||
380 | if (pending & ATMEL_US_DCDIC) | ||
381 | uart_handle_dcd_change(port, !(status & ATMEL_US_DCD)); | ||
382 | if (pending & ATMEL_US_CTSIC) | ||
383 | uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); | ||
384 | if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC | ATMEL_US_CTSIC)) | ||
385 | wake_up_interruptible(&port->info->delta_msr_wait); | ||
386 | |||
387 | /* Interrupt transmit */ | ||
388 | if (pending & ATMEL_US_TXRDY) | ||
389 | atmel_tx_chars(port); | ||
390 | 419 | ||
391 | if (pass_counter++ > ATMEL_ISR_PASS_LIMIT) | 420 | if (pass_counter++ > ATMEL_ISR_PASS_LIMIT) |
392 | break; | 421 | break; |
@@ -414,7 +443,8 @@ static int atmel_startup(struct uart_port *port) | |||
414 | /* | 443 | /* |
415 | * Allocate the IRQ | 444 | * Allocate the IRQ |
416 | */ | 445 | */ |
417 | retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED, "atmel_serial", port); | 446 | retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED, |
447 | "atmel_serial", port); | ||
418 | if (retval) { | 448 | if (retval) { |
419 | printk("atmel_serial: atmel_startup - Can't get irq\n"); | 449 | printk("atmel_serial: atmel_startup - Can't get irq\n"); |
420 | return retval; | 450 | return retval; |
@@ -436,9 +466,11 @@ static int atmel_startup(struct uart_port *port) | |||
436 | * Finally, enable the serial port | 466 | * Finally, enable the serial port |
437 | */ | 467 | */ |
438 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); | 468 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); |
439 | UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); /* enable xmit & rcvr */ | 469 | /* enable xmit & rcvr */ |
470 | UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); | ||
440 | 471 | ||
441 | UART_PUT_IER(port, ATMEL_US_RXRDY); /* enable receive only */ | 472 | /* enable receive only */ |
473 | UART_PUT_IER(port, ATMEL_US_RXRDY); | ||
442 | 474 | ||
443 | return 0; | 475 | return 0; |
444 | } | 476 | } |
@@ -470,45 +502,48 @@ static void atmel_shutdown(struct uart_port *port) | |||
470 | /* | 502 | /* |
471 | * Power / Clock management. | 503 | * Power / Clock management. |
472 | */ | 504 | */ |
473 | static void atmel_serial_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) | 505 | static void atmel_serial_pm(struct uart_port *port, unsigned int state, |
506 | unsigned int oldstate) | ||
474 | { | 507 | { |
475 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; | 508 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *)port; |
476 | 509 | ||
477 | switch (state) { | 510 | switch (state) { |
478 | case 0: | 511 | case 0: |
479 | /* | 512 | /* |
480 | * Enable the peripheral clock for this serial port. | 513 | * Enable the peripheral clock for this serial port. |
481 | * This is called on uart_open() or a resume event. | 514 | * This is called on uart_open() or a resume event. |
482 | */ | 515 | */ |
483 | clk_enable(atmel_port->clk); | 516 | clk_enable(atmel_port->clk); |
484 | break; | 517 | break; |
485 | case 3: | 518 | case 3: |
486 | /* | 519 | /* |
487 | * Disable the peripheral clock for this serial port. | 520 | * Disable the peripheral clock for this serial port. |
488 | * This is called on uart_close() or a suspend event. | 521 | * This is called on uart_close() or a suspend event. |
489 | */ | 522 | */ |
490 | clk_disable(atmel_port->clk); | 523 | clk_disable(atmel_port->clk); |
491 | break; | 524 | break; |
492 | default: | 525 | default: |
493 | printk(KERN_ERR "atmel_serial: unknown pm %d\n", state); | 526 | printk(KERN_ERR "atmel_serial: unknown pm %d\n", state); |
494 | } | 527 | } |
495 | } | 528 | } |
496 | 529 | ||
497 | /* | 530 | /* |
498 | * Change the port parameters | 531 | * Change the port parameters |
499 | */ | 532 | */ |
500 | static void atmel_set_termios(struct uart_port *port, struct ktermios * termios, struct ktermios * old) | 533 | static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, |
534 | struct ktermios *old) | ||
501 | { | 535 | { |
502 | unsigned long flags; | 536 | unsigned long flags; |
503 | unsigned int mode, imr, quot, baud; | 537 | unsigned int mode, imr, quot, baud; |
504 | 538 | ||
505 | /* Get current mode register */ | 539 | /* Get current mode register */ |
506 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR); | 540 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL |
541 | | ATMEL_US_NBSTOP | ATMEL_US_PAR); | ||
507 | 542 | ||
508 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 543 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); |
509 | quot = uart_get_divisor(port, baud); | 544 | quot = uart_get_divisor(port, baud); |
510 | 545 | ||
511 | if (quot > 65535) { /* BRGR is 16-bit, so switch to slower clock */ | 546 | if (quot > 65535) { /* BRGR is 16-bit, so switch to slower clock */ |
512 | quot /= 8; | 547 | quot /= 8; |
513 | mode |= ATMEL_US_USCLKS_MCK_DIV8; | 548 | mode |= ATMEL_US_USCLKS_MCK_DIV8; |
514 | } | 549 | } |
@@ -535,18 +570,17 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios * termios, | |||
535 | 570 | ||
536 | /* parity */ | 571 | /* parity */ |
537 | if (termios->c_cflag & PARENB) { | 572 | if (termios->c_cflag & PARENB) { |
538 | if (termios->c_cflag & CMSPAR) { /* Mark or Space parity */ | 573 | /* Mark or Space parity */ |
574 | if (termios->c_cflag & CMSPAR) { | ||
539 | if (termios->c_cflag & PARODD) | 575 | if (termios->c_cflag & PARODD) |
540 | mode |= ATMEL_US_PAR_MARK; | 576 | mode |= ATMEL_US_PAR_MARK; |
541 | else | 577 | else |
542 | mode |= ATMEL_US_PAR_SPACE; | 578 | mode |= ATMEL_US_PAR_SPACE; |
543 | } | 579 | } else if (termios->c_cflag & PARODD) |
544 | else if (termios->c_cflag & PARODD) | ||
545 | mode |= ATMEL_US_PAR_ODD; | 580 | mode |= ATMEL_US_PAR_ODD; |
546 | else | 581 | else |
547 | mode |= ATMEL_US_PAR_EVEN; | 582 | mode |= ATMEL_US_PAR_EVEN; |
548 | } | 583 | } else |
549 | else | ||
550 | mode |= ATMEL_US_PAR_NONE; | 584 | mode |= ATMEL_US_PAR_NONE; |
551 | 585 | ||
552 | spin_lock_irqsave(&port->lock, flags); | 586 | spin_lock_irqsave(&port->lock, flags); |
@@ -572,16 +606,16 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios * termios, | |||
572 | if (termios->c_iflag & IGNPAR) | 606 | if (termios->c_iflag & IGNPAR) |
573 | port->ignore_status_mask |= ATMEL_US_OVRE; | 607 | port->ignore_status_mask |= ATMEL_US_OVRE; |
574 | } | 608 | } |
575 | 609 | /* TODO: Ignore all characters if CREAD is set.*/ | |
576 | // TODO: Ignore all characters if CREAD is set. | ||
577 | 610 | ||
578 | /* update the per-port timeout */ | 611 | /* update the per-port timeout */ |
579 | uart_update_timeout(port, termios->c_cflag, baud); | 612 | uart_update_timeout(port, termios->c_cflag, baud); |
580 | 613 | ||
581 | /* disable interrupts and drain transmitter */ | 614 | /* save/disable interrupts and drain transmitter */ |
582 | imr = UART_GET_IMR(port); /* get interrupt mask */ | 615 | imr = UART_GET_IMR(port); |
583 | UART_PUT_IDR(port, -1); /* disable all interrupts */ | 616 | UART_PUT_IDR(port, -1); |
584 | while (!(UART_GET_CSR(port) & ATMEL_US_TXEMPTY)) { barrier(); } | 617 | while (!(UART_GET_CSR(port) & ATMEL_US_TXEMPTY)) |
618 | barrier(); | ||
585 | 619 | ||
586 | /* disable receiver and transmitter */ | 620 | /* disable receiver and transmitter */ |
587 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); | 621 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); |
@@ -707,7 +741,8 @@ static struct uart_ops atmel_pops = { | |||
707 | /* | 741 | /* |
708 | * Configure the port from the platform device resource info. | 742 | * Configure the port from the platform device resource info. |
709 | */ | 743 | */ |
710 | static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, struct platform_device *pdev) | 744 | static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, |
745 | struct platform_device *pdev) | ||
711 | { | 746 | { |
712 | struct uart_port *port = &atmel_port->uart; | 747 | struct uart_port *port = &atmel_port->uart; |
713 | struct atmel_uart_data *data = pdev->dev.platform_data; | 748 | struct atmel_uart_data *data = pdev->dev.platform_data; |
@@ -730,7 +765,8 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, struct | |||
730 | port->membase = NULL; | 765 | port->membase = NULL; |
731 | } | 766 | } |
732 | 767 | ||
733 | if (!atmel_port->clk) { /* for console, the clock could already be configured */ | 768 | /* for console, the clock could already be configured */ |
769 | if (!atmel_port->clk) { | ||
734 | atmel_port->clk = clk_get(&pdev->dev, "usart"); | 770 | atmel_port->clk = clk_get(&pdev->dev, "usart"); |
735 | clk_enable(atmel_port->clk); | 771 | clk_enable(atmel_port->clk); |
736 | port->uartclk = clk_get_rate(atmel_port->clk); | 772 | port->uartclk = clk_get_rate(atmel_port->clk); |
@@ -754,7 +790,6 @@ void __init atmel_register_uart_fns(struct atmel_port_fns *fns) | |||
754 | atmel_pops.set_wake = fns->set_wake; | 790 | atmel_pops.set_wake = fns->set_wake; |
755 | } | 791 | } |
756 | 792 | ||
757 | |||
758 | #ifdef CONFIG_SERIAL_ATMEL_CONSOLE | 793 | #ifdef CONFIG_SERIAL_ATMEL_CONSOLE |
759 | static void atmel_console_putchar(struct uart_port *port, int ch) | 794 | static void atmel_console_putchar(struct uart_port *port, int ch) |
760 | { | 795 | { |
@@ -772,28 +807,30 @@ static void atmel_console_write(struct console *co, const char *s, u_int count) | |||
772 | unsigned int status, imr; | 807 | unsigned int status, imr; |
773 | 808 | ||
774 | /* | 809 | /* |
775 | * First, save IMR and then disable interrupts | 810 | * First, save IMR and then disable interrupts |
776 | */ | 811 | */ |
777 | imr = UART_GET_IMR(port); /* get interrupt mask */ | 812 | imr = UART_GET_IMR(port); |
778 | UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY); | 813 | UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY); |
779 | 814 | ||
780 | uart_console_write(port, s, count, atmel_console_putchar); | 815 | uart_console_write(port, s, count, atmel_console_putchar); |
781 | 816 | ||
782 | /* | 817 | /* |
783 | * Finally, wait for transmitter to become empty | 818 | * Finally, wait for transmitter to become empty |
784 | * and restore IMR | 819 | * and restore IMR |
785 | */ | 820 | */ |
786 | do { | 821 | do { |
787 | status = UART_GET_CSR(port); | 822 | status = UART_GET_CSR(port); |
788 | } while (!(status & ATMEL_US_TXRDY)); | 823 | } while (!(status & ATMEL_US_TXRDY)); |
789 | UART_PUT_IER(port, imr); /* set interrupts back the way they were */ | 824 | /* set interrupts back the way they were */ |
825 | UART_PUT_IER(port, imr); | ||
790 | } | 826 | } |
791 | 827 | ||
792 | /* | 828 | /* |
793 | * If the port was already initialised (eg, by a boot loader), try to determine | 829 | * If the port was already initialised (eg, by a boot loader), |
794 | * the current setup. | 830 | * try to determine the current setup. |
795 | */ | 831 | */ |
796 | static void __init atmel_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits) | 832 | static void __init atmel_console_get_options(struct uart_port *port, int *baud, |
833 | int *parity, int *bits) | ||
797 | { | 834 | { |
798 | unsigned int mr, quot; | 835 | unsigned int mr, quot; |
799 | 836 | ||
@@ -835,10 +872,12 @@ static int __init atmel_console_setup(struct console *co, char *options) | |||
835 | int parity = 'n'; | 872 | int parity = 'n'; |
836 | int flow = 'n'; | 873 | int flow = 'n'; |
837 | 874 | ||
838 | if (port->membase == 0) /* Port not initialized yet - delay setup */ | 875 | if (port->membase == NULL) { |
876 | /* Port not initialized yet - delay setup */ | ||
839 | return -ENODEV; | 877 | return -ENODEV; |
878 | } | ||
840 | 879 | ||
841 | UART_PUT_IDR(port, -1); /* disable interrupts */ | 880 | UART_PUT_IDR(port, -1); |
842 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); | 881 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); |
843 | UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); | 882 | UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); |
844 | 883 | ||
@@ -870,13 +909,16 @@ static struct console atmel_console = { | |||
870 | static int __init atmel_console_init(void) | 909 | static int __init atmel_console_init(void) |
871 | { | 910 | { |
872 | if (atmel_default_console_device) { | 911 | if (atmel_default_console_device) { |
873 | add_preferred_console(ATMEL_DEVICENAME, atmel_default_console_device->id, NULL); | 912 | add_preferred_console(ATMEL_DEVICENAME, |
874 | atmel_init_port(&(atmel_ports[atmel_default_console_device->id]), atmel_default_console_device); | 913 | atmel_default_console_device->id, NULL); |
914 | atmel_init_port(&atmel_ports[atmel_default_console_device->id], | ||
915 | atmel_default_console_device); | ||
875 | register_console(&atmel_console); | 916 | register_console(&atmel_console); |
876 | } | 917 | } |
877 | 918 | ||
878 | return 0; | 919 | return 0; |
879 | } | 920 | } |
921 | |||
880 | console_initcall(atmel_console_init); | 922 | console_initcall(atmel_console_init); |
881 | 923 | ||
882 | /* | 924 | /* |
@@ -884,11 +926,13 @@ console_initcall(atmel_console_init); | |||
884 | */ | 926 | */ |
885 | static int __init atmel_late_console_init(void) | 927 | static int __init atmel_late_console_init(void) |
886 | { | 928 | { |
887 | if (atmel_default_console_device && !(atmel_console.flags & CON_ENABLED)) | 929 | if (atmel_default_console_device |
930 | && !(atmel_console.flags & CON_ENABLED)) | ||
888 | register_console(&atmel_console); | 931 | register_console(&atmel_console); |
889 | 932 | ||
890 | return 0; | 933 | return 0; |
891 | } | 934 | } |
935 | |||
892 | core_initcall(atmel_late_console_init); | 936 | core_initcall(atmel_late_console_init); |
893 | 937 | ||
894 | #else | 938 | #else |
@@ -896,22 +940,24 @@ core_initcall(atmel_late_console_init); | |||
896 | #endif | 940 | #endif |
897 | 941 | ||
898 | static struct uart_driver atmel_uart = { | 942 | static struct uart_driver atmel_uart = { |
899 | .owner = THIS_MODULE, | 943 | .owner = THIS_MODULE, |
900 | .driver_name = "atmel_serial", | 944 | .driver_name = "atmel_serial", |
901 | .dev_name = ATMEL_DEVICENAME, | 945 | .dev_name = ATMEL_DEVICENAME, |
902 | .major = SERIAL_ATMEL_MAJOR, | 946 | .major = SERIAL_ATMEL_MAJOR, |
903 | .minor = MINOR_START, | 947 | .minor = MINOR_START, |
904 | .nr = ATMEL_MAX_UART, | 948 | .nr = ATMEL_MAX_UART, |
905 | .cons = ATMEL_CONSOLE_DEVICE, | 949 | .cons = ATMEL_CONSOLE_DEVICE, |
906 | }; | 950 | }; |
907 | 951 | ||
908 | #ifdef CONFIG_PM | 952 | #ifdef CONFIG_PM |
909 | static int atmel_serial_suspend(struct platform_device *pdev, pm_message_t state) | 953 | static int atmel_serial_suspend(struct platform_device *pdev, |
954 | pm_message_t state) | ||
910 | { | 955 | { |
911 | struct uart_port *port = platform_get_drvdata(pdev); | 956 | struct uart_port *port = platform_get_drvdata(pdev); |
912 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; | 957 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *)port; |
913 | 958 | ||
914 | if (device_may_wakeup(&pdev->dev) && !at91_suspend_entering_slow_clock()) | 959 | if (device_may_wakeup(&pdev->dev) |
960 | && !at91_suspend_entering_slow_clock()) | ||
915 | enable_irq_wake(port->irq); | 961 | enable_irq_wake(port->irq); |
916 | else { | 962 | else { |
917 | uart_suspend_port(&atmel_uart, port); | 963 | uart_suspend_port(&atmel_uart, port); |
@@ -924,13 +970,12 @@ static int atmel_serial_suspend(struct platform_device *pdev, pm_message_t state | |||
924 | static int atmel_serial_resume(struct platform_device *pdev) | 970 | static int atmel_serial_resume(struct platform_device *pdev) |
925 | { | 971 | { |
926 | struct uart_port *port = platform_get_drvdata(pdev); | 972 | struct uart_port *port = platform_get_drvdata(pdev); |
927 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; | 973 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *)port; |
928 | 974 | ||
929 | if (atmel_port->suspended) { | 975 | if (atmel_port->suspended) { |
930 | uart_resume_port(&atmel_uart, port); | 976 | uart_resume_port(&atmel_uart, port); |
931 | atmel_port->suspended = 0; | 977 | atmel_port->suspended = 0; |
932 | } | 978 | } else |
933 | else | ||
934 | disable_irq_wake(port->irq); | 979 | disable_irq_wake(port->irq); |
935 | 980 | ||
936 | return 0; | 981 | return 0; |
@@ -960,7 +1005,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) | |||
960 | static int __devexit atmel_serial_remove(struct platform_device *pdev) | 1005 | static int __devexit atmel_serial_remove(struct platform_device *pdev) |
961 | { | 1006 | { |
962 | struct uart_port *port = platform_get_drvdata(pdev); | 1007 | struct uart_port *port = platform_get_drvdata(pdev); |
963 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; | 1008 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *)port; |
964 | int ret = 0; | 1009 | int ret = 0; |
965 | 1010 | ||
966 | clk_disable(atmel_port->clk); | 1011 | clk_disable(atmel_port->clk); |