示例#1
0
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;
}
示例#2
0
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;
}
示例#3
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;
}
示例#4
0
/**
 * 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;
		}
	}
示例#5
0
/**
 * 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;
}
示例#6
0
/**
 * 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;
}
示例#7
0
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;
}
示例#9
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;
}
示例#10
0
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;
}
示例#11
0
文件: of.c 项目: janfj/dd-wrt
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;
}
示例#12
0
文件: base.c 项目: NooNameR/k3_bravo
/**
 *	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;
}
示例#13
0
/**
 * 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;
}
示例#14
0
文件: axon_msi.c 项目: DenisLug/mptcp
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;
}
示例#15
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);
	}
}
示例#16
0
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;
}
示例#17
0
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;
}
示例#18
0
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;
}
示例#19
0
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();
}
示例#20
0
文件: base.c 项目: NooNameR/k3_bravo
/**
 *	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;
}
示例#21
0
/**
 *	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;
}
示例#22
0
/**
 * 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;
}
示例#23
0
文件: base.c 项目: NooNameR/k3_bravo
/**
 *	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;
}
示例#25
0
/**
 *	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;
}
示例#26
0
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", &reg))
			continue;
		if (reg == tegra_bct_strapping)
			return of_node_get(iter);
	}

	return NULL;
}
示例#27
0
/**
 *	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;
}
示例#28
0
/**
 * 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;
}
示例#29
0
文件: irq.c 项目: Lyude/linux
/**
 * 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;
}
示例#30
0
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);
	}