Merge branch 'device-properties'
* device-properties: device property: Introduce firmware node type for platform data device property: Make it possible to use secondary firmware nodes driver core: Implement device property accessors through fwnode ones driver core: property: Update fwnode_property_read_string_array() driver core: Add comments about returning array counts ACPI: Introduce has_acpi_companion() driver core / ACPI: Represent ACPI companions using fwnode_handle
This commit is contained in:
Коммит
9a9ca16e7a
|
@ -102,7 +102,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
|
|||
pdevinfo.id = -1;
|
||||
pdevinfo.res = resources;
|
||||
pdevinfo.num_res = count;
|
||||
pdevinfo.acpi_node.companion = adev;
|
||||
pdevinfo.fwnode = acpi_fwnode_handle(adev);
|
||||
pdevinfo.dma_mask = DMA_BIT_MASK(32);
|
||||
pdev = platform_device_register_full(&pdevinfo);
|
||||
if (IS_ERR(pdev))
|
||||
|
|
|
@ -615,7 +615,7 @@ void acpi_dock_add(struct acpi_device *adev)
|
|||
memset(&pdevinfo, 0, sizeof(pdevinfo));
|
||||
pdevinfo.name = "dock";
|
||||
pdevinfo.id = dock_station_count;
|
||||
pdevinfo.acpi_node.companion = adev;
|
||||
pdevinfo.fwnode = acpi_fwnode_handle(adev);
|
||||
pdevinfo.data = &ds;
|
||||
pdevinfo.size_data = sizeof(ds);
|
||||
dd = platform_device_register_full(&pdevinfo);
|
||||
|
|
|
@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
unsigned int node_id;
|
||||
int retval = -EINVAL;
|
||||
|
||||
if (ACPI_COMPANION(dev)) {
|
||||
if (has_acpi_companion(dev)) {
|
||||
if (acpi_dev) {
|
||||
dev_warn(dev, "ACPI companion already set\n");
|
||||
return -EINVAL;
|
||||
|
@ -220,7 +220,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
list_add(&physical_node->node, physnode_list);
|
||||
acpi_dev->physical_node_count++;
|
||||
|
||||
if (!ACPI_COMPANION(dev))
|
||||
if (!has_acpi_companion(dev))
|
||||
ACPI_COMPANION_SET(dev, acpi_dev);
|
||||
|
||||
acpi_physnode_link_name(physical_node_name, node_id);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -2133,3 +2134,53 @@ define_dev_printk_level(dev_notice, KERN_NOTICE);
|
|||
define_dev_printk_level(_dev_info, KERN_INFO);
|
||||
|
||||
#endif
|
||||
|
||||
static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return fwnode && !IS_ERR(fwnode->secondary);
|
||||
}
|
||||
|
||||
/**
|
||||
* set_primary_fwnode - Change the primary firmware node of a given device.
|
||||
* @dev: Device to handle.
|
||||
* @fwnode: New primary firmware node of the device.
|
||||
*
|
||||
* Set the device's firmware node pointer to @fwnode, but if a secondary
|
||||
* firmware node of the device is present, preserve it.
|
||||
*/
|
||||
void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
||||
{
|
||||
if (fwnode) {
|
||||
struct fwnode_handle *fn = dev->fwnode;
|
||||
|
||||
if (fwnode_is_primary(fn))
|
||||
fn = fn->secondary;
|
||||
|
||||
fwnode->secondary = fn;
|
||||
dev->fwnode = fwnode;
|
||||
} else {
|
||||
dev->fwnode = fwnode_is_primary(dev->fwnode) ?
|
||||
dev->fwnode->secondary : NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(set_primary_fwnode);
|
||||
|
||||
/**
|
||||
* set_secondary_fwnode - Change the secondary firmware node of a given device.
|
||||
* @dev: Device to handle.
|
||||
* @fwnode: New secondary firmware node of the device.
|
||||
*
|
||||
* If a primary firmware node of the device is present, set its secondary
|
||||
* pointer to @fwnode. Otherwise, set the device's firmware node pointer to
|
||||
* @fwnode.
|
||||
*/
|
||||
void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
||||
{
|
||||
if (fwnode)
|
||||
fwnode->secondary = ERR_PTR(-ENODEV);
|
||||
|
||||
if (fwnode_is_primary(dev->fwnode))
|
||||
dev->fwnode->secondary = fwnode;
|
||||
else
|
||||
dev->fwnode = fwnode;
|
||||
}
|
||||
|
|
|
@ -454,7 +454,7 @@ struct platform_device *platform_device_register_full(
|
|||
goto err_alloc;
|
||||
|
||||
pdev->dev.parent = pdevinfo->parent;
|
||||
ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion);
|
||||
pdev->dev.fwnode = pdevinfo->fwnode;
|
||||
|
||||
if (pdevinfo->dma_mask) {
|
||||
/*
|
||||
|
|
|
@ -10,10 +10,102 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/property.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
/**
|
||||
* device_add_property_set - Add a collection of properties to a device object.
|
||||
* @dev: Device to add properties to.
|
||||
* @pset: Collection of properties to add.
|
||||
*
|
||||
* Associate a collection of device properties represented by @pset with @dev
|
||||
* as its secondary firmware node.
|
||||
*/
|
||||
void device_add_property_set(struct device *dev, struct property_set *pset)
|
||||
{
|
||||
if (pset)
|
||||
pset->fwnode.type = FWNODE_PDATA;
|
||||
|
||||
set_secondary_fwnode(dev, &pset->fwnode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_add_property_set);
|
||||
|
||||
static inline bool is_pset(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return fwnode && fwnode->type == FWNODE_PDATA;
|
||||
}
|
||||
|
||||
static inline struct property_set *to_pset(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return is_pset(fwnode) ?
|
||||
container_of(fwnode, struct property_set, fwnode) : NULL;
|
||||
}
|
||||
|
||||
static struct property_entry *pset_prop_get(struct property_set *pset,
|
||||
const char *name)
|
||||
{
|
||||
struct property_entry *prop;
|
||||
|
||||
if (!pset || !pset->properties)
|
||||
return NULL;
|
||||
|
||||
for (prop = pset->properties; prop->name; prop++)
|
||||
if (!strcmp(name, prop->name))
|
||||
return prop;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int pset_prop_read_array(struct property_set *pset, const char *name,
|
||||
enum dev_prop_type type, void *val, size_t nval)
|
||||
{
|
||||
struct property_entry *prop;
|
||||
unsigned int item_size;
|
||||
|
||||
prop = pset_prop_get(pset, name);
|
||||
if (!prop)
|
||||
return -ENODATA;
|
||||
|
||||
if (prop->type != type)
|
||||
return -EPROTO;
|
||||
|
||||
if (!val)
|
||||
return prop->nval;
|
||||
|
||||
if (prop->nval < nval)
|
||||
return -EOVERFLOW;
|
||||
|
||||
switch (type) {
|
||||
case DEV_PROP_U8:
|
||||
item_size = sizeof(u8);
|
||||
break;
|
||||
case DEV_PROP_U16:
|
||||
item_size = sizeof(u16);
|
||||
break;
|
||||
case DEV_PROP_U32:
|
||||
item_size = sizeof(u32);
|
||||
break;
|
||||
case DEV_PROP_U64:
|
||||
item_size = sizeof(u64);
|
||||
break;
|
||||
case DEV_PROP_STRING:
|
||||
item_size = sizeof(const char *);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(val, prop->value.raw_data, nval * item_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct fwnode_handle *dev_fwnode(struct device *dev)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_OF) && dev->of_node ?
|
||||
&dev->of_node->fwnode : dev->fwnode;
|
||||
}
|
||||
|
||||
/**
|
||||
* device_property_present - check if a property of a device is present
|
||||
|
@ -24,10 +116,7 @@
|
|||
*/
|
||||
bool device_property_present(struct device *dev, const char *propname)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_OF) && dev->of_node)
|
||||
return of_property_read_bool(dev->of_node, propname);
|
||||
|
||||
return !acpi_dev_prop_get(ACPI_COMPANION(dev), propname, NULL);
|
||||
return fwnode_property_present(dev_fwnode(dev), propname);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_property_present);
|
||||
|
||||
|
@ -43,32 +132,22 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
|
|||
else if (is_acpi_node(fwnode))
|
||||
return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL);
|
||||
|
||||
return false;
|
||||
return !!pset_prop_get(to_pset(fwnode), propname);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fwnode_property_present);
|
||||
|
||||
#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
|
||||
(val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
|
||||
: of_property_count_elems_of_size((node), (propname), sizeof(type))
|
||||
|
||||
#define DEV_PROP_READ_ARRAY(_dev_, _propname_, _type_, _proptype_, _val_, _nval_) \
|
||||
IS_ENABLED(CONFIG_OF) && _dev_->of_node ? \
|
||||
(OF_DEV_PROP_READ_ARRAY(_dev_->of_node, _propname_, _type_, \
|
||||
_val_, _nval_)) : \
|
||||
acpi_dev_prop_read(ACPI_COMPANION(_dev_), _propname_, \
|
||||
_proptype_, _val_, _nval_)
|
||||
|
||||
/**
|
||||
* device_property_read_u8_array - return a u8 array property of a device
|
||||
* @dev: Device to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Function reads an array of u8 properties with @propname from the device
|
||||
* firmware description and stores them to @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 numbers,
|
||||
|
@ -77,7 +156,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_present);
|
|||
int device_property_read_u8_array(struct device *dev, const char *propname,
|
||||
u8 *val, size_t nval)
|
||||
{
|
||||
return DEV_PROP_READ_ARRAY(dev, propname, u8, DEV_PROP_U8, val, nval);
|
||||
return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_property_read_u8_array);
|
||||
|
||||
|
@ -85,13 +164,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u8_array);
|
|||
* device_property_read_u16_array - return a u16 array property of a device
|
||||
* @dev: Device to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Function reads an array of u16 properties with @propname from the device
|
||||
* firmware description and stores them to @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 numbers,
|
||||
|
@ -100,7 +180,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u8_array);
|
|||
int device_property_read_u16_array(struct device *dev, const char *propname,
|
||||
u16 *val, size_t nval)
|
||||
{
|
||||
return DEV_PROP_READ_ARRAY(dev, propname, u16, DEV_PROP_U16, val, nval);
|
||||
return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_property_read_u16_array);
|
||||
|
||||
|
@ -108,13 +188,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u16_array);
|
|||
* device_property_read_u32_array - return a u32 array property of a device
|
||||
* @dev: Device to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Function reads an array of u32 properties with @propname from the device
|
||||
* firmware description and stores them to @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 numbers,
|
||||
|
@ -123,7 +204,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u16_array);
|
|||
int device_property_read_u32_array(struct device *dev, const char *propname,
|
||||
u32 *val, size_t nval)
|
||||
{
|
||||
return DEV_PROP_READ_ARRAY(dev, propname, u32, DEV_PROP_U32, val, nval);
|
||||
return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_property_read_u32_array);
|
||||
|
||||
|
@ -131,13 +212,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u32_array);
|
|||
* device_property_read_u64_array - return a u64 array property of a device
|
||||
* @dev: Device to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Function reads an array of u64 properties with @propname from the device
|
||||
* firmware description and stores them to @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 numbers,
|
||||
|
@ -146,7 +228,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u32_array);
|
|||
int device_property_read_u64_array(struct device *dev, const char *propname,
|
||||
u64 *val, size_t nval)
|
||||
{
|
||||
return DEV_PROP_READ_ARRAY(dev, propname, u64, DEV_PROP_U64, val, nval);
|
||||
return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_property_read_u64_array);
|
||||
|
||||
|
@ -154,13 +236,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u64_array);
|
|||
* device_property_read_string_array - return a string array property of device
|
||||
* @dev: Device to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Function reads an array of string properties with @propname from the device
|
||||
* firmware description and stores them to @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 or %-EILSEQ if the property is not an array of strings,
|
||||
|
@ -169,10 +252,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u64_array);
|
|||
int device_property_read_string_array(struct device *dev, const char *propname,
|
||||
const char **val, size_t nval)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_OF) && dev->of_node ?
|
||||
of_property_read_string_array(dev->of_node, propname, val, nval) :
|
||||
acpi_dev_prop_read(ACPI_COMPANION(dev), propname,
|
||||
DEV_PROP_STRING, val, nval);
|
||||
return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_property_read_string_array);
|
||||
|
||||
|
@ -193,13 +273,14 @@ EXPORT_SYMBOL_GPL(device_property_read_string_array);
|
|||
int device_property_read_string(struct device *dev, const char *propname,
|
||||
const char **val)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_OF) && dev->of_node ?
|
||||
of_property_read_string(dev->of_node, propname, val) :
|
||||
acpi_dev_prop_read(ACPI_COMPANION(dev), propname,
|
||||
DEV_PROP_STRING, val, 1);
|
||||
return fwnode_property_read_string(dev_fwnode(dev), propname, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_property_read_string);
|
||||
|
||||
#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
|
||||
(val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
|
||||
: of_property_count_elems_of_size((node), (propname), sizeof(type))
|
||||
|
||||
#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
|
||||
({ \
|
||||
int _ret_; \
|
||||
|
@ -210,7 +291,8 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
|
|||
_ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \
|
||||
_proptype_, _val_, _nval_); \
|
||||
else \
|
||||
_ret_ = -ENXIO; \
|
||||
_ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
|
||||
_proptype_, _val_, _nval_); \
|
||||
_ret_; \
|
||||
})
|
||||
|
||||
|
@ -218,13 +300,14 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
|
|||
* fwnode_property_read_u8_array - return a u8 array property of firmware node
|
||||
* @fwnode: Firmware node to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Read an array of u8 properties with @propname from @fwnode and stores them to
|
||||
* @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 numbers,
|
||||
|
@ -243,13 +326,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
|
|||
* fwnode_property_read_u16_array - return a u16 array property of firmware node
|
||||
* @fwnode: Firmware node to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Read an array of u16 properties with @propname from @fwnode and store them to
|
||||
* @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 numbers,
|
||||
|
@ -268,13 +352,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
|
|||
* fwnode_property_read_u32_array - return a u32 array property of firmware node
|
||||
* @fwnode: Firmware node to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Read an array of u32 properties with @propname from @fwnode store them to
|
||||
* @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 numbers,
|
||||
|
@ -293,13 +378,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
|
|||
* fwnode_property_read_u64_array - return a u64 array property firmware node
|
||||
* @fwnode: Firmware node to get the property of
|
||||
* @propname: Name of the property
|
||||
* @val: The values are stored here
|
||||
* @val: The values are stored here or %NULL to return the number of values
|
||||
* @nval: Size of the @val array
|
||||
*
|
||||
* Read an array of u64 properties with @propname from @fwnode and store them to
|
||||
* @val if found.
|
||||
*
|
||||
* Return: %0 if the property was found (success),
|
||||
* 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 numbers,
|
||||
|
@ -318,13 +404,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
|
|||
* 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
|
||||
* @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: %0 if the property was found (success),
|
||||
* 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,
|
||||
|
@ -336,13 +423,16 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
|
|||
size_t nval)
|
||||
{
|
||||
if (is_of_node(fwnode))
|
||||
return of_property_read_string_array(of_node(fwnode), propname,
|
||||
val, nval);
|
||||
return val ?
|
||||
of_property_read_string_array(of_node(fwnode), propname,
|
||||
val, nval) :
|
||||
of_property_count_strings(of_node(fwnode), propname);
|
||||
else if (is_acpi_node(fwnode))
|
||||
return acpi_dev_prop_read(acpi_node(fwnode), propname,
|
||||
DEV_PROP_STRING, val, nval);
|
||||
|
||||
return -ENXIO;
|
||||
return pset_prop_read_array(to_pset(fwnode), propname,
|
||||
DEV_PROP_STRING, val, nval);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
enum of_gpio_flags;
|
||||
|
||||
struct acpi_device;
|
||||
|
||||
/**
|
||||
* struct acpi_gpio_info - ACPI GPIO specific information
|
||||
* @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo
|
||||
|
|
|
@ -166,7 +166,7 @@ static int dw_i2c_probe(struct platform_device *pdev)
|
|||
/* fast mode by default because of legacy reasons */
|
||||
clk_freq = 400000;
|
||||
|
||||
if (ACPI_COMPANION(&pdev->dev)) {
|
||||
if (has_acpi_companion(&pdev->dev)) {
|
||||
dw_i2c_acpi_configure(pdev);
|
||||
} else if (pdev->dev.of_node) {
|
||||
of_property_read_u32(pdev->dev.of_node,
|
||||
|
@ -286,7 +286,7 @@ static int dw_i2c_remove(struct platform_device *pdev)
|
|||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
if (ACPI_COMPANION(&pdev->dev))
|
||||
if (has_acpi_companion(&pdev->dev))
|
||||
dw_i2c_acpi_unconfigure(pdev);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -133,7 +133,7 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
|
|||
return AE_OK;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.acpi_node.companion = adev;
|
||||
info.fwnode = acpi_fwnode_handle(adev);
|
||||
info.irq = -1;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
|
@ -971,7 +971,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
|
|||
client->dev.bus = &i2c_bus_type;
|
||||
client->dev.type = &i2c_client_type;
|
||||
client->dev.of_node = info->of_node;
|
||||
ACPI_COMPANION_SET(&client->dev, info->acpi_node.companion);
|
||||
client->dev.fwnode = info->fwnode;
|
||||
|
||||
i2c_dev_set_name(adap, client);
|
||||
status = device_register(&client->dev);
|
||||
|
|
|
@ -684,7 +684,7 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf
|
|||
if (dev_is_pci(dev)) {
|
||||
pdev = to_pci_dev(dev);
|
||||
segment = pci_domain_nr(pdev->bus);
|
||||
} else if (ACPI_COMPANION(dev))
|
||||
} else if (has_acpi_companion(dev))
|
||||
dev = &ACPI_COMPANION(dev)->dev;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -387,7 +387,8 @@ static inline bool is_acpi_node(struct fwnode_handle *fwnode)
|
|||
|
||||
static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return fwnode ? container_of(fwnode, struct acpi_device, fwnode) : NULL;
|
||||
return is_acpi_node(fwnode) ?
|
||||
container_of(fwnode, struct acpi_device, fwnode) : NULL;
|
||||
}
|
||||
|
||||
static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
|
||||
|
|
|
@ -53,10 +53,16 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
|
|||
return adev ? adev->handle : NULL;
|
||||
}
|
||||
|
||||
#define ACPI_COMPANION(dev) ((dev)->acpi_node.companion)
|
||||
#define ACPI_COMPANION_SET(dev, adev) ACPI_COMPANION(dev) = (adev)
|
||||
#define ACPI_COMPANION(dev) acpi_node((dev)->fwnode)
|
||||
#define ACPI_COMPANION_SET(dev, adev) set_primary_fwnode(dev, (adev) ? \
|
||||
acpi_fwnode_handle(adev) : NULL)
|
||||
#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev))
|
||||
|
||||
static inline bool has_acpi_companion(struct device *dev)
|
||||
{
|
||||
return is_acpi_node(dev->fwnode);
|
||||
}
|
||||
|
||||
static inline void acpi_preset_companion(struct device *dev,
|
||||
struct acpi_device *parent, u64 addr)
|
||||
{
|
||||
|
@ -471,6 +477,11 @@ static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool has_acpi_companion(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline const char *acpi_dev_name(struct acpi_device *adev)
|
||||
{
|
||||
return NULL;
|
||||
|
|
|
@ -38,6 +38,7 @@ struct class;
|
|||
struct subsys_private;
|
||||
struct bus_type;
|
||||
struct device_node;
|
||||
struct fwnode_handle;
|
||||
struct iommu_ops;
|
||||
struct iommu_group;
|
||||
|
||||
|
@ -650,14 +651,6 @@ struct device_dma_parameters {
|
|||
unsigned long segment_boundary_mask;
|
||||
};
|
||||
|
||||
struct acpi_device;
|
||||
|
||||
struct acpi_dev_node {
|
||||
#ifdef CONFIG_ACPI
|
||||
struct acpi_device *companion;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* struct device - The basic device structure
|
||||
* @parent: The device's "parent" device, the device to which it is attached.
|
||||
|
@ -703,7 +696,7 @@ struct acpi_dev_node {
|
|||
* @cma_area: Contiguous memory area for dma allocations
|
||||
* @archdata: For arch-specific additions.
|
||||
* @of_node: Associated device tree node.
|
||||
* @acpi_node: Associated ACPI device node.
|
||||
* @fwnode: Associated device node supplied by platform firmware.
|
||||
* @devt: For creating the sysfs "dev".
|
||||
* @id: device instance
|
||||
* @devres_lock: Spinlock to protect the resource of the device.
|
||||
|
@ -779,7 +772,7 @@ struct device {
|
|||
struct dev_archdata archdata;
|
||||
|
||||
struct device_node *of_node; /* associated device tree node */
|
||||
struct acpi_dev_node acpi_node; /* associated ACPI device node */
|
||||
struct fwnode_handle *fwnode; /* firmware device node */
|
||||
|
||||
dev_t devt; /* dev_t, creates the sysfs "dev" */
|
||||
u32 id; /* device instance */
|
||||
|
@ -947,6 +940,9 @@ extern void unlock_device_hotplug(void);
|
|||
extern int lock_device_hotplug_sysfs(void);
|
||||
extern int device_offline(struct device *dev);
|
||||
extern int device_online(struct device *dev);
|
||||
extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
|
||||
extern void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
|
||||
|
||||
/*
|
||||
* Root device objects for grouping under /sys/devices
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* fwnode.h - Firmware device node object handle type definition.
|
||||
*
|
||||
* Copyright (C) 2015, Intel Corporation
|
||||
* Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FWNODE_H_
|
||||
#define _LINUX_FWNODE_H_
|
||||
|
||||
enum fwnode_type {
|
||||
FWNODE_INVALID = 0,
|
||||
FWNODE_OF,
|
||||
FWNODE_ACPI,
|
||||
FWNODE_PDATA,
|
||||
};
|
||||
|
||||
struct fwnode_handle {
|
||||
enum fwnode_type type;
|
||||
struct fwnode_handle *secondary;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -278,7 +278,7 @@ static inline int i2c_slave_event(struct i2c_client *client,
|
|||
* @platform_data: stored in i2c_client.dev.platform_data
|
||||
* @archdata: copied into i2c_client.dev.archdata
|
||||
* @of_node: pointer to OpenFirmware device node
|
||||
* @acpi_node: ACPI device node
|
||||
* @fwnode: device node supplied by the platform firmware
|
||||
* @irq: stored in i2c_client.irq
|
||||
*
|
||||
* I2C doesn't actually support hardware probing, although controllers and
|
||||
|
@ -299,7 +299,7 @@ struct i2c_board_info {
|
|||
void *platform_data;
|
||||
struct dev_archdata *archdata;
|
||||
struct device_node *of_node;
|
||||
struct acpi_dev_node acpi_node;
|
||||
struct fwnode_handle *fwnode;
|
||||
int irq;
|
||||
};
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ extern int platform_add_devices(struct platform_device **, int);
|
|||
|
||||
struct platform_device_info {
|
||||
struct device *parent;
|
||||
struct acpi_dev_node acpi_node;
|
||||
struct fwnode_handle *fwnode;
|
||||
|
||||
const char *name;
|
||||
int id;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef _LINUX_PROPERTY_H_
|
||||
#define _LINUX_PROPERTY_H_
|
||||
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
struct device;
|
||||
|
@ -40,16 +41,6 @@ int device_property_read_string_array(struct device *dev, const char *propname,
|
|||
int device_property_read_string(struct device *dev, const char *propname,
|
||||
const char **val);
|
||||
|
||||
enum fwnode_type {
|
||||
FWNODE_INVALID = 0,
|
||||
FWNODE_OF,
|
||||
FWNODE_ACPI,
|
||||
};
|
||||
|
||||
struct fwnode_handle {
|
||||
enum fwnode_type type;
|
||||
};
|
||||
|
||||
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname);
|
||||
int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
|
||||
const char *propname, u8 *val,
|
||||
|
@ -140,4 +131,37 @@ static inline int fwnode_property_read_u64(struct fwnode_handle *fwnode,
|
|||
return fwnode_property_read_u64_array(fwnode, propname, val, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct property_entry - "Built-in" device property representation.
|
||||
* @name: Name of the property.
|
||||
* @type: Type of the property.
|
||||
* @nval: Number of items of type @type making up the value.
|
||||
* @value: Value of the property (an array of @nval items of type @type).
|
||||
*/
|
||||
struct property_entry {
|
||||
const char *name;
|
||||
enum dev_prop_type type;
|
||||
size_t nval;
|
||||
union {
|
||||
void *raw_data;
|
||||
u8 *u8_data;
|
||||
u16 *u16_data;
|
||||
u32 *u32_data;
|
||||
u64 *u64_data;
|
||||
const char **str;
|
||||
} value;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct property_set - Collection of "built-in" device properties.
|
||||
* @fwnode: Handle to be pointed to by the fwnode field of struct device.
|
||||
* @properties: Array of properties terminated with a null entry.
|
||||
*/
|
||||
struct property_set {
|
||||
struct fwnode_handle fwnode;
|
||||
struct property_entry *properties;
|
||||
};
|
||||
|
||||
void device_add_property_set(struct device *dev, struct property_set *pset);
|
||||
|
||||
#endif /* _LINUX_PROPERTY_H_ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче