Merge branches 'pm-sleep', 'pm-domains', 'pm-opp' and 'powercap'
* pm-sleep: PM / wakeirq: remove unnecessary parentheses PM / core: Clean up some function headers in power.h PM / hibernate: memory_bm_find_bit(): Tighten node optimisation * pm-domains: PM / Domains: Convert to dev_to_genpd_safe() in genpd_syscore_switch() mmc: tmio: Avoid boilerplate code in ->runtime_suspend() PM / Domains: Implement the ->start() callback for genpd PM / Domains: Introduce dev_pm_domain_start() * pm-opp: PM / OPP: Support adjusting OPP voltages at runtime * powercap: powercap/intel_rapl: add support for Cometlake desktop powercap/intel_rapl: add support for CometLake Mobile
This commit is contained in:
commit
5a97aa5bbc
|
@ -187,6 +187,26 @@ void dev_pm_domain_detach(struct device *dev, bool power_off)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
|
||||
|
||||
/**
|
||||
* dev_pm_domain_start - Start the device through its PM domain.
|
||||
* @dev: Device to start.
|
||||
*
|
||||
* This function should typically be called during probe by a subsystem/driver,
|
||||
* when it needs to start its device from the PM domain's perspective. Note
|
||||
* that, it's assumed that the PM domain is already powered on when this
|
||||
* function is called.
|
||||
*
|
||||
* Returns 0 on success and negative error values on failures.
|
||||
*/
|
||||
int dev_pm_domain_start(struct device *dev)
|
||||
{
|
||||
if (dev->pm_domain && dev->pm_domain->start)
|
||||
return dev->pm_domain->start(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_domain_start);
|
||||
|
||||
/**
|
||||
* dev_pm_domain_set - Set PM domain of a device.
|
||||
* @dev: Device whose PM domain is to be set.
|
||||
|
|
|
@ -634,6 +634,13 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int genpd_dev_pm_start(struct device *dev)
|
||||
{
|
||||
struct generic_pm_domain *genpd = dev_to_genpd(dev);
|
||||
|
||||
return genpd_start_dev(genpd, dev);
|
||||
}
|
||||
|
||||
static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
|
||||
unsigned long val, void *ptr)
|
||||
{
|
||||
|
@ -922,24 +929,6 @@ static int __init genpd_power_off_unused(void)
|
|||
}
|
||||
late_initcall(genpd_power_off_unused);
|
||||
|
||||
#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_GENERIC_DOMAINS_OF)
|
||||
|
||||
static bool genpd_present(const struct generic_pm_domain *genpd)
|
||||
{
|
||||
const struct generic_pm_domain *gpd;
|
||||
|
||||
if (IS_ERR_OR_NULL(genpd))
|
||||
return false;
|
||||
|
||||
list_for_each_entry(gpd, &gpd_list, gpd_list_node)
|
||||
if (gpd == genpd)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
/**
|
||||
|
@ -1354,8 +1343,8 @@ static void genpd_syscore_switch(struct device *dev, bool suspend)
|
|||
{
|
||||
struct generic_pm_domain *genpd;
|
||||
|
||||
genpd = dev_to_genpd(dev);
|
||||
if (!genpd_present(genpd))
|
||||
genpd = dev_to_genpd_safe(dev);
|
||||
if (!genpd)
|
||||
return;
|
||||
|
||||
if (suspend) {
|
||||
|
@ -1805,6 +1794,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
|
|||
genpd->domain.ops.poweroff_noirq = genpd_poweroff_noirq;
|
||||
genpd->domain.ops.restore_noirq = genpd_restore_noirq;
|
||||
genpd->domain.ops.complete = genpd_complete;
|
||||
genpd->domain.start = genpd_dev_pm_start;
|
||||
|
||||
if (genpd->flags & GENPD_FLAG_PM_CLK) {
|
||||
genpd->dev_ops.stop = pm_clk_suspend;
|
||||
|
@ -2020,6 +2010,16 @@ static int genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool genpd_present(const struct generic_pm_domain *genpd)
|
||||
{
|
||||
const struct generic_pm_domain *gpd;
|
||||
|
||||
list_for_each_entry(gpd, &gpd_list, gpd_list_node)
|
||||
if (gpd == genpd)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_genpd_add_provider_simple() - Register a simple PM domain provider
|
||||
* @np: Device node pointer associated with the PM domain provider.
|
||||
|
|
|
@ -117,6 +117,13 @@ static inline bool device_pm_initialized(struct device *dev)
|
|||
return dev->power.in_dpm_list;
|
||||
}
|
||||
|
||||
/* drivers/base/power/wakeup_stats.c */
|
||||
extern int wakeup_source_sysfs_add(struct device *parent,
|
||||
struct wakeup_source *ws);
|
||||
extern void wakeup_source_sysfs_remove(struct wakeup_source *ws);
|
||||
|
||||
extern int pm_wakeup_source_sysfs_add(struct device *parent);
|
||||
|
||||
#else /* !CONFIG_PM_SLEEP */
|
||||
|
||||
static inline void device_pm_sleep_init(struct device *dev) {}
|
||||
|
@ -141,6 +148,11 @@ static inline bool device_pm_initialized(struct device *dev)
|
|||
return device_is_registered(dev);
|
||||
}
|
||||
|
||||
static inline int pm_wakeup_source_sysfs_add(struct device *parent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_PM_SLEEP */
|
||||
|
||||
static inline void device_pm_init(struct device *dev)
|
||||
|
@ -149,21 +161,3 @@ static inline void device_pm_init(struct device *dev)
|
|||
device_pm_sleep_init(dev);
|
||||
pm_runtime_init(dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
/* drivers/base/power/wakeup_stats.c */
|
||||
extern int wakeup_source_sysfs_add(struct device *parent,
|
||||
struct wakeup_source *ws);
|
||||
extern void wakeup_source_sysfs_remove(struct wakeup_source *ws);
|
||||
|
||||
extern int pm_wakeup_source_sysfs_add(struct device *parent);
|
||||
|
||||
#else /* !CONFIG_PM_SLEEP */
|
||||
|
||||
static inline int pm_wakeup_source_sysfs_add(struct device *parent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
|
|
@ -272,7 +272,7 @@ void dev_pm_enable_wake_irq_check(struct device *dev,
|
|||
{
|
||||
struct wake_irq *wirq = dev->power.wakeirq;
|
||||
|
||||
if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK)))
|
||||
if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
|
||||
return;
|
||||
|
||||
if (likely(wirq->status & WAKE_IRQ_DEDICATED_MANAGED)) {
|
||||
|
@ -299,7 +299,7 @@ void dev_pm_disable_wake_irq_check(struct device *dev)
|
|||
{
|
||||
struct wake_irq *wirq = dev->power.wakeirq;
|
||||
|
||||
if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK)))
|
||||
if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
|
||||
return;
|
||||
|
||||
if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
|
||||
|
|
|
@ -163,7 +163,6 @@ struct tmio_mmc_host {
|
|||
unsigned long last_req_ts;
|
||||
struct mutex ios_lock; /* protect set_ios() context */
|
||||
bool native_hotplug;
|
||||
bool runtime_synced;
|
||||
bool sdio_irq_enabled;
|
||||
|
||||
/* Mandatory callback */
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
@ -1248,10 +1249,12 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
|
|||
/* See if we also get DMA */
|
||||
tmio_mmc_request_dma(_host, pdata);
|
||||
|
||||
dev_pm_domain_start(&pdev->dev);
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret)
|
||||
|
@ -1333,11 +1336,6 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
|
|||
{
|
||||
struct tmio_mmc_host *host = dev_get_drvdata(dev);
|
||||
|
||||
if (!host->runtime_synced) {
|
||||
host->runtime_synced = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmio_mmc_clk_enable(host);
|
||||
tmio_mmc_hw_reset(host->mmc);
|
||||
|
||||
|
|
|
@ -2102,6 +2102,75 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
|
|||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* dev_pm_opp_adjust_voltage() - helper to change the voltage of an OPP
|
||||
* @dev: device for which we do this operation
|
||||
* @freq: OPP frequency to adjust voltage of
|
||||
* @u_volt: new OPP target voltage
|
||||
* @u_volt_min: new OPP min voltage
|
||||
* @u_volt_max: new OPP max voltage
|
||||
*
|
||||
* Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the
|
||||
* copy operation, returns 0 if no modifcation was done OR modification was
|
||||
* successful.
|
||||
*/
|
||||
int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
|
||||
unsigned long u_volt, unsigned long u_volt_min,
|
||||
unsigned long u_volt_max)
|
||||
|
||||
{
|
||||
struct opp_table *opp_table;
|
||||
struct dev_pm_opp *tmp_opp, *opp = ERR_PTR(-ENODEV);
|
||||
int r = 0;
|
||||
|
||||
/* Find the opp_table */
|
||||
opp_table = _find_opp_table(dev);
|
||||
if (IS_ERR(opp_table)) {
|
||||
r = PTR_ERR(opp_table);
|
||||
dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
mutex_lock(&opp_table->lock);
|
||||
|
||||
/* Do we have the frequency? */
|
||||
list_for_each_entry(tmp_opp, &opp_table->opp_list, node) {
|
||||
if (tmp_opp->rate == freq) {
|
||||
opp = tmp_opp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ERR(opp)) {
|
||||
r = PTR_ERR(opp);
|
||||
goto adjust_unlock;
|
||||
}
|
||||
|
||||
/* Is update really needed? */
|
||||
if (opp->supplies->u_volt == u_volt)
|
||||
goto adjust_unlock;
|
||||
|
||||
opp->supplies->u_volt = u_volt;
|
||||
opp->supplies->u_volt_min = u_volt_min;
|
||||
opp->supplies->u_volt_max = u_volt_max;
|
||||
|
||||
dev_pm_opp_get(opp);
|
||||
mutex_unlock(&opp_table->lock);
|
||||
|
||||
/* Notify the voltage change of the OPP */
|
||||
blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ADJUST_VOLTAGE,
|
||||
opp);
|
||||
|
||||
dev_pm_opp_put(opp);
|
||||
goto adjust_put_table;
|
||||
|
||||
adjust_unlock:
|
||||
mutex_unlock(&opp_table->lock);
|
||||
adjust_put_table:
|
||||
dev_pm_opp_put_opp_table(opp_table);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* dev_pm_opp_enable() - Enable a specific OPP
|
||||
* @dev: device for which we do this operation
|
||||
|
|
|
@ -978,6 +978,8 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
|
|||
INTEL_CPU_FAM6(ICELAKE_NNPI, rapl_defaults_core),
|
||||
INTEL_CPU_FAM6(ICELAKE_X, rapl_defaults_hsw_server),
|
||||
INTEL_CPU_FAM6(ICELAKE_D, rapl_defaults_hsw_server),
|
||||
INTEL_CPU_FAM6(COMETLAKE_L, rapl_defaults_core),
|
||||
INTEL_CPU_FAM6(COMETLAKE, rapl_defaults_core),
|
||||
|
||||
INTEL_CPU_FAM6(ATOM_SILVERMONT, rapl_defaults_byt),
|
||||
INTEL_CPU_FAM6(ATOM_AIRMONT, rapl_defaults_cht),
|
||||
|
|
|
@ -637,6 +637,7 @@ extern void dev_pm_put_subsys_data(struct device *dev);
|
|||
* struct dev_pm_domain - power management domain representation.
|
||||
*
|
||||
* @ops: Power management operations associated with this domain.
|
||||
* @start: Called when a user needs to start the device via the domain.
|
||||
* @detach: Called when removing a device from the domain.
|
||||
* @activate: Called before executing probe routines for bus types and drivers.
|
||||
* @sync: Called after successful driver probe.
|
||||
|
@ -648,6 +649,7 @@ extern void dev_pm_put_subsys_data(struct device *dev);
|
|||
*/
|
||||
struct dev_pm_domain {
|
||||
struct dev_pm_ops ops;
|
||||
int (*start)(struct device *dev);
|
||||
void (*detach)(struct device *dev, bool power_off);
|
||||
int (*activate)(struct device *dev);
|
||||
void (*sync)(struct device *dev);
|
||||
|
|
|
@ -366,6 +366,7 @@ struct device *dev_pm_domain_attach_by_id(struct device *dev,
|
|||
struct device *dev_pm_domain_attach_by_name(struct device *dev,
|
||||
const char *name);
|
||||
void dev_pm_domain_detach(struct device *dev, bool power_off);
|
||||
int dev_pm_domain_start(struct device *dev);
|
||||
void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
|
||||
#else
|
||||
static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
|
||||
|
@ -383,6 +384,10 @@ static inline struct device *dev_pm_domain_attach_by_name(struct device *dev,
|
|||
return NULL;
|
||||
}
|
||||
static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
|
||||
static inline int dev_pm_domain_start(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void dev_pm_domain_set(struct device *dev,
|
||||
struct dev_pm_domain *pd) {}
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,7 @@ struct opp_table;
|
|||
|
||||
enum dev_pm_opp_event {
|
||||
OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
|
||||
OPP_EVENT_ADJUST_VOLTAGE,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -113,6 +114,10 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq,
|
|||
void dev_pm_opp_remove(struct device *dev, unsigned long freq);
|
||||
void dev_pm_opp_remove_all_dynamic(struct device *dev);
|
||||
|
||||
int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
|
||||
unsigned long u_volt, unsigned long u_volt_min,
|
||||
unsigned long u_volt_max);
|
||||
|
||||
int dev_pm_opp_enable(struct device *dev, unsigned long freq);
|
||||
|
||||
int dev_pm_opp_disable(struct device *dev, unsigned long freq);
|
||||
|
@ -242,6 +247,14 @@ static inline void dev_pm_opp_remove_all_dynamic(struct device *dev)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int
|
||||
dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
|
||||
unsigned long u_volt, unsigned long u_volt_min,
|
||||
unsigned long u_volt_max)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -734,8 +734,15 @@ static int memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn,
|
|||
* We have found the zone. Now walk the radix tree to find the leaf node
|
||||
* for our PFN.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the zone we wish to scan is the the current zone and the
|
||||
* pfn falls into the current node then we do not need to walk
|
||||
* the tree.
|
||||
*/
|
||||
node = bm->cur.node;
|
||||
if (((pfn - zone->start_pfn) & ~BM_BLOCK_MASK) == bm->cur.node_pfn)
|
||||
if (zone == bm->cur.zone &&
|
||||
((pfn - zone->start_pfn) & ~BM_BLOCK_MASK) == bm->cur.node_pfn)
|
||||
goto node_found;
|
||||
|
||||
node = zone->rtree;
|
||||
|
|
Loading…
Reference in New Issue