mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
Merge branch 'device-properties'
* device-properties: device property: avoid allocations of 0 length device property: the secondary fwnode needs to depend on the primary device property: add spaces to PROPERTY_ENTRY_STRING macro include/linux/property.h: fix build issues with gcc-4.4.4 i2c: designware: Convert to use unified device property API mfd: intel-lpss: Pass HSUART configuration via properties mfd: intel-lpss: Pass SDA hold time to I2C host controller driver mfd: intel-lpss: Add support for passing device properties mfd: core: propagate device properties to sub devices drivers driver core: Do not overwrite secondary fwnode with NULL if it is set driver core: platform: Add support for built-in device properties device property: Take a copy of the property set device property: Fallback to secondary fwnode if primary misses the property device property: return -EINVAL when property isn't found in ACPI device property: improve readability of macros device property: helper macros for property entry creation device property: keep single value inplace device property: refactor built-in properties support device property: rename helper functions device property: always check for fwnode type
This commit is contained in:
@@ -346,7 +346,7 @@ void acpi_free_properties(struct acpi_device *adev)
|
||||
*
|
||||
* Return: %0 if property with @name has been found (success),
|
||||
* %-EINVAL if the arguments are invalid,
|
||||
* %-ENODATA if the property doesn't exist,
|
||||
* %-EINVAL if the property doesn't exist,
|
||||
* %-EPROTO if the property value type doesn't match @type.
|
||||
*/
|
||||
static int acpi_data_get_property(struct acpi_device_data *data,
|
||||
@@ -360,7 +360,7 @@ static int acpi_data_get_property(struct acpi_device_data *data,
|
||||
return -EINVAL;
|
||||
|
||||
if (!data->pointer || !data->properties)
|
||||
return -ENODATA;
|
||||
return -EINVAL;
|
||||
|
||||
properties = data->properties;
|
||||
for (i = 0; i < properties->package.count; i++) {
|
||||
@@ -375,13 +375,13 @@ static int acpi_data_get_property(struct acpi_device_data *data,
|
||||
if (!strcmp(name, propname->string.pointer)) {
|
||||
if (type != ACPI_TYPE_ANY && propvalue->type != type)
|
||||
return -EPROTO;
|
||||
else if (obj)
|
||||
if (obj)
|
||||
*obj = propvalue;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENODATA;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -439,7 +439,7 @@ int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
|
||||
*
|
||||
* Return: %0 if array property (package) with @name has been found (success),
|
||||
* %-EINVAL if the arguments are invalid,
|
||||
* %-ENODATA if the property doesn't exist,
|
||||
* %-EINVAL if the property doesn't exist,
|
||||
* %-EPROTO if the property is not a package or the type of its elements
|
||||
* doesn't match @type.
|
||||
*/
|
||||
|
||||
@@ -2261,7 +2261,10 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
||||
if (fwnode_is_primary(fn))
|
||||
fn = fn->secondary;
|
||||
|
||||
fwnode->secondary = fn;
|
||||
if (fn) {
|
||||
WARN_ON(fwnode->secondary);
|
||||
fwnode->secondary = fn;
|
||||
}
|
||||
dev->fwnode = fwnode;
|
||||
} else {
|
||||
dev->fwnode = fwnode_is_primary(dev->fwnode) ?
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk/clk-conf.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include "base.h"
|
||||
#include "power/power.h"
|
||||
@@ -298,6 +299,22 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_device_add_data);
|
||||
|
||||
/**
|
||||
* platform_device_add_properties - add built-in properties to a platform device
|
||||
* @pdev: platform device to add properties to
|
||||
* @pset: properties to add
|
||||
*
|
||||
* The function will take deep copy of the properties in @pset and attach
|
||||
* the copy to the platform device. The memory associated with properties
|
||||
* will be freed when the platform device is released.
|
||||
*/
|
||||
int platform_device_add_properties(struct platform_device *pdev,
|
||||
const struct property_set *pset)
|
||||
{
|
||||
return device_add_property_set(&pdev->dev, pset);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_device_add_properties);
|
||||
|
||||
/**
|
||||
* platform_device_add - add a platform device to device hierarchy
|
||||
* @pdev: platform device we're adding
|
||||
@@ -409,6 +426,8 @@ void platform_device_del(struct platform_device *pdev)
|
||||
if (r->parent)
|
||||
release_resource(r);
|
||||
}
|
||||
|
||||
device_remove_property_set(&pdev->dev);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_device_del);
|
||||
@@ -487,6 +506,12 @@ struct platform_device *platform_device_register_full(
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (pdevinfo->pset) {
|
||||
ret = platform_device_add_properties(pdev, pdevinfo->pset);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = platform_device_add(pdev);
|
||||
if (ret) {
|
||||
err:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/acpi.h>
|
||||
@@ -134,10 +135,10 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
|
||||
|
||||
static int dw_i2c_plat_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct dw_i2c_dev *dev;
|
||||
struct i2c_adapter *adap;
|
||||
struct resource *mem;
|
||||
struct dw_i2c_platform_data *pdata;
|
||||
int irq, r;
|
||||
u32 clk_freq, ht = 0;
|
||||
|
||||
@@ -161,33 +162,28 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
|
||||
/* fast mode by default because of legacy reasons */
|
||||
clk_freq = 400000;
|
||||
|
||||
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,
|
||||
"i2c-sda-hold-time-ns", &ht);
|
||||
|
||||
of_property_read_u32(pdev->dev.of_node,
|
||||
"i2c-sda-falling-time-ns",
|
||||
&dev->sda_falling_time);
|
||||
of_property_read_u32(pdev->dev.of_node,
|
||||
"i2c-scl-falling-time-ns",
|
||||
&dev->scl_falling_time);
|
||||
|
||||
of_property_read_u32(pdev->dev.of_node, "clock-frequency",
|
||||
&clk_freq);
|
||||
|
||||
/* Only standard mode at 100kHz and fast mode at 400kHz
|
||||
* are supported.
|
||||
*/
|
||||
if (clk_freq != 100000 && clk_freq != 400000) {
|
||||
dev_err(&pdev->dev, "Only 100kHz and 400kHz supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (pdata) {
|
||||
clk_freq = pdata->i2c_scl_freq;
|
||||
} else {
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (pdata)
|
||||
clk_freq = pdata->i2c_scl_freq;
|
||||
device_property_read_u32(&pdev->dev, "i2c-sda-hold-time-ns",
|
||||
&ht);
|
||||
device_property_read_u32(&pdev->dev, "i2c-sda-falling-time-ns",
|
||||
&dev->sda_falling_time);
|
||||
device_property_read_u32(&pdev->dev, "i2c-scl-falling-time-ns",
|
||||
&dev->scl_falling_time);
|
||||
device_property_read_u32(&pdev->dev, "clock-frequency",
|
||||
&clk_freq);
|
||||
}
|
||||
|
||||
if (has_acpi_companion(&pdev->dev))
|
||||
dw_i2c_acpi_configure(pdev);
|
||||
|
||||
/*
|
||||
* Only standard mode at 100kHz and fast mode at 400kHz are supported.
|
||||
*/
|
||||
if (clk_freq != 100000 && clk_freq != 400000) {
|
||||
dev_err(&pdev->dev, "Only 100kHz and 400kHz supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = i2c_dw_eval_lock_support(dev);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include "intel-lpss.h"
|
||||
|
||||
@@ -25,6 +26,20 @@ static const struct intel_lpss_platform_info spt_info = {
|
||||
.clk_rate = 120000000,
|
||||
};
|
||||
|
||||
static struct property_entry spt_i2c_properties[] = {
|
||||
PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct property_set spt_i2c_pset = {
|
||||
.properties = spt_i2c_properties,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info spt_i2c_info = {
|
||||
.clk_rate = 120000000,
|
||||
.pset = &spt_i2c_pset,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info bxt_info = {
|
||||
.clk_rate = 100000000,
|
||||
};
|
||||
@@ -35,8 +50,8 @@ static const struct intel_lpss_platform_info bxt_i2c_info = {
|
||||
|
||||
static const struct acpi_device_id intel_lpss_acpi_ids[] = {
|
||||
/* SPT */
|
||||
{ "INT3446", (kernel_ulong_t)&spt_info },
|
||||
{ "INT3447", (kernel_ulong_t)&spt_info },
|
||||
{ "INT3446", (kernel_ulong_t)&spt_i2c_info },
|
||||
{ "INT3447", (kernel_ulong_t)&spt_i2c_info },
|
||||
/* BXT */
|
||||
{ "80860AAC", (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ "80860ABC", (kernel_ulong_t)&bxt_info },
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include "intel-lpss.h"
|
||||
|
||||
@@ -65,9 +66,35 @@ static const struct intel_lpss_platform_info spt_info = {
|
||||
.clk_rate = 120000000,
|
||||
};
|
||||
|
||||
static struct property_entry spt_i2c_properties[] = {
|
||||
PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct property_set spt_i2c_pset = {
|
||||
.properties = spt_i2c_properties,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info spt_i2c_info = {
|
||||
.clk_rate = 120000000,
|
||||
.pset = &spt_i2c_pset,
|
||||
};
|
||||
|
||||
static struct property_entry uart_properties[] = {
|
||||
PROPERTY_ENTRY_U32("reg-io-width", 4),
|
||||
PROPERTY_ENTRY_U32("reg-shift", 2),
|
||||
PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct property_set uart_pset = {
|
||||
.properties = uart_properties,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info spt_uart_info = {
|
||||
.clk_rate = 120000000,
|
||||
.clk_con_id = "baudclk",
|
||||
.pset = &uart_pset,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info bxt_info = {
|
||||
@@ -77,6 +104,7 @@ static const struct intel_lpss_platform_info bxt_info = {
|
||||
static const struct intel_lpss_platform_info bxt_uart_info = {
|
||||
.clk_rate = 100000000,
|
||||
.clk_con_id = "baudclk",
|
||||
.pset = &uart_pset,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info bxt_i2c_info = {
|
||||
@@ -121,20 +149,20 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x9d28), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d29), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d2a), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d60), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d61), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d62), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d63), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d64), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d65), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d60), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d61), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d62), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d63), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d64), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d65), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9d66), (kernel_ulong_t)&spt_uart_info },
|
||||
/* SPT-H */
|
||||
{ PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa129), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa12a), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
|
||||
@@ -72,7 +73,7 @@ struct intel_lpss {
|
||||
enum intel_lpss_dev_type type;
|
||||
struct clk *clk;
|
||||
struct clk_lookup *clock;
|
||||
const struct mfd_cell *cell;
|
||||
struct mfd_cell *cell;
|
||||
struct device *dev;
|
||||
void __iomem *priv;
|
||||
int devid;
|
||||
@@ -217,6 +218,7 @@ static void intel_lpss_ltr_hide(struct intel_lpss *lpss)
|
||||
|
||||
static int intel_lpss_assign_devs(struct intel_lpss *lpss)
|
||||
{
|
||||
const struct mfd_cell *cell;
|
||||
unsigned int type;
|
||||
|
||||
type = lpss->caps & LPSS_PRIV_CAPS_TYPE_MASK;
|
||||
@@ -224,18 +226,22 @@ static int intel_lpss_assign_devs(struct intel_lpss *lpss)
|
||||
|
||||
switch (type) {
|
||||
case LPSS_DEV_I2C:
|
||||
lpss->cell = &intel_lpss_i2c_cell;
|
||||
cell = &intel_lpss_i2c_cell;
|
||||
break;
|
||||
case LPSS_DEV_UART:
|
||||
lpss->cell = &intel_lpss_uart_cell;
|
||||
cell = &intel_lpss_uart_cell;
|
||||
break;
|
||||
case LPSS_DEV_SPI:
|
||||
lpss->cell = &intel_lpss_spi_cell;
|
||||
cell = &intel_lpss_spi_cell;
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
lpss->cell = devm_kmemdup(lpss->dev, cell, sizeof(*cell), GFP_KERNEL);
|
||||
if (!lpss->cell)
|
||||
return -ENOMEM;
|
||||
|
||||
lpss->type = type;
|
||||
|
||||
return 0;
|
||||
@@ -401,6 +407,8 @@ int intel_lpss_probe(struct device *dev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
lpss->cell->pset = info->pset;
|
||||
|
||||
intel_lpss_init_dev(lpss);
|
||||
|
||||
lpss->devid = ida_simple_get(&intel_lpss_devid_ida, 0, 0, GFP_KERNEL);
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
struct device;
|
||||
struct resource;
|
||||
struct property_set;
|
||||
|
||||
struct intel_lpss_platform_info {
|
||||
struct resource *mem;
|
||||
int irq;
|
||||
unsigned long clk_rate;
|
||||
const char *clk_con_id;
|
||||
struct property_set *pset;
|
||||
};
|
||||
|
||||
int intel_lpss_probe(struct device *dev,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -192,6 +193,12 @@ static int mfd_add_device(struct device *parent, int id,
|
||||
goto fail_alias;
|
||||
}
|
||||
|
||||
if (cell->pset) {
|
||||
ret = platform_device_add_properties(pdev, cell->pset);
|
||||
if (ret)
|
||||
goto fail_alias;
|
||||
}
|
||||
|
||||
ret = mfd_platform_add_cell(pdev, cell, usage_count);
|
||||
if (ret)
|
||||
goto fail_alias;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
struct irq_domain;
|
||||
struct property_set;
|
||||
|
||||
/* Matches ACPI PNP id, either _HID or _CID, or ACPI _ADR */
|
||||
struct mfd_cell_acpi_match {
|
||||
@@ -44,6 +45,10 @@ struct mfd_cell {
|
||||
/* platform data passed to the sub devices drivers */
|
||||
void *platform_data;
|
||||
size_t pdata_size;
|
||||
|
||||
/* device properties passed to the sub devices drivers */
|
||||
const struct property_set *pset;
|
||||
|
||||
/*
|
||||
* Device Tree compatible string
|
||||
* See: Documentation/devicetree/usage-model.txt Chapter 2.2 for details
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define PLATFORM_DEVID_AUTO (-2)
|
||||
|
||||
struct mfd_cell;
|
||||
struct property_set;
|
||||
|
||||
struct platform_device {
|
||||
const char *name;
|
||||
@@ -70,6 +71,8 @@ struct platform_device_info {
|
||||
const void *data;
|
||||
size_t size_data;
|
||||
u64 dma_mask;
|
||||
|
||||
const struct property_set *pset;
|
||||
};
|
||||
extern struct platform_device *platform_device_register_full(
|
||||
const struct platform_device_info *pdevinfo);
|
||||
@@ -167,6 +170,8 @@ extern int platform_device_add_resources(struct platform_device *pdev,
|
||||
unsigned int num);
|
||||
extern int platform_device_add_data(struct platform_device *pdev,
|
||||
const void *data, size_t size);
|
||||
extern int platform_device_add_properties(struct platform_device *pdev,
|
||||
const struct property_set *pset);
|
||||
extern int platform_device_add(struct platform_device *pdev);
|
||||
extern void platform_device_del(struct platform_device *pdev);
|
||||
extern void platform_device_put(struct platform_device *pdev);
|
||||
|
||||
@@ -73,8 +73,8 @@ int fwnode_property_match_string(struct fwnode_handle *fwnode,
|
||||
struct fwnode_handle *device_get_next_child_node(struct device *dev,
|
||||
struct fwnode_handle *child);
|
||||
|
||||
#define device_for_each_child_node(dev, child) \
|
||||
for (child = device_get_next_child_node(dev, NULL); child; \
|
||||
#define device_for_each_child_node(dev, child) \
|
||||
for (child = device_get_next_child_node(dev, NULL); child; \
|
||||
child = device_get_next_child_node(dev, child))
|
||||
|
||||
void fwnode_handle_put(struct fwnode_handle *fwnode);
|
||||
@@ -144,24 +144,100 @@ static inline int fwnode_property_read_u64(struct fwnode_handle *fwnode,
|
||||
/**
|
||||
* 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).
|
||||
* @length: Length of data making up the value.
|
||||
* @is_array: True when the property is an array.
|
||||
* @is_string: True when property is a string.
|
||||
* @pointer: Pointer to the property (an array of items of the given type).
|
||||
* @value: Value of the property (when it is a single item of the given type).
|
||||
*/
|
||||
struct property_entry {
|
||||
const char *name;
|
||||
enum dev_prop_type type;
|
||||
size_t nval;
|
||||
size_t length;
|
||||
bool is_array;
|
||||
bool is_string;
|
||||
union {
|
||||
void *raw_data;
|
||||
u8 *u8_data;
|
||||
u16 *u16_data;
|
||||
u32 *u32_data;
|
||||
u64 *u64_data;
|
||||
const char **str;
|
||||
} value;
|
||||
union {
|
||||
void *raw_data;
|
||||
u8 *u8_data;
|
||||
u16 *u16_data;
|
||||
u32 *u32_data;
|
||||
u64 *u64_data;
|
||||
const char **str;
|
||||
} pointer;
|
||||
union {
|
||||
unsigned long long raw_data;
|
||||
u8 u8_data;
|
||||
u16 u16_data;
|
||||
u32 u32_data;
|
||||
u64 u64_data;
|
||||
const char *str;
|
||||
} value;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: the below four initializers for the anonymous union are carefully
|
||||
* crafted to avoid gcc-4.4.4's problems with initialization of anon unions
|
||||
* and structs.
|
||||
*/
|
||||
|
||||
#define PROPERTY_ENTRY_INTEGER_ARRAY(_name_, _type_, _val_) \
|
||||
{ \
|
||||
.name = _name_, \
|
||||
.length = ARRAY_SIZE(_val_) * sizeof(_type_), \
|
||||
.is_array = true, \
|
||||
.is_string = false, \
|
||||
{ .pointer = { _type_##_data = _val_ } }, \
|
||||
}
|
||||
|
||||
#define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_) \
|
||||
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u8, _val_)
|
||||
#define PROPERTY_ENTRY_U16_ARRAY(_name_, _val_) \
|
||||
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u16, _val_)
|
||||
#define PROPERTY_ENTRY_U32_ARRAY(_name_, _val_) \
|
||||
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u32, _val_)
|
||||
#define PROPERTY_ENTRY_U64_ARRAY(_name_, _val_) \
|
||||
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u64, _val_)
|
||||
|
||||
#define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_) \
|
||||
{ \
|
||||
.name = _name_, \
|
||||
.length = ARRAY_SIZE(_val_) * sizeof(const char *), \
|
||||
.is_array = true, \
|
||||
.is_string = true, \
|
||||
{ .pointer = { .str = _val_ } }, \
|
||||
}
|
||||
|
||||
#define PROPERTY_ENTRY_INTEGER(_name_, _type_, _val_) \
|
||||
{ \
|
||||
.name = _name_, \
|
||||
.length = sizeof(_type_), \
|
||||
.is_string = false, \
|
||||
{ .value = { ._type_##_data = _val_ } }, \
|
||||
}
|
||||
|
||||
#define PROPERTY_ENTRY_U8(_name_, _val_) \
|
||||
PROPERTY_ENTRY_INTEGER(_name_, u8, _val_)
|
||||
#define PROPERTY_ENTRY_U16(_name_, _val_) \
|
||||
PROPERTY_ENTRY_INTEGER(_name_, u16, _val_)
|
||||
#define PROPERTY_ENTRY_U32(_name_, _val_) \
|
||||
PROPERTY_ENTRY_INTEGER(_name_, u32, _val_)
|
||||
#define PROPERTY_ENTRY_U64(_name_, _val_) \
|
||||
PROPERTY_ENTRY_INTEGER(_name_, u64, _val_)
|
||||
|
||||
#define PROPERTY_ENTRY_STRING(_name_, _val_) \
|
||||
{ \
|
||||
.name = _name_, \
|
||||
.length = sizeof(_val_), \
|
||||
.is_string = true, \
|
||||
{ .value = { .str = _val_ } }, \
|
||||
}
|
||||
|
||||
#define PROPERTY_ENTRY_BOOL(_name_) \
|
||||
{ \
|
||||
.name = _name_, \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct property_set - Collection of "built-in" device properties.
|
||||
* @fwnode: Handle to be pointed to by the fwnode field of struct device.
|
||||
@@ -172,7 +248,8 @@ struct property_set {
|
||||
struct property_entry *properties;
|
||||
};
|
||||
|
||||
void device_add_property_set(struct device *dev, struct property_set *pset);
|
||||
int device_add_property_set(struct device *dev, const struct property_set *pset);
|
||||
void device_remove_property_set(struct device *dev);
|
||||
|
||||
bool device_dma_supported(struct device *dev);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user