diff options
author | Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 2007-05-08 11:03:02 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-07-12 12:41:13 -0400 |
commit | 891649409edbed528728b4a104d29e43e9d7473a (patch) | |
tree | 837091ee652d4b6905736c8d12cdc74397d6d1b7 /drivers | |
parent | 8c41286edffef0d6e7fb770b178275c8beb24055 (diff) |
[MIPS] separate platform_device registration for VR41xx serial interface
Signed-off-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/serial/vr41xx_siu.c | 143 |
1 files changed, 30 insertions, 113 deletions
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index cf0e663b42ed..85309acb75f6 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for NEC VR4100 series Serial Interface Unit. | 2 | * Driver for NEC VR4100 series Serial Interface Unit. |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2004-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> |
5 | * | 5 | * |
6 | * Based on drivers/serial/8250.c, by Russell King. | 6 | * Based on drivers/serial/8250.c, by Russell King. |
7 | * | 7 | * |
@@ -25,12 +25,12 @@ | |||
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #include <linux/console.h> | 27 | #include <linux/console.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/err.h> | ||
30 | #include <linux/ioport.h> | ||
31 | #include <linux/init.h> | 29 | #include <linux/init.h> |
32 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/ioport.h> | ||
33 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/serial.h> | 34 | #include <linux/serial.h> |
35 | #include <linux/serial_core.h> | 35 | #include <linux/serial_core.h> |
36 | #include <linux/serial_reg.h> | 36 | #include <linux/serial_reg.h> |
@@ -38,11 +38,9 @@ | |||
38 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
39 | 39 | ||
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | #include <asm/vr41xx/irq.h> | ||
42 | #include <asm/vr41xx/siu.h> | 41 | #include <asm/vr41xx/siu.h> |
43 | #include <asm/vr41xx/vr41xx.h> | 42 | #include <asm/vr41xx/vr41xx.h> |
44 | 43 | ||
45 | #define SIU_PORTS_MAX 2 | ||
46 | #define SIU_BAUD_BASE 1152000 | 44 | #define SIU_BAUD_BASE 1152000 |
47 | #define SIU_MAJOR 204 | 45 | #define SIU_MAJOR 204 |
48 | #define SIU_MINOR_BASE 82 | 46 | #define SIU_MINOR_BASE 82 |
@@ -60,32 +58,13 @@ | |||
60 | #define IRUSESEL 0x02 | 58 | #define IRUSESEL 0x02 |
61 | #define SIRSEL 0x01 | 59 | #define SIRSEL 0x01 |
62 | 60 | ||
63 | struct siu_port { | 61 | static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { |
64 | unsigned int type; | 62 | [0 ... SIU_PORTS_MAX-1] = { |
65 | unsigned int irq; | 63 | .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), |
66 | unsigned long start; | 64 | .irq = -1, |
67 | }; | 65 | }, |
68 | |||
69 | static const struct siu_port siu_type1_ports[] = { | ||
70 | { .type = PORT_VR41XX_SIU, | ||
71 | .irq = SIU_IRQ, | ||
72 | .start = 0x0c000000UL, }, | ||
73 | }; | ||
74 | |||
75 | #define SIU_TYPE1_NR_PORTS (sizeof(siu_type1_ports) / sizeof(struct siu_port)) | ||
76 | |||
77 | static const struct siu_port siu_type2_ports[] = { | ||
78 | { .type = PORT_VR41XX_SIU, | ||
79 | .irq = SIU_IRQ, | ||
80 | .start = 0x0f000800UL, }, | ||
81 | { .type = PORT_VR41XX_DSIU, | ||
82 | .irq = DSIU_IRQ, | ||
83 | .start = 0x0f000820UL, }, | ||
84 | }; | 66 | }; |
85 | 67 | ||
86 | #define SIU_TYPE2_NR_PORTS (sizeof(siu_type2_ports) / sizeof(struct siu_port)) | ||
87 | |||
88 | static struct uart_port siu_uart_ports[SIU_PORTS_MAX]; | ||
89 | static uint8_t lsr_break_flag[SIU_PORTS_MAX]; | 68 | static uint8_t lsr_break_flag[SIU_PORTS_MAX]; |
90 | 69 | ||
91 | #define siu_read(port, offset) readb((port)->membase + (offset)) | 70 | #define siu_read(port, offset) readb((port)->membase + (offset)) |
@@ -110,7 +89,6 @@ void vr41xx_select_siu_interface(siu_interface_t interface) | |||
110 | 89 | ||
111 | spin_unlock_irqrestore(&port->lock, flags); | 90 | spin_unlock_irqrestore(&port->lock, flags); |
112 | } | 91 | } |
113 | |||
114 | EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface); | 92 | EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface); |
115 | 93 | ||
116 | void vr41xx_use_irda(irda_use_t use) | 94 | void vr41xx_use_irda(irda_use_t use) |
@@ -132,7 +110,6 @@ void vr41xx_use_irda(irda_use_t use) | |||
132 | 110 | ||
133 | spin_unlock_irqrestore(&port->lock, flags); | 111 | spin_unlock_irqrestore(&port->lock, flags); |
134 | } | 112 | } |
135 | |||
136 | EXPORT_SYMBOL_GPL(vr41xx_use_irda); | 113 | EXPORT_SYMBOL_GPL(vr41xx_use_irda); |
137 | 114 | ||
138 | void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) | 115 | void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) |
@@ -166,7 +143,6 @@ void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) | |||
166 | 143 | ||
167 | spin_unlock_irqrestore(&port->lock, flags); | 144 | spin_unlock_irqrestore(&port->lock, flags); |
168 | } | 145 | } |
169 | |||
170 | EXPORT_SYMBOL_GPL(vr41xx_select_irda_module); | 146 | EXPORT_SYMBOL_GPL(vr41xx_select_irda_module); |
171 | 147 | ||
172 | static inline void siu_clear_fifo(struct uart_port *port) | 148 | static inline void siu_clear_fifo(struct uart_port *port) |
@@ -177,21 +153,6 @@ static inline void siu_clear_fifo(struct uart_port *port) | |||
177 | siu_write(port, UART_FCR, 0); | 153 | siu_write(port, UART_FCR, 0); |
178 | } | 154 | } |
179 | 155 | ||
180 | static inline int siu_probe_ports(void) | ||
181 | { | ||
182 | switch (current_cpu_data.cputype) { | ||
183 | case CPU_VR4111: | ||
184 | case CPU_VR4121: | ||
185 | return SIU_TYPE1_NR_PORTS; | ||
186 | case CPU_VR4122: | ||
187 | case CPU_VR4131: | ||
188 | case CPU_VR4133: | ||
189 | return SIU_TYPE2_NR_PORTS; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static inline unsigned long siu_port_size(struct uart_port *port) | 156 | static inline unsigned long siu_port_size(struct uart_port *port) |
196 | { | 157 | { |
197 | switch (port->type) { | 158 | switch (port->type) { |
@@ -206,21 +167,10 @@ static inline unsigned long siu_port_size(struct uart_port *port) | |||
206 | 167 | ||
207 | static inline unsigned int siu_check_type(struct uart_port *port) | 168 | static inline unsigned int siu_check_type(struct uart_port *port) |
208 | { | 169 | { |
209 | switch (current_cpu_data.cputype) { | 170 | if (port->line == 0) |
210 | case CPU_VR4111: | 171 | return PORT_VR41XX_SIU; |
211 | case CPU_VR4121: | 172 | if (port->line == 1 && port->irq != -1) |
212 | if (port->line == 0) | 173 | return PORT_VR41XX_DSIU; |
213 | return PORT_VR41XX_SIU; | ||
214 | break; | ||
215 | case CPU_VR4122: | ||
216 | case CPU_VR4131: | ||
217 | case CPU_VR4133: | ||
218 | if (port->line == 0) | ||
219 | return PORT_VR41XX_SIU; | ||
220 | else if (port->line == 1) | ||
221 | return PORT_VR41XX_DSIU; | ||
222 | break; | ||
223 | } | ||
224 | 174 | ||
225 | return PORT_UNKNOWN; | 175 | return PORT_UNKNOWN; |
226 | } | 176 | } |
@@ -751,44 +701,34 @@ static struct uart_ops siu_uart_ops = { | |||
751 | .verify_port = siu_verify_port, | 701 | .verify_port = siu_verify_port, |
752 | }; | 702 | }; |
753 | 703 | ||
754 | static int siu_init_ports(void) | 704 | static int siu_init_ports(struct platform_device *pdev) |
755 | { | 705 | { |
756 | const struct siu_port *siu; | ||
757 | struct uart_port *port; | 706 | struct uart_port *port; |
758 | int i, num; | 707 | struct resource *res; |
708 | int *type = pdev->dev.platform_data; | ||
709 | int i; | ||
759 | 710 | ||
760 | switch (current_cpu_data.cputype) { | 711 | if (!type) |
761 | case CPU_VR4111: | ||
762 | case CPU_VR4121: | ||
763 | siu = siu_type1_ports; | ||
764 | break; | ||
765 | case CPU_VR4122: | ||
766 | case CPU_VR4131: | ||
767 | case CPU_VR4133: | ||
768 | siu = siu_type2_ports; | ||
769 | break; | ||
770 | default: | ||
771 | return 0; | 712 | return 0; |
772 | } | ||
773 | 713 | ||
774 | port = siu_uart_ports; | 714 | port = siu_uart_ports; |
775 | num = siu_probe_ports(); | 715 | for (i = 0; i < SIU_PORTS_MAX; i++) { |
776 | for (i = 0; i < num; i++) { | 716 | port->type = type[i]; |
777 | spin_lock_init(&port->lock); | 717 | if (port->type == PORT_UNKNOWN) |
778 | port->irq = siu->irq; | 718 | continue; |
719 | port->irq = platform_get_irq(pdev, i); | ||
779 | port->uartclk = SIU_BAUD_BASE * 16; | 720 | port->uartclk = SIU_BAUD_BASE * 16; |
780 | port->fifosize = 16; | 721 | port->fifosize = 16; |
781 | port->regshift = 0; | 722 | port->regshift = 0; |
782 | port->iotype = UPIO_MEM; | 723 | port->iotype = UPIO_MEM; |
783 | port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; | 724 | port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; |
784 | port->type = siu->type; | ||
785 | port->line = i; | 725 | port->line = i; |
786 | port->mapbase = siu->start; | 726 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); |
787 | siu++; | 727 | port->mapbase = res->start; |
788 | port++; | 728 | port++; |
789 | } | 729 | } |
790 | 730 | ||
791 | return num; | 731 | return i; |
792 | } | 732 | } |
793 | 733 | ||
794 | #ifdef CONFIG_SERIAL_VR41XX_CONSOLE | 734 | #ifdef CONFIG_SERIAL_VR41XX_CONSOLE |
@@ -883,13 +823,9 @@ static struct console siu_console = { | |||
883 | static int __devinit siu_console_init(void) | 823 | static int __devinit siu_console_init(void) |
884 | { | 824 | { |
885 | struct uart_port *port; | 825 | struct uart_port *port; |
886 | int num, i; | 826 | int i; |
887 | |||
888 | num = siu_init_ports(); | ||
889 | if (num <= 0) | ||
890 | return -ENODEV; | ||
891 | 827 | ||
892 | for (i = 0; i < num; i++) { | 828 | for (i = 0; i < SIU_PORTS_MAX; i++) { |
893 | port = &siu_uart_ports[i]; | 829 | port = &siu_uart_ports[i]; |
894 | port->ops = &siu_uart_ops; | 830 | port->ops = &siu_uart_ops; |
895 | } | 831 | } |
@@ -920,7 +856,7 @@ static int __devinit siu_probe(struct platform_device *dev) | |||
920 | struct uart_port *port; | 856 | struct uart_port *port; |
921 | int num, i, retval; | 857 | int num, i, retval; |
922 | 858 | ||
923 | num = siu_init_ports(); | 859 | num = siu_init_ports(dev); |
924 | if (num <= 0) | 860 | if (num <= 0) |
925 | return -ENODEV; | 861 | return -ENODEV; |
926 | 862 | ||
@@ -998,8 +934,6 @@ static int siu_resume(struct platform_device *dev) | |||
998 | return 0; | 934 | return 0; |
999 | } | 935 | } |
1000 | 936 | ||
1001 | static struct platform_device *siu_platform_device; | ||
1002 | |||
1003 | static struct platform_driver siu_device_driver = { | 937 | static struct platform_driver siu_device_driver = { |
1004 | .probe = siu_probe, | 938 | .probe = siu_probe, |
1005 | .remove = __devexit_p(siu_remove), | 939 | .remove = __devexit_p(siu_remove), |
@@ -1013,29 +947,12 @@ static struct platform_driver siu_device_driver = { | |||
1013 | 947 | ||
1014 | static int __init vr41xx_siu_init(void) | 948 | static int __init vr41xx_siu_init(void) |
1015 | { | 949 | { |
1016 | int retval; | 950 | return platform_driver_register(&siu_device_driver); |
1017 | |||
1018 | siu_platform_device = platform_device_alloc("SIU", -1); | ||
1019 | if (!siu_platform_device) | ||
1020 | return -ENOMEM; | ||
1021 | |||
1022 | retval = platform_device_add(siu_platform_device); | ||
1023 | if (retval < 0) { | ||
1024 | platform_device_put(siu_platform_device); | ||
1025 | return retval; | ||
1026 | } | ||
1027 | |||
1028 | retval = platform_driver_register(&siu_device_driver); | ||
1029 | if (retval < 0) | ||
1030 | platform_device_unregister(siu_platform_device); | ||
1031 | |||
1032 | return retval; | ||
1033 | } | 951 | } |
1034 | 952 | ||
1035 | static void __exit vr41xx_siu_exit(void) | 953 | static void __exit vr41xx_siu_exit(void) |
1036 | { | 954 | { |
1037 | platform_driver_unregister(&siu_device_driver); | 955 | platform_driver_unregister(&siu_device_driver); |
1038 | platform_device_unregister(siu_platform_device); | ||
1039 | } | 956 | } |
1040 | 957 | ||
1041 | module_init(vr41xx_siu_init); | 958 | module_init(vr41xx_siu_init); |