diff options
| -rw-r--r-- | arch/arm/mach-imx/mx1ads.c | 10 | ||||
| -rw-r--r-- | drivers/serial/imx.c | 129 |
2 files changed, 64 insertions, 75 deletions
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index a9778c1587ab..9635d5812bcd 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c | |||
| @@ -69,6 +69,11 @@ static struct resource imx_uart1_resources[] = { | |||
| 69 | .end = (UART1_MINT_TX), | 69 | .end = (UART1_MINT_TX), |
| 70 | .flags = IORESOURCE_IRQ, | 70 | .flags = IORESOURCE_IRQ, |
| 71 | }, | 71 | }, |
| 72 | [3] = { | ||
| 73 | .start = UART1_MINT_RTS, | ||
| 74 | .end = UART1_MINT_RTS, | ||
| 75 | .flags = IORESOURCE_IRQ, | ||
| 76 | }, | ||
| 72 | }; | 77 | }; |
| 73 | 78 | ||
| 74 | static struct platform_device imx_uart1_device = { | 79 | static struct platform_device imx_uart1_device = { |
| @@ -97,6 +102,11 @@ static struct resource imx_uart2_resources[] = { | |||
| 97 | .end = (UART2_MINT_TX), | 102 | .end = (UART2_MINT_TX), |
| 98 | .flags = IORESOURCE_IRQ, | 103 | .flags = IORESOURCE_IRQ, |
| 99 | }, | 104 | }, |
| 105 | [3] = { | ||
| 106 | .start = UART2_MINT_RTS, | ||
| 107 | .end = UART2_MINT_RTS, | ||
| 108 | .flags = IORESOURCE_IRQ, | ||
| 109 | }, | ||
| 100 | }; | 110 | }; |
| 101 | 111 | ||
| 102 | static struct platform_device imx_uart2_device = { | 112 | static struct platform_device imx_uart2_device = { |
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; |
