Esempio n. 1
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);
}
Esempio n. 2
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;
}
Esempio n. 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;
}
Esempio n. 4
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;
}