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 | } |