static int __init envctrl_init(void) { #ifdef CONFIG_PCI struct linux_ebus *ebus = NULL; struct linux_ebus_device *edev = NULL; struct linux_ebus_child *edev_child = NULL; int i = 0; /* Traverse through ebus and ebus device list for i2c device and * adc and gpio nodes. */ for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { if (!strcmp(edev->prom_name, "i2c")) { i2c = ioremap( edev->resource[0].start, sizeof(struct pcf8584_reg)); for_each_edevchild(edev, edev_child) { if (!strcmp("gpio", edev_child->prom_name)) { i2c_childlist[i].i2ctype = I2C_GPIO; envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); } if (!strcmp("adc", edev_child->prom_name)) { i2c_childlist[i].i2ctype = I2C_ADC; envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); } } goto done; } } }
static int __init envctrl_init(void) { #ifdef CONFIG_PCI struct linux_ebus *ebus = NULL; struct linux_ebus_device *edev = NULL; struct linux_ebus_child *edev_child = NULL; int err, i = 0; for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { if (!strcmp(edev->prom_name, "bbc")) { /* If we find a boot-bus controller node, * then this envctrl driver is not for us. */ return -ENODEV; } } } /* Traverse through ebus and ebus device list for i2c device and * adc and gpio nodes. */ for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { if (!strcmp(edev->prom_name, "i2c")) { i2c = ioremap( edev->resource[0].start, sizeof(struct pcf8584_reg)); for_each_edevchild(edev, edev_child) { if (!strcmp("gpio", edev_child->prom_name)) { i2c_childlist[i].i2ctype = I2C_GPIO; envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); } if (!strcmp("adc", edev_child->prom_name)) { i2c_childlist[i].i2ctype = I2C_ADC; envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); } } goto done; } } }
static int __devinit envctrl_probe(struct of_device *op, const struct of_device_id *match) { 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->node->child; while (dp) { if (!strcmp(dp->name, "gpio")) { i2c_childlist[index].i2ctype = I2C_GPIO; envctrl_init_i2c_child(dp, &(i2c_childlist[index++])); } else if (!strcmp(dp->name, "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; }