diff options
author | Haojian Zhuang <haojian.zhuang@marvell.com> | 2012-02-29 03:09:05 -0500 |
---|---|---|
committer | Haojian Zhuang <haojian.zhuang@gmail.com> | 2012-03-06 20:30:10 -0500 |
commit | 699c20f3e6310aa2ff18610c7d0885ed54d64337 (patch) | |
tree | d1a2c136ab22e230c2e39599b8eddd8f05628961 /drivers/tty/serial/pxa.c | |
parent | 192cfd58774b4d17b2fe8bdc77d89c2ef4e0591d (diff) |
serial: pxa: add OF support
Parse uart device id from alias in DTS file.
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Diffstat (limited to 'drivers/tty/serial/pxa.c')
-rw-r--r-- | drivers/tty/serial/pxa.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 5c8e3bba6c84..cdf4b2bfad80 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/circ_buf.h> | 36 | #include <linux/circ_buf.h> |
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/of.h> | ||
39 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
40 | #include <linux/tty.h> | 41 | #include <linux/tty.h> |
41 | #include <linux/tty_flip.h> | 42 | #include <linux/tty_flip.h> |
@@ -44,6 +45,8 @@ | |||
44 | #include <linux/io.h> | 45 | #include <linux/io.h> |
45 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
46 | 47 | ||
48 | #define PXA_NAME_LEN 8 | ||
49 | |||
47 | struct uart_pxa_port { | 50 | struct uart_pxa_port { |
48 | struct uart_port port; | 51 | struct uart_port port; |
49 | unsigned char ier; | 52 | unsigned char ier; |
@@ -51,7 +54,7 @@ struct uart_pxa_port { | |||
51 | unsigned char mcr; | 54 | unsigned char mcr; |
52 | unsigned int lsr_break_flag; | 55 | unsigned int lsr_break_flag; |
53 | struct clk *clk; | 56 | struct clk *clk; |
54 | char *name; | 57 | char name[PXA_NAME_LEN]; |
55 | }; | 58 | }; |
56 | 59 | ||
57 | static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) | 60 | static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) |
@@ -781,6 +784,31 @@ static const struct dev_pm_ops serial_pxa_pm_ops = { | |||
781 | }; | 784 | }; |
782 | #endif | 785 | #endif |
783 | 786 | ||
787 | static struct of_device_id serial_pxa_dt_ids[] = { | ||
788 | { .compatible = "mrvl,pxa-uart", }, | ||
789 | { .compatible = "mrvl,mmp-uart", }, | ||
790 | {} | ||
791 | }; | ||
792 | MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); | ||
793 | |||
794 | static int serial_pxa_probe_dt(struct platform_device *pdev, | ||
795 | struct uart_pxa_port *sport) | ||
796 | { | ||
797 | struct device_node *np = pdev->dev.of_node; | ||
798 | int ret; | ||
799 | |||
800 | if (!np) | ||
801 | return 1; | ||
802 | |||
803 | ret = of_alias_get_id(np, "serial"); | ||
804 | if (ret < 0) { | ||
805 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); | ||
806 | return ret; | ||
807 | } | ||
808 | sport->port.line = ret; | ||
809 | return 0; | ||
810 | } | ||
811 | |||
784 | static int serial_pxa_probe(struct platform_device *dev) | 812 | static int serial_pxa_probe(struct platform_device *dev) |
785 | { | 813 | { |
786 | struct uart_pxa_port *sport; | 814 | struct uart_pxa_port *sport; |
@@ -808,20 +836,16 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
808 | sport->port.irq = irqres->start; | 836 | sport->port.irq = irqres->start; |
809 | sport->port.fifosize = 64; | 837 | sport->port.fifosize = 64; |
810 | sport->port.ops = &serial_pxa_pops; | 838 | sport->port.ops = &serial_pxa_pops; |
811 | sport->port.line = dev->id; | ||
812 | sport->port.dev = &dev->dev; | 839 | sport->port.dev = &dev->dev; |
813 | sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; | 840 | sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; |
814 | sport->port.uartclk = clk_get_rate(sport->clk); | 841 | sport->port.uartclk = clk_get_rate(sport->clk); |
815 | 842 | ||
816 | switch (dev->id) { | 843 | ret = serial_pxa_probe_dt(dev, sport); |
817 | case 0: sport->name = "FFUART"; break; | 844 | if (ret > 0) |
818 | case 1: sport->name = "BTUART"; break; | 845 | sport->port.line = dev->id; |
819 | case 2: sport->name = "STUART"; break; | 846 | else if (ret < 0) |
820 | case 3: sport->name = "HWUART"; break; | 847 | goto err_clk; |
821 | default: | 848 | snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1); |
822 | sport->name = "???"; | ||
823 | break; | ||
824 | } | ||
825 | 849 | ||
826 | sport->port.membase = ioremap(mmres->start, resource_size(mmres)); | 850 | sport->port.membase = ioremap(mmres->start, resource_size(mmres)); |
827 | if (!sport->port.membase) { | 851 | if (!sport->port.membase) { |
@@ -829,7 +853,7 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
829 | goto err_clk; | 853 | goto err_clk; |
830 | } | 854 | } |
831 | 855 | ||
832 | serial_pxa_ports[dev->id] = sport; | 856 | serial_pxa_ports[sport->port.line] = sport; |
833 | 857 | ||
834 | uart_add_one_port(&serial_pxa_reg, &sport->port); | 858 | uart_add_one_port(&serial_pxa_reg, &sport->port); |
835 | platform_set_drvdata(dev, sport); | 859 | platform_set_drvdata(dev, sport); |
@@ -866,6 +890,7 @@ static struct platform_driver serial_pxa_driver = { | |||
866 | #ifdef CONFIG_PM | 890 | #ifdef CONFIG_PM |
867 | .pm = &serial_pxa_pm_ops, | 891 | .pm = &serial_pxa_pm_ops, |
868 | #endif | 892 | #endif |
893 | .of_match_table = serial_pxa_dt_ids, | ||
869 | }, | 894 | }, |
870 | }; | 895 | }; |
871 | 896 | ||