aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/acpi/processor.h5
-rw-r--r--include/linux/acpi.h26
-rw-r--r--include/linux/cpuidle.h180
-rw-r--r--include/linux/tick.h9
4 files changed, 194 insertions, 26 deletions
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 99934a999e6..26d79f6db8a 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -3,6 +3,7 @@
#include <linux/kernel.h>
#include <linux/cpu.h>
+#include <linux/cpuidle.h>
#include <asm/acpi.h>
@@ -75,7 +76,9 @@ struct acpi_processor_cx {
};
struct acpi_processor_power {
+ struct cpuidle_device dev;
struct acpi_processor_cx *state;
+ struct acpi_processor_cx *bm_state;
unsigned long bm_check_timestamp;
u32 default_state;
u32 bm_activity;
@@ -199,6 +202,7 @@ struct acpi_processor_flags {
u8 bm_check:1;
u8 has_cst:1;
u8 power_setup_done:1;
+ u8 bm_rld_set:1;
};
struct acpi_processor {
@@ -322,6 +326,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
struct acpi_device *device);
int acpi_processor_suspend(struct acpi_device * device, pm_message_t state);
int acpi_processor_resume(struct acpi_device * device);
+extern struct cpuidle_driver acpi_idle_driver;
/* in processor_thermal.c */
int acpi_processor_get_limit_info(struct acpi_processor *pr);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index bf5e0009de7..8ccedf7a0a5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -189,32 +189,6 @@ extern int ec_transaction(u8 command,
extern int acpi_blacklisted(void);
extern void acpi_bios_year(char *s);
-#define ACPI_CSTATE_LIMIT_DEFINED /* for driver builds */
-#ifdef CONFIG_ACPI
-
-/*
- * Set highest legal C-state
- * 0: C0 okay, but not C1
- * 1: C1 okay, but not C2
- * 2: C2 okay, but not C3 etc.
- */
-
-extern unsigned int max_cstate;
-
-static inline unsigned int acpi_get_cstate_limit(void)
-{
- return max_cstate;
-}
-static inline void acpi_set_cstate_limit(unsigned int new_limit)
-{
- max_cstate = new_limit;
- return;
-}
-#else
-static inline unsigned int acpi_get_cstate_limit(void) { return 0; }
-static inline void acpi_set_cstate_limit(unsigned int new_limit) { return; }
-#endif
-
#ifdef CONFIG_ACPI_NUMA
int acpi_get_pxm(acpi_handle handle);
int acpi_get_node(acpi_handle *handle);
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
new file mode 100644
index 00000000000..16a51546db4
--- /dev/null
+++ b/include/linux/cpuidle.h
@@ -0,0 +1,180 @@
+/*
+ * cpuidle.h - a generic framework for CPU idle power management
+ *
+ * (C) 2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * Shaohua Li <shaohua.li@intel.com>
+ * Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#ifndef _LINUX_CPUIDLE_H
+#define _LINUX_CPUIDLE_H
+
+#include <linux/percpu.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include <linux/completion.h>
+
+#define CPUIDLE_STATE_MAX 8
+#define CPUIDLE_NAME_LEN 16
+
+struct cpuidle_device;
+
+
+/****************************
+ * CPUIDLE DEVICE INTERFACE *
+ ****************************/
+
+struct cpuidle_state {
+ char name[CPUIDLE_NAME_LEN];
+ void *driver_data;
+
+ unsigned int flags;
+ unsigned int exit_latency; /* in US */
+ unsigned int power_usage; /* in mW */
+ unsigned int target_residency; /* in US */
+
+ unsigned int usage;
+ unsigned int time; /* in US */
+
+ int (*enter) (struct cpuidle_device *dev,
+ struct cpuidle_state *state);
+};
+
+/* Idle State Flags */
+#define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */
+#define CPUIDLE_FLAG_CHECK_BM (0x02) /* BM activity will exit state */
+#define CPUIDLE_FLAG_SHALLOW (0x10) /* low latency, minimal savings */
+#define CPUIDLE_FLAG_BALANCED (0x20) /* medium latency, moderate savings */
+#define CPUIDLE_FLAG_DEEP (0x40) /* high latency, large savings */
+
+#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
+
+/**
+ * cpuidle_get_statedata - retrieves private driver state data
+ * @state: the state
+ */
+static inline void * cpuidle_get_statedata(struct cpuidle_state *state)
+{
+ return state->driver_data;
+}
+
+/**
+ * cpuidle_set_statedata - stores private driver state data
+ * @state: the state
+ * @data: the private data
+ */
+static inline void
+cpuidle_set_statedata(struct cpuidle_state *state, void *data)
+{
+ state->driver_data = data;
+}
+
+struct cpuidle_state_kobj {
+ struct cpuidle_state *state;
+ struct completion kobj_unregister;
+ struct kobject kobj;
+};
+
+struct cpuidle_device {
+ int enabled:1;
+ unsigned int cpu;
+
+ int last_residency;
+ int state_count;
+ struct cpuidle_state states[CPUIDLE_STATE_MAX];
+ struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
+ struct cpuidle_state *last_state;
+
+ struct list_head device_list;
+ struct kobject kobj;
+ struct completion kobj_unregister;
+ void *governor_data;
+};
+
+DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+
+/**
+ * cpuidle_get_last_residency - retrieves the last state's residency time
+ * @dev: the target CPU
+ *
+ * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set
+ */
+static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
+{
+ return dev->last_residency;
+}
+
+
+/****************************
+ * CPUIDLE DRIVER INTERFACE *
+ ****************************/
+
+struct cpuidle_driver {
+ char name[CPUIDLE_NAME_LEN];
+ struct module *owner;
+};
+
+#ifdef CONFIG_CPU_IDLE
+
+extern int cpuidle_register_driver(struct cpuidle_driver *drv);
+extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
+extern int cpuidle_register_device(struct cpuidle_device *dev);
+extern void cpuidle_unregister_device(struct cpuidle_device *dev);
+
+extern void cpuidle_pause_and_lock(void);
+extern void cpuidle_resume_and_unlock(void);
+extern int cpuidle_enable_device(struct cpuidle_device *dev);
+extern void cpuidle_disable_device(struct cpuidle_device *dev);
+
+#else
+
+static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
+{return 0;}
+static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
+static inline int cpuidle_register_device(struct cpuidle_device *dev)
+{return 0;}
+static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
+
+static inline void cpuidle_pause_and_lock(void) { }
+static inline void cpuidle_resume_and_unlock(void) { }
+static inline int cpuidle_enable_device(struct cpuidle_device *dev)
+{return 0;}
+static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
+
+#endif
+
+/******************************
+ * CPUIDLE GOVERNOR INTERFACE *
+ ******************************/
+
+struct cpuidle_governor {
+ char name[CPUIDLE_NAME_LEN];
+ struct list_head governor_list;
+ unsigned int rating;
+
+ int (*enable) (struct cpuidle_device *dev);
+ void (*disable) (struct cpuidle_device *dev);
+
+ int (*select) (struct cpuidle_device *dev);
+ void (*reflect) (struct cpuidle_device *dev);
+
+ struct module *owner;
+};
+
+#ifdef CONFIG_CPU_IDLE
+
+extern int cpuidle_register_governor(struct cpuidle_governor *gov);
+extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
+
+#else
+
+static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
+{return 0;}
+static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { }
+
+#endif
+
+#endif /* _LINUX_CPUIDLE_H */
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 9a7252e089b..f4a1395e05f 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -40,6 +40,7 @@ enum tick_nohz_mode {
* @idle_sleeps: Number of idle calls, where the sched tick was stopped
* @idle_entrytime: Time when the idle call was entered
* @idle_sleeptime: Sum of the time slept in idle with sched tick stopped
+ * @sleep_length: Duration of the current idle sleep
*/
struct tick_sched {
struct hrtimer sched_timer;
@@ -52,6 +53,7 @@ struct tick_sched {
unsigned long idle_sleeps;
ktime_t idle_entrytime;
ktime_t idle_sleeptime;
+ ktime_t sleep_length;
unsigned long last_jiffies;
unsigned long next_jiffies;
ktime_t idle_expires;
@@ -100,10 +102,17 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
extern void tick_nohz_stop_sched_tick(void);
extern void tick_nohz_restart_sched_tick(void);
extern void tick_nohz_update_jiffies(void);
+extern ktime_t tick_nohz_get_sleep_length(void);
# else
static inline void tick_nohz_stop_sched_tick(void) { }
static inline void tick_nohz_restart_sched_tick(void) { }
static inline void tick_nohz_update_jiffies(void) { }
+static inline ktime_t tick_nohz_get_sleep_length(void)
+{
+ ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
+
+ return len;
+}
# endif /* !NO_HZ */
#endif