mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
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:
commit
9d066a2527
9555 changed files with 487676 additions and 191925 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, ®map_mmio, config)) {
|
||||
case REGMAP_ENDIAN_DEFAULT:
|
||||
case REGMAP_ENDIAN_LITTLE:
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue