1 | /* |
2 | * Copyright (C) 2007-2009 Geert Uytterhoeven |
3 | * |
4 | * This file is subject to the terms and conditions of the GNU General Public |
5 | * License. See the file COPYING in the main directory of this archive |
6 | * for more details. |
7 | */ |
8 | |
9 | #include <linux/err.h> |
10 | #include <linux/init.h> |
11 | #include <linux/platform_device.h> |
12 | #include <linux/zorro.h> |
13 | |
14 | #include <asm/amigahw.h> |
15 | #include <asm/amigayle.h> |
16 | #include <asm/byteorder.h> |
17 | |
18 | |
19 | #ifdef CONFIG_ZORRO |
20 | |
21 | static const struct resource zorro_resources[] __initconst = { |
22 | /* Zorro II regions (on Zorro II/III) */ |
23 | { |
24 | .name = "Zorro II exp" , |
25 | .start = 0x00e80000, |
26 | .end = 0x00efffff, |
27 | .flags = IORESOURCE_MEM, |
28 | }, { |
29 | .name = "Zorro II mem" , |
30 | .start = 0x00200000, |
31 | .end = 0x009fffff, |
32 | .flags = IORESOURCE_MEM, |
33 | }, |
34 | /* Zorro III regions (on Zorro III only) */ |
35 | { |
36 | .name = "Zorro III exp" , |
37 | .start = 0xff000000, |
38 | .end = 0xffffffff, |
39 | .flags = IORESOURCE_MEM, |
40 | }, { |
41 | .name = "Zorro III cfg" , |
42 | .start = 0x40000000, |
43 | .end = 0x7fffffff, |
44 | .flags = IORESOURCE_MEM, |
45 | } |
46 | }; |
47 | |
48 | |
49 | static int __init amiga_init_bus(void) |
50 | { |
51 | struct platform_device *pdev; |
52 | unsigned int n; |
53 | |
54 | if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) |
55 | return -ENODEV; |
56 | |
57 | n = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2; |
58 | pdev = platform_device_register_simple("amiga-zorro" , -1, |
59 | zorro_resources, n); |
60 | return PTR_ERR_OR_ZERO(pdev); |
61 | } |
62 | |
63 | subsys_initcall(amiga_init_bus); |
64 | |
65 | |
66 | static int __init z_dev_present(zorro_id id) |
67 | { |
68 | unsigned int i; |
69 | |
70 | for (i = 0; i < zorro_num_autocon; i++) { |
71 | const struct ExpansionRom *rom = &zorro_autocon_init[i].rom; |
72 | if (be16_to_cpu(rom->er_Manufacturer) == ZORRO_MANUF(id) && |
73 | rom->er_Product == ZORRO_PROD(id)) |
74 | return 1; |
75 | } |
76 | |
77 | return 0; |
78 | } |
79 | |
80 | #else /* !CONFIG_ZORRO */ |
81 | |
82 | static inline int z_dev_present(zorro_id id) { return 0; } |
83 | |
84 | #endif /* !CONFIG_ZORRO */ |
85 | |
86 | |
87 | static const struct resource a3000_scsi_resource __initconst = { |
88 | .start = 0xdd0000, |
89 | .end = 0xdd00ff, |
90 | .flags = IORESOURCE_MEM, |
91 | }; |
92 | |
93 | |
94 | static const struct resource a4000t_scsi_resource __initconst = { |
95 | .start = 0xdd0000, |
96 | .end = 0xdd0fff, |
97 | .flags = IORESOURCE_MEM, |
98 | }; |
99 | |
100 | |
101 | static const struct resource a1200_ide_resource __initconst = { |
102 | .start = 0xda0000, |
103 | .end = 0xda1fff, |
104 | .flags = IORESOURCE_MEM, |
105 | }; |
106 | |
107 | static const struct gayle_ide_platform_data a1200_ide_pdata __initconst = { |
108 | .base = 0xda0000, |
109 | .irqport = 0xda9000, |
110 | .explicit_ack = 1, |
111 | }; |
112 | |
113 | |
114 | static const struct resource a4000_ide_resource __initconst = { |
115 | .start = 0xdd2000, |
116 | .end = 0xdd3fff, |
117 | .flags = IORESOURCE_MEM, |
118 | }; |
119 | |
120 | static const struct gayle_ide_platform_data a4000_ide_pdata __initconst = { |
121 | .base = 0xdd2020, |
122 | .irqport = 0xdd3020, |
123 | .explicit_ack = 0, |
124 | }; |
125 | |
126 | |
127 | static const struct resource amiga_rtc_resource __initconst = { |
128 | .start = 0x00dc0000, |
129 | .end = 0x00dcffff, |
130 | .flags = IORESOURCE_MEM, |
131 | }; |
132 | |
133 | |
134 | static int __init amiga_init_devices(void) |
135 | { |
136 | struct platform_device *pdev; |
137 | int error; |
138 | |
139 | if (!MACH_IS_AMIGA) |
140 | return -ENODEV; |
141 | |
142 | /* video hardware */ |
143 | if (AMIGAHW_PRESENT(AMI_VIDEO)) { |
144 | pdev = platform_device_register_simple(name: "amiga-video" , id: -1, NULL, |
145 | num: 0); |
146 | if (IS_ERR(ptr: pdev)) |
147 | return PTR_ERR(ptr: pdev); |
148 | } |
149 | |
150 | |
151 | /* sound hardware */ |
152 | if (AMIGAHW_PRESENT(AMI_AUDIO)) { |
153 | pdev = platform_device_register_simple(name: "amiga-audio" , id: -1, NULL, |
154 | num: 0); |
155 | if (IS_ERR(ptr: pdev)) |
156 | return PTR_ERR(ptr: pdev); |
157 | } |
158 | |
159 | |
160 | /* storage interfaces */ |
161 | if (AMIGAHW_PRESENT(AMI_FLOPPY)) { |
162 | pdev = platform_device_register_simple(name: "amiga-floppy" , id: -1, |
163 | NULL, num: 0); |
164 | if (IS_ERR(ptr: pdev)) |
165 | return PTR_ERR(ptr: pdev); |
166 | } |
167 | |
168 | if (AMIGAHW_PRESENT(A3000_SCSI)) { |
169 | pdev = platform_device_register_simple(name: "amiga-a3000-scsi" , id: -1, |
170 | res: &a3000_scsi_resource, num: 1); |
171 | if (IS_ERR(ptr: pdev)) |
172 | return PTR_ERR(ptr: pdev); |
173 | } |
174 | |
175 | if (AMIGAHW_PRESENT(A4000_SCSI)) { |
176 | pdev = platform_device_register_simple(name: "amiga-a4000t-scsi" , id: -1, |
177 | res: &a4000t_scsi_resource, |
178 | num: 1); |
179 | if (IS_ERR(ptr: pdev)) |
180 | return PTR_ERR(ptr: pdev); |
181 | } |
182 | |
183 | if (AMIGAHW_PRESENT(A1200_IDE) || |
184 | z_dev_present(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE)) { |
185 | pdev = platform_device_register_simple(name: "amiga-gayle-ide" , id: -1, |
186 | res: &a1200_ide_resource, num: 1); |
187 | if (IS_ERR(ptr: pdev)) |
188 | return PTR_ERR(ptr: pdev); |
189 | error = platform_device_add_data(pdev, data: &a1200_ide_pdata, |
190 | size: sizeof(a1200_ide_pdata)); |
191 | if (error) |
192 | return error; |
193 | } |
194 | |
195 | if (AMIGAHW_PRESENT(A4000_IDE)) { |
196 | pdev = platform_device_register_simple(name: "amiga-gayle-ide" , id: -1, |
197 | res: &a4000_ide_resource, num: 1); |
198 | if (IS_ERR(ptr: pdev)) |
199 | return PTR_ERR(ptr: pdev); |
200 | error = platform_device_add_data(pdev, data: &a4000_ide_pdata, |
201 | size: sizeof(a4000_ide_pdata)); |
202 | if (error) |
203 | return error; |
204 | } |
205 | |
206 | |
207 | /* other I/O hardware */ |
208 | if (AMIGAHW_PRESENT(AMI_KEYBOARD)) { |
209 | pdev = platform_device_register_simple(name: "amiga-keyboard" , id: -1, |
210 | NULL, num: 0); |
211 | if (IS_ERR(ptr: pdev)) |
212 | return PTR_ERR(ptr: pdev); |
213 | } |
214 | |
215 | if (AMIGAHW_PRESENT(AMI_MOUSE)) { |
216 | pdev = platform_device_register_simple(name: "amiga-mouse" , id: -1, NULL, |
217 | num: 0); |
218 | if (IS_ERR(ptr: pdev)) |
219 | return PTR_ERR(ptr: pdev); |
220 | } |
221 | |
222 | if (AMIGAHW_PRESENT(AMI_SERIAL)) { |
223 | pdev = platform_device_register_simple(name: "amiga-serial" , id: -1, |
224 | NULL, num: 0); |
225 | if (IS_ERR(ptr: pdev)) |
226 | return PTR_ERR(ptr: pdev); |
227 | } |
228 | |
229 | if (AMIGAHW_PRESENT(AMI_PARALLEL)) { |
230 | pdev = platform_device_register_simple(name: "amiga-parallel" , id: -1, |
231 | NULL, num: 0); |
232 | if (IS_ERR(ptr: pdev)) |
233 | return PTR_ERR(ptr: pdev); |
234 | } |
235 | |
236 | |
237 | /* real time clocks */ |
238 | if (AMIGAHW_PRESENT(A2000_CLK)) { |
239 | pdev = platform_device_register_simple(name: "rtc-msm6242" , id: -1, |
240 | res: &amiga_rtc_resource, num: 1); |
241 | if (IS_ERR(ptr: pdev)) |
242 | return PTR_ERR(ptr: pdev); |
243 | } |
244 | |
245 | if (AMIGAHW_PRESENT(A3000_CLK)) { |
246 | pdev = platform_device_register_simple(name: "rtc-rp5c01" , id: -1, |
247 | res: &amiga_rtc_resource, num: 1); |
248 | if (IS_ERR(ptr: pdev)) |
249 | return PTR_ERR(ptr: pdev); |
250 | } |
251 | |
252 | return 0; |
253 | } |
254 | |
255 | arch_initcall(amiga_init_devices); |
256 | |