static struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt( struct platform_device *pdev) { struct mc13xxx_leds *leds = platform_get_drvdata(pdev); struct mc13xxx_leds_platform_data *pdata; struct device_node *parent, *child; struct device *dev = &pdev->dev; int i = 0, ret = -ENODATA; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); of_node_get(dev->parent->of_node); parent = of_find_node_by_name(dev->parent->of_node, "leds"); if (!parent) goto out_node_put; ret = of_property_read_u32_array(parent, "led-control", pdata->led_control, leds->devtype->num_regs); if (ret) goto out_node_put; pdata->num_leds = of_get_child_count(parent); pdata->led = devm_kzalloc(dev, pdata->num_leds * sizeof(*pdata->led), GFP_KERNEL); if (!pdata->led) { ret = -ENOMEM; goto out_node_put; } for_each_child_of_node(parent, child) { const char *str; u32 tmp; if (of_property_read_u32(child, "reg", &tmp)) continue; pdata->led[i].id = leds->devtype->led_min + tmp; if (!of_property_read_string(child, "label", &str)) pdata->led[i].name = str; if (!of_property_read_string(child, "linux,default-trigger", &str)) pdata->led[i].default_trigger = str; i++; } pdata->num_leds = i; ret = i > 0 ? 0 : -ENODATA; out_node_put: of_node_put(parent); return ret ? ERR_PTR(ret) : pdata; }
static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct device_node* np; struct macio_chip* chip; if (ent->vendor != PCI_VENDOR_ID_APPLE) return -ENODEV; /* Note regarding refcounting: We assume pci_device_to_OF_node() is * ported to new OF APIs and returns a node with refcount incremented. */ np = pci_device_to_OF_node(pdev); if (np == NULL) return -ENODEV; /* The above assumption is wrong !!! * fix that here for now until I fix the arch code */ of_node_get(np); /* We also assume that pmac_feature will have done a get() on nodes * stored in the macio chips array */ chip = macio_find(np, macio_unknown); of_node_put(np); if (chip == NULL) return -ENODEV; /* XXX Need locking ??? */ if (chip->lbus.pdev == NULL) { chip->lbus.pdev = pdev; chip->lbus.chip = chip; pci_set_drvdata(pdev, &chip->lbus); pci_set_master(pdev); } printk(KERN_INFO "MacIO PCI driver attached to %s chipset\n", chip->name); /* * HACK ALERT: The WallStreet PowerBook and some OHare based machines * have 2 macio ASICs. I must probe the "main" one first or IDE * ordering will be incorrect. So I put on "hold" the second one since * it seem to appear first on PCI */ if (chip->type == macio_gatwick || chip->type == macio_ohareII) if (macio_chips[0].lbus.pdev == NULL) { macio_on_hold = chip; return 0; } macio_pci_add_devices(chip); if (macio_on_hold && macio_chips[0].lbus.pdev != NULL) { macio_pci_add_devices(macio_on_hold); macio_on_hold = NULL; } return 0; }
static int __init of_create_spu(struct spu *spu, void *data) { int ret; struct device_node *spe = (struct device_node *)data; static int legacy_map = 0, legacy_irq = 0; spu->devnode = of_node_get(spe); spu->spe_id = find_spu_unit_number(spe); spu->node = of_node_to_nid(spe); if (spu->node >= MAX_NUMNODES) { printk(KERN_WARNING "SPE %s on node %d ignored," " node number too big\n", spe->full_name, spu->node); printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); ret = -ENODEV; goto out; } ret = spu_map_device(spu); if (ret) { if (!legacy_map) { legacy_map = 1; printk(KERN_WARNING "%s: Legacy device tree found, " "trying to map old style\n", __FUNCTION__); } ret = spu_map_device_old(spu); if (ret) { printk(KERN_ERR "Unable to map %s\n", spu->name); goto out; } } ret = spu_map_interrupts(spu, spe); if (ret) { if (!legacy_irq) { legacy_irq = 1; printk(KERN_WARNING "%s: Legacy device tree found, " "trying old style irq\n", __FUNCTION__); } ret = spu_map_interrupts_old(spu, spe); if (ret) { printk(KERN_ERR "%s: could not map interrupts", spu->name); goto out_unmap; } } pr_debug("Using SPE %s %p %p %p %p %d\n", spu->name, spu->local_store, spu->problem, spu->priv1, spu->priv2, spu->number); goto out; out_unmap: spu_unmap(spu); out: return ret; }
/** * of_regulator_match - extract multiple regulator init data from device tree. * @dev: device requesting the data * @node: parent device node of the regulators * @matches: match table for the regulators * @num_matches: number of entries in match table * * This function uses a match table specified by the regulator driver to * parse regulator init data from the device tree. @node is expected to * contain a set of child nodes, each providing the init data for one * regulator. The data parsed from a child node will be matched to a regulator * based on either the deprecated property regulator-compatible if present, * or otherwise the child node's name. Note that the match table is modified * in place and an additional of_node reference is taken for each matched * regulator. * * Returns the number of matches found or a negative error code on failure. */ int of_regulator_match(struct device *dev, struct device_node *node, struct of_regulator_match *matches, unsigned int num_matches) { unsigned int count = 0; unsigned int i; const char *name; struct device_node *child; struct devm_of_regulator_matches *devm_matches; if (!dev || !node) return -EINVAL; devm_matches = devres_alloc(devm_of_regulator_put_matches, sizeof(struct devm_of_regulator_matches), GFP_KERNEL); if (!devm_matches) return -ENOMEM; devm_matches->matches = matches; devm_matches->num_matches = num_matches; devres_add(dev, devm_matches); for (i = 0; i < num_matches; i++) { struct of_regulator_match *match = &matches[i]; match->init_data = NULL; match->of_node = NULL; } for_each_child_of_node(node, child) { name = of_get_property(child, "regulator-compatible", NULL); if (!name) name = child->name; for (i = 0; i < num_matches; i++) { struct of_regulator_match *match = &matches[i]; if (match->of_node) continue; if (strcmp(match->name, name)) continue; match->init_data = of_get_regulator_init_data(dev, child, match->desc); if (!match->init_data) { dev_err(dev, "failed to parse DT for regulator %pOFn\n", child); of_node_put(child); return -EINVAL; } match->of_node = of_node_get(child); count++; break; } }
/** * vio_register_device_node: - Register a new vio device. * @of_node: The OF node for this device. * * Creates and initializes a vio_dev structure from the data in * of_node (dev.platform_data) and adds it to the list of virtual devices. * Returns a pointer to the created vio_dev or NULL if node has * NULL device_type or compatible fields. */ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) { struct vio_dev *viodev; const unsigned int *unit_address; /* we need the 'device_type' property, in order to match with drivers */ if (of_node->type == NULL) { printk(KERN_WARNING "%s: node %s missing 'device_type'\n", __FUNCTION__, of_node->name ? of_node->name : "<unknown>"); return NULL; } unit_address = get_property(of_node, "reg", NULL); if (unit_address == NULL) { printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__, of_node->name ? of_node->name : "<unknown>"); return NULL; } /* allocate a vio_dev for this node */ viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL); if (viodev == NULL) return NULL; viodev->dev.platform_data = of_node_get(of_node); viodev->irq = irq_of_parse_and_map(of_node, 0); snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); viodev->name = of_node->name; viodev->type = of_node->type; viodev->unit_address = *unit_address; if (firmware_has_feature(FW_FEATURE_ISERIES)) { unit_address = get_property(of_node, "linux,unit_address", NULL); if (unit_address != NULL) viodev->unit_address = *unit_address; } viodev->iommu_table = vio_build_iommu_table(viodev); /* init generic 'struct device' fields: */ viodev->dev.parent = &vio_bus_device.dev; viodev->dev.bus = &vio_bus_type; viodev->dev.release = vio_dev_release; /* register with generic device framework */ if (device_register(&viodev->dev)) { printk(KERN_ERR "%s: failed to register device %s\n", __FUNCTION__, viodev->dev.bus_id); /* XXX free TCE table */ kfree(viodev); return NULL; } return viodev; }
/** * thermal_zone_of_sensor_register - registers a sensor to a DT thermal zone * @dev: a valid struct device pointer of a sensor device. Must contain * a valid .of_node, for the sensor node. * @sensor_id: a sensor identifier, in case the sensor IP has more * than one sensors * @data: a private pointer (owned by the caller) that will be passed * back, when a temperature reading is needed. * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. * * This function will search the list of thermal zones described in device * tree and look for the zone that refer to the sensor device pointed by * @dev->of_node as temperature providers. For the zone pointing to the * sensor node, the sensor will be added to the DT thermal zone device. * * The thermal zone temperature is provided by the @get_temp function * pointer. When called, it will have the private pointer @data back. * * The thermal zone temperature trend is provided by the @get_trend function * pointer. When called, it will have the private pointer @data back. * * TODO: * 01 - This function must enqueue the new sensor instead of using * it as the only source of temperature values. * * 02 - There must be a way to match the sensor with all thermal zones * that refer to it. * * Return: On success returns a valid struct thermal_zone_device, * otherwise, it returns a corresponding ERR_PTR(). Caller must * check the return value with help of IS_ERR() helper. */ struct thermal_zone_device * thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, const struct thermal_zone_of_device_ops *ops) { struct device_node *np, *child, *sensor_np; struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); np = of_find_node_by_name(NULL, "thermal-zones"); if (!np) return ERR_PTR(-ENODEV); if (!dev || !dev->of_node) { of_node_put(np); return ERR_PTR(-EINVAL); } sensor_np = of_node_get(dev->of_node); for_each_child_of_node(np, child) { struct of_phandle_args sensor_specs; int ret, id; /* Check whether child is enabled or not */ if (!of_device_is_available(child)) continue; /* For now, thermal framework supports only 1 sensor per zone */ ret = of_parse_phandle_with_args(child, "thermal-sensors", "#thermal-sensor-cells", 0, &sensor_specs); if (ret) continue; if (sensor_specs.args_count >= 1) { id = sensor_specs.args[0]; WARN(sensor_specs.args_count > 1, "%s: too many cells in sensor specifier %d\n", sensor_specs.np->name, sensor_specs.args_count); } else { id = 0; } if (sensor_specs.np == sensor_np && id == sensor_id) { tzd = thermal_zone_of_add_sensor(child, sensor_np, data, ops); of_node_put(sensor_specs.np); of_node_put(child); goto exit; } of_node_put(sensor_specs.np); } exit: of_node_put(sensor_np); of_node_put(np); return tzd; }
static int __init opal_init(void) { struct device_node *np, *consoles; int rc; opal_node = of_find_node_by_path("/ibm,opal"); if (!opal_node) { pr_warn("Device node not found\n"); return -ENODEV; } /* Register OPAL consoles if any ports */ if (firmware_has_feature(FW_FEATURE_OPALv2)) consoles = of_find_node_by_path("/ibm,opal/consoles"); else consoles = of_node_get(opal_node); if (consoles) { for_each_child_of_node(consoles, np) { if (strcmp(np->name, "serial")) continue; of_platform_device_create(np, NULL, NULL); } of_node_put(consoles); } /* Create i2c platform devices */ opal_i2c_create_devs(); /* Setup a heatbeat thread if requested by OPAL */ opal_init_heartbeat(); /* Find all OPAL interrupts and request them */ opal_irq_init(opal_node); /* Create "opal" kobject under /sys/firmware */ rc = opal_sysfs_init(); if (rc == 0) { /* Setup dump region interface */ opal_dump_region_init(); /* Setup error log interface */ rc = opal_elog_init(); /* Setup code update interface */ opal_flash_init(); /* Setup platform dump extract interface */ opal_platform_dump_init(); /* Setup system parameters interface */ opal_sys_param_init(); /* Setup message log interface. */ opal_msglog_init(); } /* Initialize OPAL IPMI backend */ opal_ipmi_init(opal_node); return 0; }
static int __init opal_init(void) { struct device_node *np, *consoles; const __be32 *irqs; int rc, i, irqlen; opal_node = of_find_node_by_path("/ibm,opal"); if (!opal_node) { pr_warn("opal: Node not found\n"); return -ENODEV; } /* Register OPAL consoles if any ports */ if (firmware_has_feature(FW_FEATURE_OPALv2)) consoles = of_find_node_by_path("/ibm,opal/consoles"); else consoles = of_node_get(opal_node); if (consoles) { for_each_child_of_node(consoles, np) { if (strcmp(np->name, "serial")) continue; of_platform_device_create(np, NULL, NULL); } of_node_put(consoles); } /* Find all OPAL interrupts and request them */ irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); pr_debug("opal: Found %d interrupts reserved for OPAL\n", irqs ? (irqlen / 4) : 0); opal_irq_count = irqlen / 4; opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL); for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) { unsigned int hwirq = be32_to_cpup(irqs); unsigned int irq = irq_create_mapping(NULL, hwirq); if (irq == NO_IRQ) { pr_warning("opal: Failed to map irq 0x%x\n", hwirq); continue; } rc = request_irq(irq, opal_interrupt, 0, "opal", NULL); if (rc) pr_warning("opal: Error %d requesting irq %d" " (0x%x)\n", rc, irq, hwirq); opal_irqs[i] = irq; } /* Create "opal" kobject under /sys/firmware */ rc = opal_sysfs_init(); if (rc == 0) { /* Setup code update interface */ opal_flash_init(); } return 0; }
static struct amba_device *of_amba_device_create(struct device_node *node, const char *bus_id, void *platform_data, struct device *parent) { struct amba_device *dev; const void *prop; int i, ret; pr_debug("Creating amba device %s\n", node->full_name); if (!of_device_is_available(node)) return NULL; dev = amba_device_alloc(NULL, 0, 0); if (!dev) return NULL; /* setup generic device info */ dev->dev.coherent_dma_mask = ~0; dev->dev.of_node = of_node_get(node); dev->dev.parent = parent; dev->dev.platform_data = platform_data; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); else of_device_make_bus_id(&dev->dev); /* setup amba-specific device info */ dev->dma_mask = ~0; /* Allow the HW Peripheral ID to be overridden */ prop = of_get_property(node, "arm,primecell-periphid", NULL); if (prop) dev->periphid = of_read_ulong(prop, 1); /* Decode the IRQs and address ranges */ for (i = 0; i < AMBA_NR_IRQS; i++) dev->irq[i] = irq_of_parse_and_map(node, i); ret = of_address_to_resource(node, 0, &dev->res); if (ret) goto err_free; ret = amba_device_add(dev, &iomem_resource); if (ret) goto err_free; return dev; err_free: amba_device_put(dev); return NULL; }
struct device_node *of_get_parent(const struct device_node *node) { const struct device_node *np; if (!node) return NULL; np = of_node_get(node->parent); return (struct device_node *)np; }
static struct device_node *__pcibios_get_phb_of_node(struct pci_bus *bus) { /* This should only be called for PHBs */ if (WARN_ON(bus->self || bus->parent)) return NULL; if (pcibios_get_phb_of_node) return pcibios_get_phb_of_node(bus); /* Look for a node pointer in either the intermediary device we * create above the root bus or it's own parent. Normally only * the later is populated. */ if (bus->bridge->of_node) return of_node_get(bus->bridge->of_node); if (bus->bridge->parent && bus->bridge->parent->of_node) return of_node_get(bus->bridge->parent->of_node); return NULL; }
/** * of_get_parent - Get a node's parent if any * @node: Node to get parent * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_get_parent(const struct device_node *node) { struct device_node *np; if (!node) return NULL; read_lock(&devtree_lock); np = of_node_get(node->parent); read_unlock(&devtree_lock); return np; }
/** * of_find_node_by_phandle - Find a node given a phandle * @handle: phandle of the node to find * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_find_node_by_phandle(phandle handle) { struct device_node *np; raw_spin_lock(&devtree_lock); for (np = of_allnodes; np; np = np->allnext) if (np->phandle == handle) break; of_node_get(np); raw_spin_unlock(&devtree_lock); return np; }
static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg) { struct device_node *dn; struct msi_desc *entry; int len; const u32 *prop; dn = of_node_get(pci_device_to_OF_node(dev)); if (!dn) { dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); return -ENODEV; } entry = first_pci_msi_entry(dev); for (; dn; dn = of_get_next_parent(dn)) { if (entry->msi_attrib.is_64) { prop = of_get_property(dn, "msi-address-64", &len); if (prop) break; } prop = of_get_property(dn, "msi-address-32", &len); if (prop) break; } if (!prop) { dev_dbg(&dev->dev, "axon_msi: no msi-address-(32|64) properties found\n"); return -ENOENT; } switch (len) { case 8: msg->address_hi = prop[0]; msg->address_lo = prop[1]; break; case 4: msg->address_hi = 0; msg->address_lo = prop[0]; break; default: dev_dbg(&dev->dev, "axon_msi: malformed msi-address-(32|64) property\n"); of_node_put(dn); return -EINVAL; } of_node_put(dn); return 0; }
static void vexpress_sysreg_find_prop(struct device_node *node, const char *name, u32 *val) { of_node_get(node); while (node) { if (of_property_read_u32(node, name, val) == 0) { of_node_put(node); return; } node = of_get_next_parent(node); } }
int of_platform_bus_probe(struct device_node *root, struct of_device_id *matches, struct device *parent) { struct device_node *child; struct of_device *dev; int rc = 0; if (matches == NULL) matches = of_default_bus_ids; if (matches == OF_NO_DEEP_PROBE) return -EINVAL; if (root == NULL) root = of_find_node_by_path("/"); else of_node_get(root); pr_debug("of_platform_bus_probe()\n"); pr_debug(" starting at: %s\n", root->full_name); /* Do a self check of bus type, if there's a match, create * children */ if (of_match_node(matches, root)) { pr_debug(" root match, create all sub devices\n"); dev = of_platform_device_create(root, NULL, parent); if (dev == NULL) { rc = -ENOMEM; goto bail; } pr_debug(" create all sub busses\n"); rc = of_platform_bus_create(root, matches, &dev->dev); goto bail; } for (child = NULL; (child = of_get_next_child(root, child)); ) { if (!of_match_node(matches, child)) continue; pr_debug(" match: %s\n", child->full_name); dev = of_platform_device_create(child, NULL, parent); if (dev == NULL) rc = -ENOMEM; else rc = of_platform_bus_create(child, matches, &dev->dev); if (rc) { of_node_put(child); break; } } bail: of_node_put(root); return rc; }
int of_mm_gpiochip_add(struct device_node *np, struct of_mm_gpio_chip *mm_gc) { int ret = -ENOMEM; struct of_gpio_chip *of_gc = &mm_gc->of_gc; if (of_gc->gc.ngpio > ARCH_OF_GPIOS_PER_CHIP) { ret = -ENOSPC; goto err; } mm_gc->of_gc.gc.label = kstrdup(np->full_name, GFP_KERNEL); if (!mm_gc->of_gc.gc.label) goto err; mm_gc->regs = of_iomap(np, 0); if (!mm_gc->regs) goto err1; ret = of_get_gpiochip_base(np); if (ret < 0) goto err2; mm_gc->of_gc.gc.base = ret; if (!of_gc->xlate) of_gc->xlate = of_gpio_simple_xlate; if (mm_gc->save_regs) mm_gc->save_regs(mm_gc); np->data = &mm_gc->of_gc; ret = gpiochip_add(&mm_gc->of_gc.gc); if (ret) goto err3; /* We don't want to lose the node and its ->data */ of_node_get(np); pr_debug("%s: registered as generic GPIO chip, base is %d\n", np->full_name, mm_gc->of_gc.gc.base); return 0; err3: np->data = NULL; err2: iounmap(mm_gc->regs); err1: kfree(mm_gc->of_gc.gc.label); err: pr_err("%s: GPIO chip registration failed with status %d\n", np->full_name, ret); return ret; }
struct vexpress_config_func *__vexpress_config_func_get(struct device *dev, struct device_node *node) { struct device_node *bridge_node; struct vexpress_config_func *func; int i; if (WARN_ON(dev && node && dev->of_node != node)) return NULL; if (dev && !node) node = dev->of_node; func = kzalloc(sizeof(*func), GFP_KERNEL); if (!func) return NULL; bridge_node = of_node_get(node); while (bridge_node) { const __be32 *prop = of_get_property(bridge_node, "arm,vexpress,config-bridge", NULL); if (prop) { bridge_node = of_find_node_by_phandle( be32_to_cpup(prop)); break; } bridge_node = of_get_next_parent(bridge_node); } mutex_lock(&vexpress_config_bridges_mutex); for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++) { struct vexpress_config_bridge *bridge = &vexpress_config_bridges[i]; if (test_bit(i, vexpress_config_bridges_map) && bridge->node == bridge_node) { func->bridge = bridge; func->func = bridge->info->func_get(dev, node); break; } } mutex_unlock(&vexpress_config_bridges_mutex); if (!func->func) { of_node_put(node); kfree(func); return NULL; } return func; }
void __init tsi108_pci_int_init(struct device_node *node) { DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); pci_irq_node = of_node_get(node); pci_irq_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &pci_irq_host_ops, 0); if (pci_irq_host == NULL) { printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n"); return; } init_pci_source(); }
/** * of_get_next_parent - Iterate to a node's parent * @node: Node to get parent of * * This is like of_get_parent() except that it drops the * refcount on the passed node, making it suitable for iterating * through a node's parents. * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_get_next_parent(struct device_node *node) { struct device_node *parent; if (!node) return NULL; read_lock(&devtree_lock); parent = of_node_get(node->parent); of_node_put(node); read_unlock(&devtree_lock); return parent; }
/** * of_get_parent - Get a node's parent if any * @node: Node to get parent * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_get_parent(const struct device_node *node) { struct device_node *np; unsigned long flags; if (!node) return NULL; raw_spin_lock_irqsave(&devtree_lock, flags); np = of_node_get(node->parent); raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; }
/** * of_find_all_nodes - Get next node in global list * @prev: Previous node or NULL to start iteration * of_node_put() will be called on it * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_find_all_nodes(struct device_node *prev) { struct device_node *np; raw_spin_lock(&devtree_lock); np = prev ? prev->allnext : of_allnodes; for (; np != NULL; np = np->allnext) if (of_node_get(np)) break; of_node_put(prev); raw_spin_unlock(&devtree_lock); return np; }
/** * of_find_node_by_path - Find a node matching a full OF path * @path: The full path to match * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_find_node_by_path(const char *path) { struct device_node *np = allnodes; read_lock(&devtree_lock); for (; np; np = np->allnext) { if (np->full_name && (of_node_cmp(np->full_name, path) == 0) && of_node_get(np)) break; } read_unlock(&devtree_lock); return np; }
static struct act8931_board *act8931_parse_dt(struct act8931 *act8931) { struct act8931_board *pdata; struct device_node *regs; struct device_node *node; int i, count; node = of_node_get(act8931->dev->of_node); if (!node) { pr_err("%s: could not find pmic node\n", __func__); return NULL; } regs = of_get_child_by_name(node, "regulators"); if (!regs) return NULL; count = of_regulator_match(act8931->dev, regs, act8931_reg_matches, ACT8931_NUM_REGULATORS); of_node_put(regs); if ((count < 0) || (count > ACT8931_NUM_REGULATORS)) return NULL; pdata = devm_kzalloc(act8931->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return NULL; for (i = 0; i < count; i++) { pdata->act8931_init_data[i] = act8931_reg_matches[i].init_data; pdata->of_node[i] = act8931_reg_matches[i].of_node; } pdata->irq_gpio = of_get_named_gpio(node, "gpios", 0); if (!gpio_is_valid(pdata->irq_gpio)) { pr_err("%s: invalid gpio: %d\n", __func__, pdata->irq_gpio); return NULL; } pdata->pwr_hold_gpio = of_get_named_gpio(node, "gpios", 1); if (!gpio_is_valid(pdata->pwr_hold_gpio)) { pr_err("%s: invalid gpio: %d\n", __func__, pdata->pwr_hold_gpio); return NULL; } pdata->pm_off = of_property_read_bool(node, "act8931,system-power-controller"); return pdata; }
/** * of_find_node_by_path - Find a node matching a full OF path * @path: The full path to match * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_find_node_by_path(const char *path) { struct device_node *np = of_allnodes; unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); for (; np; np = np->allnext) { if (np->full_name && (of_node_cmp(np->full_name, path) == 0) && of_node_get(np)) break; } raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; }
static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np) { struct device_node *iter; u32 reg; for_each_child_of_node(np, iter) { if (of_property_read_u32(np, "nvidia,ram-code", ®)) continue; if (reg == tegra_bct_strapping) return of_node_get(iter); } return NULL; }
/** * of_get_next_parent - Iterate to a node's parent * @node: Node to get parent of * * This is like of_get_parent() except that it drops the * refcount on the passed node, making it suitable for iterating * through a node's parents. * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_get_next_parent(struct device_node *node) { struct device_node *parent; unsigned long flags; if (!node) return NULL; raw_spin_lock_irqsave(&devtree_lock, flags); parent = of_node_get(node->parent); of_node_put(node); raw_spin_unlock_irqrestore(&devtree_lock, flags); return parent; }
/** * of_dma_is_coherent - Check if device is coherent * @np: device node * * It returns true if "dma-coherent" property was found * for this device in DT. */ bool of_dma_is_coherent(struct device_node *np) { struct device_node *node = of_node_get(np); while (node) { if (of_property_read_bool(node, "dma-coherent")) { of_node_put(node); return true; } node = of_get_next_parent(node); } of_node_put(node); return false; }
/** * of_irq_find_parent - Given a device node, find its interrupt parent node * @child: pointer to device node * * Returns a pointer to the interrupt parent node, or NULL if the interrupt * parent could not be determined. */ struct device_node *of_irq_find_parent(struct device_node *child) { struct device_node *p; phandle parent; if (!of_node_get(child)) return NULL; do { if (of_property_read_u32(child, "interrupt-parent", &parent)) { p = of_get_parent(child); } else { if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) p = of_node_get(of_irq_dflt_pic); else p = of_find_node_by_phandle(parent); } of_node_put(child); child = p; } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); return p; }
static int __init arch_timer_mem_init(struct device_node *np) { struct device_node *frame, *best_frame = NULL; void __iomem *cntctlbase, *base; unsigned int irq, ret = -EINVAL; u32 cnttidr; arch_timers_present |= ARCH_MEM_TIMER; cntctlbase = of_iomap(np, 0); if (!cntctlbase) { pr_err("arch_timer: Can't find CNTCTLBase\n"); return -ENXIO; } cnttidr = readl_relaxed(cntctlbase + CNTTIDR); /* * Try to find a virtual capable frame. Otherwise fall back to a * physical capable frame. */ for_each_available_child_of_node(np, frame) { int n; u32 cntacr; if (of_property_read_u32(frame, "frame-number", &n)) { pr_err("arch_timer: Missing frame-number\n"); of_node_put(frame); goto out; } /* Try enabling everything, and see what sticks */ cntacr = CNTACR_RFRQ | CNTACR_RWPT | CNTACR_RPCT | CNTACR_RWVT | CNTACR_RVOFF | CNTACR_RVCT; writel_relaxed(cntacr, cntctlbase + CNTACR(n)); cntacr = readl_relaxed(cntctlbase + CNTACR(n)); if ((cnttidr & CNTTIDR_VIRT(n)) && !(~cntacr & (CNTACR_RWVT | CNTACR_RVCT))) { of_node_put(best_frame); best_frame = frame; arch_timer_mem_use_virtual = true; break; } if (~cntacr & (CNTACR_RWPT | CNTACR_RPCT)) continue; of_node_put(best_frame); best_frame = of_node_get(frame); }