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:
Rafael J. Wysocki 2015-04-13 00:35:54 +02:00
Родитель 34a1b99b9b 16ba08d5c9
Коммит 9a9ca16e7a
17 изменённых файлов: 292 добавлений и 90 удалений

Просмотреть файл

@ -102,7 +102,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
pdevinfo.id = -1; pdevinfo.id = -1;
pdevinfo.res = resources; pdevinfo.res = resources;
pdevinfo.num_res = count; pdevinfo.num_res = count;
pdevinfo.acpi_node.companion = adev; pdevinfo.fwnode = acpi_fwnode_handle(adev);
pdevinfo.dma_mask = DMA_BIT_MASK(32); pdevinfo.dma_mask = DMA_BIT_MASK(32);
pdev = platform_device_register_full(&pdevinfo); pdev = platform_device_register_full(&pdevinfo);
if (IS_ERR(pdev)) if (IS_ERR(pdev))

Просмотреть файл

@ -615,7 +615,7 @@ void acpi_dock_add(struct acpi_device *adev)
memset(&pdevinfo, 0, sizeof(pdevinfo)); memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo.name = "dock"; pdevinfo.name = "dock";
pdevinfo.id = dock_station_count; pdevinfo.id = dock_station_count;
pdevinfo.acpi_node.companion = adev; pdevinfo.fwnode = acpi_fwnode_handle(adev);
pdevinfo.data = &ds; pdevinfo.data = &ds;
pdevinfo.size_data = sizeof(ds); pdevinfo.size_data = sizeof(ds);
dd = platform_device_register_full(&pdevinfo); 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; unsigned int node_id;
int retval = -EINVAL; int retval = -EINVAL;
if (ACPI_COMPANION(dev)) { if (has_acpi_companion(dev)) {
if (acpi_dev) { if (acpi_dev) {
dev_warn(dev, "ACPI companion already set\n"); dev_warn(dev, "ACPI companion already set\n");
return -EINVAL; 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); list_add(&physical_node->node, physnode_list);
acpi_dev->physical_node_count++; acpi_dev->physical_node_count++;
if (!ACPI_COMPANION(dev)) if (!has_acpi_companion(dev))
ACPI_COMPANION_SET(dev, acpi_dev); ACPI_COMPANION_SET(dev, acpi_dev);
acpi_physnode_link_name(physical_node_name, node_id); acpi_physnode_link_name(physical_node_name, node_id);

Просмотреть файл

@ -12,6 +12,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/fwnode.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.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); define_dev_printk_level(_dev_info, KERN_INFO);
#endif #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; goto err_alloc;
pdev->dev.parent = pdevinfo->parent; pdev->dev.parent = pdevinfo->parent;
ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); pdev->dev.fwnode = pdevinfo->fwnode;
if (pdevinfo->dma_mask) { if (pdevinfo->dma_mask) {
/* /*

Просмотреть файл

@ -10,10 +10,102 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/property.h>
#include <linux/export.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/of.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 * 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) bool device_property_present(struct device *dev, const char *propname)
{ {
if (IS_ENABLED(CONFIG_OF) && dev->of_node) return fwnode_property_present(dev_fwnode(dev), propname);
return of_property_read_bool(dev->of_node, propname);
return !acpi_dev_prop_get(ACPI_COMPANION(dev), propname, NULL);
} }
EXPORT_SYMBOL_GPL(device_property_present); 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)) else if (is_acpi_node(fwnode))
return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL); 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); 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 * device_property_read_u8_array - return a u8 array property of a device
* @dev: Device to get the property of * @dev: Device to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Function reads an array of u8 properties with @propname from the device * Function reads an array of u8 properties with @propname from the device
* firmware description and stores them to @val if found. * 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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of numbers, * %-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, int device_property_read_u8_array(struct device *dev, const char *propname,
u8 *val, size_t nval) 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); 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 * device_property_read_u16_array - return a u16 array property of a device
* @dev: Device to get the property of * @dev: Device to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Function reads an array of u16 properties with @propname from the device * Function reads an array of u16 properties with @propname from the device
* firmware description and stores them to @val if found. * 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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of numbers, * %-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, int device_property_read_u16_array(struct device *dev, const char *propname,
u16 *val, size_t nval) 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); 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 * device_property_read_u32_array - return a u32 array property of a device
* @dev: Device to get the property of * @dev: Device to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Function reads an array of u32 properties with @propname from the device * Function reads an array of u32 properties with @propname from the device
* firmware description and stores them to @val if found. * 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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of numbers, * %-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, int device_property_read_u32_array(struct device *dev, const char *propname,
u32 *val, size_t nval) 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); 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 * device_property_read_u64_array - return a u64 array property of a device
* @dev: Device to get the property of * @dev: Device to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Function reads an array of u64 properties with @propname from the device * Function reads an array of u64 properties with @propname from the device
* firmware description and stores them to @val if found. * 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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of numbers, * %-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, int device_property_read_u64_array(struct device *dev, const char *propname,
u64 *val, size_t nval) 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); 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 * device_property_read_string_array - return a string array property of device
* @dev: Device to get the property of * @dev: Device to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Function reads an array of string properties with @propname from the device * Function reads an array of string properties with @propname from the device
* firmware description and stores them to @val if found. * 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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO or %-EILSEQ if the property is not an array of strings, * %-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, int device_property_read_string_array(struct device *dev, const char *propname,
const char **val, size_t nval) const char **val, size_t nval)
{ {
return IS_ENABLED(CONFIG_OF) && dev->of_node ? return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
of_property_read_string_array(dev->of_node, propname, val, nval) :
acpi_dev_prop_read(ACPI_COMPANION(dev), propname,
DEV_PROP_STRING, val, nval);
} }
EXPORT_SYMBOL_GPL(device_property_read_string_array); 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, int device_property_read_string(struct device *dev, const char *propname,
const char **val) const char **val)
{ {
return IS_ENABLED(CONFIG_OF) && dev->of_node ? return fwnode_property_read_string(dev_fwnode(dev), propname, val);
of_property_read_string(dev->of_node, propname, val) :
acpi_dev_prop_read(ACPI_COMPANION(dev), propname,
DEV_PROP_STRING, val, 1);
} }
EXPORT_SYMBOL_GPL(device_property_read_string); 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_) \ #define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
({ \ ({ \
int _ret_; \ int _ret_; \
@ -210,7 +291,8 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
_ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \ _ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \
_proptype_, _val_, _nval_); \ _proptype_, _val_, _nval_); \
else \ else \
_ret_ = -ENXIO; \ _ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
_proptype_, _val_, _nval_); \
_ret_; \ _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_property_read_u8_array - return a u8 array property of firmware node
* @fwnode: Firmware node to get the property of * @fwnode: Firmware node to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Read an array of u8 properties with @propname from @fwnode and stores them to * Read an array of u8 properties with @propname from @fwnode and stores them to
* @val if found. * @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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of numbers, * %-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_property_read_u16_array - return a u16 array property of firmware node
* @fwnode: Firmware node to get the property of * @fwnode: Firmware node to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Read an array of u16 properties with @propname from @fwnode and store them to * Read an array of u16 properties with @propname from @fwnode and store them to
* @val if found. * @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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of numbers, * %-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_property_read_u32_array - return a u32 array property of firmware node
* @fwnode: Firmware node to get the property of * @fwnode: Firmware node to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Read an array of u32 properties with @propname from @fwnode store them to * Read an array of u32 properties with @propname from @fwnode store them to
* @val if found. * @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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of numbers, * %-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_property_read_u64_array - return a u64 array property firmware node
* @fwnode: Firmware node to get the property of * @fwnode: Firmware node to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Read an array of u64 properties with @propname from @fwnode and store them to * Read an array of u64 properties with @propname from @fwnode and store them to
* @val if found. * @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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of numbers, * %-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_property_read_string_array - return string array property of a node
* @fwnode: Firmware node to get the property of * @fwnode: Firmware node to get the property of
* @propname: Name of the property * @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 * @nval: Size of the @val array
* *
* Read an string list property @propname from the given firmware node and store * Read an string list property @propname from the given firmware node and store
* them to @val if found. * 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, * %-EINVAL if given arguments are not valid,
* %-ENODATA if the property does not have a value, * %-ENODATA if the property does not have a value,
* %-EPROTO if the property is not an array of strings, * %-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) size_t nval)
{ {
if (is_of_node(fwnode)) if (is_of_node(fwnode))
return of_property_read_string_array(of_node(fwnode), propname, return val ?
val, nval); 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)) else if (is_acpi_node(fwnode))
return acpi_dev_prop_read(acpi_node(fwnode), propname, return acpi_dev_prop_read(acpi_node(fwnode), propname,
DEV_PROP_STRING, val, nval); 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); EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);

Просмотреть файл

@ -17,6 +17,8 @@
enum of_gpio_flags; enum of_gpio_flags;
struct acpi_device;
/** /**
* struct acpi_gpio_info - ACPI GPIO specific information * struct acpi_gpio_info - ACPI GPIO specific information
* @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo * @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 */ /* fast mode by default because of legacy reasons */
clk_freq = 400000; clk_freq = 400000;
if (ACPI_COMPANION(&pdev->dev)) { if (has_acpi_companion(&pdev->dev)) {
dw_i2c_acpi_configure(pdev); dw_i2c_acpi_configure(pdev);
} else if (pdev->dev.of_node) { } else if (pdev->dev.of_node) {
of_property_read_u32(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_put(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
if (ACPI_COMPANION(&pdev->dev)) if (has_acpi_companion(&pdev->dev))
dw_i2c_acpi_unconfigure(pdev); dw_i2c_acpi_unconfigure(pdev);
return 0; return 0;

Просмотреть файл

@ -133,7 +133,7 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
return AE_OK; return AE_OK;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.acpi_node.companion = adev; info.fwnode = acpi_fwnode_handle(adev);
info.irq = -1; info.irq = -1;
INIT_LIST_HEAD(&resource_list); 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.bus = &i2c_bus_type;
client->dev.type = &i2c_client_type; client->dev.type = &i2c_client_type;
client->dev.of_node = info->of_node; 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); i2c_dev_set_name(adap, client);
status = device_register(&client->dev); 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)) { if (dev_is_pci(dev)) {
pdev = to_pci_dev(dev); pdev = to_pci_dev(dev);
segment = pci_domain_nr(pdev->bus); segment = pci_domain_nr(pdev->bus);
} else if (ACPI_COMPANION(dev)) } else if (has_acpi_companion(dev))
dev = &ACPI_COMPANION(dev)->dev; dev = &ACPI_COMPANION(dev)->dev;
rcu_read_lock(); 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) 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) 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; return adev ? adev->handle : NULL;
} }
#define ACPI_COMPANION(dev) ((dev)->acpi_node.companion) #define ACPI_COMPANION(dev) acpi_node((dev)->fwnode)
#define ACPI_COMPANION_SET(dev, adev) ACPI_COMPANION(dev) = (adev) #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)) #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, static inline void acpi_preset_companion(struct device *dev,
struct acpi_device *parent, u64 addr) struct acpi_device *parent, u64 addr)
{ {
@ -471,6 +477,11 @@ static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
return NULL; return NULL;
} }
static inline bool has_acpi_companion(struct device *dev)
{
return false;
}
static inline const char *acpi_dev_name(struct acpi_device *adev) static inline const char *acpi_dev_name(struct acpi_device *adev)
{ {
return NULL; return NULL;

Просмотреть файл

@ -38,6 +38,7 @@ struct class;
struct subsys_private; struct subsys_private;
struct bus_type; struct bus_type;
struct device_node; struct device_node;
struct fwnode_handle;
struct iommu_ops; struct iommu_ops;
struct iommu_group; struct iommu_group;
@ -650,14 +651,6 @@ struct device_dma_parameters {
unsigned long segment_boundary_mask; 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 * struct device - The basic device structure
* @parent: The device's "parent" device, the device to which it is attached. * @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 * @cma_area: Contiguous memory area for dma allocations
* @archdata: For arch-specific additions. * @archdata: For arch-specific additions.
* @of_node: Associated device tree node. * @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". * @devt: For creating the sysfs "dev".
* @id: device instance * @id: device instance
* @devres_lock: Spinlock to protect the resource of the device. * @devres_lock: Spinlock to protect the resource of the device.
@ -779,7 +772,7 @@ struct device {
struct dev_archdata archdata; struct dev_archdata archdata;
struct device_node *of_node; /* associated device tree node */ 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" */ dev_t devt; /* dev_t, creates the sysfs "dev" */
u32 id; /* device instance */ u32 id; /* device instance */
@ -947,6 +940,9 @@ extern void unlock_device_hotplug(void);
extern int lock_device_hotplug_sysfs(void); extern int lock_device_hotplug_sysfs(void);
extern int device_offline(struct device *dev); extern int device_offline(struct device *dev);
extern int device_online(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 * Root device objects for grouping under /sys/devices
*/ */

27
include/linux/fwnode.h Normal file
Просмотреть файл

@ -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 * @platform_data: stored in i2c_client.dev.platform_data
* @archdata: copied into i2c_client.dev.archdata * @archdata: copied into i2c_client.dev.archdata
* @of_node: pointer to OpenFirmware device node * @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 * @irq: stored in i2c_client.irq
* *
* I2C doesn't actually support hardware probing, although controllers and * I2C doesn't actually support hardware probing, although controllers and
@ -299,7 +299,7 @@ struct i2c_board_info {
void *platform_data; void *platform_data;
struct dev_archdata *archdata; struct dev_archdata *archdata;
struct device_node *of_node; struct device_node *of_node;
struct acpi_dev_node acpi_node; struct fwnode_handle *fwnode;
int irq; int irq;
}; };

Просмотреть файл

@ -59,7 +59,7 @@ extern int platform_add_devices(struct platform_device **, int);
struct platform_device_info { struct platform_device_info {
struct device *parent; struct device *parent;
struct acpi_dev_node acpi_node; struct fwnode_handle *fwnode;
const char *name; const char *name;
int id; int id;

Просмотреть файл

@ -13,6 +13,7 @@
#ifndef _LINUX_PROPERTY_H_ #ifndef _LINUX_PROPERTY_H_
#define _LINUX_PROPERTY_H_ #define _LINUX_PROPERTY_H_
#include <linux/fwnode.h>
#include <linux/types.h> #include <linux/types.h>
struct device; 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, int device_property_read_string(struct device *dev, const char *propname,
const char **val); 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); bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname);
int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
const char *propname, u8 *val, 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); 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_ */ #endif /* _LINUX_PROPERTY_H_ */