Merge branches 'pm-opp' and 'pm-cpufreq-fixes'

* pm-opp:
  PM / OPP: Add 'UNKNOWN' status for shared_opp in struct opp_table

* pm-cpufreq-fixes:
  cpufreq: intel_pstate: Adjust _PSS[0] freqeuency if needed
This commit is contained in:
Rafael J. Wysocki 2016-06-18 01:55:13 +02:00
commit 9d066a2527
9555 changed files with 487676 additions and 191925 deletions

View file

@ -4,6 +4,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 Intel Deutschland GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@ -41,12 +42,12 @@ static bool devcd_disabled;
struct devcd_entry {
struct device devcd_dev;
const void *data;
void *data;
size_t datalen;
struct module *owner;
ssize_t (*read)(char *buffer, loff_t offset, size_t count,
const void *data, size_t datalen);
void (*free)(const void *data);
void *data, size_t datalen);
void (*free)(void *data);
struct delayed_work del_wk;
struct device *failing_dev;
};
@ -174,7 +175,7 @@ static struct class devcd_class = {
};
static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count,
const void *data, size_t datalen)
void *data, size_t datalen)
{
if (offset > datalen)
return -EINVAL;
@ -188,6 +189,11 @@ static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count,
return count;
}
static void devcd_freev(void *data)
{
vfree(data);
}
/**
* dev_coredumpv - create device coredump with vmalloc data
* @dev: the struct device for the crashed device
@ -198,10 +204,10 @@ static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count,
* This function takes ownership of the vmalloc'ed data and will free
* it when it is no longer used. See dev_coredumpm() for more information.
*/
void dev_coredumpv(struct device *dev, const void *data, size_t datalen,
void dev_coredumpv(struct device *dev, void *data, size_t datalen,
gfp_t gfp)
{
dev_coredumpm(dev, NULL, data, datalen, gfp, devcd_readv, vfree);
dev_coredumpm(dev, NULL, data, datalen, gfp, devcd_readv, devcd_freev);
}
EXPORT_SYMBOL_GPL(dev_coredumpv);
@ -212,6 +218,44 @@ static int devcd_match_failing(struct device *dev, const void *failing)
return devcd->failing_dev == failing;
}
/**
* devcd_free_sgtable - free all the memory of the given scatterlist table
* (i.e. both pages and scatterlist instances)
* NOTE: if two tables allocated with devcd_alloc_sgtable and then chained
* using the sg_chain function then that function should be called only once
* on the chained table
* @table: pointer to sg_table to free
*/
static void devcd_free_sgtable(void *data)
{
_devcd_free_sgtable(data);
}
/**
* devcd_read_from_table - copy data from sg_table to a given buffer
* and return the number of bytes read
* @buffer: the buffer to copy the data to it
* @buf_len: the length of the buffer
* @data: the scatterlist table to copy from
* @offset: start copy from @offset@ bytes from the head of the data
* in the given scatterlist
* @data_len: the length of the data in the sg_table
*/
static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset,
size_t buf_len, void *data,
size_t data_len)
{
struct scatterlist *table = data;
if (offset > data_len)
return -EINVAL;
if (offset + buf_len > data_len)
buf_len = data_len - offset;
return sg_pcopy_to_buffer(table, sg_nents(table), buffer, buf_len,
offset);
}
/**
* dev_coredumpm - create device coredump with read/free methods
* @dev: the struct device for the crashed device
@ -228,10 +272,10 @@ static int devcd_match_failing(struct device *dev, const void *failing)
* function will be called to free the data.
*/
void dev_coredumpm(struct device *dev, struct module *owner,
const void *data, size_t datalen, gfp_t gfp,
void *data, size_t datalen, gfp_t gfp,
ssize_t (*read)(char *buffer, loff_t offset, size_t count,
const void *data, size_t datalen),
void (*free)(const void *data))
void *data, size_t datalen),
void (*free)(void *data))
{
static atomic_t devcd_count = ATOMIC_INIT(0);
struct devcd_entry *devcd;
@ -291,6 +335,27 @@ void dev_coredumpm(struct device *dev, struct module *owner,
}
EXPORT_SYMBOL_GPL(dev_coredumpm);
/**
* dev_coredumpmsg - create device coredump that uses scatterlist as data
* parameter
* @dev: the struct device for the crashed device
* @table: the dump data
* @datalen: length of the data
* @gfp: allocation flags
*
* Creates a new device coredump for the given device. If a previous one hasn't
* been read yet, the new coredump is discarded. The data lifetime is determined
* by the device coredump framework and when it is no longer needed
* it will free the data.
*/
void dev_coredumpsg(struct device *dev, struct scatterlist *table,
size_t datalen, gfp_t gfp)
{
dev_coredumpm(dev, NULL, table, datalen, gfp, devcd_read_from_sgtable,
devcd_free_sgtable);
}
EXPORT_SYMBOL_GPL(dev_coredumpsg);
static int __init devcoredump_init(void)
{
return class_register(&devcd_class);

View file

@ -322,16 +322,16 @@ 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
* @properties: null terminated array of 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.
* The function will take deep copy of @properties 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)
struct property_entry *properties)
{
return device_add_property_set(&pdev->dev, pset);
return device_add_properties(&pdev->dev, properties);
}
EXPORT_SYMBOL_GPL(platform_device_add_properties);
@ -447,7 +447,7 @@ void platform_device_del(struct platform_device *pdev)
release_resource(r);
}
device_remove_property_set(&pdev->dev);
device_remove_properties(&pdev->dev);
}
}
EXPORT_SYMBOL_GPL(platform_device_del);
@ -526,8 +526,9 @@ struct platform_device *platform_device_register_full(
if (ret)
goto err;
if (pdevinfo->pset) {
ret = platform_device_add_properties(pdev, pdevinfo->pset);
if (pdevinfo->properties) {
ret = platform_device_add_properties(pdev,
pdevinfo->properties);
if (ret)
goto err;
}

View file

@ -159,7 +159,7 @@ int of_pm_clk_add_clks(struct device *dev)
count = of_count_phandle_with_args(dev->of_node, "clocks",
"#clock-cells");
if (count == 0)
if (count <= 0)
return -ENODEV;
clks = kcalloc(count, sizeof(*clks), GFP_KERNEL);

View file

@ -229,17 +229,6 @@ static int genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth)
return ret;
}
static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
{
return GENPD_DEV_CALLBACK(genpd, int, save_state, dev);
}
static int genpd_restore_dev(struct generic_pm_domain *genpd,
struct device *dev)
{
return GENPD_DEV_CALLBACK(genpd, int, restore_state, dev);
}
static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
unsigned long val, void *ptr)
{
@ -372,17 +361,63 @@ static void genpd_power_off_work_fn(struct work_struct *work)
}
/**
* pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
* __genpd_runtime_suspend - walk the hierarchy of ->runtime_suspend() callbacks
* @dev: Device to handle.
*/
static int __genpd_runtime_suspend(struct device *dev)
{
int (*cb)(struct device *__dev);
if (dev->type && dev->type->pm)
cb = dev->type->pm->runtime_suspend;
else if (dev->class && dev->class->pm)
cb = dev->class->pm->runtime_suspend;
else if (dev->bus && dev->bus->pm)
cb = dev->bus->pm->runtime_suspend;
else
cb = NULL;
if (!cb && dev->driver && dev->driver->pm)
cb = dev->driver->pm->runtime_suspend;
return cb ? cb(dev) : 0;
}
/**
* __genpd_runtime_resume - walk the hierarchy of ->runtime_resume() callbacks
* @dev: Device to handle.
*/
static int __genpd_runtime_resume(struct device *dev)
{
int (*cb)(struct device *__dev);
if (dev->type && dev->type->pm)
cb = dev->type->pm->runtime_resume;
else if (dev->class && dev->class->pm)
cb = dev->class->pm->runtime_resume;
else if (dev->bus && dev->bus->pm)
cb = dev->bus->pm->runtime_resume;
else
cb = NULL;
if (!cb && dev->driver && dev->driver->pm)
cb = dev->driver->pm->runtime_resume;
return cb ? cb(dev) : 0;
}
/**
* genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
* @dev: Device to suspend.
*
* Carry out a runtime suspend of a device under the assumption that its
* pm_domain field points to the domain member of an object of type
* struct generic_pm_domain representing a PM domain consisting of I/O devices.
*/
static int pm_genpd_runtime_suspend(struct device *dev)
static int genpd_runtime_suspend(struct device *dev)
{
struct generic_pm_domain *genpd;
bool (*stop_ok)(struct device *__dev);
bool (*suspend_ok)(struct device *__dev);
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
bool runtime_pm = pm_runtime_enabled(dev);
ktime_t time_start;
@ -401,21 +436,21 @@ static int pm_genpd_runtime_suspend(struct device *dev)
* runtime PM is disabled. Under these circumstances, we shall skip
* validating/measuring the PM QoS latency.
*/
stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
if (runtime_pm && stop_ok && !stop_ok(dev))
suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL;
if (runtime_pm && suspend_ok && !suspend_ok(dev))
return -EBUSY;
/* Measure suspend latency. */
if (runtime_pm)
time_start = ktime_get();
ret = genpd_save_dev(genpd, dev);
ret = __genpd_runtime_suspend(dev);
if (ret)
return ret;
ret = genpd_stop_dev(genpd, dev);
if (ret) {
genpd_restore_dev(genpd, dev);
__genpd_runtime_resume(dev);
return ret;
}
@ -446,14 +481,14 @@ static int pm_genpd_runtime_suspend(struct device *dev)
}
/**
* pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
* genpd_runtime_resume - Resume a device belonging to I/O PM domain.
* @dev: Device to resume.
*
* Carry out a runtime resume of a device under the assumption that its
* pm_domain field points to the domain member of an object of type
* struct generic_pm_domain representing a PM domain consisting of I/O devices.
*/
static int pm_genpd_runtime_resume(struct device *dev)
static int genpd_runtime_resume(struct device *dev)
{
struct generic_pm_domain *genpd;
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
@ -491,7 +526,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
if (ret)
goto err_poweroff;
ret = genpd_restore_dev(genpd, dev);
ret = __genpd_runtime_resume(dev);
if (ret)
goto err_stop;
@ -695,15 +730,6 @@ static int pm_genpd_prepare(struct device *dev)
* at this point and a system wakeup event should be reported if it's
* set up to wake up the system from sleep states.
*/
pm_runtime_get_noresume(dev);
if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
pm_wakeup_event(dev, 0);
if (pm_wakeup_pending()) {
pm_runtime_put(dev);
return -EBUSY;
}
if (resume_needed(dev, genpd))
pm_runtime_resume(dev);
@ -716,10 +742,8 @@ static int pm_genpd_prepare(struct device *dev)
mutex_unlock(&genpd->lock);
if (genpd->suspend_power_off) {
pm_runtime_put_noidle(dev);
if (genpd->suspend_power_off)
return 0;
}
/*
* The PM domain must be in the GPD_STATE_ACTIVE state at this point,
@ -741,7 +765,6 @@ static int pm_genpd_prepare(struct device *dev)
pm_runtime_enable(dev);
}
pm_runtime_put(dev);
return ret;
}
@ -1427,54 +1450,6 @@ out:
}
EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
/* Default device callbacks for generic PM domains. */
/**
* pm_genpd_default_save_state - Default "save device state" for PM domains.
* @dev: Device to handle.
*/
static int pm_genpd_default_save_state(struct device *dev)
{
int (*cb)(struct device *__dev);
if (dev->type && dev->type->pm)
cb = dev->type->pm->runtime_suspend;
else if (dev->class && dev->class->pm)
cb = dev->class->pm->runtime_suspend;
else if (dev->bus && dev->bus->pm)
cb = dev->bus->pm->runtime_suspend;
else
cb = NULL;
if (!cb && dev->driver && dev->driver->pm)
cb = dev->driver->pm->runtime_suspend;
return cb ? cb(dev) : 0;
}
/**
* pm_genpd_default_restore_state - Default PM domains "restore device state".
* @dev: Device to handle.
*/
static int pm_genpd_default_restore_state(struct device *dev)
{
int (*cb)(struct device *__dev);
if (dev->type && dev->type->pm)
cb = dev->type->pm->runtime_resume;
else if (dev->class && dev->class->pm)
cb = dev->class->pm->runtime_resume;
else if (dev->bus && dev->bus->pm)
cb = dev->bus->pm->runtime_resume;
else
cb = NULL;
if (!cb && dev->driver && dev->driver->pm)
cb = dev->driver->pm->runtime_resume;
return cb ? cb(dev) : 0;
}
/**
* pm_genpd_init - Initialize a generic I/O PM domain object.
* @genpd: PM domain object to initialize.
@ -1498,8 +1473,8 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
genpd->device_count = 0;
genpd->max_off_time_ns = -1;
genpd->max_off_time_changed = true;
genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
genpd->domain.ops.runtime_suspend = genpd_runtime_suspend;
genpd->domain.ops.runtime_resume = genpd_runtime_resume;
genpd->domain.ops.prepare = pm_genpd_prepare;
genpd->domain.ops.suspend = pm_genpd_suspend;
genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
@ -1520,8 +1495,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
genpd->domain.ops.restore_early = pm_genpd_resume_early;
genpd->domain.ops.restore = pm_genpd_resume;
genpd->domain.ops.complete = pm_genpd_complete;
genpd->dev_ops.save_state = pm_genpd_default_save_state;
genpd->dev_ops.restore_state = pm_genpd_default_restore_state;
if (genpd->flags & GENPD_FLAG_PM_CLK) {
genpd->dev_ops.stop = pm_clk_suspend;

View file

@ -37,10 +37,10 @@ static int dev_update_qos_constraint(struct device *dev, void *data)
}
/**
* default_stop_ok - Default PM domain governor routine for stopping devices.
* default_suspend_ok - Default PM domain governor routine to suspend devices.
* @dev: Device to check.
*/
static bool default_stop_ok(struct device *dev)
static bool default_suspend_ok(struct device *dev)
{
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
unsigned long flags;
@ -51,13 +51,13 @@ static bool default_stop_ok(struct device *dev)
spin_lock_irqsave(&dev->power.lock, flags);
if (!td->constraint_changed) {
bool ret = td->cached_stop_ok;
bool ret = td->cached_suspend_ok;
spin_unlock_irqrestore(&dev->power.lock, flags);
return ret;
}
td->constraint_changed = false;
td->cached_stop_ok = false;
td->cached_suspend_ok = false;
td->effective_constraint_ns = -1;
constraint_ns = __dev_pm_qos_read_value(dev);
@ -83,13 +83,13 @@ static bool default_stop_ok(struct device *dev)
return false;
}
td->effective_constraint_ns = constraint_ns;
td->cached_stop_ok = constraint_ns >= 0;
td->cached_suspend_ok = constraint_ns >= 0;
/*
* The children have been suspended already, so we don't need to take
* their stop latencies into account here.
* their suspend latencies into account here.
*/
return td->cached_stop_ok;
return td->cached_suspend_ok;
}
/**
@ -150,7 +150,7 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
*/
td = &to_gpd_data(pdd)->td;
constraint_ns = td->effective_constraint_ns;
/* default_stop_ok() need not be called before us. */
/* default_suspend_ok() need not be called before us. */
if (constraint_ns < 0) {
constraint_ns = dev_pm_qos_read_value(pdd->dev);
constraint_ns *= NSEC_PER_USEC;
@ -227,7 +227,7 @@ static bool always_on_power_down_ok(struct dev_pm_domain *domain)
}
struct dev_power_governor simple_qos_governor = {
.stop_ok = default_stop_ok,
.suspend_ok = default_suspend_ok,
.power_down_ok = default_power_down_ok,
};
@ -236,5 +236,5 @@ struct dev_power_governor simple_qos_governor = {
*/
struct dev_power_governor pm_domain_always_on_gov = {
.power_down_ok = always_on_power_down_ok,
.stop_ok = default_stop_ok,
.suspend_ok = default_suspend_ok,
};

View file

@ -1267,14 +1267,15 @@ int dpm_suspend_late(pm_message_t state)
error = device_suspend_late(dev);
mutex_lock(&dpm_list_mtx);
if (!list_empty(&dev->power.entry))
list_move(&dev->power.entry, &dpm_late_early_list);
if (error) {
pm_dev_err(dev, state, " late", error);
dpm_save_failed_dev(dev_name(dev));
put_device(dev);
break;
}
if (!list_empty(&dev->power.entry))
list_move(&dev->power.entry, &dpm_late_early_list);
put_device(dev);
if (async_error)
@ -1556,7 +1557,6 @@ int dpm_suspend(pm_message_t state)
static int device_prepare(struct device *dev, pm_message_t state)
{
int (*callback)(struct device *) = NULL;
char *info = NULL;
int ret = 0;
if (dev->power.syscore)
@ -1579,24 +1579,17 @@ static int device_prepare(struct device *dev, pm_message_t state)
goto unlock;
}
if (dev->pm_domain) {
info = "preparing power domain ";
if (dev->pm_domain)
callback = dev->pm_domain->ops.prepare;
} else if (dev->type && dev->type->pm) {
info = "preparing type ";
else if (dev->type && dev->type->pm)
callback = dev->type->pm->prepare;
} else if (dev->class && dev->class->pm) {
info = "preparing class ";
else if (dev->class && dev->class->pm)
callback = dev->class->pm->prepare;
} else if (dev->bus && dev->bus->pm) {
info = "preparing bus ";
else if (dev->bus && dev->bus->pm)
callback = dev->bus->pm->prepare;
}
if (!callback && dev->driver && dev->driver->pm) {
info = "preparing driver ";
if (!callback && dev->driver && dev->driver->pm)
callback = dev->driver->pm->prepare;
}
if (callback)
ret = callback(dev);

View file

@ -1506,11 +1506,16 @@ int pm_runtime_force_resume(struct device *dev)
goto out;
}
ret = callback(dev);
ret = pm_runtime_set_active(dev);
if (ret)
goto out;
pm_runtime_set_active(dev);
ret = callback(dev);
if (ret) {
pm_runtime_set_suspended(dev);
goto out;
}
pm_runtime_mark_last_busy(dev);
out:
pm_runtime_enable(dev);

