Пример #1
0
/**
 * of_platform_device_create_pdata - Alloc, initialize and register an of_device
 * @np: pointer to node to create device for
 * @bus_id: name to assign device
 * @platform_data: pointer to populate platform_data pointer with
 * @parent: Linux device model parent device.
 *
 * Returns pointer to created platform device, or NULL if a device was not
 * registered.  Unavailable devices will not get registered.
 */
static struct platform_device *of_platform_device_create_pdata(
    struct device_node *np,
    const char *bus_id,
    void *platform_data,
    struct device *parent)
{
    struct platform_device *dev;

    if (!of_device_is_available(np) ||
            of_node_test_and_set_flag(np, OF_POPULATED))
        return NULL;

    dev = of_device_alloc(np, bus_id, parent);
    if (!dev)
        goto err_clear_flag;

    dev->dev.bus = &platform_bus_type;
    dev->dev.platform_data = platform_data;
    of_dma_configure(&dev->dev, dev->dev.of_node);
    of_msi_configure(&dev->dev, dev->dev.of_node);

    if (of_device_add(dev) != 0) {
        of_dma_deconfigure(&dev->dev);
        platform_device_put(dev);
        goto err_clear_flag;
    }

    return dev;

err_clear_flag:
    of_node_clear_flag(np, OF_POPULATED);
    return NULL;
}
Пример #2
0
void of_i2c_register_devices(struct i2c_adapter *adap)
{
	struct device_node *bus, *node;
	struct i2c_client *client;

	/* Only register child devices if the adapter has a node pointer set */
	if (!adap->dev.of_node)
		return;

	dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");

	bus = of_get_child_by_name(adap->dev.of_node, "i2c-bus");
	if (!bus)
		bus = of_node_get(adap->dev.of_node);

	for_each_available_child_of_node(bus, node) {
		if (of_node_test_and_set_flag(node, OF_POPULATED))
			continue;

		client = of_i2c_register_device(adap, node);
		if (IS_ERR(client)) {
			dev_err(&adap->dev,
				 "Failed to create I2C device for %pOF\n",
				 node);
			of_node_clear_flag(node, OF_POPULATED);
		}
	}

	of_node_put(bus);
}
Пример #3
0
static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
			 void *arg)
{
	struct of_reconfig_data *rd = arg;
	struct i2c_adapter *adap;
	struct i2c_client *client;

	switch (of_reconfig_get_state_change(action, rd)) {
	case OF_RECONFIG_CHANGE_ADD:
		adap = of_find_i2c_adapter_by_node(rd->dn->parent);
		if (adap == NULL)
			return NOTIFY_OK;	/* not for us */

		if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) {
			put_device(&adap->dev);
			return NOTIFY_OK;
		}

		client = of_i2c_register_device(adap, rd->dn);
		put_device(&adap->dev);

		if (IS_ERR(client)) {
			dev_err(&adap->dev, "failed to create client for '%pOF'\n",
				 rd->dn);
			of_node_clear_flag(rd->dn, OF_POPULATED);
			return notifier_from_errno(PTR_ERR(client));
		}
		break;
	case OF_RECONFIG_CHANGE_REMOVE:
		/* already depopulated? */
		if (!of_node_check_flag(rd->dn, OF_POPULATED))
			return NOTIFY_OK;

		/* find our device by node */
		client = of_find_i2c_device_by_node(rd->dn);
		if (client == NULL)
			return NOTIFY_OK;	/* no? not meant for us */

		/* unregister takes one ref away */
		i2c_unregister_device(client);

		/* and put the reference of the find */
		put_device(&client->dev);
		break;
	}

	return NOTIFY_OK;
}
Пример #4
0
static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
{
	struct clk_hw *hw;
	const char *clk_name = node->name;
	unsigned long flags = 0;
	u32 div, mult;
	int ret;

	if (of_property_read_u32(node, "clock-div", &div)) {
		pr_err("%s Fixed factor clock <%pOFn> must have a clock-div property\n",
			__func__, node);
		return ERR_PTR(-EIO);
	}

	if (of_property_read_u32(node, "clock-mult", &mult)) {
		pr_err("%s Fixed factor clock <%pOFn> must have a clock-mult property\n",
			__func__, node);
		return ERR_PTR(-EIO);
	}

	of_property_read_string(node, "clock-output-names", &clk_name);

	if (of_match_node(set_rate_parent_matches, node))
		flags |= CLK_SET_RATE_PARENT;

	hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
					    flags, mult, div);
	if (IS_ERR(hw)) {
		/*
		 * Clear OF_POPULATED flag so that clock registration can be
		 * attempted again from probe function.
		 */
		of_node_clear_flag(node, OF_POPULATED);
		return ERR_CAST(hw);
	}

	ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
	if (ret) {
		clk_hw_unregister_fixed_factor(hw);
		return ERR_PTR(ret);
	}

	return hw;
}
Пример #5
0
static int __init imx_gpc_init(struct device_node *node,
			       struct device_node *parent)
{
	struct irq_domain *parent_domain, *domain;
	int i;

	if (!parent) {
		pr_err("%pOF: no parent, giving up\n", node);
		return -ENODEV;
	}

	parent_domain = irq_find_host(parent);
	if (!parent_domain) {
		pr_err("%pOF: unable to obtain parent domain\n", node);
		return -ENXIO;
	}

	gpc_base = of_iomap(node, 0);
	if (WARN_ON(!gpc_base))
	        return -ENOMEM;

	domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
					  node, &imx_gpc_domain_ops,
					  NULL);
	if (!domain) {
		iounmap(gpc_base);
		return -ENOMEM;
	}

	/* Initially mask all interrupts */
	for (i = 0; i < IMR_NUM; i++)
		writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);

	/*
	 * Clear the OF_POPULATED flag set in of_irq_init so that
	 * later the GPC power domain driver will not be skipped.
	 */
	of_node_clear_flag(node, OF_POPULATED);

	return 0;
}
Пример #6
0
static int __init exynos_pmu_irq_init(struct device_node *node,
				      struct device_node *parent)
{
	struct irq_domain *parent_domain, *domain;

	if (!parent) {
		pr_err("%s: no parent, giving up\n", node->full_name);
		return -ENODEV;
	}

	parent_domain = irq_find_host(parent);
	if (!parent_domain) {
		pr_err("%s: unable to obtain parent domain\n", node->full_name);
		return -ENXIO;
	}

	pmu_base_addr = of_iomap(node, 0);

	if (!pmu_base_addr) {
		pr_err("%s: failed to find exynos pmu register\n",
		       node->full_name);
		return -ENOMEM;
	}

	domain = irq_domain_add_hierarchy(parent_domain, 0, 0,
					  node, &exynos_pmu_domain_ops,
					  NULL);
	if (!domain) {
		iounmap(pmu_base_addr);
		return -ENOMEM;
	}

	/*
	 * Clear the OF_POPULATED flag set in of_irq_init so that
	 * later the Exynos PMU platform device won't be skipped.
	 */
	of_node_clear_flag(node, OF_POPULATED);

	return 0;
}
Пример #7
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) ||
            of_node_test_and_set_flag(node, OF_POPULATED))
        return NULL;

    dev = amba_device_alloc(NULL, 0, 0);
    if (!dev)
        goto err_clear_flag;

    /* setup generic device info */
    dev->dev.of_node = of_node_get(node);
    dev->dev.fwnode = &node->fwnode;
    dev->dev.parent = parent ? : &platform_bus;
    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);
    of_dma_configure(&dev->dev, dev->dev.of_node);

    /* 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) {
        pr_err("amba: of_address_to_resource() failed (%d) for %s\n",
               ret, node->full_name);
        goto err_free;
    }

    ret = amba_device_add(dev, &iomem_resource);
    if (ret) {
        pr_err("amba_device_add() failed (%d) for %s\n",
               ret, node->full_name);
        goto err_free;
    }

    return dev;

err_free:
    amba_device_put(dev);
err_clear_flag:
    of_node_clear_flag(node, OF_POPULATED);
    return NULL;
}