diff options
Diffstat (limited to 'drivers/serial/imx.c')
-rw-r--r-- | drivers/serial/imx.c | 129 |
1 files changed, 54 insertions, 75 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 77968432b81e..8d6cb745bd93 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -176,6 +176,8 @@ | |||
176 | 176 | ||
177 | #define DRIVER_NAME "IMX-uart" | 177 | #define DRIVER_NAME "IMX-uart" |
178 | 178 | ||
179 | #define UART_NR 8 | ||
180 | |||
179 | struct imx_port { | 181 | struct imx_port { |
180 | struct uart_port port; | 182 | struct uart_port port; |
181 | struct timer_list timer; | 183 | struct timer_list timer; |
@@ -829,65 +831,7 @@ static struct uart_ops imx_pops = { | |||
829 | .verify_port = imx_verify_port, | 831 | .verify_port = imx_verify_port, |
830 | }; | 832 | }; |
831 | 833 | ||
832 | static struct imx_port imx_ports[] = { | 834 | static struct imx_port *imx_ports[UART_NR]; |
833 | { | ||
834 | .txirq = UART1_MINT_TX, | ||
835 | .rxirq = UART1_MINT_RX, | ||
836 | .rtsirq = UART1_MINT_RTS, | ||
837 | .port = { | ||
838 | .type = PORT_IMX, | ||
839 | .iotype = UPIO_MEM, | ||
840 | .membase = (void *)IMX_UART1_BASE, | ||
841 | .mapbase = 0x00206000, | ||
842 | .irq = UART1_MINT_RX, | ||
843 | .fifosize = 32, | ||
844 | .flags = UPF_BOOT_AUTOCONF, | ||
845 | .ops = &imx_pops, | ||
846 | .line = 0, | ||
847 | }, | ||
848 | }, { | ||
849 | .txirq = UART2_MINT_TX, | ||
850 | .rxirq = UART2_MINT_RX, | ||
851 | .rtsirq = UART2_MINT_RTS, | ||
852 | .port = { | ||
853 | .type = PORT_IMX, | ||
854 | .iotype = UPIO_MEM, | ||
855 | .membase = (void *)IMX_UART2_BASE, | ||
856 | .mapbase = 0x00207000, | ||
857 | .irq = UART2_MINT_RX, | ||
858 | .fifosize = 32, | ||
859 | .flags = UPF_BOOT_AUTOCONF, | ||
860 | .ops = &imx_pops, | ||
861 | .line = 1, | ||
862 | }, | ||
863 | } | ||
864 | }; | ||
865 | |||
866 | /* | ||
867 | * Setup the IMX serial ports. | ||
868 | * Note also that we support "console=ttySMXx" where "x" is either 0 or 1. | ||
869 | * Which serial port this ends up being depends on the machine you're | ||
870 | * running this kernel on. I'm not convinced that this is a good idea, | ||
871 | * but that's the way it traditionally works. | ||
872 | * | ||
873 | */ | ||
874 | static void __init imx_init_ports(void) | ||
875 | { | ||
876 | static int first = 1; | ||
877 | int i; | ||
878 | |||
879 | if (!first) | ||
880 | return; | ||
881 | first = 0; | ||
882 | |||
883 | for (i = 0; i < ARRAY_SIZE(imx_ports); i++) { | ||
884 | init_timer(&imx_ports[i].timer); | ||
885 | imx_ports[i].timer.function = imx_timeout; | ||
886 | imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; | ||
887 | |||
888 | imx_ports[i].port.uartclk = imx_get_perclk1(); | ||
889 | } | ||
890 | } | ||
891 | 835 | ||
892 | #ifdef CONFIG_SERIAL_IMX_CONSOLE | 836 | #ifdef CONFIG_SERIAL_IMX_CONSOLE |
893 | static void imx_console_putchar(struct uart_port *port, int ch) | 837 | static void imx_console_putchar(struct uart_port *port, int ch) |
@@ -906,7 +850,7 @@ static void imx_console_putchar(struct uart_port *port, int ch) | |||
906 | static void | 850 | static void |
907 | imx_console_write(struct console *co, const char *s, unsigned int count) | 851 | imx_console_write(struct console *co, const char *s, unsigned int count) |
908 | { | 852 | { |
909 | struct imx_port *sport = &imx_ports[co->index]; | 853 | struct imx_port *sport = imx_ports[co->index]; |
910 | unsigned int old_ucr1, old_ucr2; | 854 | unsigned int old_ucr1, old_ucr2; |
911 | 855 | ||
912 | /* | 856 | /* |
@@ -1012,7 +956,7 @@ imx_console_setup(struct console *co, char *options) | |||
1012 | */ | 956 | */ |
1013 | if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) | 957 | if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) |
1014 | co->index = 0; | 958 | co->index = 0; |
1015 | sport = &imx_ports[co->index]; | 959 | sport = imx_ports[co->index]; |
1016 | 960 | ||
1017 | if (options) | 961 | if (options) |
1018 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 962 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
@@ -1035,14 +979,6 @@ static struct console imx_console = { | |||
1035 | .data = &imx_reg, | 979 | .data = &imx_reg, |
1036 | }; | 980 | }; |
1037 | 981 | ||
1038 | static int __init imx_rs_console_init(void) | ||
1039 | { | ||
1040 | imx_init_ports(); | ||
1041 | register_console(&imx_console); | ||
1042 | return 0; | ||
1043 | } | ||
1044 | console_initcall(imx_rs_console_init); | ||
1045 | |||
1046 | #define IMX_CONSOLE &imx_console | 982 | #define IMX_CONSOLE &imx_console |
1047 | #else | 983 | #else |
1048 | #define IMX_CONSOLE NULL | 984 | #define IMX_CONSOLE NULL |
@@ -1080,21 +1016,63 @@ static int serial_imx_resume(struct platform_device *dev) | |||
1080 | 1016 | ||
1081 | static int serial_imx_probe(struct platform_device *pdev) | 1017 | static int serial_imx_probe(struct platform_device *pdev) |
1082 | { | 1018 | { |
1019 | struct imx_port *sport; | ||
1083 | struct imxuart_platform_data *pdata; | 1020 | struct imxuart_platform_data *pdata; |
1021 | void __iomem *base; | ||
1022 | int ret = 0; | ||
1023 | struct resource *res; | ||
1024 | |||
1025 | sport = kzalloc(sizeof(*sport), GFP_KERNEL); | ||
1026 | if (!sport) | ||
1027 | return -ENOMEM; | ||
1084 | 1028 | ||
1085 | imx_ports[pdev->id].port.dev = &pdev->dev; | 1029 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1030 | if (!res) { | ||
1031 | ret = -ENODEV; | ||
1032 | goto free; | ||
1033 | } | ||
1034 | |||
1035 | base = ioremap(res->start, PAGE_SIZE); | ||
1036 | if (!base) { | ||
1037 | ret = -ENOMEM; | ||
1038 | goto free; | ||
1039 | } | ||
1040 | |||
1041 | sport->port.dev = &pdev->dev; | ||
1042 | sport->port.mapbase = res->start; | ||
1043 | sport->port.membase = base; | ||
1044 | sport->port.type = PORT_IMX, | ||
1045 | sport->port.iotype = UPIO_MEM; | ||
1046 | sport->port.irq = platform_get_irq(pdev, 0); | ||
1047 | sport->rxirq = platform_get_irq(pdev, 0); | ||
1048 | sport->txirq = platform_get_irq(pdev, 1); | ||
1049 | sport->rtsirq = platform_get_irq(pdev, 2); | ||
1050 | sport->port.fifosize = 32; | ||
1051 | sport->port.ops = &imx_pops; | ||
1052 | sport->port.flags = UPF_BOOT_AUTOCONF; | ||
1053 | sport->port.line = pdev->id; | ||
1054 | init_timer(&sport->timer); | ||
1055 | sport->timer.function = imx_timeout; | ||
1056 | sport->timer.data = (unsigned long)sport; | ||
1057 | sport->port.uartclk = imx_get_perclk1(); | ||
1058 | |||
1059 | imx_ports[pdev->id] = sport; | ||
1086 | 1060 | ||
1087 | pdata = pdev->dev.platform_data; | 1061 | pdata = pdev->dev.platform_data; |
1088 | if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) | 1062 | if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) |
1089 | imx_ports[pdev->id].have_rtscts = 1; | 1063 | sport->have_rtscts = 1; |
1090 | 1064 | ||
1091 | if (pdata->init) | 1065 | if (pdata->init) |
1092 | pdata->init(pdev); | 1066 | pdata->init(pdev); |
1093 | 1067 | ||
1094 | uart_add_one_port(&imx_reg, &imx_ports[pdev->id].port); | 1068 | uart_add_one_port(&imx_reg, &sport->port); |
1095 | platform_set_drvdata(pdev, &imx_ports[pdev->id]); | 1069 | platform_set_drvdata(pdev, &sport->port); |
1096 | 1070 | ||
1097 | return 0; | 1071 | return 0; |
1072 | free: | ||
1073 | kfree(sport); | ||
1074 | |||
1075 | return ret; | ||
1098 | } | 1076 | } |
1099 | 1077 | ||
1100 | static int serial_imx_remove(struct platform_device *pdev) | 1078 | static int serial_imx_remove(struct platform_device *pdev) |
@@ -1112,6 +1090,9 @@ static int serial_imx_remove(struct platform_device *pdev) | |||
1112 | if (pdata->exit) | 1090 | if (pdata->exit) |
1113 | pdata->exit(pdev); | 1091 | pdata->exit(pdev); |
1114 | 1092 | ||
1093 | iounmap(sport->port.membase); | ||
1094 | kfree(sport); | ||
1095 | |||
1115 | return 0; | 1096 | return 0; |
1116 | } | 1097 | } |
1117 | 1098 | ||
@@ -1133,8 +1114,6 @@ static int __init imx_serial_init(void) | |||
1133 | 1114 | ||
1134 | printk(KERN_INFO "Serial: IMX driver\n"); | 1115 | printk(KERN_INFO "Serial: IMX driver\n"); |
1135 | 1116 | ||
1136 | imx_init_ports(); | ||
1137 | |||
1138 | ret = uart_register_driver(&imx_reg); | 1117 | ret = uart_register_driver(&imx_reg); |
1139 | if (ret) | 1118 | if (ret) |
1140 | return ret; | 1119 | return ret; |