View file

@ -19,9 +19,14 @@
#include <linux/etherdevice.h>
#include <linux/phy.h>
struct property_set {
struct fwnode_handle fwnode;
struct property_entry *properties;
};
static inline bool is_pset_node(struct fwnode_handle *fwnode)
{
return fwnode && fwnode->type == FWNODE_PDATA;
return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA;
}
static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)
@ -801,14 +806,14 @@ static struct property_set *pset_copy_set(const struct property_set *pset)
}
/**
* device_remove_property_set - Remove properties from a device object.
* device_remove_properties - Remove properties from a device object.
* @dev: Device whose properties to remove.
*
* The function removes properties previously associated to the device
* secondary firmware node with device_add_property_set(). Memory allocated
* secondary firmware node with device_add_properties(). Memory allocated
* to the properties will also be released.
*/
void device_remove_property_set(struct device *dev)
void device_remove_properties(struct device *dev)
{
struct fwnode_handle *fwnode;
@ -831,24 +836,27 @@ void device_remove_property_set(struct device *dev)
}
}
}
EXPORT_SYMBOL_GPL(device_remove_property_set);
EXPORT_SYMBOL_GPL(device_remove_properties);
/**
* device_add_property_set - Add a collection of properties to a device object.
* device_add_properties - Add a collection of properties to a device object.
* @dev: Device to add properties to.
* @pset: Collection of properties to add.
* @properties: Collection of properties to add.
*
* Associate a collection of device properties represented by @pset with @dev
* as its secondary firmware node. The function takes a copy of @pset.
* Associate a collection of device properties represented by @properties with
* @dev as its secondary firmware node. The function takes a copy of
* @properties.
*/
int device_add_property_set(struct device *dev, const struct property_set *pset)
int device_add_properties(struct device *dev, struct property_entry *properties)
{
struct property_set *p;
struct property_set *p, pset;
if (!pset)
if (!properties)
return -EINVAL;
p = pset_copy_set(pset);
pset.properties = properties;
p = pset_copy_set(&pset);
if (IS_ERR(p))
return PTR_ERR(p);
@ -856,7 +864,7 @@ int device_add_property_set(struct device *dev, const struct property_set *pset)
set_secondary_fwnode(dev, &p->fwnode);
return 0;
}
EXPORT_SYMBOL_GPL(device_add_property_set);
EXPORT_SYMBOL_GPL(device_add_properties);
/**
* device_get_next_child_node - Return the next child node handle for a device

View file

@ -13,6 +13,7 @@
#ifndef _REGMAP_INTERNAL_H
#define _REGMAP_INTERNAL_H
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/fs.h>
#include <linux/list.h>

View file

@ -27,7 +27,7 @@ static int regcache_flat_init(struct regmap *map)
int i;
unsigned int *cache;
if (!map || map->reg_stride_order < 0)
if (!map || map->reg_stride_order < 0 || !map->max_register)
return -EINVAL;
map->cache = kcalloc(regcache_flat_get_index(map, map->max_register)

View file

@ -529,7 +529,7 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty);
* regcache_cache_bypass: Put a register map into cache bypass mode
*
* @map: map to configure
* @cache_bypass: flag if changes should not be written to the hardware
* @cache_bypass: flag if changes should not be written to the cache
*
* When a register map is marked with the cache bypass option, writes
* to the register map API will only update the hardware and not the

View file

@ -23,6 +23,8 @@
#include <linux/regmap.h>
#include <linux/slab.h>
#include "internal.h"
struct regmap_mmio_context {
void __iomem *regs;
unsigned val_bytes;
@ -212,6 +214,7 @@ static const struct regmap_bus regmap_mmio = {
.reg_write = regmap_mmio_write,
.reg_read = regmap_mmio_read,
.free_context = regmap_mmio_free_context,
.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
};
static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
@ -245,7 +248,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
ctx->val_bytes = config->val_bits / 8;
ctx->clk = ERR_PTR(-ENODEV);
switch (config->reg_format_endian) {
switch (regmap_get_val_endian(dev, &regmap_mmio, config)) {
case REGMAP_ENDIAN_DEFAULT:
case REGMAP_ENDIAN_LITTLE:
#ifdef __LITTLE_ENDIAN

View file

@ -142,7 +142,7 @@ static int regmap_spmi_ext_read(void *context,
while (val_size) {
len = min_t(size_t, val_size, 8);
err = spmi_ext_register_readl(context, addr, val, val_size);
err = spmi_ext_register_readl(context, addr, val, len);
if (err)
goto err_out;