Commit 7791bd23 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'pm-domains'

* pm-domains:
  PM / Domains: Fix build warning for CONFIG_PM_RUNTIME unset
  PM / Domains: Replace plain integer with NULL pointer in domain.c file
  PM / Domains: Add missing static storage class specifier in domain.c file
  PM / Domains: Allow device callbacks to be added at any time
  PM / Domains: Add device domain data reference counter
  PM / Domains: Add preliminary support for cpuidle, v2
  PM / Domains: Do not stop devices after restoring their states
  PM / Domains: Use subsystem runtime suspend/resume callbacks by default
parents 3db0bc97 8e9afafd
This diff is collapsed.
...@@ -281,6 +281,7 @@ static void poll_idle_init(struct cpuidle_driver *drv) ...@@ -281,6 +281,7 @@ static void poll_idle_init(struct cpuidle_driver *drv)
state->power_usage = -1; state->power_usage = -1;
state->flags = 0; state->flags = 0;
state->enter = poll_idle; state->enter = poll_idle;
state->disabled = false;
} }
#else #else
static void poll_idle_init(struct cpuidle_driver *drv) {} static void poll_idle_init(struct cpuidle_driver *drv) {}
......
...@@ -281,6 +281,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -281,6 +281,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
* unless the timer is happening really really soon. * unless the timer is happening really really soon.
*/ */
if (data->expected_us > 5 && if (data->expected_us > 5 &&
!drv->states[CPUIDLE_DRIVER_STATE_START].disabled &&
dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0)
data->last_state_idx = CPUIDLE_DRIVER_STATE_START; data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
...@@ -292,7 +293,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -292,7 +293,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
struct cpuidle_state *s = &drv->states[i]; struct cpuidle_state *s = &drv->states[i];
struct cpuidle_state_usage *su = &dev->states_usage[i]; struct cpuidle_state_usage *su = &dev->states_usage[i];
if (su->disable) if (s->disabled || su->disable)
continue; continue;
if (s->target_residency > data->predicted_us) if (s->target_residency > data->predicted_us)
continue; continue;
......
...@@ -47,6 +47,7 @@ struct cpuidle_state { ...@@ -47,6 +47,7 @@ struct cpuidle_state {
unsigned int exit_latency; /* in US */ unsigned int exit_latency; /* in US */
int power_usage; /* in mW */ int power_usage; /* in mW */
unsigned int target_residency; /* in US */ unsigned int target_residency; /* in US */
bool disabled; /* disabled on all CPUs */
int (*enter) (struct cpuidle_device *dev, int (*enter) (struct cpuidle_device *dev,
struct cpuidle_driver *drv, struct cpuidle_driver *drv,
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/cpuidle.h>
enum gpd_status { enum gpd_status {
GPD_STATE_ACTIVE = 0, /* PM domain is active */ GPD_STATE_ACTIVE = 0, /* PM domain is active */
...@@ -45,6 +46,11 @@ struct gpd_dev_ops { ...@@ -45,6 +46,11 @@ struct gpd_dev_ops {
bool (*active_wakeup)(struct device *dev); bool (*active_wakeup)(struct device *dev);
}; };
struct gpd_cpu_data {
unsigned int saved_exit_latency;
struct cpuidle_state *idle_state;
};
struct generic_pm_domain { struct generic_pm_domain {
struct dev_pm_domain domain; /* PM domain operations */ struct dev_pm_domain domain; /* PM domain operations */
struct list_head gpd_list_node; /* Node in the global PM domains list */ struct list_head gpd_list_node; /* Node in the global PM domains list */
...@@ -75,6 +81,7 @@ struct generic_pm_domain { ...@@ -75,6 +81,7 @@ struct generic_pm_domain {
bool max_off_time_changed; bool max_off_time_changed;
bool cached_power_down_ok; bool cached_power_down_ok;
struct device_node *of_node; /* Node in device tree */ struct device_node *of_node; /* Node in device tree */
struct gpd_cpu_data *cpu_data;
}; };
static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd) static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
...@@ -105,6 +112,7 @@ struct generic_pm_domain_data { ...@@ -105,6 +112,7 @@ struct generic_pm_domain_data {
struct gpd_timing_data td; struct gpd_timing_data td;
struct notifier_block nb; struct notifier_block nb;
struct mutex lock; struct mutex lock;
unsigned int refcount;
bool need_restore; bool need_restore;
bool always_on; bool always_on;
}; };
...@@ -155,6 +163,8 @@ extern int pm_genpd_add_callbacks(struct device *dev, ...@@ -155,6 +163,8 @@ extern int pm_genpd_add_callbacks(struct device *dev,
struct gpd_dev_ops *ops, struct gpd_dev_ops *ops,
struct gpd_timing_data *td); struct gpd_timing_data *td);
extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td); extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);
extern int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state);
extern int genpd_detach_cpuidle(struct generic_pm_domain *genpd);
extern void pm_genpd_init(struct generic_pm_domain *genpd, extern void pm_genpd_init(struct generic_pm_domain *genpd,
struct dev_power_governor *gov, bool is_off); struct dev_power_governor *gov, bool is_off);
...@@ -211,6 +221,14 @@ static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td) ...@@ -211,6 +221,14 @@ static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
{ {
return -ENOSYS; return -ENOSYS;
} }
static inline int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st)
{
return -ENOSYS;
}
static inline int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
{
return -ENOSYS;
}
static inline void pm_genpd_init(struct generic_pm_domain *genpd, static inline void pm_genpd_init(struct generic_pm_domain *genpd,
struct dev_power_governor *gov, bool is_off) struct dev_power_governor *gov, bool is_off)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment