in char/envctrl.c [1024:1098]
static int envctrl_probe(struct platform_device *op)
{
struct device_node *dp;
int index, err;
if (i2c)
return -EINVAL;
i2c = of_ioremap(&op->resource[0], 0, 0x2, DRIVER_NAME);
if (!i2c)
return -ENOMEM;
index = 0;
dp = op->dev.of_node->child;
while (dp) {
if (of_node_name_eq(dp, "gpio")) {
i2c_childlist[index].i2ctype = I2C_GPIO;
envctrl_init_i2c_child(dp, &(i2c_childlist[index++]));
} else if (of_node_name_eq(dp, "adc")) {
i2c_childlist[index].i2ctype = I2C_ADC;
envctrl_init_i2c_child(dp, &(i2c_childlist[index++]));
}
dp = dp->sibling;
}
/* Set device address. */
writeb(CONTROL_PIN, i2c + PCF8584_CSR);
writeb(PCF8584_ADDRESS, i2c + PCF8584_DATA);
/* Set system clock and SCL frequencies. */
writeb(CONTROL_PIN | CONTROL_ES1, i2c + PCF8584_CSR);
writeb(CLK_4_43 | BUS_CLK_90, i2c + PCF8584_DATA);
/* Enable serial interface. */
writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_ACK, i2c + PCF8584_CSR);
udelay(200);
/* Register the device as a minor miscellaneous device. */
err = misc_register(&envctrl_dev);
if (err) {
printk(KERN_ERR PFX "Unable to get misc minor %d\n",
envctrl_dev.minor);
goto out_iounmap;
}
/* Note above traversal routine post-incremented 'i' to accommodate
* a next child device, so we decrement before reverse-traversal of
* child devices.
*/
printk(KERN_INFO PFX "Initialized ");
for (--index; index >= 0; --index) {
printk("[%s 0x%lx]%s",
(I2C_ADC == i2c_childlist[index].i2ctype) ? "adc" :
((I2C_GPIO == i2c_childlist[index].i2ctype) ? "gpio" : "unknown"),
i2c_childlist[index].addr, (0 == index) ? "\n" : " ");
}
kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld");
if (IS_ERR(kenvctrld_task)) {
err = PTR_ERR(kenvctrld_task);
goto out_deregister;
}
return 0;
out_deregister:
misc_deregister(&envctrl_dev);
out_iounmap:
of_iounmap(&op->resource[0], i2c, 0x2);
for (index = 0; index < ENVCTRL_MAX_CPU * 2; index++)
kfree(i2c_childlist[index].tables);
return err;
}