diff options
Diffstat (limited to 'drivers/serial/amba-pl011.c')
-rw-r--r-- | drivers/serial/amba-pl011.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 8b2b9700f3e4..bf82e28770a9 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -70,6 +70,23 @@ struct uart_amba_port { | |||
70 | struct clk *clk; | 70 | struct clk *clk; |
71 | unsigned int im; /* interrupt mask */ | 71 | unsigned int im; /* interrupt mask */ |
72 | unsigned int old_status; | 72 | unsigned int old_status; |
73 | unsigned int ifls; /* vendor-specific */ | ||
74 | }; | ||
75 | |||
76 | /* There is by now at least one vendor with differing details, so handle it */ | ||
77 | struct vendor_data { | ||
78 | unsigned int ifls; | ||
79 | unsigned int fifosize; | ||
80 | }; | ||
81 | |||
82 | static struct vendor_data vendor_arm = { | ||
83 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, | ||
84 | .fifosize = 16, | ||
85 | }; | ||
86 | |||
87 | static struct vendor_data vendor_st = { | ||
88 | .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, | ||
89 | .fifosize = 64, | ||
73 | }; | 90 | }; |
74 | 91 | ||
75 | static void pl011_stop_tx(struct uart_port *port) | 92 | static void pl011_stop_tx(struct uart_port *port) |
@@ -360,8 +377,7 @@ static int pl011_startup(struct uart_port *port) | |||
360 | if (retval) | 377 | if (retval) |
361 | goto clk_dis; | 378 | goto clk_dis; |
362 | 379 | ||
363 | writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, | 380 | writew(uap->ifls, uap->port.membase + UART011_IFLS); |
364 | uap->port.membase + UART011_IFLS); | ||
365 | 381 | ||
366 | /* | 382 | /* |
367 | * Provoke TX FIFO interrupt into asserting. | 383 | * Provoke TX FIFO interrupt into asserting. |
@@ -729,9 +745,10 @@ static struct uart_driver amba_reg = { | |||
729 | .cons = AMBA_CONSOLE, | 745 | .cons = AMBA_CONSOLE, |
730 | }; | 746 | }; |
731 | 747 | ||
732 | static int pl011_probe(struct amba_device *dev, void *id) | 748 | static int pl011_probe(struct amba_device *dev, struct amba_id *id) |
733 | { | 749 | { |
734 | struct uart_amba_port *uap; | 750 | struct uart_amba_port *uap; |
751 | struct vendor_data *vendor = id->data; | ||
735 | void __iomem *base; | 752 | void __iomem *base; |
736 | int i, ret; | 753 | int i, ret; |
737 | 754 | ||
@@ -750,7 +767,7 @@ static int pl011_probe(struct amba_device *dev, void *id) | |||
750 | goto out; | 767 | goto out; |
751 | } | 768 | } |
752 | 769 | ||
753 | base = ioremap(dev->res.start, PAGE_SIZE); | 770 | base = ioremap(dev->res.start, resource_size(&dev->res)); |
754 | if (!base) { | 771 | if (!base) { |
755 | ret = -ENOMEM; | 772 | ret = -ENOMEM; |
756 | goto free; | 773 | goto free; |
@@ -762,12 +779,13 @@ static int pl011_probe(struct amba_device *dev, void *id) | |||
762 | goto unmap; | 779 | goto unmap; |
763 | } | 780 | } |
764 | 781 | ||
782 | uap->ifls = vendor->ifls; | ||
765 | uap->port.dev = &dev->dev; | 783 | uap->port.dev = &dev->dev; |
766 | uap->port.mapbase = dev->res.start; | 784 | uap->port.mapbase = dev->res.start; |
767 | uap->port.membase = base; | 785 | uap->port.membase = base; |
768 | uap->port.iotype = UPIO_MEM; | 786 | uap->port.iotype = UPIO_MEM; |
769 | uap->port.irq = dev->irq[0]; | 787 | uap->port.irq = dev->irq[0]; |
770 | uap->port.fifosize = 16; | 788 | uap->port.fifosize = vendor->fifosize; |
771 | uap->port.ops = &amba_pl011_pops; | 789 | uap->port.ops = &amba_pl011_pops; |
772 | uap->port.flags = UPF_BOOT_AUTOCONF; | 790 | uap->port.flags = UPF_BOOT_AUTOCONF; |
773 | uap->port.line = i; | 791 | uap->port.line = i; |
@@ -812,6 +830,12 @@ static struct amba_id pl011_ids[] __initdata = { | |||
812 | { | 830 | { |
813 | .id = 0x00041011, | 831 | .id = 0x00041011, |
814 | .mask = 0x000fffff, | 832 | .mask = 0x000fffff, |
833 | .data = &vendor_arm, | ||
834 | }, | ||
835 | { | ||
836 | .id = 0x00380802, | ||
837 | .mask = 0x00ffffff, | ||
838 | .data = &vendor_st, | ||
815 | }, | 839 | }, |
816 | { 0, 0 }, | 840 | { 0, 0 }, |
817 | }; | 841 | }; |
@@ -845,7 +869,11 @@ static void __exit pl011_exit(void) | |||
845 | uart_unregister_driver(&amba_reg); | 869 | uart_unregister_driver(&amba_reg); |
846 | } | 870 | } |
847 | 871 | ||
848 | module_init(pl011_init); | 872 | /* |
873 | * While this can be a module, if builtin it's most likely the console | ||
874 | * So let's leave module_exit but move module_init to an earlier place | ||
875 | */ | ||
876 | arch_initcall(pl011_init); | ||
849 | module_exit(pl011_exit); | 877 | module_exit(pl011_exit); |
850 | 878 | ||
851 | MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd"); | 879 | MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd"); |