Ejemplo n.º 1
0
/**
 * fwnode_property_read_string - return a string property of a firmware node
 * @fwnode: Firmware node to get the property of
 * @propname: Name of the property
 * @val: The value is stored here
 *
 * Read property @propname from the given firmware node and store the value into
 * @val if found.  The value is checked to be a string.
 *
 * Return: %0 if the property was found (success),
 *	   %-EINVAL if given arguments are not valid,
 *	   %-ENODATA if the property does not have a value,
 *	   %-EPROTO or %-EILSEQ if the property is not a string,
 *	   %-ENXIO if no suitable firmware interface is present.
 */
int fwnode_property_read_string(struct fwnode_handle *fwnode,
				const char *propname, const char **val)
{
	if (is_of_node(fwnode))
		return of_property_read_string(to_of_node(fwnode), propname, val);
	else if (is_acpi_node(fwnode))
		return acpi_dev_prop_read(to_a
Ejemplo n.º 2
0
/**
 * fwnode_property_read_string_array - return string array property of a node
 * @fwnode: Firmware node to get the property of
 * @propname: Name of the property
 * @val: The values are stored here or %NULL to return the number of values
 * @nval: Size of the @val array
 *
 * Read an string list property @propname from the given firmware node and store
 * them to @val if found.
 *
 * Return: number of values if @val was %NULL,
 *         %0 if the property was found (success),
 *	   %-EINVAL if given arguments are not valid,
 *	   %-ENODATA if the property does not have a value,
 *	   %-EPROTO if the property is not an array of strings,
 *	   %-EOVERFLOW if the size of the property is not as expected,
 *	   %-ENXIO if no suitable firmware interface is present.
 */
int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
                                      const char *propname, const char **val,
                                      size_t nval)
{
    if (is_of_node(fwnode))
        return val ?
               of_property_read_string_array(to_of_node(fwnode),
                                             propname, val, nval) :
               of_property_count_strings(to_of_node(fwnode), propname);
    else if (is_acpi_node(fwnode))
        return acpi_dev_prop_read(to_acpi_node(fwnode), propname,
                                  DEV_PROP_STRING, val, nval);

    return pset_prop_read_array(to_pset(fwnode), propname,
                                DEV_PROP_STRING, val, nval);
}
Ejemplo n.º 3
0
/**
 * fwnode_property_present - check if a property of a firmware node is present
 * @fwnode: Firmware node whose property to check
 * @propname: Name of the property
 */
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
{
    if (is_of_node(fwnode))
        return of_property_read_bool(to_of_node(fwnode), propname);
    else if (is_acpi_node(fwnode))
        return !acpi_dev_prop_get(to_acpi_node(fwnode), propname, NULL);

    return !!pset_prop_get(to_pset(fwnode), propname);
}
Ejemplo n.º 4
0
static int __fwnode_property_read_string(struct fwnode_handle *fwnode,
					 const char *propname, const char **val)
{
	if (is_of_node(fwnode))
		return of_property_read_string(to_of_node(fwnode), propname, val);
	else if (is_acpi_node(fwnode))
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, 1);
	else if (is_pset_node(fwnode))
		return pset_prop_read_string(to_pset_node(fwnode), propname, val);
	return -ENXIO;
}
Ejemplo n.º 5
0
static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
					       const char *propname,
					       const char **val, size_t nval)
{
	if (is_of_node(fwnode))
		return val ?
			of_property_read_string_array(to_of_node(fwnode),
						      propname, val, nval) :
			of_property_count_strings(to_of_node(fwnode), propname);
	else if (is_acpi_node(fwnode))
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, nval);
	else if (is_pset_node(fwnode))
		return val ?
			pset_prop_read_string_array(to_pset_node(fwnode),
						    propname, val, nval) :
			pset_prop_count_elems_of_size(to_pset_node(fwnode),
						      propname,
						      sizeof(const char *));
	return -ENXIO;
}
Ejemplo n.º 6
0
/**
 * fwnode_property_read_string - return a string property of a firmware node
 * @fwnode: Firmware node to get the property of
 * @propname: Name of the property
 * @val: The value is stored here
 *
 * Read property @propname from the given firmware node and store the value into
 * @val if found.  The value is checked to be a string.
 *
 * Return: %0 if the property was found (success),
 *	   %-EINVAL if given arguments are not valid,
 *	   %-ENODATA if the property does not have a value,
 *	   %-EPROTO or %-EILSEQ if the property is not a string,
 *	   %-ENXIO if no suitable firmware interface is present.
 */
int fwnode_property_read_string(struct fwnode_handle *fwnode,
				const char *propname, const char **val)
{
	if (is_of_node(fwnode))
		return of_property_read_string(to_of_node(fwnode), propname, val);
	else if (is_acpi_node(fwnode))
		return acpi_dev_prop_read(to_acpi_node(fwnode), propname,
					  DEV_PROP_STRING, val, 1);

	return pset_prop_read_array(to_pset(fwnode), propname,
				    DEV_PROP_STRING, val, 1);
}
Ejemplo n.º 7
0
/**
 * device_get_next_child_node - Return the next child node handle for a device
 * @dev: Device to find the next child node for.
 * @child: Handle to one of the device's child nodes or a null handle.
 */
struct fwnode_handle *device_get_next_child_node(struct device *dev,
						 struct fwnode_handle *child)
{
	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
		struct device_node *node;

		node = of_get_next_available_child(dev->of_node, to_of_node(child));
		if (node)
			return &node->fwnode;
	} else if (IS_ENABLED(CONFIG_ACPI)) {
		return acpi_get_next_subnode(dev, child);
	}
	return NULL;
}
Ejemplo n.º 8
0
/**
 * fwnode_irq_get - Get IRQ directly from a fwnode
 * @fwnode:	Pointer to the firmware node
 * @index:	Zero-based index of the IRQ
 *
 * Returns Linux IRQ number on success. Other values are determined
 * accordingly to acpi_/of_ irq_get() operation.
 */
int fwnode_irq_get(struct fwnode_handle *fwnode, unsigned int index)
{
	struct device_node *of_node = to_of_node(fwnode);
	struct resource res;
	int ret;

	if (IS_ENABLED(CONFIG_OF) && of_node)
		return of_irq_get(of_node, index);

	ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res);
	if (ret)
		return ret;

	return res.start;
}
Ejemplo n.º 9
0
/**
 * fwnode_get_reference_node - Find the firmware node referenced
 * @fwnode: Firmware node to get the property from.
 * @propname: Name of the property
 * @index: Index of the reference
 *
 * Returns referenced fwnode handler pointer, or an NULL if not found
 */
struct fwnode_handle *fwnode_get_reference_node(struct fwnode_handle *fwnode,
					 const char *propname, int index)
{
	if (is_of_node(fwnode)) {
		struct device_node *np;
		np = of_parse_phandle(to_of_node(fwnode), propname, index);
		if(!np)
			return NULL;
		return &np->fwnode;
	} else if (is_acpi_node(fwnode)) {
		struct acpi_device *adev;
		adev = acpi_dev_get_reference_device(to_acpi_device_node(fwnode),
						     propname, index);
		if(!adev)
			return NULL;
		return acpi_fwnode_handle(adev);
	}
	return NULL;
}
Ejemplo n.º 10
0
/**
 * device_get_named_child_node - Return first matching named child node handle
 * @dev: Device to find the named child node for.
 * @childname: String to match child node name against.
 */
struct fwnode_handle *device_get_named_child_node(struct device *dev,
						  const char *childname)
{
	struct fwnode_handle *child;

	/*
	 * Find first matching named child node of this device.
	 * For ACPI this will be a data only sub-node.
	 */
	device_for_each_child_node(dev, child) {
		if (is_of_node(child)) {
			if (!of_node_cmp(to_of_node(child)->name, childname))
				return child;
		} else if (is_acpi_data_node(child)) {
			if (acpi_data_node_match(child, childname))
				return child;
		}
	}

	return NULL;
}
Ejemplo n.º 11
0
static int rvin_digital_graph_init(struct rvin_dev *vin)
{
	struct v4l2_async_subdev **subdevs = NULL;
	int ret;

	ret = rvin_digital_graph_parse(vin);
	if (ret)
		return ret;

	if (!vin->digital.asd.match.fwnode.fwnode) {
		vin_dbg(vin, "No digital subdevice found\n");
		return -ENODEV;
	}

	/* Register the subdevices notifier. */
	subdevs = devm_kzalloc(vin->dev, sizeof(*subdevs), GFP_KERNEL);
	if (subdevs == NULL)
		return -ENOMEM;

	subdevs[0] = &vin->digital.asd;

	vin_dbg(vin, "Found digital subdevice %s\n",
		of_node_full_name(to_of_node(subdevs[0]->match.fwnode.fwnode)));

	vin->notifier.num_subdevs = 1;
	vin->notifier.subdevs = subdevs;
	vin->notifier.bound = rvin_digital_notify_bound;
	vin->notifier.unbind = rvin_digital_notify_unbind;
	vin->notifier.complete = rvin_digital_notify_complete;

	ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
	if (ret < 0) {
		vin_err(vin, "Notifier registration failed\n");
		return ret;
	}

	return 0;
}
Ejemplo n.º 12
0
/**
 * __irq_domain_add() - Allocate a new irq_domain data structure
 * @fwnode: firmware node for the interrupt controller
 * @size: Size of linear map; 0 for radix mapping only
 * @hwirq_max: Maximum number of interrupts supported by controller
 * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
 *              direct mapping
 * @ops: domain callbacks
 * @host_data: Controller private data pointer
 *
 * Allocates and initialize and irq_domain structure.
 * Returns pointer to IRQ domain, or NULL on failure.
 */
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
				    irq_hw_number_t hwirq_max, int direct_max,
				    const struct irq_domain_ops *ops,
				    void *host_data)
{
	struct device_node *of_node = to_of_node(fwnode);
	struct irqchip_fwid *fwid;
	struct irq_domain *domain;

	static atomic_t unknown_domains;

	domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size),
			      GFP_KERNEL, of_node_to_nid(of_node));
	if (WARN_ON(!domain))
		return NULL;

	if (fwnode && is_fwnode_irqchip(fwnode)) {
		fwid = container_of(fwnode, struct irqchip_fwid, fwnode);

		switch (fwid->type) {
		case IRQCHIP_FWNODE_NAMED:
		case IRQCHIP_FWNODE_NAMED_ID:
			domain->name = kstrdup(fwid->name, GFP_KERNEL);
			if (!domain->name) {
				kfree(domain);
				return NULL;
			}
			domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
			break;
		default:
			domain->fwnode = fwnode;
			domain->name = fwid->name;
			break;
		}
#ifdef CONFIG_ACPI
	} else if (is_acpi_device_node(fwnode)) {
Ejemplo n.º 13
0
/**
 * fwnode_handle_put - Drop reference to a device node
 * @fwnode: Pointer to the device node to drop the reference to.
 *
 * This has to be used when terminating device_for_each_child_node() iteration
 * with break or return to prevent stale device node references from being left
 * behind.
 */
void fwnode_handle_put(struct fwnode_handle *fwnode)
{
	if (is_of_node(fwnode))
		of_node_put(to_of_node(fwnode));
}
Ejemplo n.º 14
0
/**
 * platform_device_register_full - add a platform-level device with
 * resources and platform-specific data
 *
 * @pdevinfo: data used to create device
 *
 * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
 */
struct platform_device *platform_device_register_full(
		const struct platform_device_info *pdevinfo)
{
	int ret = -ENOMEM;
	struct platform_device *pdev;

	pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);
	if (!pdev)
		return ERR_PTR(-ENOMEM);

	pdev->dev.parent = pdevinfo->parent;
	pdev->dev.fwnode = pdevinfo->fwnode;
	pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode));
	pdev->dev.of_node_reused = pdevinfo->of_node_reused;

	if (pdevinfo->dma_mask) {
		/*
		 * This memory isn't freed when the device is put,
		 * I don't have a nice idea for that though.  Conceptually
		 * dma_mask in struct device should not be a pointer.
		 * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
		 */
		pdev->dev.dma_mask =
			kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
		if (!pdev->dev.dma_mask)
			goto err;

		kmemleak_ignore(pdev->dev.dma_mask);

		*pdev->dev.dma_mask = pdevinfo->dma_mask;
		pdev->dev.coherent_dma_mask = pdevinfo->dma_mask;
	}

	ret = platform_device_add_resources(pdev,
			pdevinfo->res, pdevinfo->num_res);
	if (ret)
		goto err;

	ret = platform_device_add_data(pdev,
			pdevinfo->data, pdevinfo->size_data);
	if (ret)
		goto err;

	if (pdevinfo->properties) {
		ret = platform_device_add_properties(pdev,
						     pdevinfo->properties);
		if (ret)
			goto err;
	}

	ret = platform_device_add(pdev);
	if (ret) {
err:
		ACPI_COMPANION_SET(&pdev->dev, NULL);
		kfree(pdev->dev.dma_mask);
		platform_device_put(pdev);
		return ERR_PTR(ret);
	}

	return pdev;
}
Ejemplo n.º 15
0
/*
 * Translate properties into platform_data
 */
static struct gpio_keys_platform_data *
gpio_keys_get_devtree_pdata(struct device *dev)
{
	struct gpio_keys_platform_data *pdata;
	struct gpio_keys_button *button;
	struct fwnode_handle *child;
	int nbuttons;

	nbuttons = device_get_child_node_count(dev);
	if (nbuttons == 0)
		return ERR_PTR(-ENODEV);

	pdata = devm_kzalloc(dev,
			     sizeof(*pdata) + nbuttons * sizeof(*button),
			     GFP_KERNEL);
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	button = (struct gpio_keys_button *)(pdata + 1);

	pdata->buttons = button;
	pdata->nbuttons = nbuttons;

	pdata->rep = device_property_read_bool(dev, "autorepeat");

	device_property_read_string(dev, "label", &pdata->name);

	device_for_each_child_node(dev, child) {
		if (is_of_node(child))
			button->irq =
				irq_of_parse_and_map(to_of_node(child), 0);

		if (fwnode_property_read_u32(child, "linux,code",
					     &button->code)) {
			dev_err(dev, "Button without keycode\n");
			fwnode_handle_put(child);
			return ERR_PTR(-EINVAL);
		}

		fwnode_property_read_string(child, "label", &button->desc);

		if (fwnode_property_read_u32(child, "linux,input-type",
					     &button->type))
			button->type = EV_KEY;

		button->wakeup =
			fwnode_property_read_bool(child, "wakeup-source") ||
			/* legacy name */
			fwnode_property_read_bool(child, "gpio-key,wakeup");

		button->can_disable =
			fwnode_property_read_bool(child, "linux,can-disable");

		if (fwnode_property_read_u32(child, "debounce-interval",
					 &button->debounce_interval))
			button->debounce_interval = 5;

		button++;
	}

	return pdata;
}