mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 13:44:26 -04:00
Merge branch 'pm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
* 'pm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (63 commits) PM / Clocks: Remove redundant NULL checks before kfree() PM / Documentation: Update docs about suspend and CPU hotplug ACPI / PM: Add Sony VGN-FW21E to nonvs blacklist. ARM: mach-shmobile: sh7372 A4R support (v4) ARM: mach-shmobile: sh7372 A3SP support (v4) PM / Sleep: Mark devices involved in wakeup signaling during suspend PM / Hibernate: Improve performance of LZO/plain hibernation, checksum image PM / Hibernate: Do not initialize static and extern variables to 0 PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too PM / Hibernate: Add resumedelay kernel param in addition to resumewait MAINTAINERS: Update linux-pm list address PM / ACPI: Blacklist Vaio VGN-FW520F machine known to require acpi_sleep=nonvs PM / ACPI: Blacklist Sony Vaio known to require acpi_sleep=nonvs PM / Hibernate: Add resumewait param to support MMC-like devices as resume file PM / Hibernate: Fix typo in a kerneldoc comment PM / Hibernate: Freeze kernel threads after preallocating memory PM: Update the policy on default wakeup settings PM / VT: Cleanup #if defined uglyness and fix compile error PM / Suspend: Off by one in pm_suspend() PM / Hibernate: Include storage keys in hibernation image on s390 ...
This commit is contained in:
commit
7e0bb71e75
99 changed files with 4720 additions and 1044 deletions
238
include/linux/devfreq.h
Normal file
238
include/linux/devfreq.h
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* devfreq: Generic Dynamic Voltage and Frequency Scaling (DVFS) Framework
|
||||
* for Non-CPU Devices.
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_DEVFREQ_H__
|
||||
#define __LINUX_DEVFREQ_H__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/opp.h>
|
||||
|
||||
#define DEVFREQ_NAME_LEN 16
|
||||
|
||||
struct devfreq;
|
||||
|
||||
/**
|
||||
* struct devfreq_dev_status - Data given from devfreq user device to
|
||||
* governors. Represents the performance
|
||||
* statistics.
|
||||
* @total_time The total time represented by this instance of
|
||||
* devfreq_dev_status
|
||||
* @busy_time The time that the device was working among the
|
||||
* total_time.
|
||||
* @current_frequency The operating frequency.
|
||||
* @private_data An entry not specified by the devfreq framework.
|
||||
* A device and a specific governor may have their
|
||||
* own protocol with private_data. However, because
|
||||
* this is governor-specific, a governor using this
|
||||
* will be only compatible with devices aware of it.
|
||||
*/
|
||||
struct devfreq_dev_status {
|
||||
/* both since the last measure */
|
||||
unsigned long total_time;
|
||||
unsigned long busy_time;
|
||||
unsigned long current_frequency;
|
||||
void *private_date;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct devfreq_dev_profile - Devfreq's user device profile
|
||||
* @initial_freq The operating frequency when devfreq_add_device() is
|
||||
* called.
|
||||
* @polling_ms The polling interval in ms. 0 disables polling.
|
||||
* @target The device should set its operating frequency at
|
||||
* freq or lowest-upper-than-freq value. If freq is
|
||||
* higher than any operable frequency, set maximum.
|
||||
* Before returning, target function should set
|
||||
* freq at the current frequency.
|
||||
* @get_dev_status The device should provide the current performance
|
||||
* status to devfreq, which is used by governors.
|
||||
* @exit An optional callback that is called when devfreq
|
||||
* is removing the devfreq object due to error or
|
||||
* from devfreq_remove_device() call. If the user
|
||||
* has registered devfreq->nb at a notifier-head,
|
||||
* this is the time to unregister it.
|
||||
*/
|
||||
struct devfreq_dev_profile {
|
||||
unsigned long initial_freq;
|
||||
unsigned int polling_ms;
|
||||
|
||||
int (*target)(struct device *dev, unsigned long *freq);
|
||||
int (*get_dev_status)(struct device *dev,
|
||||
struct devfreq_dev_status *stat);
|
||||
void (*exit)(struct device *dev);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct devfreq_governor - Devfreq policy governor
|
||||
* @name Governor's name
|
||||
* @get_target_freq Returns desired operating frequency for the device.
|
||||
* Basically, get_target_freq will run
|
||||
* devfreq_dev_profile.get_dev_status() to get the
|
||||
* status of the device (load = busy_time / total_time).
|
||||
* If no_central_polling is set, this callback is called
|
||||
* only with update_devfreq() notified by OPP.
|
||||
* @init Called when the devfreq is being attached to a device
|
||||
* @exit Called when the devfreq is being removed from a
|
||||
* device. Governor should stop any internal routines
|
||||
* before return because related data may be
|
||||
* freed after exit().
|
||||
* @no_central_polling Do not use devfreq's central polling mechanism.
|
||||
* When this is set, devfreq will not call
|
||||
* get_target_freq with devfreq_monitor(). However,
|
||||
* devfreq will call get_target_freq with
|
||||
* devfreq_update() notified by OPP framework.
|
||||
*
|
||||
* Note that the callbacks are called with devfreq->lock locked by devfreq.
|
||||
*/
|
||||
struct devfreq_governor {
|
||||
const char name[DEVFREQ_NAME_LEN];
|
||||
int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
|
||||
int (*init)(struct devfreq *this);
|
||||
void (*exit)(struct devfreq *this);
|
||||
const bool no_central_polling;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct devfreq - Device devfreq structure
|
||||
* @node list node - contains the devices with devfreq that have been
|
||||
* registered.
|
||||
* @lock a mutex to protect accessing devfreq.
|
||||
* @dev device registered by devfreq class. dev.parent is the device
|
||||
* using devfreq.
|
||||
* @profile device-specific devfreq profile
|
||||
* @governor method how to choose frequency based on the usage.
|
||||
* @nb notifier block used to notify devfreq object that it should
|
||||
* reevaluate operable frequencies. Devfreq users may use
|
||||
* devfreq.nb to the corresponding register notifier call chain.
|
||||
* @polling_jiffies interval in jiffies.
|
||||
* @previous_freq previously configured frequency value.
|
||||
* @next_polling the number of remaining jiffies to poll with
|
||||
* "devfreq_monitor" executions to reevaluate
|
||||
* frequency/voltage of the device. Set by
|
||||
* profile's polling_ms interval.
|
||||
* @data Private data of the governor. The devfreq framework does not
|
||||
* touch this.
|
||||
* @being_removed a flag to mark that this object is being removed in
|
||||
* order to prevent trying to remove the object multiple times.
|
||||
*
|
||||
* This structure stores the devfreq information for a give device.
|
||||
*
|
||||
* Note that when a governor accesses entries in struct devfreq in its
|
||||
* functions except for the context of callbacks defined in struct
|
||||
* devfreq_governor, the governor should protect its access with the
|
||||
* struct mutex lock in struct devfreq. A governor may use this mutex
|
||||
* to protect its own private data in void *data as well.
|
||||
*/
|
||||
struct devfreq {
|
||||
struct list_head node;
|
||||
|
||||
struct mutex lock;
|
||||
struct device dev;
|
||||
struct devfreq_dev_profile *profile;
|
||||
const struct devfreq_governor *governor;
|
||||
struct notifier_block nb;
|
||||
|
||||
unsigned long polling_jiffies;
|
||||
unsigned long previous_freq;
|
||||
unsigned int next_polling;
|
||||
|
||||
void *data; /* private data for governors */
|
||||
|
||||
bool being_removed;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PM_DEVFREQ)
|
||||
extern struct devfreq *devfreq_add_device(struct device *dev,
|
||||
struct devfreq_dev_profile *profile,
|
||||
const struct devfreq_governor *governor,
|
||||
void *data);
|
||||
extern int devfreq_remove_device(struct devfreq *devfreq);
|
||||
|
||||
/* Helper functions for devfreq user device driver with OPP. */
|
||||
extern struct opp *devfreq_recommended_opp(struct device *dev,
|
||||
unsigned long *freq);
|
||||
extern int devfreq_register_opp_notifier(struct device *dev,
|
||||
struct devfreq *devfreq);
|
||||
extern int devfreq_unregister_opp_notifier(struct device *dev,
|
||||
struct devfreq *devfreq);
|
||||
|
||||
#ifdef CONFIG_DEVFREQ_GOV_POWERSAVE
|
||||
extern const struct devfreq_governor devfreq_powersave;
|
||||
#endif
|
||||
#ifdef CONFIG_DEVFREQ_GOV_PERFORMANCE
|
||||
extern const struct devfreq_governor devfreq_performance;
|
||||
#endif
|
||||
#ifdef CONFIG_DEVFREQ_GOV_USERSPACE
|
||||
extern const struct devfreq_governor devfreq_userspace;
|
||||
#endif
|
||||
#ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND
|
||||
extern const struct devfreq_governor devfreq_simple_ondemand;
|
||||
/**
|
||||
* struct devfreq_simple_ondemand_data - void *data fed to struct devfreq
|
||||
* and devfreq_add_device
|
||||
* @ upthreshold If the load is over this value, the frequency jumps.
|
||||
* Specify 0 to use the default. Valid value = 0 to 100.
|
||||
* @ downdifferential If the load is under upthreshold - downdifferential,
|
||||
* the governor may consider slowing the frequency down.
|
||||
* Specify 0 to use the default. Valid value = 0 to 100.
|
||||
* downdifferential < upthreshold must hold.
|
||||
*
|
||||
* If the fed devfreq_simple_ondemand_data pointer is NULL to the governor,
|
||||
* the governor uses the default values.
|
||||
*/
|
||||
struct devfreq_simple_ondemand_data {
|
||||
unsigned int upthreshold;
|
||||
unsigned int downdifferential;
|
||||
};
|
||||
#endif
|
||||
|
||||
#else /* !CONFIG_PM_DEVFREQ */
|
||||
static struct devfreq *devfreq_add_device(struct device *dev,
|
||||
struct devfreq_dev_profile *profile,
|
||||
struct devfreq_governor *governor,
|
||||
void *data);
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int devfreq_remove_device(struct devfreq *devfreq);
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct opp *devfreq_recommended_opp(struct device *dev,
|
||||
unsigned long *freq)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int devfreq_register_opp_notifier(struct device *dev,
|
||||
struct devfreq *devfreq)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int devfreq_unregister_opp_notifier(struct device *dev,
|
||||
struct devfreq *devfreq)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#define devfreq_powersave NULL
|
||||
#define devfreq_performance NULL
|
||||
#define devfreq_userspace NULL
|
||||
#define devfreq_simple_ondemand NULL
|
||||
|
||||
#endif /* CONFIG_PM_DEVFREQ */
|
||||
|
||||
#endif /* __LINUX_DEVFREQ_H__ */
|
||||
|
|
@ -638,6 +638,11 @@ static inline void set_dev_node(struct device *dev, int node)
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline struct pm_subsys_data *dev_to_psd(struct device *dev)
|
||||
{
|
||||
return dev ? dev->power.subsys_data : NULL;
|
||||
}
|
||||
|
||||
static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
|
||||
{
|
||||
return dev->kobj.uevent_suppress;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ extern int thaw_process(struct task_struct *p);
|
|||
|
||||
extern void refrigerator(void);
|
||||
extern int freeze_processes(void);
|
||||
extern int freeze_kernel_threads(void);
|
||||
extern void thaw_processes(void);
|
||||
|
||||
static inline int try_to_freeze(void)
|
||||
|
|
@ -171,7 +172,8 @@ static inline void clear_freeze_flag(struct task_struct *p) {}
|
|||
static inline int thaw_process(struct task_struct *p) { return 1; }
|
||||
|
||||
static inline void refrigerator(void) {}
|
||||
static inline int freeze_processes(void) { BUG(); return 0; }
|
||||
static inline int freeze_processes(void) { return -ENOSYS; }
|
||||
static inline int freeze_kernel_threads(void) { return -ENOSYS; }
|
||||
static inline void thaw_processes(void) {}
|
||||
|
||||
static inline int try_to_freeze(void) { return 0; }
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include <linux/if_link.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/pm_qos_params.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/atomic.h>
|
||||
|
|
@ -969,7 +969,7 @@ struct net_device {
|
|||
*/
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
struct pm_qos_request_list pm_qos_req;
|
||||
struct pm_qos_request pm_qos_req;
|
||||
|
||||
/* device name hash chain */
|
||||
struct hlist_node name_hlist;
|
||||
|
|
|
|||
|
|
@ -16,9 +16,14 @@
|
|||
|
||||
#include <linux/err.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
struct opp;
|
||||
|
||||
enum opp_event {
|
||||
OPP_EVENT_ADD, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PM_OPP)
|
||||
|
||||
unsigned long opp_get_voltage(struct opp *opp);
|
||||
|
|
@ -40,6 +45,8 @@ int opp_enable(struct device *dev, unsigned long freq);
|
|||
|
||||
int opp_disable(struct device *dev, unsigned long freq);
|
||||
|
||||
struct srcu_notifier_head *opp_get_notifier(struct device *dev);
|
||||
|
||||
#else
|
||||
static inline unsigned long opp_get_voltage(struct opp *opp)
|
||||
{
|
||||
|
|
@ -89,6 +96,11 @@ static inline int opp_disable(struct device *dev, unsigned long freq)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct srcu_notifier_head *opp_get_notifier(struct device *dev)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP)
|
||||
|
|
|
|||
|
|
@ -326,6 +326,7 @@ extern struct dev_pm_ops generic_subsys_pm_ops;
|
|||
* requested by a driver.
|
||||
*/
|
||||
|
||||
#define PM_EVENT_INVALID (-1)
|
||||
#define PM_EVENT_ON 0x0000
|
||||
#define PM_EVENT_FREEZE 0x0001
|
||||
#define PM_EVENT_SUSPEND 0x0002
|
||||
|
|
@ -346,6 +347,7 @@ extern struct dev_pm_ops generic_subsys_pm_ops;
|
|||
#define PM_EVENT_AUTO_SUSPEND (PM_EVENT_AUTO | PM_EVENT_SUSPEND)
|
||||
#define PM_EVENT_AUTO_RESUME (PM_EVENT_AUTO | PM_EVENT_RESUME)
|
||||
|
||||
#define PMSG_INVALID ((struct pm_message){ .event = PM_EVENT_INVALID, })
|
||||
#define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, })
|
||||
#define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, })
|
||||
#define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, })
|
||||
|
|
@ -366,6 +368,8 @@ extern struct dev_pm_ops generic_subsys_pm_ops;
|
|||
#define PMSG_AUTO_RESUME ((struct pm_message) \
|
||||
{ .event = PM_EVENT_AUTO_RESUME, })
|
||||
|
||||
#define PMSG_IS_AUTO(msg) (((msg).event & PM_EVENT_AUTO) != 0)
|
||||
|
||||
/**
|
||||
* Device run-time power management status.
|
||||
*
|
||||
|
|
@ -421,6 +425,22 @@ enum rpm_request {
|
|||
|
||||
struct wakeup_source;
|
||||
|
||||
struct pm_domain_data {
|
||||
struct list_head list_node;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
struct pm_subsys_data {
|
||||
spinlock_t lock;
|
||||
unsigned int refcount;
|
||||
#ifdef CONFIG_PM_CLK
|
||||
struct list_head clock_list;
|
||||
#endif
|
||||
#ifdef CONFIG_PM_GENERIC_DOMAINS
|
||||
struct pm_domain_data *domain_data;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dev_pm_info {
|
||||
pm_message_t power_state;
|
||||
unsigned int can_wakeup:1;
|
||||
|
|
@ -432,6 +452,7 @@ struct dev_pm_info {
|
|||
struct list_head entry;
|
||||
struct completion completion;
|
||||
struct wakeup_source *wakeup;
|
||||
bool wakeup_path:1;
|
||||
#else
|
||||
unsigned int should_wakeup:1;
|
||||
#endif
|
||||
|
|
@ -462,10 +483,13 @@ struct dev_pm_info {
|
|||
unsigned long suspended_jiffies;
|
||||
unsigned long accounting_timestamp;
|
||||
#endif
|
||||
void *subsys_data; /* Owned by the subsystem. */
|
||||
struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */
|
||||
struct pm_qos_constraints *constraints;
|
||||
};
|
||||
|
||||
extern void update_pm_runtime_accounting(struct device *dev);
|
||||
extern int dev_pm_get_subsys_data(struct device *dev);
|
||||
extern int dev_pm_put_subsys_data(struct device *dev);
|
||||
|
||||
/*
|
||||
* Power domains provide callbacks that are executed during system suspend,
|
||||
|
|
|
|||
71
include/linux/pm_clock.h
Normal file
71
include/linux/pm_clock.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* pm_clock.h - Definitions and headers related to device clocks.
|
||||
*
|
||||
* Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
|
||||
*
|
||||
* This file is released under the GPLv2.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_PM_CLOCK_H
|
||||
#define _LINUX_PM_CLOCK_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
struct pm_clk_notifier_block {
|
||||
struct notifier_block nb;
|
||||
struct dev_pm_domain *pm_domain;
|
||||
char *con_ids[];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_CLK
|
||||
static inline bool pm_clk_no_clocks(struct device *dev)
|
||||
{
|
||||
return dev && dev->power.subsys_data
|
||||
&& list_empty(&dev->power.subsys_data->clock_list);
|
||||
}
|
||||
|
||||
extern void pm_clk_init(struct device *dev);
|
||||
extern int pm_clk_create(struct device *dev);
|
||||
extern void pm_clk_destroy(struct device *dev);
|
||||
extern int pm_clk_add(struct device *dev, const char *con_id);
|
||||
extern void pm_clk_remove(struct device *dev, const char *con_id);
|
||||
extern int pm_clk_suspend(struct device *dev);
|
||||
extern int pm_clk_resume(struct device *dev);
|
||||
#else
|
||||
static inline bool pm_clk_no_clocks(struct device *dev)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static inline void pm_clk_init(struct device *dev)
|
||||
{
|
||||
}
|
||||
static inline int pm_clk_create(struct device *dev)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline void pm_clk_destroy(struct device *dev)
|
||||
{
|
||||
}
|
||||
static inline int pm_clk_add(struct device *dev, const char *con_id)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline void pm_clk_remove(struct device *dev, const char *con_id)
|
||||
{
|
||||
}
|
||||
#define pm_clk_suspend NULL
|
||||
#define pm_clk_resume NULL
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
extern void pm_clk_add_notifier(struct bus_type *bus,
|
||||
struct pm_clk_notifier_block *clknb);
|
||||
#else
|
||||
static inline void pm_clk_add_notifier(struct bus_type *bus,
|
||||
struct pm_clk_notifier_block *clknb)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
enum gpd_status {
|
||||
GPD_STATE_ACTIVE = 0, /* PM domain is active */
|
||||
GPD_STATE_WAIT_MASTER, /* PM domain's master is being waited for */
|
||||
GPD_STATE_BUSY, /* Something is happening to the PM domain */
|
||||
GPD_STATE_REPEAT, /* Power off in progress, to be repeated */
|
||||
GPD_STATE_POWER_OFF, /* PM domain is off */
|
||||
|
|
@ -25,15 +26,14 @@ struct dev_power_governor {
|
|||
struct generic_pm_domain {
|
||||
struct dev_pm_domain domain; /* PM domain operations */
|
||||
struct list_head gpd_list_node; /* Node in the global PM domains list */
|
||||
struct list_head sd_node; /* Node in the parent's subdomain list */
|
||||
struct generic_pm_domain *parent; /* Parent PM domain */
|
||||
struct list_head sd_list; /* List of dubdomains */
|
||||
struct list_head master_links; /* Links with PM domain as a master */
|
||||
struct list_head slave_links; /* Links with PM domain as a slave */
|
||||
struct list_head dev_list; /* List of devices */
|
||||
struct mutex lock;
|
||||
struct dev_power_governor *gov;
|
||||
struct work_struct power_off_work;
|
||||
unsigned int in_progress; /* Number of devices being suspended now */
|
||||
unsigned int sd_count; /* Number of subdomains with power "on" */
|
||||
atomic_t sd_count; /* Number of subdomains with power "on" */
|
||||
enum gpd_status status; /* Current state of the domain */
|
||||
wait_queue_head_t status_wait_queue;
|
||||
struct task_struct *poweroff_task; /* Powering off task */
|
||||
|
|
@ -42,6 +42,7 @@ struct generic_pm_domain {
|
|||
unsigned int suspended_count; /* System suspend device counter */
|
||||
unsigned int prepared_count; /* Suspend counter of prepared devices */
|
||||
bool suspend_power_off; /* Power status before system suspend */
|
||||
bool dev_irq_safe; /* Device callbacks are IRQ-safe */
|
||||
int (*power_off)(struct generic_pm_domain *domain);
|
||||
int (*power_on)(struct generic_pm_domain *domain);
|
||||
int (*start_device)(struct device *dev);
|
||||
|
|
@ -54,12 +55,23 @@ static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
|
|||
return container_of(pd, struct generic_pm_domain, domain);
|
||||
}
|
||||
|
||||
struct dev_list_entry {
|
||||
struct list_head node;
|
||||
struct device *dev;
|
||||
struct gpd_link {
|
||||
struct generic_pm_domain *master;
|
||||
struct list_head master_node;
|
||||
struct generic_pm_domain *slave;
|
||||
struct list_head slave_node;
|
||||
};
|
||||
|
||||
struct generic_pm_domain_data {
|
||||
struct pm_domain_data base;
|
||||
bool need_restore;
|
||||
};
|
||||
|
||||
static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
|
||||
{
|
||||
return container_of(pdd, struct generic_pm_domain_data, base);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_GENERIC_DOMAINS
|
||||
extern int pm_genpd_add_device(struct generic_pm_domain *genpd,
|
||||
struct device *dev);
|
||||
|
|
|
|||
155
include/linux/pm_qos.h
Normal file
155
include/linux/pm_qos.h
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
#ifndef _LINUX_PM_QOS_H
|
||||
#define _LINUX_PM_QOS_H
|
||||
/* interface for the pm_qos_power infrastructure of the linux kernel.
|
||||
*
|
||||
* Mark Gross <mgross@linux.intel.com>
|
||||
*/
|
||||
#include <linux/plist.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#define PM_QOS_RESERVED 0
|
||||
#define PM_QOS_CPU_DMA_LATENCY 1
|
||||
#define PM_QOS_NETWORK_LATENCY 2
|
||||
#define PM_QOS_NETWORK_THROUGHPUT 3
|
||||
|
||||
#define PM_QOS_NUM_CLASSES 4
|
||||
#define PM_QOS_DEFAULT_VALUE -1
|
||||
|
||||
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
|
||||
#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
|
||||
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
|
||||
#define PM_QOS_DEV_LAT_DEFAULT_VALUE 0
|
||||
|
||||
struct pm_qos_request {
|
||||
struct plist_node node;
|
||||
int pm_qos_class;
|
||||
};
|
||||
|
||||
struct dev_pm_qos_request {
|
||||
struct plist_node node;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
enum pm_qos_type {
|
||||
PM_QOS_UNITIALIZED,
|
||||
PM_QOS_MAX, /* return the largest value */
|
||||
PM_QOS_MIN /* return the smallest value */
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: The lockless read path depends on the CPU accessing
|
||||
* target_value atomically. Atomic access is only guaranteed on all CPU
|
||||
* types linux supports for 32 bit quantites
|
||||
*/
|
||||
struct pm_qos_constraints {
|
||||
struct plist_head list;
|
||||
s32 target_value; /* Do not change to 64 bit */
|
||||
s32 default_value;
|
||||
enum pm_qos_type type;
|
||||
struct blocking_notifier_head *notifiers;
|
||||
};
|
||||
|
||||
/* Action requested to pm_qos_update_target */
|
||||
enum pm_qos_req_action {
|
||||
PM_QOS_ADD_REQ, /* Add a new request */
|
||||
PM_QOS_UPDATE_REQ, /* Update an existing request */
|
||||
PM_QOS_REMOVE_REQ /* Remove an existing request */
|
||||
};
|
||||
|
||||
static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req)
|
||||
{
|
||||
return req->dev != 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
|
||||
enum pm_qos_req_action action, int value);
|
||||
void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class,
|
||||
s32 value);
|
||||
void pm_qos_update_request(struct pm_qos_request *req,
|
||||
s32 new_value);
|
||||
void pm_qos_remove_request(struct pm_qos_request *req);
|
||||
|
||||
int pm_qos_request(int pm_qos_class);
|
||||
int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
|
||||
int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
|
||||
int pm_qos_request_active(struct pm_qos_request *req);
|
||||
s32 pm_qos_read_value(struct pm_qos_constraints *c);
|
||||
|
||||
s32 dev_pm_qos_read_value(struct device *dev);
|
||||
int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
|
||||
s32 value);
|
||||
int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value);
|
||||
int dev_pm_qos_remove_request(struct dev_pm_qos_request *req);
|
||||
int dev_pm_qos_add_notifier(struct device *dev,
|
||||
struct notifier_block *notifier);
|
||||
int dev_pm_qos_remove_notifier(struct device *dev,
|
||||
struct notifier_block *notifier);
|
||||
int dev_pm_qos_add_global_notifier(struct notifier_block *notifier);
|
||||
int dev_pm_qos_remove_global_notifier(struct notifier_block *notifier);
|
||||
void dev_pm_qos_constraints_init(struct device *dev);
|
||||
void dev_pm_qos_constraints_destroy(struct device *dev);
|
||||
#else
|
||||
static inline int pm_qos_update_target(struct pm_qos_constraints *c,
|
||||
struct plist_node *node,
|
||||
enum pm_qos_req_action action,
|
||||
int value)
|
||||
{ return 0; }
|
||||
static inline void pm_qos_add_request(struct pm_qos_request *req,
|
||||
int pm_qos_class, s32 value)
|
||||
{ return; }
|
||||
static inline void pm_qos_update_request(struct pm_qos_request *req,
|
||||
s32 new_value)
|
||||
{ return; }
|
||||
static inline void pm_qos_remove_request(struct pm_qos_request *req)
|
||||
{ return; }
|
||||
|
||||
static inline int pm_qos_request(int pm_qos_class)
|
||||
{ return 0; }
|
||||
static inline int pm_qos_add_notifier(int pm_qos_class,
|
||||
struct notifier_block *notifier)
|
||||
{ return 0; }
|
||||
static inline int pm_qos_remove_notifier(int pm_qos_class,
|
||||
struct notifier_block *notifier)
|
||||
{ return 0; }
|
||||
static inline int pm_qos_request_active(struct pm_qos_request *req)
|
||||
{ return 0; }
|
||||
static inline s32 pm_qos_read_value(struct pm_qos_constraints *c)
|
||||
{ return 0; }
|
||||
|
||||
static inline s32 dev_pm_qos_read_value(struct device *dev)
|
||||
{ return 0; }
|
||||
static inline int dev_pm_qos_add_request(struct device *dev,
|
||||
struct dev_pm_qos_request *req,
|
||||
s32 value)
|
||||
{ return 0; }
|
||||
static inline int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
|
||||
s32 new_value)
|
||||
{ return 0; }
|
||||
static inline int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
|
||||
{ return 0; }
|
||||
static inline int dev_pm_qos_add_notifier(struct device *dev,
|
||||
struct notifier_block *notifier)
|
||||
{ return 0; }
|
||||
static inline int dev_pm_qos_remove_notifier(struct device *dev,
|
||||
struct notifier_block *notifier)
|
||||
{ return 0; }
|
||||
static inline int dev_pm_qos_add_global_notifier(
|
||||
struct notifier_block *notifier)
|
||||
{ return 0; }
|
||||
static inline int dev_pm_qos_remove_global_notifier(
|
||||
struct notifier_block *notifier)
|
||||
{ return 0; }
|
||||
static inline void dev_pm_qos_constraints_init(struct device *dev)
|
||||
{
|
||||
dev->power.power_state = PMSG_ON;
|
||||
}
|
||||
static inline void dev_pm_qos_constraints_destroy(struct device *dev)
|
||||
{
|
||||
dev->power.power_state = PMSG_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef _LINUX_PM_QOS_PARAMS_H
|
||||
#define _LINUX_PM_QOS_PARAMS_H
|
||||
/* interface for the pm_qos_power infrastructure of the linux kernel.
|
||||
*
|
||||
* Mark Gross <mgross@linux.intel.com>
|
||||
*/
|
||||
#include <linux/plist.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/miscdevice.h>
|
||||
|
||||
#define PM_QOS_RESERVED 0
|
||||
#define PM_QOS_CPU_DMA_LATENCY 1
|
||||
#define PM_QOS_NETWORK_LATENCY 2
|
||||
#define PM_QOS_NETWORK_THROUGHPUT 3
|
||||
|
||||
#define PM_QOS_NUM_CLASSES 4
|
||||
#define PM_QOS_DEFAULT_VALUE -1
|
||||
|
||||
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
|
||||
#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
|
||||
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
|
||||
|
||||
struct pm_qos_request_list {
|
||||
struct plist_node list;
|
||||
int pm_qos_class;
|
||||
};
|
||||
|
||||
void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
|
||||
void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
|
||||
s32 new_value);
|
||||
void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
|
||||
|
||||
int pm_qos_request(int pm_qos_class);
|
||||
int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
|
||||
int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
|
||||
int pm_qos_request_active(struct pm_qos_request_list *req);
|
||||
|
||||
#endif
|
||||
|
|
@ -251,46 +251,4 @@ static inline void pm_runtime_dont_use_autosuspend(struct device *dev)
|
|||
__pm_runtime_use_autosuspend(dev, false);
|
||||
}
|
||||
|
||||
struct pm_clk_notifier_block {
|
||||
struct notifier_block nb;
|
||||
struct dev_pm_domain *pm_domain;
|
||||
char *con_ids[];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_CLK
|
||||
extern int pm_clk_init(struct device *dev);
|
||||
extern void pm_clk_destroy(struct device *dev);
|
||||
extern int pm_clk_add(struct device *dev, const char *con_id);
|
||||
extern void pm_clk_remove(struct device *dev, const char *con_id);
|
||||
extern int pm_clk_suspend(struct device *dev);
|
||||
extern int pm_clk_resume(struct device *dev);
|
||||
#else
|
||||
static inline int pm_clk_init(struct device *dev)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline void pm_clk_destroy(struct device *dev)
|
||||
{
|
||||
}
|
||||
static inline int pm_clk_add(struct device *dev, const char *con_id)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline void pm_clk_remove(struct device *dev, const char *con_id)
|
||||
{
|
||||
}
|
||||
#define pm_clk_suspend NULL
|
||||
#define pm_clk_resume NULL
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
extern void pm_clk_add_notifier(struct bus_type *bus,
|
||||
struct pm_clk_notifier_block *clknb);
|
||||
#else
|
||||
static inline void pm_clk_add_notifier(struct bus_type *bus,
|
||||
struct pm_clk_notifier_block *clknb)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,15 +8,18 @@
|
|||
#include <linux/mm.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
|
||||
#ifdef CONFIG_VT
|
||||
extern void pm_set_vt_switch(int);
|
||||
extern int pm_prepare_console(void);
|
||||
extern void pm_restore_console(void);
|
||||
#else
|
||||
static inline void pm_set_vt_switch(int do_switch)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VT_CONSOLE_SLEEP
|
||||
extern int pm_prepare_console(void);
|
||||
extern void pm_restore_console(void);
|
||||
#else
|
||||
static inline int pm_prepare_console(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -34,6 +37,58 @@ typedef int __bitwise suspend_state_t;
|
|||
#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
|
||||
#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
|
||||
|
||||
enum suspend_stat_step {
|
||||
SUSPEND_FREEZE = 1,
|
||||
SUSPEND_PREPARE,
|
||||
SUSPEND_SUSPEND,
|
||||
SUSPEND_SUSPEND_NOIRQ,
|
||||
SUSPEND_RESUME_NOIRQ,
|
||||
SUSPEND_RESUME
|
||||
};
|
||||
|
||||
struct suspend_stats {
|
||||
int success;
|
||||
int fail;
|
||||
int failed_freeze;
|
||||
int failed_prepare;
|
||||
int failed_suspend;
|
||||
int failed_suspend_noirq;
|
||||
int failed_resume;
|
||||
int failed_resume_noirq;
|
||||
#define REC_FAILED_NUM 2
|
||||
int last_failed_dev;
|
||||
char failed_devs[REC_FAILED_NUM][40];
|
||||
int last_failed_errno;
|
||||
int errno[REC_FAILED_NUM];
|
||||
int last_failed_step;
|
||||
enum suspend_stat_step failed_steps[REC_FAILED_NUM];
|
||||
};
|
||||
|
||||
extern struct suspend_stats suspend_stats;
|
||||
|
||||
static inline void dpm_save_failed_dev(const char *name)
|
||||
{
|
||||
strlcpy(suspend_stats.failed_devs[suspend_stats.last_failed_dev],
|
||||
name,
|
||||
sizeof(suspend_stats.failed_devs[0]));
|
||||
suspend_stats.last_failed_dev++;
|
||||
suspend_stats.last_failed_dev %= REC_FAILED_NUM;
|
||||
}
|
||||
|
||||
static inline void dpm_save_failed_errno(int err)
|
||||
{
|
||||
suspend_stats.errno[suspend_stats.last_failed_errno] = err;
|
||||
suspend_stats.last_failed_errno++;
|
||||
suspend_stats.last_failed_errno %= REC_FAILED_NUM;
|
||||
}
|
||||
|
||||
static inline void dpm_save_failed_step(enum suspend_stat_step step)
|
||||
{
|
||||
suspend_stats.failed_steps[suspend_stats.last_failed_step] = step;
|
||||
suspend_stats.last_failed_step++;
|
||||
suspend_stats.last_failed_step %= REC_FAILED_NUM;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct platform_suspend_ops - Callbacks for managing platform dependent
|
||||
* system sleep states.
|
||||
|
|
@ -334,4 +389,38 @@ static inline void unlock_system_sleep(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_SAVE_PAGE_KEYS
|
||||
/*
|
||||
* The ARCH_SAVE_PAGE_KEYS functions can be used by an architecture
|
||||
* to save/restore additional information to/from the array of page
|
||||
* frame numbers in the hibernation image. For s390 this is used to
|
||||
* save and restore the storage key for each page that is included
|
||||
* in the hibernation image.
|
||||
*/
|
||||
unsigned long page_key_additional_pages(unsigned long pages);
|
||||
int page_key_alloc(unsigned long pages);
|
||||
void page_key_free(void);
|
||||
void page_key_read(unsigned long *pfn);
|
||||
void page_key_memorize(unsigned long *pfn);
|
||||
void page_key_write(void *address);
|
||||
|
||||
#else /* !CONFIG_ARCH_SAVE_PAGE_KEYS */
|
||||
|
||||
static inline unsigned long page_key_additional_pages(unsigned long pages)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int page_key_alloc(unsigned long pages)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void page_key_free(void) {}
|
||||
static inline void page_key_read(unsigned long *pfn) {}
|
||||
static inline void page_key_memorize(unsigned long *pfn) {}
|
||||
static inline void page_key_write(void *address) {}
|
||||
|
||||
#endif /* !CONFIG_ARCH_SAVE_PAGE_KEYS */
|
||||
|
||||
#endif /* _LINUX_SUSPEND_H */
|
||||
|
|
|
|||
Loading…
Reference in a new issue