diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_soc.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_soc.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 3289fab01e92..727453d3e8b9 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c | |||
@@ -305,6 +305,64 @@ err: | |||
305 | 305 | ||
306 | arch_initcall(gfar_of_init); | 306 | arch_initcall(gfar_of_init); |
307 | 307 | ||
308 | #ifdef CONFIG_I2C_BOARDINFO | ||
309 | #include <linux/i2c.h> | ||
310 | struct i2c_driver_device { | ||
311 | char *of_device; | ||
312 | char *i2c_driver; | ||
313 | char *i2c_type; | ||
314 | }; | ||
315 | |||
316 | static struct i2c_driver_device i2c_devices[] __initdata = { | ||
317 | {"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",}, | ||
318 | {"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",}, | ||
319 | {"ricoh,rv5c386", "rtc-rs5c372", "rv5c386",}, | ||
320 | {"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",}, | ||
321 | }; | ||
322 | |||
323 | static int __init of_find_i2c_driver(struct device_node *node, struct i2c_board_info *info) | ||
324 | { | ||
325 | int i; | ||
326 | |||
327 | for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) { | ||
328 | if (!of_device_is_compatible(node, i2c_devices[i].of_device)) | ||
329 | continue; | ||
330 | strncpy(info->driver_name, i2c_devices[i].i2c_driver, KOBJ_NAME_LEN); | ||
331 | strncpy(info->type, i2c_devices[i].i2c_type, I2C_NAME_SIZE); | ||
332 | return 0; | ||
333 | } | ||
334 | return -ENODEV; | ||
335 | } | ||
336 | |||
337 | static void __init of_register_i2c_devices(struct device_node *adap_node, int bus_num) | ||
338 | { | ||
339 | struct device_node *node = NULL; | ||
340 | |||
341 | while ((node = of_get_next_child(adap_node, node))) { | ||
342 | struct i2c_board_info info; | ||
343 | const u32 *addr; | ||
344 | int len; | ||
345 | |||
346 | addr = of_get_property(node, "reg", &len); | ||
347 | if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { | ||
348 | printk(KERN_WARNING "fsl_ioc.c: invalid i2c device entry\n"); | ||
349 | continue; | ||
350 | } | ||
351 | |||
352 | info.irq = irq_of_parse_and_map(node, 0); | ||
353 | if (info.irq == NO_IRQ) | ||
354 | info.irq = -1; | ||
355 | |||
356 | if (of_find_i2c_driver(node, &info) < 0) | ||
357 | continue; | ||
358 | |||
359 | info.platform_data = NULL; | ||
360 | info.addr = *addr; | ||
361 | |||
362 | i2c_register_board_info(bus_num, &info, 1); | ||
363 | } | ||
364 | } | ||
365 | |||
308 | static int __init fsl_i2c_of_init(void) | 366 | static int __init fsl_i2c_of_init(void) |
309 | { | 367 | { |
310 | struct device_node *np; | 368 | struct device_node *np; |
@@ -349,6 +407,8 @@ static int __init fsl_i2c_of_init(void) | |||
349 | fsl_i2c_platform_data)); | 407 | fsl_i2c_platform_data)); |
350 | if (ret) | 408 | if (ret) |
351 | goto unreg; | 409 | goto unreg; |
410 | |||
411 | of_register_i2c_devices(np, i); | ||
352 | } | 412 | } |
353 | 413 | ||
354 | return 0; | 414 | return 0; |
@@ -360,6 +420,7 @@ err: | |||
360 | } | 420 | } |
361 | 421 | ||
362 | arch_initcall(fsl_i2c_of_init); | 422 | arch_initcall(fsl_i2c_of_init); |
423 | #endif | ||
363 | 424 | ||
364 | #ifdef CONFIG_PPC_83xx | 425 | #ifdef CONFIG_PPC_83xx |
365 | static int __init mpc83xx_wdt_init(void) | 426 | static int __init mpc83xx_wdt_init(void) |