Skip to content

Commit

Permalink
[POWERPC] Add of_register_i2c_devices()
Browse files Browse the repository at this point in the history
Scan the device tree for i2c devices, check their "compatible" property
against a hard-coded table, and, if found, register with i2c boardinfo.
This provides the infrastructure needed to find i2c devices in the
device tree and register them with the i2c subsystem.

This and the following commit let the linkstation work with the new i2c
API and thus fix a regression.

Signed-off-by: G. Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Guennadi Liakhovetski authored and Paul Mackerras committed Jul 26, 2007
1 parent 56d6d1a commit d13ae86
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions arch/powerpc/sysdev/fsl_soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,64 @@ static int __init gfar_of_init(void)

arch_initcall(gfar_of_init);

#ifdef CONFIG_I2C_BOARDINFO
#include <linux/i2c.h>
struct i2c_driver_device {
char *of_device;
char *i2c_driver;
char *i2c_type;
};

static struct i2c_driver_device i2c_devices[] __initdata = {
{"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
{"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
{"ricoh,rv5c386", "rtc-rs5c372", "rv5c386",},
{"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
};

static int __init of_find_i2c_driver(struct device_node *node, struct i2c_board_info *info)
{
int i;

for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
if (!of_device_is_compatible(node, i2c_devices[i].of_device))
continue;
strncpy(info->driver_name, i2c_devices[i].i2c_driver, KOBJ_NAME_LEN);
strncpy(info->type, i2c_devices[i].i2c_type, I2C_NAME_SIZE);
return 0;
}
return -ENODEV;
}

static void __init of_register_i2c_devices(struct device_node *adap_node, int bus_num)
{
struct device_node *node = NULL;

while ((node = of_get_next_child(adap_node, node))) {
struct i2c_board_info info;
const u32 *addr;
int len;

addr = of_get_property(node, "reg", &len);
if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
printk(KERN_WARNING "fsl_ioc.c: invalid i2c device entry\n");
continue;
}

info.irq = irq_of_parse_and_map(node, 0);
if (info.irq == NO_IRQ)
info.irq = -1;

if (of_find_i2c_driver(node, &info) < 0)
continue;

info.platform_data = NULL;
info.addr = *addr;

i2c_register_board_info(bus_num, &info, 1);
}
}

static int __init fsl_i2c_of_init(void)
{
struct device_node *np;
Expand Down Expand Up @@ -349,6 +407,8 @@ static int __init fsl_i2c_of_init(void)
fsl_i2c_platform_data));
if (ret)
goto unreg;

of_register_i2c_devices(np, i);
}

return 0;
Expand All @@ -360,6 +420,7 @@ static int __init fsl_i2c_of_init(void)
}

arch_initcall(fsl_i2c_of_init);
#endif

#ifdef CONFIG_PPC_83xx
static int __init mpc83xx_wdt_init(void)
Expand Down

0 comments on commit d13ae86

Please sign in to comment.