PM: Do not use the syscore flag for runtime PM
The syscore device PM flag used to mark the devices (belonging to PM domains) that should never be turned off, except for the system core (syscore) suspend/hibernation and resume stages, need not be accessed by the runtime PM core functions, because all of the devices it is set for need to be marked as "irq safe" anyway and are protected from being turned off by runtime PM by ensuring that their usage counters are always set. For this reason, make the syscore flag system-wide PM-specific and simplify the code used for manipulating it, because it need not acquire the device's power.lock any more. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
This commit is contained in:
parent
3cb6f10a4d
commit
feb70af0e3
|
@ -83,18 +83,3 @@ int dev_pm_put_subsys_data(struct device *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
|
EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
|
||||||
|
|
||||||
/**
|
|
||||||
* dev_pm_syscore_device - Set/unset the given device's power.syscore flag.
|
|
||||||
* @dev: Device whose flag is to be modified.
|
|
||||||
* @val: New value of the flag.
|
|
||||||
*/
|
|
||||||
void dev_pm_syscore_device(struct device *dev, bool val)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->power.lock, flags);
|
|
||||||
dev->power.syscore = val;
|
|
||||||
spin_unlock_irqrestore(&dev->power.lock, flags);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(dev_pm_syscore_device);
|
|
||||||
|
|
|
@ -442,7 +442,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
|
||||||
not_suspended = 0;
|
not_suspended = 0;
|
||||||
list_for_each_entry(pdd, &genpd->dev_list, list_node)
|
list_for_each_entry(pdd, &genpd->dev_list, list_node)
|
||||||
if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
|
if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
|
||||||
|| pdd->dev->power.irq_safe || pdd->dev->power.syscore))
|
|| pdd->dev->power.irq_safe))
|
||||||
not_suspended++;
|
not_suspended++;
|
||||||
|
|
||||||
if (not_suspended > genpd->in_progress)
|
if (not_suspended > genpd->in_progress)
|
||||||
|
|
|
@ -134,7 +134,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
|
||||||
|
|
||||||
if (dev->power.runtime_error)
|
if (dev->power.runtime_error)
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
else if (dev->power.disable_depth > 0 || dev->power.syscore)
|
else if (dev->power.disable_depth > 0)
|
||||||
retval = -EACCES;
|
retval = -EACCES;
|
||||||
else if (atomic_read(&dev->power.usage_count) > 0)
|
else if (atomic_read(&dev->power.usage_count) > 0)
|
||||||
retval = -EAGAIN;
|
retval = -EAGAIN;
|
||||||
|
|
|
@ -772,6 +772,13 @@ static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
|
||||||
dev->power.ignore_children = enable;
|
dev->power.ignore_children = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void dev_pm_syscore_device(struct device *dev, bool val)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
dev->power.syscore = val;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline void device_lock(struct device *dev)
|
static inline void device_lock(struct device *dev)
|
||||||
{
|
{
|
||||||
mutex_lock(&dev->mutex);
|
mutex_lock(&dev->mutex);
|
||||||
|
|
|
@ -43,12 +43,8 @@ struct device;
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
extern const char power_group_name[]; /* = "power" */
|
extern const char power_group_name[]; /* = "power" */
|
||||||
|
|
||||||
extern void dev_pm_syscore_device(struct device *dev, bool val);
|
|
||||||
#else
|
#else
|
||||||
#define power_group_name NULL
|
#define power_group_name NULL
|
||||||
|
|
||||||
static inline void dev_pm_syscore_device(struct device *dev, bool val) {}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct pm_message {
|
typedef struct pm_message {
|
||||||
|
@ -515,13 +511,13 @@ struct dev_pm_info {
|
||||||
bool is_suspended:1; /* Ditto */
|
bool is_suspended:1; /* Ditto */
|
||||||
bool ignore_children:1;
|
bool ignore_children:1;
|
||||||
bool early_init:1; /* Owned by the PM core */
|
bool early_init:1; /* Owned by the PM core */
|
||||||
bool syscore:1;
|
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
struct list_head entry;
|
struct list_head entry;
|
||||||
struct completion completion;
|
struct completion completion;
|
||||||
struct wakeup_source *wakeup;
|
struct wakeup_source *wakeup;
|
||||||
bool wakeup_path:1;
|
bool wakeup_path:1;
|
||||||
|
bool syscore:1;
|
||||||
#else
|
#else
|
||||||
unsigned int should_wakeup:1;
|
unsigned int should_wakeup:1;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue