[POWERPC] Convert to mac-address for ethernet MAC address data.
[linux-2.6] / arch / powerpc / sysdev / fsl_soc.c
1 /*
2  * FSL SoC setup code
3  *
4  * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5  *
6  * This program is free software; you can redistribute  it and/or modify it
7  * under  the terms of  the GNU General  Public License as published by the
8  * Free Software Foundation;  either version 2 of the  License, or (at your
9  * option) any later version.
10  */
11
12 #include <linux/stddef.h>
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/errno.h>
16 #include <linux/major.h>
17 #include <linux/delay.h>
18 #include <linux/irq.h>
19 #include <linux/module.h>
20 #include <linux/device.h>
21 #include <linux/platform_device.h>
22 #include <linux/fsl_devices.h>
23
24 #include <asm/system.h>
25 #include <asm/atomic.h>
26 #include <asm/io.h>
27 #include <asm/irq.h>
28 #include <asm/prom.h>
29 #include <sysdev/fsl_soc.h>
30 #include <mm/mmu_decl.h>
31
32 static phys_addr_t immrbase = -1;
33
34 phys_addr_t get_immrbase(void)
35 {
36         struct device_node *soc;
37
38         if (immrbase != -1)
39                 return immrbase;
40
41         soc = of_find_node_by_type(NULL, "soc");
42         if (soc) {
43                 unsigned int size;
44                 void *prop = get_property(soc, "reg", &size);
45                 immrbase = of_translate_address(soc, prop);
46                 of_node_put(soc);
47         };
48
49         return immrbase;
50 }
51
52 EXPORT_SYMBOL(get_immrbase);
53
54 static int __init gfar_mdio_of_init(void)
55 {
56         struct device_node *np;
57         unsigned int i;
58         struct platform_device *mdio_dev;
59         struct resource res;
60         int ret;
61
62         for (np = NULL, i = 0;
63              (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL;
64              i++) {
65                 int k;
66                 struct device_node *child = NULL;
67                 struct gianfar_mdio_data mdio_data;
68
69                 memset(&res, 0, sizeof(res));
70                 memset(&mdio_data, 0, sizeof(mdio_data));
71
72                 ret = of_address_to_resource(np, 0, &res);
73                 if (ret)
74                         goto err;
75
76                 mdio_dev =
77                     platform_device_register_simple("fsl-gianfar_mdio",
78                                                     res.start, &res, 1);
79                 if (IS_ERR(mdio_dev)) {
80                         ret = PTR_ERR(mdio_dev);
81                         goto err;
82                 }
83
84                 for (k = 0; k < 32; k++)
85                         mdio_data.irq[k] = -1;
86
87                 while ((child = of_get_next_child(np, child)) != NULL) {
88                         if (child->n_intrs) {
89                                 u32 *id =
90                                     (u32 *) get_property(child, "reg", NULL);
91                                 mdio_data.irq[*id] = child->intrs[0].line;
92                         }
93                 }
94
95                 ret =
96                     platform_device_add_data(mdio_dev, &mdio_data,
97                                              sizeof(struct gianfar_mdio_data));
98                 if (ret)
99                         goto unreg;
100         }
101
102         return 0;
103
104 unreg:
105         platform_device_unregister(mdio_dev);
106 err:
107         return ret;
108 }
109
110 arch_initcall(gfar_mdio_of_init);
111
112 static const char *gfar_tx_intr = "tx";
113 static const char *gfar_rx_intr = "rx";
114 static const char *gfar_err_intr = "error";
115
116 static int __init gfar_of_init(void)
117 {
118         struct device_node *np;
119         unsigned int i;
120         struct platform_device *gfar_dev;
121         struct resource res;
122         int ret;
123
124         for (np = NULL, i = 0;
125              (np = of_find_compatible_node(np, "network", "gianfar")) != NULL;
126              i++) {
127                 struct resource r[4];
128                 struct device_node *phy, *mdio;
129                 struct gianfar_platform_data gfar_data;
130                 unsigned int *id;
131                 char *model;
132                 void *mac_addr;
133                 phandle *ph;
134
135                 memset(r, 0, sizeof(r));
136                 memset(&gfar_data, 0, sizeof(gfar_data));
137
138                 ret = of_address_to_resource(np, 0, &r[0]);
139                 if (ret)
140                         goto err;
141
142                 r[1].start = np->intrs[0].line;
143                 r[1].end = np->intrs[0].line;
144                 r[1].flags = IORESOURCE_IRQ;
145
146                 model = get_property(np, "model", NULL);
147
148                 /* If we aren't the FEC we have multiple interrupts */
149                 if (model && strcasecmp(model, "FEC")) {
150                         r[1].name = gfar_tx_intr;
151
152                         r[2].name = gfar_rx_intr;
153                         r[2].start = np->intrs[1].line;
154                         r[2].end = np->intrs[1].line;
155                         r[2].flags = IORESOURCE_IRQ;
156
157                         r[3].name = gfar_err_intr;
158                         r[3].start = np->intrs[2].line;
159                         r[3].end = np->intrs[2].line;
160                         r[3].flags = IORESOURCE_IRQ;
161                 }
162
163                 gfar_dev =
164                     platform_device_register_simple("fsl-gianfar", i, &r[0],
165                                                     np->n_intrs + 1);
166
167                 if (IS_ERR(gfar_dev)) {
168                         ret = PTR_ERR(gfar_dev);
169                         goto err;
170                 }
171
172                 mac_addr = get_property(np, "local-mac-address", NULL);
173                 if (mac_addr == NULL)
174                         mac_addr = get_property(np, "mac-address", NULL);
175                 if (mac_addr == NULL) {
176                         /* Obsolete */
177                         mac_addr = get_property(np, "address", NULL);
178                 }
179
180                 if (mac_addr)
181                         memcpy(gfar_data.mac_addr, mac_addr, 6);
182
183                 if (model && !strcasecmp(model, "TSEC"))
184                         gfar_data.device_flags =
185                             FSL_GIANFAR_DEV_HAS_GIGABIT |
186                             FSL_GIANFAR_DEV_HAS_COALESCE |
187                             FSL_GIANFAR_DEV_HAS_RMON |
188                             FSL_GIANFAR_DEV_HAS_MULTI_INTR;
189                 if (model && !strcasecmp(model, "eTSEC"))
190                         gfar_data.device_flags =
191                             FSL_GIANFAR_DEV_HAS_GIGABIT |
192                             FSL_GIANFAR_DEV_HAS_COALESCE |
193                             FSL_GIANFAR_DEV_HAS_RMON |
194                             FSL_GIANFAR_DEV_HAS_MULTI_INTR |
195                             FSL_GIANFAR_DEV_HAS_CSUM |
196                             FSL_GIANFAR_DEV_HAS_VLAN |
197                             FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
198
199                 ph = (phandle *) get_property(np, "phy-handle", NULL);
200                 phy = of_find_node_by_phandle(*ph);
201
202                 if (phy == NULL) {
203                         ret = -ENODEV;
204                         goto unreg;
205                 }
206
207                 mdio = of_get_parent(phy);
208
209                 id = (u32 *) get_property(phy, "reg", NULL);
210                 ret = of_address_to_resource(mdio, 0, &res);
211                 if (ret) {
212                         of_node_put(phy);
213                         of_node_put(mdio);
214                         goto unreg;
215                 }
216
217                 gfar_data.phy_id = *id;
218                 gfar_data.bus_id = res.start;
219
220                 of_node_put(phy);
221                 of_node_put(mdio);
222
223                 ret =
224                     platform_device_add_data(gfar_dev, &gfar_data,
225                                              sizeof(struct
226                                                     gianfar_platform_data));
227                 if (ret)
228                         goto unreg;
229         }
230
231         return 0;
232
233 unreg:
234         platform_device_unregister(gfar_dev);
235 err:
236         return ret;
237 }
238
239 arch_initcall(gfar_of_init);
240
241 static int __init fsl_i2c_of_init(void)
242 {
243         struct device_node *np;
244         unsigned int i;
245         struct platform_device *i2c_dev;
246         int ret;
247
248         for (np = NULL, i = 0;
249              (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
250              i++) {
251                 struct resource r[2];
252                 struct fsl_i2c_platform_data i2c_data;
253                 unsigned char *flags = NULL;
254
255                 memset(&r, 0, sizeof(r));
256                 memset(&i2c_data, 0, sizeof(i2c_data));
257
258                 ret = of_address_to_resource(np, 0, &r[0]);
259                 if (ret)
260                         goto err;
261
262                 r[1].start = np->intrs[0].line;
263                 r[1].end = np->intrs[0].line;
264                 r[1].flags = IORESOURCE_IRQ;
265
266                 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
267                 if (IS_ERR(i2c_dev)) {
268                         ret = PTR_ERR(i2c_dev);
269                         goto err;
270                 }
271
272                 i2c_data.device_flags = 0;
273                 flags = get_property(np, "dfsrr", NULL);
274                 if (flags)
275                         i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
276
277                 flags = get_property(np, "fsl5200-clocking", NULL);
278                 if (flags)
279                         i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
280
281                 ret =
282                     platform_device_add_data(i2c_dev, &i2c_data,
283                                              sizeof(struct
284                                                     fsl_i2c_platform_data));
285                 if (ret)
286                         goto unreg;
287         }
288
289         return 0;
290
291 unreg:
292         platform_device_unregister(i2c_dev);
293 err:
294         return ret;
295 }
296
297 arch_initcall(fsl_i2c_of_init);
298
299 #ifdef CONFIG_PPC_83xx
300 static int __init mpc83xx_wdt_init(void)
301 {
302         struct resource r;
303         struct device_node *soc, *np;
304         struct platform_device *dev;
305         unsigned int *freq;
306         int ret;
307
308         np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
309
310         if (!np) {
311                 ret = -ENODEV;
312                 goto nodev;
313         }
314
315         soc = of_find_node_by_type(NULL, "soc");
316
317         if (!soc) {
318                 ret = -ENODEV;
319                 goto nosoc;
320         }
321
322         freq = (unsigned int *)get_property(soc, "bus-frequency", NULL);
323         if (!freq) {
324                 ret = -ENODEV;
325                 goto err;
326         }
327
328         memset(&r, 0, sizeof(r));
329
330         ret = of_address_to_resource(np, 0, &r);
331         if (ret)
332                 goto err;
333
334         dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
335         if (IS_ERR(dev)) {
336                 ret = PTR_ERR(dev);
337                 goto err;
338         }
339
340         ret = platform_device_add_data(dev, freq, sizeof(int));
341         if (ret)
342                 goto unreg;
343
344         of_node_put(soc);
345         of_node_put(np);
346
347         return 0;
348
349 unreg:
350         platform_device_unregister(dev);
351 err:
352         of_node_put(soc);
353 nosoc:
354         of_node_put(np);
355 nodev:
356         return ret;
357 }
358
359 arch_initcall(mpc83xx_wdt_init);
360 #endif
361
362 static enum fsl_usb2_phy_modes determine_usb_phy(char * phy_type)
363 {
364         if (!phy_type)
365                 return FSL_USB2_PHY_NONE;
366         if (!strcasecmp(phy_type, "ulpi"))
367                 return FSL_USB2_PHY_ULPI;
368         if (!strcasecmp(phy_type, "utmi"))
369                 return FSL_USB2_PHY_UTMI;
370         if (!strcasecmp(phy_type, "utmi_wide"))
371                 return FSL_USB2_PHY_UTMI_WIDE;
372         if (!strcasecmp(phy_type, "serial"))
373                 return FSL_USB2_PHY_SERIAL;
374
375         return FSL_USB2_PHY_NONE;
376 }
377
378 static int __init fsl_usb_of_init(void)
379 {
380         struct device_node *np;
381         unsigned int i;
382         struct platform_device *usb_dev_mph = NULL, *usb_dev_dr = NULL;
383         int ret;
384
385         for (np = NULL, i = 0;
386              (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL;
387              i++) {
388                 struct resource r[2];
389                 struct fsl_usb2_platform_data usb_data;
390                 unsigned char *prop = NULL;
391
392                 memset(&r, 0, sizeof(r));
393                 memset(&usb_data, 0, sizeof(usb_data));
394
395                 ret = of_address_to_resource(np, 0, &r[0]);
396                 if (ret)
397                         goto err;
398
399                 r[1].start = np->intrs[0].line;
400                 r[1].end = np->intrs[0].line;
401                 r[1].flags = IORESOURCE_IRQ;
402
403                 usb_dev_mph =
404                     platform_device_register_simple("fsl-ehci", i, r, 2);
405                 if (IS_ERR(usb_dev_mph)) {
406                         ret = PTR_ERR(usb_dev_mph);
407                         goto err;
408                 }
409
410                 usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
411                 usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
412
413                 usb_data.operating_mode = FSL_USB2_MPH_HOST;
414
415                 prop = get_property(np, "port0", NULL);
416                 if (prop)
417                         usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
418
419                 prop = get_property(np, "port1", NULL);
420                 if (prop)
421                         usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
422
423                 prop = get_property(np, "phy_type", NULL);
424                 usb_data.phy_mode = determine_usb_phy(prop);
425
426                 ret =
427                     platform_device_add_data(usb_dev_mph, &usb_data,
428                                              sizeof(struct
429                                                     fsl_usb2_platform_data));
430                 if (ret)
431                         goto unreg_mph;
432         }
433
434         for (np = NULL;
435              (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
436              i++) {
437                 struct resource r[2];
438                 struct fsl_usb2_platform_data usb_data;
439                 unsigned char *prop = NULL;
440
441                 memset(&r, 0, sizeof(r));
442                 memset(&usb_data, 0, sizeof(usb_data));
443
444                 ret = of_address_to_resource(np, 0, &r[0]);
445                 if (ret)
446                         goto unreg_mph;
447
448                 r[1].start = np->intrs[0].line;
449                 r[1].end = np->intrs[0].line;
450                 r[1].flags = IORESOURCE_IRQ;
451
452                 usb_dev_dr =
453                     platform_device_register_simple("fsl-ehci", i, r, 2);
454                 if (IS_ERR(usb_dev_dr)) {
455                         ret = PTR_ERR(usb_dev_dr);
456                         goto err;
457                 }
458
459                 usb_dev_dr->dev.coherent_dma_mask = 0xffffffffUL;
460                 usb_dev_dr->dev.dma_mask = &usb_dev_dr->dev.coherent_dma_mask;
461
462                 usb_data.operating_mode = FSL_USB2_DR_HOST;
463
464                 prop = get_property(np, "phy_type", NULL);
465                 usb_data.phy_mode = determine_usb_phy(prop);
466
467                 ret =
468                     platform_device_add_data(usb_dev_dr, &usb_data,
469                                              sizeof(struct
470                                                     fsl_usb2_platform_data));
471                 if (ret)
472                         goto unreg_dr;
473         }
474         return 0;
475
476 unreg_dr:
477         if (usb_dev_dr)
478                 platform_device_unregister(usb_dev_dr);
479 unreg_mph:
480         if (usb_dev_mph)
481                 platform_device_unregister(usb_dev_mph);
482 err:
483         return ret;
484 }
485
486 arch_initcall(fsl_usb_of_init);