summaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c51
-rw-r--r--drivers/base/platform.c2
-rw-r--r--drivers/base/power/main.c20
-rw-r--r--drivers/base/power/trace.c6
-rw-r--r--drivers/base/property.c198
-rw-r--r--drivers/base/regmap/internal.h8
-rw-r--r--drivers/base/regmap/regcache-rbtree.c2
-rw-r--r--drivers/base/regmap/regcache.c22
-rw-r--r--drivers/base/regmap/regmap-irq.c3
-rw-r--r--drivers/base/regmap/regmap.c32
10 files changed, 252 insertions, 92 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 07304a3..c7e2a9a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -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;
+}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 9421fed..17f0204 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -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) {
/*
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 9717d5f..3d874ec 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -23,7 +23,7 @@
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
-#include <linux/resume-trace.h>
+#include <linux/pm-trace.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/async.h>
@@ -1017,6 +1017,9 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
char *info = NULL;
int error = 0;
+ TRACE_DEVICE(dev);
+ TRACE_SUSPEND(0);
+
if (async_error)
goto Complete;
@@ -1057,6 +1060,7 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
Complete:
complete_all(&dev->power.completion);
+ TRACE_SUSPEND(error);
return error;
}
@@ -1078,7 +1082,7 @@ static int device_suspend_noirq(struct device *dev)
{
reinit_completion(&dev->power.completion);
- if (pm_async_enabled && dev->power.async_suspend) {
+ if (is_async(dev)) {
get_device(dev);
async_schedule(async_suspend_noirq, dev);
return 0;
@@ -1157,6 +1161,9 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
char *info = NULL;
int error = 0;
+ TRACE_DEVICE(dev);
+ TRACE_SUSPEND(0);
+
__pm_runtime_disable(dev, false);
if (async_error)
@@ -1198,6 +1205,7 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
async_error = error;
Complete:
+ TRACE_SUSPEND(error);
complete_all(&dev->power.completion);
return error;
}
@@ -1219,7 +1227,7 @@ static int device_suspend_late(struct device *dev)
{
reinit_completion(&dev->power.completion);
- if (pm_async_enabled && dev->power.async_suspend) {
+ if (is_async(dev)) {
get_device(dev);
async_schedule(async_suspend_late, dev);
return 0;
@@ -1338,6 +1346,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
int error = 0;
DECLARE_DPM_WATCHDOG_ON_STACK(wd);
+ TRACE_DEVICE(dev);
+ TRACE_SUSPEND(0);
+
dpm_wait_for_children(dev, async);
if (async_error)
@@ -1444,6 +1455,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
if (error)
async_error = error;
+ TRACE_SUSPEND(error);
return error;
}
@@ -1465,7 +1477,7 @@ static int device_suspend(struct device *dev)
{
reinit_completion(&dev->power.completion);
- if (pm_async_enabled && dev->power.async_suspend) {
+ if (is_async(dev)) {
get_device(dev);
async_schedule(async_suspend, dev);
return 0;
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c
index d94a1f51..a311cfa 100644
--- a/drivers/base/power/trace.c
+++ b/drivers/base/power/trace.c
@@ -7,7 +7,7 @@
* devices may be working.
*/
-#include <linux/resume-trace.h>
+#include <linux/pm-trace.h>
#include <linux/export.h>
#include <linux/rtc.h>
@@ -154,7 +154,7 @@ EXPORT_SYMBOL(set_trace_device);
* it's not any guarantee, but it's a high _likelihood_ that
* the match is valid).
*/
-void generate_resume_trace(const void *tracedata, unsigned int user)
+void generate_pm_trace(const void *tracedata, unsigned int user)
{
unsigned short lineno = *(unsigned short *)tracedata;
const char *file = *(const char **)(tracedata + 2);
@@ -164,7 +164,7 @@ void generate_resume_trace(const void *tracedata, unsigned int user)
file_hash_value = hash_string(lineno, file, FILEHASH);
set_magic_time(user_hash_value, file_hash_value, dev_hash_value);
}
-EXPORT_SYMBOL(generate_resume_trace);
+EXPORT_SYMBOL(generate_pm_trace);
extern char __tracedata_start, __tracedata_end;
static int show_file_hash(unsigned int value)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index c458458..6a3f7d8 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -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);
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index beb8b27..a13587b 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -243,4 +243,12 @@ extern struct regcache_ops regcache_rbtree_ops;
extern struct regcache_ops regcache_lzo_ops;
extern struct regcache_ops regcache_flat_ops;
+static inline const char *regmap_name(const struct regmap *map)
+{
+ if (map->dev)
+ return dev_name(map->dev);
+
+ return map->name;
+}
+
#endif
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index d453a2c..81751a4 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -307,7 +307,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
if (pos == 0) {
memmove(blk + offset * map->cache_word_size,
blk, rbnode->blklen * map->cache_word_size);
- bitmap_shift_right(present, present, offset, blklen);
+ bitmap_shift_left(present, present, offset, blklen);
}
/* update the rbnode block, its size and the base register */
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index f373c35..87db989 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -218,7 +218,7 @@ int regcache_read(struct regmap *map,
ret = map->cache_ops->read(map, reg, value);
if (ret == 0)
- trace_regmap_reg_read_cache(map->dev, reg, *value);
+ trace_regmap_reg_read_cache(map, reg, *value);
return ret;
}
@@ -311,7 +311,7 @@ int regcache_sync(struct regmap *map)
dev_dbg(map->dev, "Syncing %s cache\n",
map->cache_ops->name);
name = map->cache_ops->name;
- trace_regcache_sync(map->dev, name, "start");
+ trace_regcache_sync(map, name, "start");
if (!map->cache_dirty)
goto out;
@@ -346,7 +346,7 @@ out:
regmap_async_complete(map);
- trace_regcache_sync(map->dev, name, "stop");
+ trace_regcache_sync(map, name, "stop");
return ret;
}
@@ -381,7 +381,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
name = map->cache_ops->name;
dev_dbg(map->dev, "Syncing %s cache from %d-%d\n", name, min, max);
- trace_regcache_sync(map->dev, name, "start region");
+ trace_regcache_sync(map, name, "start region");
if (!map->cache_dirty)
goto out;
@@ -401,7 +401,7 @@ out:
regmap_async_complete(map);
- trace_regcache_sync(map->dev, name, "stop region");
+ trace_regcache_sync(map, name, "stop region");
return ret;
}
@@ -428,7 +428,7 @@ int regcache_drop_region(struct regmap *map, unsigned int min,
map->lock(map->lock_arg);
- trace_regcache_drop_region(map->dev, min, max);
+ trace_regcache_drop_region(map, min, max);
ret = map->cache_ops->drop(map, min, max);
@@ -455,7 +455,7 @@ void regcache_cache_only(struct regmap *map, bool enable)
map->lock(map->lock_arg);
WARN_ON(map->cache_bypass && enable);
map->cache_only = enable;
- trace_regmap_cache_only(map->dev, enable);
+ trace_regmap_cache_only(map, enable);
map->unlock(map->lock_arg);
}
EXPORT_SYMBOL_GPL(regcache_cache_only);
@@ -493,7 +493,7 @@ void regcache_cache_bypass(struct regmap *map, bool enable)
map->lock(map->lock_arg);
WARN_ON(map->cache_only && enable);
map->cache_bypass = enable;
- trace_regmap_cache_bypass(map->dev, enable);
+ trace_regmap_cache_bypass(map, enable);
map->unlock(map->lock_arg);
}
EXPORT_SYMBOL_GPL(regcache_cache_bypass);
@@ -608,7 +608,8 @@ static int regcache_sync_block_single(struct regmap *map, void *block,
for (i = start; i < end; i++) {
regtmp = block_base + (i * map->reg_stride);
- if (!regcache_reg_present(cache_present, i))
+ if (!regcache_reg_present(cache_present, i) ||
+ !regmap_writeable(map, regtmp))
continue;
val = regcache_get_val(map, block, i);
@@ -677,7 +678,8 @@ static int regcache_sync_block_raw(struct regmap *map, void *block,
for (i = start; i < end; i++) {
regtmp = block_base + (i * map->reg_stride);
- if (!regcache_reg_present(cache_present, i)) {
+ if (!regcache_reg_present(cache_present, i) ||
+ !regmap_writeable(map, regtmp)) {
ret = regcache_sync_block_raw_flush(map, &data,
base, regtmp);
if (ret != 0)
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 6299a50..a6c3f75 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -499,7 +499,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
goto err_alloc;
}
- ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags,
+ ret = request_threaded_irq(irq, NULL, regmap_irq_thread,
+ irq_flags | IRQF_ONESHOT,
chip->name, d);
if (ret != 0) {
dev_err(map->dev, "Failed to request IRQ %d for %s: %d\n",
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index f99b098..dbfe6a6 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1281,7 +1281,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
if (map->async && map->bus->async_write) {
struct regmap_async *async;
- trace_regmap_async_write_start(map->dev, reg, val_len);
+ trace_regmap_async_write_start(map, reg, val_len);
spin_lock_irqsave(&map->async_lock, flags);
async = list_first_entry_or_null(&map->async_free,
@@ -1339,8 +1339,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
return ret;
}
- trace_regmap_hw_write_start(map->dev, reg,
- val_len / map->format.val_bytes);
+ trace_regmap_hw_write_start(map, reg, val_len / map->format.val_bytes);
/* If we're doing a single register write we can probably just
* send the work_buf directly, otherwise try to do a gather
@@ -1372,8 +1371,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
kfree(buf);
}
- trace_regmap_hw_write_done(map->dev, reg,
- val_len / map->format.val_bytes);
+ trace_regmap_hw_write_done(map, reg, val_len / map->format.val_bytes);
return ret;
}
@@ -1407,12 +1405,12 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
map->format.format_write(map, reg, val);
- trace_regmap_hw_write_start(map->dev, reg, 1);
+ trace_regmap_hw_write_start(map, reg, 1);
ret = map->bus->write(map->bus_context, map->work_buf,
map->format.buf_size);
- trace_regmap_hw_write_done(map->dev, reg, 1);
+ trace_regmap_hw_write_done(map, reg, 1);
return ret;
}
@@ -1470,7 +1468,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
dev_info(map->dev, "%x <= %x\n", reg, val);
#endif
- trace_regmap_reg_write(map->dev, reg, val);
+ trace_regmap_reg_write(map, reg, val);
return map->reg_write(context, reg, val);
}
@@ -1773,7 +1771,7 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
for (i = 0; i < num_regs; i++) {
int reg = regs[i].reg;
int val = regs[i].def;
- trace_regmap_hw_write_start(map->dev, reg, 1);
+ trace_regmap_hw_write_start(map, reg, 1);
map->format.format_reg(u8, reg, map->reg_shift);
u8 += reg_bytes + pad_bytes;
map->format.format_val(u8, val, 0);
@@ -1788,7 +1786,7 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
for (i = 0; i < num_regs; i++) {
int reg = regs[i].reg;
- trace_regmap_hw_write_done(map->dev, reg, 1);
+ trace_regmap_hw_write_done(map, reg, 1);
}
return ret;
}
@@ -2059,15 +2057,13 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
*/
u8[0] |= map->read_flag_mask;
- trace_regmap_hw_read_start(map->dev, reg,
- val_len / map->format.val_bytes);
+ trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);
ret = map->bus->read(map->bus_context, map->work_buf,
map->format.reg_bytes + map->format.pad_bytes,
val, val_len);
- trace_regmap_hw_read_done(map->dev, reg,
- val_len / map->format.val_bytes);
+ trace_regmap_hw_read_done(map, reg, val_len / map->format.val_bytes);
return ret;
}
@@ -2123,7 +2119,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
dev_info(map->dev, "%x => %x\n", reg, *val);
#endif
- trace_regmap_reg_read(map->dev, reg, *val);
+ trace_regmap_reg_read(map, reg, *val);
if (!map->cache_bypass)
regcache_write(map, reg, *val);
@@ -2480,7 +2476,7 @@ void regmap_async_complete_cb(struct regmap_async *async, int ret)
struct regmap *map = async->map;
bool wake;
- trace_regmap_async_io_complete(map->dev);
+ trace_regmap_async_io_complete(map);
spin_lock(&map->async_lock);
list_move(&async->list, &map->async_free);
@@ -2525,7 +2521,7 @@ int regmap_async_complete(struct regmap *map)
if (!map->bus || !map->bus->async_write)
return 0;
- trace_regmap_async_complete_start(map->dev);
+ trace_regmap_async_complete_start(map);
wait_event(map->async_waitq, regmap_async_is_done(map));
@@ -2534,7 +2530,7 @@ int regmap_async_complete(struct regmap *map)
map->async_ret = 0;
spin_unlock_irqrestore(&map->async_lock, flags);
- trace_regmap_async_complete_done(map->dev);
+ trace_regmap_async_complete_done(map);
return ret;
}
OpenPOWER on IntegriCloud