diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2010-08-03 22:56:17 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2010-08-03 22:56:17 -0400 |
| commit | 701ec7a7b04a62c74ab1b83b59a3fd35c0ba5fdb (patch) | |
| tree | c07aa954f48ec45c422641052d46008697a4a6b1 /drivers/serial | |
| parent | 285eba57db7bd7d7c3c5929fb8621fdcaaea1b00 (diff) | |
| parent | 3a09b1be53d23df780a0cd0e4087a05e2ca4a00c (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
arch/arm/configs/ap4evb_defconfig
arch/arm/configs/g3evm_defconfig
arch/arm/configs/g4evm_defconfig
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/serial')
| -rw-r--r-- | drivers/serial/amba-pl010.c | 2 | ||||
| -rw-r--r-- | drivers/serial/amba-pl011.c | 90 | ||||
| -rw-r--r-- | drivers/serial/atmel_serial.c | 1 | ||||
| -rw-r--r-- | drivers/serial/suncore.c | 4 | ||||
| -rw-r--r-- | drivers/serial/sunsu.c | 13 |
5 files changed, 90 insertions, 20 deletions
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index b09a638d051f..50441ffe8e38 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
| @@ -782,7 +782,7 @@ static int pl010_resume(struct amba_device *dev) | |||
| 782 | return 0; | 782 | return 0; |
| 783 | } | 783 | } |
| 784 | 784 | ||
| 785 | static struct amba_id pl010_ids[] __initdata = { | 785 | static struct amba_id pl010_ids[] = { |
| 786 | { | 786 | { |
| 787 | .id = 0x00041010, | 787 | .id = 0x00041010, |
| 788 | .mask = 0x000fffff, | 788 | .mask = 0x000fffff, |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index eb4cb480b93e..6ca7a44f29c2 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
| @@ -69,9 +69,12 @@ | |||
| 69 | struct uart_amba_port { | 69 | struct uart_amba_port { |
| 70 | struct uart_port port; | 70 | struct uart_port port; |
| 71 | struct clk *clk; | 71 | struct clk *clk; |
| 72 | unsigned int im; /* interrupt mask */ | 72 | unsigned int im; /* interrupt mask */ |
| 73 | unsigned int old_status; | 73 | unsigned int old_status; |
| 74 | unsigned int ifls; /* vendor-specific */ | 74 | unsigned int ifls; /* vendor-specific */ |
| 75 | unsigned int lcrh_tx; /* vendor-specific */ | ||
| 76 | unsigned int lcrh_rx; /* vendor-specific */ | ||
| 77 | bool oversampling; /* vendor-specific */ | ||
| 75 | bool autorts; | 78 | bool autorts; |
| 76 | }; | 79 | }; |
| 77 | 80 | ||
| @@ -79,16 +82,25 @@ struct uart_amba_port { | |||
| 79 | struct vendor_data { | 82 | struct vendor_data { |
| 80 | unsigned int ifls; | 83 | unsigned int ifls; |
| 81 | unsigned int fifosize; | 84 | unsigned int fifosize; |
| 85 | unsigned int lcrh_tx; | ||
| 86 | unsigned int lcrh_rx; | ||
| 87 | bool oversampling; | ||
| 82 | }; | 88 | }; |
| 83 | 89 | ||
| 84 | static struct vendor_data vendor_arm = { | 90 | static struct vendor_data vendor_arm = { |
| 85 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, | 91 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, |
| 86 | .fifosize = 16, | 92 | .fifosize = 16, |
| 93 | .lcrh_tx = UART011_LCRH, | ||
| 94 | .lcrh_rx = UART011_LCRH, | ||
| 95 | .oversampling = false, | ||
| 87 | }; | 96 | }; |
| 88 | 97 | ||
| 89 | static struct vendor_data vendor_st = { | 98 | static struct vendor_data vendor_st = { |
| 90 | .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, | 99 | .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, |
| 91 | .fifosize = 64, | 100 | .fifosize = 64, |
| 101 | .lcrh_tx = ST_UART011_LCRH_TX, | ||
| 102 | .lcrh_rx = ST_UART011_LCRH_RX, | ||
| 103 | .oversampling = true, | ||
| 92 | }; | 104 | }; |
| 93 | 105 | ||
| 94 | static void pl011_stop_tx(struct uart_port *port) | 106 | static void pl011_stop_tx(struct uart_port *port) |
| @@ -327,12 +339,12 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) | |||
| 327 | unsigned int lcr_h; | 339 | unsigned int lcr_h; |
| 328 | 340 | ||
| 329 | spin_lock_irqsave(&uap->port.lock, flags); | 341 | spin_lock_irqsave(&uap->port.lock, flags); |
| 330 | lcr_h = readw(uap->port.membase + UART011_LCRH); | 342 | lcr_h = readw(uap->port.membase + uap->lcrh_tx); |
| 331 | if (break_state == -1) | 343 | if (break_state == -1) |
| 332 | lcr_h |= UART01x_LCRH_BRK; | 344 | lcr_h |= UART01x_LCRH_BRK; |
| 333 | else | 345 | else |
| 334 | lcr_h &= ~UART01x_LCRH_BRK; | 346 | lcr_h &= ~UART01x_LCRH_BRK; |
| 335 | writew(lcr_h, uap->port.membase + UART011_LCRH); | 347 | writew(lcr_h, uap->port.membase + uap->lcrh_tx); |
| 336 | spin_unlock_irqrestore(&uap->port.lock, flags); | 348 | spin_unlock_irqrestore(&uap->port.lock, flags); |
| 337 | } | 349 | } |
| 338 | 350 | ||
| @@ -393,7 +405,17 @@ static int pl011_startup(struct uart_port *port) | |||
| 393 | writew(cr, uap->port.membase + UART011_CR); | 405 | writew(cr, uap->port.membase + UART011_CR); |
| 394 | writew(0, uap->port.membase + UART011_FBRD); | 406 | writew(0, uap->port.membase + UART011_FBRD); |
| 395 | writew(1, uap->port.membase + UART011_IBRD); | 407 | writew(1, uap->port.membase + UART011_IBRD); |
| 396 | writew(0, uap->port.membase + UART011_LCRH); | 408 | writew(0, uap->port.membase + uap->lcrh_rx); |
| 409 | if (uap->lcrh_tx != uap->lcrh_rx) { | ||
| 410 | int i; | ||
| 411 | /* | ||
| 412 | * Wait 10 PCLKs before writing LCRH_TX register, | ||
| 413 | * to get this delay write read only register 10 times | ||
| 414 | */ | ||
| 415 | for (i = 0; i < 10; ++i) | ||
| 416 | writew(0xff, uap->port.membase + UART011_MIS); | ||
| 417 | writew(0, uap->port.membase + uap->lcrh_tx); | ||
| 418 | } | ||
| 397 | writew(0, uap->port.membase + UART01x_DR); | 419 | writew(0, uap->port.membase + UART01x_DR); |
| 398 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) | 420 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) |
| 399 | barrier(); | 421 | barrier(); |
| @@ -422,10 +444,19 @@ static int pl011_startup(struct uart_port *port) | |||
| 422 | return retval; | 444 | return retval; |
| 423 | } | 445 | } |
| 424 | 446 | ||
| 447 | static void pl011_shutdown_channel(struct uart_amba_port *uap, | ||
| 448 | unsigned int lcrh) | ||
| 449 | { | ||
| 450 | unsigned long val; | ||
| 451 | |||
| 452 | val = readw(uap->port.membase + lcrh); | ||
| 453 | val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN); | ||
| 454 | writew(val, uap->port.membase + lcrh); | ||
| 455 | } | ||
| 456 | |||
| 425 | static void pl011_shutdown(struct uart_port *port) | 457 | static void pl011_shutdown(struct uart_port *port) |
| 426 | { | 458 | { |
| 427 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 459 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 428 | unsigned long val; | ||
| 429 | 460 | ||
| 430 | /* | 461 | /* |
| 431 | * disable all interrupts | 462 | * disable all interrupts |
| @@ -450,9 +481,9 @@ static void pl011_shutdown(struct uart_port *port) | |||
| 450 | /* | 481 | /* |
| 451 | * disable break condition and fifos | 482 | * disable break condition and fifos |
| 452 | */ | 483 | */ |
| 453 | val = readw(uap->port.membase + UART011_LCRH); | 484 | pl011_shutdown_channel(uap, uap->lcrh_rx); |
| 454 | val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN); | 485 | if (uap->lcrh_rx != uap->lcrh_tx) |
| 455 | writew(val, uap->port.membase + UART011_LCRH); | 486 | pl011_shutdown_channel(uap, uap->lcrh_tx); |
| 456 | 487 | ||
| 457 | /* | 488 | /* |
| 458 | * Shut down the clock producer | 489 | * Shut down the clock producer |
| @@ -472,8 +503,13 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 472 | /* | 503 | /* |
| 473 | * Ask the core to calculate the divisor for us. | 504 | * Ask the core to calculate the divisor for us. |
| 474 | */ | 505 | */ |
| 475 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 506 | baud = uart_get_baud_rate(port, termios, old, 0, |
| 476 | quot = port->uartclk * 4 / baud; | 507 | port->uartclk/(uap->oversampling ? 8 : 16)); |
| 508 | |||
| 509 | if (baud > port->uartclk/16) | ||
| 510 | quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud); | ||
| 511 | else | ||
| 512 | quot = DIV_ROUND_CLOSEST(port->uartclk * 4, baud); | ||
| 477 | 513 | ||
| 478 | switch (termios->c_cflag & CSIZE) { | 514 | switch (termios->c_cflag & CSIZE) { |
| 479 | case CS5: | 515 | case CS5: |
| @@ -552,6 +588,13 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 552 | uap->autorts = false; | 588 | uap->autorts = false; |
| 553 | } | 589 | } |
| 554 | 590 | ||
| 591 | if (uap->oversampling) { | ||
| 592 | if (baud > port->uartclk/16) | ||
| 593 | old_cr |= ST_UART011_CR_OVSFACT; | ||
| 594 | else | ||
| 595 | old_cr &= ~ST_UART011_CR_OVSFACT; | ||
| 596 | } | ||
| 597 | |||
| 555 | /* Set baud rate */ | 598 | /* Set baud rate */ |
| 556 | writew(quot & 0x3f, port->membase + UART011_FBRD); | 599 | writew(quot & 0x3f, port->membase + UART011_FBRD); |
| 557 | writew(quot >> 6, port->membase + UART011_IBRD); | 600 | writew(quot >> 6, port->membase + UART011_IBRD); |
| @@ -561,7 +604,17 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 561 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L | 604 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L |
| 562 | * ----------^----------^----------^----------^----- | 605 | * ----------^----------^----------^----------^----- |
| 563 | */ | 606 | */ |
| 564 | writew(lcr_h, port->membase + UART011_LCRH); | 607 | writew(lcr_h, port->membase + uap->lcrh_rx); |
| 608 | if (uap->lcrh_rx != uap->lcrh_tx) { | ||
| 609 | int i; | ||
| 610 | /* | ||
| 611 | * Wait 10 PCLKs before writing LCRH_TX register, | ||
| 612 | * to get this delay write read only register 10 times | ||
| 613 | */ | ||
| 614 | for (i = 0; i < 10; ++i) | ||
| 615 | writew(0xff, uap->port.membase + UART011_MIS); | ||
| 616 | writew(lcr_h, port->membase + uap->lcrh_tx); | ||
| 617 | } | ||
| 565 | writew(old_cr, port->membase + UART011_CR); | 618 | writew(old_cr, port->membase + UART011_CR); |
| 566 | 619 | ||
| 567 | spin_unlock_irqrestore(&port->lock, flags); | 620 | spin_unlock_irqrestore(&port->lock, flags); |
| @@ -688,7 +741,7 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud, | |||
| 688 | if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) { | 741 | if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) { |
| 689 | unsigned int lcr_h, ibrd, fbrd; | 742 | unsigned int lcr_h, ibrd, fbrd; |
| 690 | 743 | ||
| 691 | lcr_h = readw(uap->port.membase + UART011_LCRH); | 744 | lcr_h = readw(uap->port.membase + uap->lcrh_tx); |
| 692 | 745 | ||
| 693 | *parity = 'n'; | 746 | *parity = 'n'; |
| 694 | if (lcr_h & UART01x_LCRH_PEN) { | 747 | if (lcr_h & UART01x_LCRH_PEN) { |
| @@ -707,6 +760,12 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud, | |||
| 707 | fbrd = readw(uap->port.membase + UART011_FBRD); | 760 | fbrd = readw(uap->port.membase + UART011_FBRD); |
| 708 | 761 | ||
| 709 | *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); | 762 | *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); |
| 763 | |||
| 764 | if (uap->oversampling) { | ||
| 765 | if (readw(uap->port.membase + UART011_CR) | ||
| 766 | & ST_UART011_CR_OVSFACT) | ||
| 767 | *baud *= 2; | ||
| 768 | } | ||
| 710 | } | 769 | } |
| 711 | } | 770 | } |
| 712 | 771 | ||
| @@ -800,6 +859,9 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id) | |||
| 800 | } | 859 | } |
| 801 | 860 | ||
| 802 | uap->ifls = vendor->ifls; | 861 | uap->ifls = vendor->ifls; |
| 862 | uap->lcrh_rx = vendor->lcrh_rx; | ||
| 863 | uap->lcrh_tx = vendor->lcrh_tx; | ||
| 864 | uap->oversampling = vendor->oversampling; | ||
| 803 | uap->port.dev = &dev->dev; | 865 | uap->port.dev = &dev->dev; |
| 804 | uap->port.mapbase = dev->res.start; | 866 | uap->port.mapbase = dev->res.start; |
| 805 | uap->port.membase = base; | 867 | uap->port.membase = base; |
| @@ -868,7 +930,7 @@ static int pl011_resume(struct amba_device *dev) | |||
| 868 | } | 930 | } |
| 869 | #endif | 931 | #endif |
| 870 | 932 | ||
| 871 | static struct amba_id pl011_ids[] __initdata = { | 933 | static struct amba_id pl011_ids[] = { |
| 872 | { | 934 | { |
| 873 | .id = 0x00041011, | 935 | .id = 0x00041011, |
| 874 | .mask = 0x000fffff, | 936 | .mask = 0x000fffff, |
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index eed3c2d8dd1c..a182def7007d 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/uaccess.h> | 41 | #include <linux/uaccess.h> |
| 42 | 42 | ||
| 43 | #include <asm/io.h> | 43 | #include <asm/io.h> |
| 44 | #include <asm/ioctls.h> | ||
| 44 | 45 | ||
| 45 | #include <asm/mach/serial_at91.h> | 46 | #include <asm/mach/serial_at91.h> |
| 46 | #include <mach/board.h> | 47 | #include <mach/board.h> |
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index ed7d958b0a01..544f2e25d0e5 100644 --- a/drivers/serial/suncore.c +++ b/drivers/serial/suncore.c | |||
| @@ -71,7 +71,9 @@ int sunserial_console_match(struct console *con, struct device_node *dp, | |||
| 71 | 71 | ||
| 72 | con->index = line; | 72 | con->index = line; |
| 73 | drv->cons = con; | 73 | drv->cons = con; |
| 74 | add_preferred_console(con->name, line, NULL); | 74 | |
| 75 | if (!console_set_on_cmdline) | ||
| 76 | add_preferred_console(con->name, line, NULL); | ||
| 75 | 77 | ||
| 76 | return 1; | 78 | return 1; |
| 77 | } | 79 | } |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 234459c2f012..ffbf4553f665 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
| @@ -1500,20 +1500,25 @@ out_unmap: | |||
| 1500 | static int __devexit su_remove(struct of_device *op) | 1500 | static int __devexit su_remove(struct of_device *op) |
| 1501 | { | 1501 | { |
| 1502 | struct uart_sunsu_port *up = dev_get_drvdata(&op->dev); | 1502 | struct uart_sunsu_port *up = dev_get_drvdata(&op->dev); |
| 1503 | bool kbdms = false; | ||
| 1503 | 1504 | ||
| 1504 | if (up->su_type == SU_PORT_MS || | 1505 | if (up->su_type == SU_PORT_MS || |
| 1505 | up->su_type == SU_PORT_KBD) { | 1506 | up->su_type == SU_PORT_KBD) |
| 1507 | kbdms = true; | ||
| 1508 | |||
| 1509 | if (kbdms) { | ||
| 1506 | #ifdef CONFIG_SERIO | 1510 | #ifdef CONFIG_SERIO |
| 1507 | serio_unregister_port(&up->serio); | 1511 | serio_unregister_port(&up->serio); |
| 1508 | #endif | 1512 | #endif |
| 1509 | kfree(up); | 1513 | } else if (up->port.type != PORT_UNKNOWN) |
| 1510 | } else if (up->port.type != PORT_UNKNOWN) { | ||
| 1511 | uart_remove_one_port(&sunsu_reg, &up->port); | 1514 | uart_remove_one_port(&sunsu_reg, &up->port); |
| 1512 | } | ||
| 1513 | 1515 | ||
| 1514 | if (up->port.membase) | 1516 | if (up->port.membase) |
| 1515 | of_iounmap(&op->resource[0], up->port.membase, up->reg_size); | 1517 | of_iounmap(&op->resource[0], up->port.membase, up->reg_size); |
| 1516 | 1518 | ||
| 1519 | if (kbdms) | ||
| 1520 | kfree(up); | ||
| 1521 | |||
| 1517 | dev_set_drvdata(&op->dev, NULL); | 1522 | dev_set_drvdata(&op->dev, NULL); |
| 1518 | 1523 | ||
| 1519 | return 0; | 1524 | return 0; |
