diff options
Diffstat (limited to 'arch/arm/mach-omap2/serial.c')
| -rw-r--r-- | arch/arm/mach-omap2/serial.c | 218 |
1 files changed, 174 insertions, 44 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 54dfeb5d5667..3771254dfa81 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
| @@ -23,19 +23,27 @@ | |||
| 23 | #include <linux/serial_reg.h> | 23 | #include <linux/serial_reg.h> |
| 24 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
| 25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 26 | #include <linux/delay.h> | ||
| 26 | 27 | ||
| 27 | #include <mach/common.h> | 28 | #include <plat/common.h> |
| 28 | #include <mach/board.h> | 29 | #include <plat/board.h> |
| 29 | #include <mach/clock.h> | 30 | #include <plat/clock.h> |
| 30 | #include <mach/control.h> | 31 | #include <plat/control.h> |
| 31 | 32 | ||
| 32 | #include "prm.h" | 33 | #include "prm.h" |
| 33 | #include "pm.h" | 34 | #include "pm.h" |
| 34 | #include "prm-regbits-34xx.h" | 35 | #include "prm-regbits-34xx.h" |
| 35 | 36 | ||
| 37 | #define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52 | ||
| 36 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ | 38 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ |
| 37 | 39 | ||
| 38 | #define DEFAULT_TIMEOUT (5 * HZ) | 40 | /* |
| 41 | * NOTE: By default the serial timeout is disabled as it causes lost characters | ||
| 42 | * over the serial ports. This means that the UART clocks will stay on until | ||
| 43 | * disabled via sysfs. This also causes that any deeper omap sleep states are | ||
| 44 | * blocked. | ||
| 45 | */ | ||
| 46 | #define DEFAULT_TIMEOUT 0 | ||
| 39 | 47 | ||
| 40 | struct omap_uart_state { | 48 | struct omap_uart_state { |
| 41 | int num; | 49 | int num; |
| @@ -73,8 +81,6 @@ static LIST_HEAD(uart_list); | |||
| 73 | 81 | ||
| 74 | static struct plat_serial8250_port serial_platform_data0[] = { | 82 | static struct plat_serial8250_port serial_platform_data0[] = { |
| 75 | { | 83 | { |
| 76 | .membase = OMAP2_IO_ADDRESS(OMAP_UART1_BASE), | ||
| 77 | .mapbase = OMAP_UART1_BASE, | ||
| 78 | .irq = 72, | 84 | .irq = 72, |
| 79 | .flags = UPF_BOOT_AUTOCONF, | 85 | .flags = UPF_BOOT_AUTOCONF, |
| 80 | .iotype = UPIO_MEM, | 86 | .iotype = UPIO_MEM, |
| @@ -87,8 +93,6 @@ static struct plat_serial8250_port serial_platform_data0[] = { | |||
| 87 | 93 | ||
| 88 | static struct plat_serial8250_port serial_platform_data1[] = { | 94 | static struct plat_serial8250_port serial_platform_data1[] = { |
| 89 | { | 95 | { |
| 90 | .membase = OMAP2_IO_ADDRESS(OMAP_UART2_BASE), | ||
| 91 | .mapbase = OMAP_UART2_BASE, | ||
| 92 | .irq = 73, | 96 | .irq = 73, |
| 93 | .flags = UPF_BOOT_AUTOCONF, | 97 | .flags = UPF_BOOT_AUTOCONF, |
| 94 | .iotype = UPIO_MEM, | 98 | .iotype = UPIO_MEM, |
| @@ -101,8 +105,6 @@ static struct plat_serial8250_port serial_platform_data1[] = { | |||
| 101 | 105 | ||
| 102 | static struct plat_serial8250_port serial_platform_data2[] = { | 106 | static struct plat_serial8250_port serial_platform_data2[] = { |
| 103 | { | 107 | { |
| 104 | .membase = OMAP2_IO_ADDRESS(OMAP_UART3_BASE), | ||
| 105 | .mapbase = OMAP_UART3_BASE, | ||
| 106 | .irq = 74, | 108 | .irq = 74, |
| 107 | .flags = UPF_BOOT_AUTOCONF, | 109 | .flags = UPF_BOOT_AUTOCONF, |
| 108 | .iotype = UPIO_MEM, | 110 | .iotype = UPIO_MEM, |
| @@ -113,11 +115,8 @@ static struct plat_serial8250_port serial_platform_data2[] = { | |||
| 113 | } | 115 | } |
| 114 | }; | 116 | }; |
| 115 | 117 | ||
| 116 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 117 | static struct plat_serial8250_port serial_platform_data3[] = { | 118 | static struct plat_serial8250_port serial_platform_data3[] = { |
| 118 | { | 119 | { |
| 119 | .membase = OMAP2_IO_ADDRESS(OMAP_UART4_BASE), | ||
| 120 | .mapbase = OMAP_UART4_BASE, | ||
| 121 | .irq = 70, | 120 | .irq = 70, |
| 122 | .flags = UPF_BOOT_AUTOCONF, | 121 | .flags = UPF_BOOT_AUTOCONF, |
| 123 | .iotype = UPIO_MEM, | 122 | .iotype = UPIO_MEM, |
| @@ -127,7 +126,22 @@ static struct plat_serial8250_port serial_platform_data3[] = { | |||
| 127 | .flags = 0 | 126 | .flags = 0 |
| 128 | } | 127 | } |
| 129 | }; | 128 | }; |
| 130 | #endif | 129 | |
| 130 | void __init omap2_set_globals_uart(struct omap_globals *omap2_globals) | ||
| 131 | { | ||
| 132 | serial_platform_data0[0].mapbase = omap2_globals->uart1_phys; | ||
| 133 | serial_platform_data1[0].mapbase = omap2_globals->uart2_phys; | ||
| 134 | serial_platform_data2[0].mapbase = omap2_globals->uart3_phys; | ||
| 135 | serial_platform_data3[0].mapbase = omap2_globals->uart4_phys; | ||
| 136 | } | ||
| 137 | |||
| 138 | static inline unsigned int __serial_read_reg(struct uart_port *up, | ||
| 139 | int offset) | ||
| 140 | { | ||
| 141 | offset <<= up->regshift; | ||
| 142 | return (unsigned int)__raw_readb(up->membase + offset); | ||
| 143 | } | ||
| 144 | |||
| 131 | static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, | 145 | static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, |
| 132 | int offset) | 146 | int offset) |
| 133 | { | 147 | { |
| @@ -135,6 +149,13 @@ static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, | |||
| 135 | return (unsigned int)__raw_readb(up->membase + offset); | 149 | return (unsigned int)__raw_readb(up->membase + offset); |
| 136 | } | 150 | } |
| 137 | 151 | ||
| 152 | static inline void __serial_write_reg(struct uart_port *up, int offset, | ||
| 153 | int value) | ||
| 154 | { | ||
| 155 | offset <<= up->regshift; | ||
| 156 | __raw_writeb(value, up->membase + offset); | ||
| 157 | } | ||
| 158 | |||
| 138 | static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, | 159 | static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, |
| 139 | int value) | 160 | int value) |
| 140 | { | 161 | { |
| @@ -159,8 +180,6 @@ static inline void __init omap_uart_reset(struct omap_uart_state *uart) | |||
| 159 | 180 | ||
| 160 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) | 181 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) |
| 161 | 182 | ||
| 162 | static int enable_off_mode; /* to be removed by full off-mode patches */ | ||
| 163 | |||
| 164 | static void omap_uart_save_context(struct omap_uart_state *uart) | 183 | static void omap_uart_save_context(struct omap_uart_state *uart) |
| 165 | { | 184 | { |
| 166 | u16 lcr = 0; | 185 | u16 lcr = 0; |
| @@ -420,7 +439,8 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) | |||
| 420 | uart->timeout = DEFAULT_TIMEOUT; | 439 | uart->timeout = DEFAULT_TIMEOUT; |
| 421 | setup_timer(&uart->timer, omap_uart_idle_timer, | 440 | setup_timer(&uart->timer, omap_uart_idle_timer, |
| 422 | (unsigned long) uart); | 441 | (unsigned long) uart); |
| 423 | mod_timer(&uart->timer, jiffies + uart->timeout); | 442 | if (uart->timeout) |
| 443 | mod_timer(&uart->timer, jiffies + uart->timeout); | ||
| 424 | omap_uart_smart_idle_enable(uart, 0); | 444 | omap_uart_smart_idle_enable(uart, 0); |
| 425 | 445 | ||
| 426 | if (cpu_is_omap34xx()) { | 446 | if (cpu_is_omap34xx()) { |
| @@ -518,7 +538,7 @@ static ssize_t sleep_timeout_store(struct device *dev, | |||
| 518 | unsigned int value; | 538 | unsigned int value; |
| 519 | 539 | ||
| 520 | if (sscanf(buf, "%u", &value) != 1) { | 540 | if (sscanf(buf, "%u", &value) != 1) { |
| 521 | printk(KERN_ERR "sleep_timeout_store: Invalid value\n"); | 541 | dev_err(dev, "sleep_timeout_store: Invalid value\n"); |
| 522 | return -EINVAL; | 542 | return -EINVAL; |
| 523 | } | 543 | } |
| 524 | 544 | ||
| @@ -539,7 +559,7 @@ static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} | |||
| 539 | #define DEV_CREATE_FILE(dev, attr) | 559 | #define DEV_CREATE_FILE(dev, attr) |
| 540 | #endif /* CONFIG_PM */ | 560 | #endif /* CONFIG_PM */ |
| 541 | 561 | ||
| 542 | static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = { | 562 | static struct omap_uart_state omap_uart[] = { |
| 543 | { | 563 | { |
| 544 | .pdev = { | 564 | .pdev = { |
| 545 | .name = "serial8250", | 565 | .name = "serial8250", |
| @@ -565,7 +585,7 @@ static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = { | |||
| 565 | }, | 585 | }, |
| 566 | }, | 586 | }, |
| 567 | }, | 587 | }, |
| 568 | #ifdef CONFIG_ARCH_OMAP4 | 588 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) |
| 569 | { | 589 | { |
| 570 | .pdev = { | 590 | .pdev = { |
| 571 | .name = "serial8250", | 591 | .name = "serial8250", |
| @@ -578,34 +598,87 @@ static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = { | |||
| 578 | #endif | 598 | #endif |
| 579 | }; | 599 | }; |
| 580 | 600 | ||
| 601 | /* | ||
| 602 | * Override the default 8250 read handler: mem_serial_in() | ||
| 603 | * Empty RX fifo read causes an abort on omap3630 and omap4 | ||
| 604 | * This function makes sure that an empty rx fifo is not read on these silicons | ||
| 605 | * (OMAP1/2/3430 are not affected) | ||
| 606 | */ | ||
| 607 | static unsigned int serial_in_override(struct uart_port *up, int offset) | ||
| 608 | { | ||
| 609 | if (UART_RX == offset) { | ||
| 610 | unsigned int lsr; | ||
| 611 | lsr = __serial_read_reg(up, UART_LSR); | ||
| 612 | if (!(lsr & UART_LSR_DR)) | ||
| 613 | return -EPERM; | ||
| 614 | } | ||
| 615 | |||
| 616 | return __serial_read_reg(up, offset); | ||
| 617 | } | ||
| 618 | |||
| 619 | static void serial_out_override(struct uart_port *up, int offset, int value) | ||
| 620 | { | ||
| 621 | unsigned int status, tmout = 10000; | ||
| 622 | |||
| 623 | status = __serial_read_reg(up, UART_LSR); | ||
| 624 | while (!(status & UART_LSR_THRE)) { | ||
| 625 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
| 626 | if (--tmout == 0) | ||
| 627 | break; | ||
| 628 | udelay(1); | ||
| 629 | status = __serial_read_reg(up, UART_LSR); | ||
| 630 | } | ||
| 631 | __serial_write_reg(up, offset, value); | ||
| 632 | } | ||
| 581 | void __init omap_serial_early_init(void) | 633 | void __init omap_serial_early_init(void) |
| 582 | { | 634 | { |
| 583 | int i; | 635 | int i, nr_ports; |
| 584 | char name[16]; | 636 | char name[16]; |
| 585 | 637 | ||
| 638 | if (!(cpu_is_omap3630() || cpu_is_omap4430())) | ||
| 639 | nr_ports = 3; | ||
| 640 | else | ||
| 641 | nr_ports = ARRAY_SIZE(omap_uart); | ||
| 642 | |||
| 586 | /* | 643 | /* |
| 587 | * Make sure the serial ports are muxed on at this point. | 644 | * Make sure the serial ports are muxed on at this point. |
| 588 | * You have to mux them off in device drivers later on | 645 | * You have to mux them off in device drivers later on |
| 589 | * if not needed. | 646 | * if not needed. |
| 590 | */ | 647 | */ |
| 591 | 648 | ||
| 592 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { | 649 | for (i = 0; i < nr_ports; i++) { |
| 593 | struct omap_uart_state *uart = &omap_uart[i]; | 650 | struct omap_uart_state *uart = &omap_uart[i]; |
| 594 | struct platform_device *pdev = &uart->pdev; | 651 | struct platform_device *pdev = &uart->pdev; |
| 595 | struct device *dev = &pdev->dev; | 652 | struct device *dev = &pdev->dev; |
| 596 | struct plat_serial8250_port *p = dev->platform_data; | 653 | struct plat_serial8250_port *p = dev->platform_data; |
| 597 | 654 | ||
| 598 | sprintf(name, "uart%d_ick", i+1); | 655 | /* Don't map zero-based physical address */ |
| 656 | if (p->mapbase == 0) { | ||
| 657 | dev_warn(dev, "no physical address for uart#%d," | ||
| 658 | " so skipping early_init...\n", i); | ||
| 659 | continue; | ||
| 660 | } | ||
| 661 | /* | ||
| 662 | * Module 4KB + L4 interconnect 4KB | ||
| 663 | * Static mapping, never released | ||
| 664 | */ | ||
| 665 | p->membase = ioremap(p->mapbase, SZ_8K); | ||
| 666 | if (!p->membase) { | ||
| 667 | dev_err(dev, "ioremap failed for uart%i\n", i + 1); | ||
| 668 | continue; | ||
| 669 | } | ||
| 670 | |||
| 671 | sprintf(name, "uart%d_ick", i + 1); | ||
| 599 | uart->ick = clk_get(NULL, name); | 672 | uart->ick = clk_get(NULL, name); |
| 600 | if (IS_ERR(uart->ick)) { | 673 | if (IS_ERR(uart->ick)) { |
| 601 | printk(KERN_ERR "Could not get uart%d_ick\n", i+1); | 674 | dev_err(dev, "Could not get uart%d_ick\n", i + 1); |
| 602 | uart->ick = NULL; | 675 | uart->ick = NULL; |
| 603 | } | 676 | } |
| 604 | 677 | ||
| 605 | sprintf(name, "uart%d_fck", i+1); | 678 | sprintf(name, "uart%d_fck", i+1); |
| 606 | uart->fck = clk_get(NULL, name); | 679 | uart->fck = clk_get(NULL, name); |
| 607 | if (IS_ERR(uart->fck)) { | 680 | if (IS_ERR(uart->fck)) { |
| 608 | printk(KERN_ERR "Could not get uart%d_fck\n", i+1); | 681 | dev_err(dev, "Could not get uart%d_fck\n", i + 1); |
| 609 | uart->fck = NULL; | 682 | uart->fck = NULL; |
| 610 | } | 683 | } |
| 611 | 684 | ||
| @@ -618,33 +691,90 @@ void __init omap_serial_early_init(void) | |||
| 618 | uart->num = i; | 691 | uart->num = i; |
| 619 | p->private_data = uart; | 692 | p->private_data = uart; |
| 620 | uart->p = p; | 693 | uart->p = p; |
| 621 | list_add_tail(&uart->node, &uart_list); | ||
| 622 | 694 | ||
| 623 | if (cpu_is_omap44xx()) | 695 | if (cpu_is_omap44xx()) |
| 624 | p->irq += 32; | 696 | p->irq += 32; |
| 625 | |||
| 626 | omap_uart_enable_clocks(uart); | ||
| 627 | } | 697 | } |
| 628 | } | 698 | } |
| 629 | 699 | ||
| 630 | void __init omap_serial_init(void) | 700 | /** |
| 701 | * omap_serial_init_port() - initialize single serial port | ||
| 702 | * @port: serial port number (0-3) | ||
| 703 | * | ||
| 704 | * This function initialies serial driver for given @port only. | ||
| 705 | * Platforms can call this function instead of omap_serial_init() | ||
| 706 | * if they don't plan to use all available UARTs as serial ports. | ||
| 707 | * | ||
| 708 | * Don't mix calls to omap_serial_init_port() and omap_serial_init(), | ||
| 709 | * use only one of the two. | ||
| 710 | */ | ||
| 711 | void __init omap_serial_init_port(int port) | ||
| 631 | { | 712 | { |
| 632 | int i; | 713 | struct omap_uart_state *uart; |
| 714 | struct platform_device *pdev; | ||
| 715 | struct device *dev; | ||
| 633 | 716 | ||
| 634 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { | 717 | BUG_ON(port < 0); |
| 635 | struct omap_uart_state *uart = &omap_uart[i]; | 718 | BUG_ON(port >= ARRAY_SIZE(omap_uart)); |
| 636 | struct platform_device *pdev = &uart->pdev; | ||
| 637 | struct device *dev = &pdev->dev; | ||
| 638 | 719 | ||
| 639 | omap_uart_reset(uart); | 720 | uart = &omap_uart[port]; |
| 640 | omap_uart_idle_init(uart); | 721 | pdev = &uart->pdev; |
| 722 | dev = &pdev->dev; | ||
| 641 | 723 | ||
| 642 | if (WARN_ON(platform_device_register(pdev))) | 724 | /* Don't proceed if there's no clocks available */ |
| 643 | continue; | 725 | if (unlikely(!uart->ick || !uart->fck)) { |
| 644 | if ((cpu_is_omap34xx() && uart->padconf) || | 726 | WARN(1, "%s: can't init uart%d, no clocks available\n", |
| 645 | (uart->wk_en && uart->wk_mask)) { | 727 | kobject_name(&dev->kobj), port); |
| 646 | device_init_wakeup(dev, true); | 728 | return; |
| 647 | DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout); | ||
| 648 | } | ||
| 649 | } | 729 | } |
| 730 | |||
| 731 | omap_uart_enable_clocks(uart); | ||
| 732 | |||
| 733 | omap_uart_reset(uart); | ||
| 734 | omap_uart_idle_init(uart); | ||
| 735 | |||
| 736 | list_add_tail(&uart->node, &uart_list); | ||
| 737 | |||
| 738 | if (WARN_ON(platform_device_register(pdev))) | ||
| 739 | return; | ||
| 740 | |||
| 741 | if ((cpu_is_omap34xx() && uart->padconf) || | ||
| 742 | (uart->wk_en && uart->wk_mask)) { | ||
| 743 | device_init_wakeup(dev, true); | ||
| 744 | DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout); | ||
| 745 | } | ||
| 746 | |||
| 747 | /* | ||
| 748 | * omap44xx: Never read empty UART fifo | ||
| 749 | * omap3xxx: Never read empty UART fifo on UARTs | ||
| 750 | * with IP rev >=0x52 | ||
| 751 | */ | ||
| 752 | if (cpu_is_omap44xx()) { | ||
| 753 | uart->p->serial_in = serial_in_override; | ||
| 754 | uart->p->serial_out = serial_out_override; | ||
| 755 | } else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF) | ||
| 756 | >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) { | ||
| 757 | uart->p->serial_in = serial_in_override; | ||
| 758 | uart->p->serial_out = serial_out_override; | ||
| 759 | } | ||
| 760 | } | ||
| 761 | |||
| 762 | /** | ||
| 763 | * omap_serial_init() - intialize all supported serial ports | ||
| 764 | * | ||
| 765 | * Initializes all available UARTs as serial ports. Platforms | ||
| 766 | * can call this function when they want to have default behaviour | ||
| 767 | * for serial ports (e.g initialize them all as serial ports). | ||
| 768 | */ | ||
| 769 | void __init omap_serial_init(void) | ||
| 770 | { | ||
| 771 | int i, nr_ports; | ||
| 772 | |||
| 773 | if (!(cpu_is_omap3630() || cpu_is_omap4430())) | ||
| 774 | nr_ports = 3; | ||
| 775 | else | ||
| 776 | nr_ports = ARRAY_SIZE(omap_uart); | ||
| 777 | |||
| 778 | for (i = 0; i < nr_ports; i++) | ||
| 779 | omap_serial_init_port(i); | ||
| 650 | } | 780 | } |
