static int gpio_dwapb_bind(struct udevice *dev) { struct gpio_dwapb_platdata *plat = dev_get_platdata(dev); struct udevice *subdev; fdt_addr_t base; int ret, bank = 0; ofnode node; /* If this is a child device, there is nothing to do here */ if (plat) return 0; base = dev_read_addr(dev); if (base == FDT_ADDR_T_NONE) { debug("Can't get the GPIO register base address\n"); return -ENXIO; } for (node = dev_read_first_subnode(dev); ofnode_valid(node); node = dev_read_next_subnode(node)) { if (!ofnode_read_bool(node, "gpio-controller")) continue; plat = devm_kcalloc(dev, 1, sizeof(*plat), GFP_KERNEL); if (!plat) return -ENOMEM; plat->base = base; plat->bank = bank; plat->pins = ofnode_read_u32_default(node, "snps,nr-gpios", 0); if (ofnode_read_string_index(node, "bank-name", 0, &plat->name)) { /* * Fall back to node name. This means accessing pins * via bank name won't work. */ plat->name = ofnode_get_name(node); } ret = device_bind(dev, dev->driver, plat->name, plat, -1, &subdev); if (ret) return ret; dev->node = node; bank++; } return 0; }
/** * pinconfig_post_bind() - post binding for PINCONFIG uclass * Recursively bind its children as pinconfig devices. * * @dev: pinconfig device * @return: 0 on success, or negative error code on failure */ static int pinconfig_post_bind(struct udevice *dev) { bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC); const char *name; ofnode node; int ret; if (!dev_of_valid(dev)) return 0; dev_for_each_subnode(node, dev) { if (pre_reloc_only && !ofnode_pre_reloc(node)) continue; /* * If this node has "compatible" property, this is not * a pin configuration node, but a normal device. skip. */ ofnode_get_property(node, "compatible", &ret); if (ret >= 0) continue; /* If this node has "gpio-controller" property, skip */ if (ofnode_read_bool(node, "gpio-controller")) continue; if (ret != -FDT_ERR_NOTFOUND) return ret; name = ofnode_get_name(node); if (!name) return -EINVAL; ret = device_bind_driver_to_node(dev, "pinconfig", name, node, NULL); if (ret) return ret; } return 0; }
bool dev_read_bool(struct udevice *dev, const char *propname) { return ofnode_read_bool(dev_ofnode(dev), propname); }