[POWERPC] Add of_register_i2c_devices()
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>
This commit is contained in:
Родитель
56d6d1a73d
Коммит
d13ae8620d
|
@ -305,6 +305,64 @@ err:
|
|||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -360,6 +420,7 @@ err:
|
|||
}
|
||||
|
||||
arch_initcall(fsl_i2c_of_init);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_83xx
|
||||
static int __init mpc83xx_wdt_init(void)
|
||||
|
|
Загрузка…
Ссылка в новой задаче