aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-firmware-acpi20
-rw-r--r--Documentation/cpuidle/sysfs.txt5
-rw-r--r--arch/arm/include/asm/cpuidle.h29
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/cpuidle.c21
-rw-r--r--arch/arm/mach-at91/cpuidle.c67
-rw-r--r--arch/arm/mach-davinci/cpuidle.c83
-rw-r--r--arch/arm/mach-kirkwood/cpuidle.c72
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c42
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c21
-rw-r--r--arch/arm/mach-shmobile/cpuidle.c31
-rw-r--r--arch/sh/kernel/cpu/shmobile/cpuidle.c10
-rw-r--r--arch/x86/kernel/acpi/boot.c3
-rw-r--r--arch/x86/kernel/smpboot.c4
-rw-r--r--drivers/acpi/Kconfig9
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/acpica/hwxface.c3
-rw-r--r--drivers/acpi/acpica/tbfadt.c8
-rw-r--r--drivers/acpi/bgrt.c175
-rw-r--r--drivers/acpi/bus.c1
-rw-r--r--drivers/acpi/ec.c8
-rw-r--r--drivers/acpi/nvs.c4
-rw-r--r--drivers/acpi/osl.c5
-rw-r--r--drivers/acpi/processor_driver.c62
-rw-r--r--drivers/acpi/processor_idle.c34
-rw-r--r--drivers/acpi/processor_thermal.c45
-rw-r--r--drivers/acpi/processor_throttling.c5
-rw-r--r--drivers/acpi/reboot.c3
-rw-r--r--drivers/acpi/scan.c5
-rw-r--r--drivers/acpi/thermal.c8
-rw-r--r--drivers/acpi/video.c50
-rw-r--r--drivers/cpuidle/cpuidle.c97
-rw-r--r--drivers/cpuidle/driver.c2
-rw-r--r--drivers/cpuidle/governors/menu.c7
-rw-r--r--drivers/cpuidle/sysfs.c40
-rw-r--r--drivers/platform/x86/intel_ips.c13
-rw-r--r--drivers/pnp/pnpacpi/core.c7
-rw-r--r--drivers/thermal/Kconfig8
-rw-r--r--drivers/thermal/Makefile1
-rw-r--r--drivers/thermal/spear_thermal.c206
-rw-r--r--drivers/thermal/thermal_sys.c94
-rw-r--r--include/linux/cpuidle.h22
-rw-r--r--include/linux/platform_data/spear_thermal.h26
-rw-r--r--tools/power/x86/turbostat/turbostat.899
-rw-r--r--tools/power/x86/turbostat/turbostat.c245
45 files changed, 1212 insertions, 491 deletions
diff --git a/Documentation/ABI/testing/sysfs-firmware-acpi b/Documentation/ABI/testing/sysfs-firmware-acpi
index 4f9ba3c2fca7..dd930c8db41f 100644
--- a/Documentation/ABI/testing/sysfs-firmware-acpi
+++ b/Documentation/ABI/testing/sysfs-firmware-acpi
@@ -1,3 +1,23 @@
1What: /sys/firmware/acpi/bgrt/
2Date: January 2012
3Contact: Matthew Garrett <mjg@redhat.com>
4Description:
5 The BGRT is an ACPI 5.0 feature that allows the OS
6 to obtain a copy of the firmware boot splash and
7 some associated metadata. This is intended to be used
8 by boot splash applications in order to interact with
9 the firmware boot splash in order to avoid jarring
10 transitions.
11
12 image: The image bitmap. Currently a 32-bit BMP.
13 status: 1 if the image is valid, 0 if firmware invalidated it.
14 type: 0 indicates image is in BMP format.
15 version: The version of the BGRT. Currently 1.
16 xoffset: The number of pixels between the left of the screen
17 and the left edge of the image.
18 yoffset: The number of pixels between the top of the screen
19 and the top edge of the image.
20
1What: /sys/firmware/acpi/interrupts/ 21What: /sys/firmware/acpi/interrupts/
2Date: February 2008 22Date: February 2008
3Contact: Len Brown <lenb@kernel.org> 23Contact: Len Brown <lenb@kernel.org>
diff --git a/Documentation/cpuidle/sysfs.txt b/Documentation/cpuidle/sysfs.txt
index 50d7b1642759..9d28a3406e74 100644
--- a/Documentation/cpuidle/sysfs.txt
+++ b/Documentation/cpuidle/sysfs.txt
@@ -36,6 +36,7 @@ drwxr-xr-x 2 root root 0 Feb 8 10:42 state3
36/sys/devices/system/cpu/cpu0/cpuidle/state0: 36/sys/devices/system/cpu/cpu0/cpuidle/state0:
37total 0 37total 0
38-r--r--r-- 1 root root 4096 Feb 8 10:42 desc 38-r--r--r-- 1 root root 4096 Feb 8 10:42 desc
39-rw-r--r-- 1 root root 4096 Feb 8 10:42 disable
39-r--r--r-- 1 root root 4096 Feb 8 10:42 latency 40-r--r--r-- 1 root root 4096 Feb 8 10:42 latency
40-r--r--r-- 1 root root 4096 Feb 8 10:42 name 41-r--r--r-- 1 root root 4096 Feb 8 10:42 name
41-r--r--r-- 1 root root 4096 Feb 8 10:42 power 42-r--r--r-- 1 root root 4096 Feb 8 10:42 power
@@ -45,6 +46,7 @@ total 0
45/sys/devices/system/cpu/cpu0/cpuidle/state1: 46/sys/devices/system/cpu/cpu0/cpuidle/state1:
46total 0 47total 0
47-r--r--r-- 1 root root 4096 Feb 8 10:42 desc 48-r--r--r-- 1 root root 4096 Feb 8 10:42 desc
49-rw-r--r-- 1 root root 4096 Feb 8 10:42 disable
48-r--r--r-- 1 root root 4096 Feb 8 10:42 latency 50-r--r--r-- 1 root root 4096 Feb 8 10:42 latency
49-r--r--r-- 1 root root 4096 Feb 8 10:42 name 51-r--r--r-- 1 root root 4096 Feb 8 10:42 name
50-r--r--r-- 1 root root 4096 Feb 8 10:42 power 52-r--r--r-- 1 root root 4096 Feb 8 10:42 power
@@ -54,6 +56,7 @@ total 0
54/sys/devices/system/cpu/cpu0/cpuidle/state2: 56/sys/devices/system/cpu/cpu0/cpuidle/state2:
55total 0 57total 0
56-r--r--r-- 1 root root 4096 Feb 8 10:42 desc 58-r--r--r-- 1 root root 4096 Feb 8 10:42 desc
59-rw-r--r-- 1 root root 4096 Feb 8 10:42 disable
57-r--r--r-- 1 root root 4096 Feb 8 10:42 latency 60-r--r--r-- 1 root root 4096 Feb 8 10:42 latency
58-r--r--r-- 1 root root 4096 Feb 8 10:42 name 61-r--r--r-- 1 root root 4096 Feb 8 10:42 name
59-r--r--r-- 1 root root 4096 Feb 8 10:42 power 62-r--r--r-- 1 root root 4096 Feb 8 10:42 power
@@ -63,6 +66,7 @@ total 0
63/sys/devices/system/cpu/cpu0/cpuidle/state3: 66/sys/devices/system/cpu/cpu0/cpuidle/state3:
64total 0 67total 0
65-r--r--r-- 1 root root 4096 Feb 8 10:42 desc 68-r--r--r-- 1 root root 4096 Feb 8 10:42 desc
69-rw-r--r-- 1 root root 4096 Feb 8 10:42 disable
66-r--r--r-- 1 root root 4096 Feb 8 10:42 latency 70-r--r--r-- 1 root root 4096 Feb 8 10:42 latency
67-r--r--r-- 1 root root 4096 Feb 8 10:42 name 71-r--r--r-- 1 root root 4096 Feb 8 10:42 name
68-r--r--r-- 1 root root 4096 Feb 8 10:42 power 72-r--r--r-- 1 root root 4096 Feb 8 10:42 power
@@ -72,6 +76,7 @@ total 0
72 76
73 77
74* desc : Small description about the idle state (string) 78* desc : Small description about the idle state (string)
79* disable : Option to disable this idle state (bool)
75* latency : Latency to exit out of this idle state (in microseconds) 80* latency : Latency to exit out of this idle state (in microseconds)
76* name : Name of the idle state (string) 81* name : Name of the idle state (string)
77* power : Power consumed while in this idle state (in milliwatts) 82* power : Power consumed while in this idle state (in milliwatts)
diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
new file mode 100644
index 000000000000..2fca60ab513a
--- /dev/null
+++ b/arch/arm/include/asm/cpuidle.h
@@ -0,0 +1,29 @@
1#ifndef __ASM_ARM_CPUIDLE_H
2#define __ASM_ARM_CPUIDLE_H
3
4#ifdef CONFIG_CPU_IDLE
5extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
6 struct cpuidle_driver *drv, int index);
7#else
8static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
9 struct cpuidle_driver *drv, int index) { return -ENODEV; }
10#endif
11
12/* Common ARM WFI state */
13#define ARM_CPUIDLE_WFI_STATE_PWR(p) {\
14 .enter = arm_cpuidle_simple_enter,\
15 .exit_latency = 1,\
16 .target_residency = 1,\
17 .power_usage = p,\
18 .flags = CPUIDLE_FLAG_TIME_VALID,\
19 .name = "WFI",\
20 .desc = "ARM WFI",\
21}
22
23/*
24 * in case power_specified == 1, give a default WFI power value needed
25 * by some governors
26 */
27#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX)
28
29#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 43b740d0e374..940c27fde498 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
21 21
22obj-$(CONFIG_LEDS) += leds.o 22obj-$(CONFIG_LEDS) += leds.o
23obj-$(CONFIG_OC_ETM) += etm.o 23obj-$(CONFIG_OC_ETM) += etm.o
24 24obj-$(CONFIG_CPU_IDLE) += cpuidle.o
25obj-$(CONFIG_ISA_DMA_API) += dma.o 25obj-$(CONFIG_ISA_DMA_API) += dma.o
26obj-$(CONFIG_ARCH_ACORN) += ecard.o 26obj-$(CONFIG_ARCH_ACORN) += ecard.o
27obj-$(CONFIG_FIQ) += fiq.o fiqasm.o 27obj-$(CONFIG_FIQ) += fiq.o fiqasm.o
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c
new file mode 100644
index 000000000000..89545f6c8403
--- /dev/null
+++ b/arch/arm/kernel/cpuidle.c
@@ -0,0 +1,21 @@
1/*
2 * Copyright 2012 Linaro Ltd.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/cpuidle.h>
13#include <asm/proc-fns.h>
14
15int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
16 struct cpuidle_driver *drv, int index)
17{
18 cpu_do_idle();
19
20 return index;
21}
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index a851e6c98421..d40b3f317f7f 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -17,9 +17,10 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/cpuidle.h> 19#include <linux/cpuidle.h>
20#include <asm/proc-fns.h>
21#include <linux/io.h> 20#include <linux/io.h>
22#include <linux/export.h> 21#include <linux/export.h>
22#include <asm/proc-fns.h>
23#include <asm/cpuidle.h>
23 24
24#include "pm.h" 25#include "pm.h"
25 26
@@ -27,66 +28,46 @@
27 28
28static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); 29static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device);
29 30
30static struct cpuidle_driver at91_idle_driver = {
31 .name = "at91_idle",
32 .owner = THIS_MODULE,
33};
34
35/* Actual code that puts the SoC in different idle states */ 31/* Actual code that puts the SoC in different idle states */
36static int at91_enter_idle(struct cpuidle_device *dev, 32static int at91_enter_idle(struct cpuidle_device *dev,
37 struct cpuidle_driver *drv, 33 struct cpuidle_driver *drv,
38 int index) 34 int index)
39{ 35{
40 struct timeval before, after;
41 int idle_time;
42 u32 saved_lpr; 36 u32 saved_lpr;
43 37
44 local_irq_disable(); 38 __asm__("b 1f; .align 5; 1:\n"
45 do_gettimeofday(&before); 39 " mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */
46 if (index == 0) 40
47 /* Wait for interrupt state */ 41 saved_lpr = sdram_selfrefresh_enable();
48 cpu_do_idle(); 42 cpu_do_idle();
49 else if (index == 1) { 43 sdram_selfrefresh_disable(saved_lpr);
50 asm("b 1f; .align 5; 1:");
51 asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */
52 saved_lpr = sdram_selfrefresh_enable();
53 cpu_do_idle();
54 sdram_selfrefresh_disable(saved_lpr);
55 }
56 do_gettimeofday(&after);
57 local_irq_enable();
58 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
59 (after.tv_usec - before.tv_usec);
60 44
61 dev->last_residency = idle_time;
62 return index; 45 return index;
63} 46}
64 47
48static struct cpuidle_driver at91_idle_driver = {
49 .name = "at91_idle",
50 .owner = THIS_MODULE,
51 .en_core_tk_irqen = 1,
52 .states[0] = ARM_CPUIDLE_WFI_STATE,
53 .states[1] = {
54 .enter = at91_enter_idle,
55 .exit_latency = 10,
56 .target_residency = 100000,
57 .flags = CPUIDLE_FLAG_TIME_VALID,
58 .name = "RAM_SR",
59 .desc = "WFI and DDR Self Refresh",
60 },
61 .state_count = AT91_MAX_STATES,
62};
63
65/* Initialize CPU idle by registering the idle states */ 64/* Initialize CPU idle by registering the idle states */
66static int at91_init_cpuidle(void) 65static int at91_init_cpuidle(void)
67{ 66{
68 struct cpuidle_device *device; 67 struct cpuidle_device *device;
69 struct cpuidle_driver *driver = &at91_idle_driver;
70 68
71 device = &per_cpu(at91_cpuidle_device, smp_processor_id()); 69 device = &per_cpu(at91_cpuidle_device, smp_processor_id());
72 device->state_count = AT91_MAX_STATES; 70 device->state_count = AT91_MAX_STATES;
73 driver->state_count = AT91_MAX_STATES;
74
75 /* Wait for interrupt state */
76 driver->states[0].enter = at91_enter_idle;
77 driver->states[0].exit_latency = 1;
78 driver->states[0].target_residency = 10000;
79 driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
80 strcpy(driver->states[0].name, "WFI");
81 strcpy(driver->states[0].desc, "Wait for interrupt");
82
83 /* Wait for interrupt and RAM self refresh state */
84 driver->states[1].enter = at91_enter_idle;
85 driver->states[1].exit_latency = 10;
86 driver->states[1].target_residency = 10000;
87 driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
88 strcpy(driver->states[1].name, "RAM_SR");
89 strcpy(driver->states[1].desc, "WFI and RAM Self Refresh");
90 71
91 cpuidle_register_driver(&at91_idle_driver); 72 cpuidle_register_driver(&at91_idle_driver);
92 73
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index a30c7c5a6d83..9107691adbdb 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -18,6 +18,7 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/export.h> 19#include <linux/export.h>
20#include <asm/proc-fns.h> 20#include <asm/proc-fns.h>
21#include <asm/cpuidle.h>
21 22
22#include <mach/cpuidle.h> 23#include <mach/cpuidle.h>
23#include <mach/ddr2.h> 24#include <mach/ddr2.h>
@@ -30,12 +31,43 @@ struct davinci_ops {
30 u32 flags; 31 u32 flags;
31}; 32};
32 33
34/* Actual code that puts the SoC in different idle states */
35static int davinci_enter_idle(struct cpuidle_device *dev,
36 struct cpuidle_driver *drv,
37 int index)
38{
39 struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
40 struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
41
42 if (ops && ops->enter)
43 ops->enter(ops->flags);
44
45 index = cpuidle_wrap_enter(dev, drv, index,
46 arm_cpuidle_simple_enter);
47
48 if (ops && ops->exit)
49 ops->exit(ops->flags);
50
51 return index;
52}
53
33/* fields in davinci_ops.flags */ 54/* fields in davinci_ops.flags */
34#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0) 55#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0)
35 56
36static struct cpuidle_driver davinci_idle_driver = { 57static struct cpuidle_driver davinci_idle_driver = {
37 .name = "cpuidle-davinci", 58 .name = "cpuidle-davinci",
38 .owner = THIS_MODULE, 59 .owner = THIS_MODULE,
60 .en_core_tk_irqen = 1,
61 .states[0] = ARM_CPUIDLE_WFI_STATE,
62 .states[1] = {
63 .enter = davinci_enter_idle,
64 .exit_latency = 10,
65 .target_residency = 100000,
66 .flags = CPUIDLE_FLAG_TIME_VALID,
67 .name = "DDR SR",
68 .desc = "WFI and DDR Self Refresh",
69 },
70 .state_count = DAVINCI_CPUIDLE_MAX_STATES,
39}; 71};
40 72
41static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); 73static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
@@ -77,41 +109,10 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
77 }, 109 },
78}; 110};
79 111
80/* Actual code that puts the SoC in different idle states */
81static int davinci_enter_idle(struct cpuidle_device *dev,
82 struct cpuidle_driver *drv,
83 int index)
84{
85 struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
86 struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
87 struct timeval before, after;
88 int idle_time;
89
90 local_irq_disable();
91 do_gettimeofday(&before);
92
93 if (ops && ops->enter)
94 ops->enter(ops->flags);
95 /* Wait for interrupt state */
96 cpu_do_idle();
97 if (ops && ops->exit)
98 ops->exit(ops->flags);
99
100 do_gettimeofday(&after);
101 local_irq_enable();
102 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
103 (after.tv_usec - before.tv_usec);
104
105 dev->last_residency = idle_time;
106
107 return index;
108}
109
110static int __init davinci_cpuidle_probe(struct platform_device *pdev) 112static int __init davinci_cpuidle_probe(struct platform_device *pdev)
111{ 113{
112 int ret; 114 int ret;
113 struct cpuidle_device *device; 115 struct cpuidle_device *device;
114 struct cpuidle_driver *driver = &davinci_idle_driver;
115 struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; 116 struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
116 117
117 device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); 118 device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
@@ -123,27 +124,11 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
123 124
124 ddr2_reg_base = pdata->ddr2_ctlr_base; 125 ddr2_reg_base = pdata->ddr2_ctlr_base;
125 126
126 /* Wait for interrupt state */
127 driver->states[0].enter = davinci_enter_idle;
128 driver->states[0].exit_latency = 1;
129 driver->states[0].target_residency = 10000;
130 driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
131 strcpy(driver->states[0].name, "WFI");
132 strcpy(driver->states[0].desc, "Wait for interrupt");
133
134 /* Wait for interrupt and DDR self refresh state */
135 driver->states[1].enter = davinci_enter_idle;
136 driver->states[1].exit_latency = 10;
137 driver->states[1].target_residency = 10000;
138 driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
139 strcpy(driver->states[1].name, "DDR SR");
140 strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
141 if (pdata->ddr2_pdown) 127 if (pdata->ddr2_pdown)
142 davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; 128 davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
143 cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); 129 cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]);
144 130
145 device->state_count = DAVINCI_CPUIDLE_MAX_STATES; 131 device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
146 driver->state_count = DAVINCI_CPUIDLE_MAX_STATES;
147 132
148 ret = cpuidle_register_driver(&davinci_idle_driver); 133 ret = cpuidle_register_driver(&davinci_idle_driver);
149 if (ret) { 134 if (ret) {
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c
index 7088180b018b..0f1710941878 100644
--- a/arch/arm/mach-kirkwood/cpuidle.c
+++ b/arch/arm/mach-kirkwood/cpuidle.c
@@ -20,77 +20,47 @@
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <asm/proc-fns.h> 22#include <asm/proc-fns.h>
23#include <asm/cpuidle.h>
23#include <mach/kirkwood.h> 24#include <mach/kirkwood.h>
24 25
25#define KIRKWOOD_MAX_STATES 2 26#define KIRKWOOD_MAX_STATES 2
26 27
27static struct cpuidle_driver kirkwood_idle_driver = {
28 .name = "kirkwood_idle",
29 .owner = THIS_MODULE,
30};
31
32static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
33
34/* Actual code that puts the SoC in different idle states */ 28/* Actual code that puts the SoC in different idle states */
35static int kirkwood_enter_idle(struct cpuidle_device *dev, 29static int kirkwood_enter_idle(struct cpuidle_device *dev,
36 struct cpuidle_driver *drv, 30 struct cpuidle_driver *drv,
37 int index) 31 int index)
38{ 32{
39 struct timeval before, after; 33 writel(0x7, DDR_OPERATION_BASE);
40 int idle_time; 34 cpu_do_idle();
41
42 local_irq_disable();
43 do_gettimeofday(&before);
44 if (index == 0)
45 /* Wait for interrupt state */
46 cpu_do_idle();
47 else if (index == 1) {
48 /*
49 * Following write will put DDR in self refresh.
50 * Note that we have 256 cycles before DDR puts it
51 * self in self-refresh, so the wait-for-interrupt
52 * call afterwards won't get the DDR from self refresh
53 * mode.
54 */
55 writel(0x7, DDR_OPERATION_BASE);
56 cpu_do_idle();
57 }
58 do_gettimeofday(&after);
59 local_irq_enable();
60 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
61 (after.tv_usec - before.tv_usec);
62
63 /* Update last residency */
64 dev->last_residency = idle_time;
65 35
66 return index; 36 return index;
67} 37}
68 38
39static struct cpuidle_driver kirkwood_idle_driver = {
40 .name = "kirkwood_idle",
41 .owner = THIS_MODULE,
42 .en_core_tk_irqen = 1,
43 .states[0] = ARM_CPUIDLE_WFI_STATE,
44 .states[1] = {
45 .enter = kirkwood_enter_idle,
46 .exit_latency = 10,
47 .target_residency = 100000,
48 .flags = CPUIDLE_FLAG_TIME_VALID,
49 .name = "DDR SR",
50 .desc = "WFI and DDR Self Refresh",
51 },
52 .state_count = KIRKWOOD_MAX_STATES,
53};
54
55static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
56
69/* Initialize CPU idle by registering the idle states */ 57/* Initialize CPU idle by registering the idle states */
70static int kirkwood_init_cpuidle(void) 58static int kirkwood_init_cpuidle(void)
71{ 59{
72 struct cpuidle_device *device; 60 struct cpuidle_device *device;
73 struct cpuidle_driver *driver = &kirkwood_idle_driver;
74 61
75 device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); 62 device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
76 device->state_count = KIRKWOOD_MAX_STATES; 63 device->state_count = KIRKWOOD_MAX_STATES;
77 driver->state_count = KIRKWOOD_MAX_STATES;
78
79 /* Wait for interrupt state */
80 driver->states[0].enter = kirkwood_enter_idle;
81 driver->states[0].exit_latency = 1;
82 driver->states[0].target_residency = 10000;
83 driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
84 strcpy(driver->states[0].name, "WFI");
85 strcpy(driver->states[0].desc, "Wait for interrupt");
86
87 /* Wait for interrupt and DDR self refresh state */
88 driver->states[1].enter = kirkwood_enter_idle;
89 driver->states[1].exit_latency = 10;
90 driver->states[1].target_residency = 10000;
91 driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
92 strcpy(driver->states[1].name, "DDR SR");
93 strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
94 64
95 cpuidle_register_driver(&kirkwood_idle_driver); 65 cpuidle_register_driver(&kirkwood_idle_driver);
96 if (cpuidle_register_device(device)) { 66 if (cpuidle_register_device(device)) {
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 464cffde58fe..535866489ce3 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -87,29 +87,14 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
87 return 0; 87 return 0;
88} 88}
89 89
90/** 90static int __omap3_enter_idle(struct cpuidle_device *dev,
91 * omap3_enter_idle - Programs OMAP3 to enter the specified state
92 * @dev: cpuidle device
93 * @drv: cpuidle driver
94 * @index: the index of state to be entered
95 *
96 * Called from the CPUidle framework to program the device to the
97 * specified target state selected by the governor.
98 */
99static int omap3_enter_idle(struct cpuidle_device *dev,
100 struct cpuidle_driver *drv, 91 struct cpuidle_driver *drv,
101 int index) 92 int index)
102{ 93{
103 struct omap3_idle_statedata *cx = 94 struct omap3_idle_statedata *cx =
104 cpuidle_get_statedata(&dev->states_usage[index]); 95 cpuidle_get_statedata(&dev->states_usage[index]);
105 struct timespec ts_preidle, ts_postidle, ts_idle;
106 u32 mpu_state = cx->mpu_state, core_state = cx->core_state; 96 u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
107 int idle_time;
108
109 /* Used to keep track of the total time in idle */
110 getnstimeofday(&ts_preidle);
111 97
112 local_irq_disable();
113 local_fiq_disable(); 98 local_fiq_disable();
114 99
115 pwrdm_set_next_pwrst(mpu_pd, mpu_state); 100 pwrdm_set_next_pwrst(mpu_pd, mpu_state);
@@ -148,22 +133,29 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
148 } 133 }
149 134
150return_sleep_time: 135return_sleep_time:
151 getnstimeofday(&ts_postidle);
152 ts_idle = timespec_sub(ts_postidle, ts_preidle);
153 136
154 local_irq_enable();
155 local_fiq_enable(); 137 local_fiq_enable();
156 138
157 idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \
158 USEC_PER_SEC;
159
160 /* Update cpuidle counters */
161 dev->last_residency = idle_time;
162
163 return index; 139 return index;
164} 140}
165 141
166/** 142/**
143 * omap3_enter_idle - Programs OMAP3 to enter the specified state
144 * @dev: cpuidle device
145 * @drv: cpuidle driver
146 * @index: the index of state to be entered
147 *
148 * Called from the CPUidle framework to program the device to the
149 * specified target state selected by the governor.
150 */
151static inline int omap3_enter_idle(struct cpuidle_device *dev,
152 struct cpuidle_driver *drv,
153 int index)
154{
155 return cpuidle_wrap_enter(dev, drv, index, __omap3_enter_idle);
156}
157
158/**
167 * next_valid_state - Find next valid C-state 159 * next_valid_state - Find next valid C-state
168 * @dev: cpuidle device 160 * @dev: cpuidle device
169 * @drv: cpuidle driver 161 * @drv: cpuidle driver
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 72e018b9b260..f386cbe9c889 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -62,15 +62,9 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
62{ 62{
63 struct omap4_idle_statedata *cx = 63 struct omap4_idle_statedata *cx =
64 cpuidle_get_statedata(&dev->states_usage[index]); 64 cpuidle_get_statedata(&dev->states_usage[index]);
65 struct timespec ts_preidle, ts_postidle, ts_idle;
66 u32 cpu1_state; 65 u32 cpu1_state;
67 int idle_time;
68 int cpu_id = smp_processor_id(); 66 int cpu_id = smp_processor_id();
69 67
70 /* Used to keep track of the total time in idle */
71 getnstimeofday(&ts_preidle);
72
73 local_irq_disable();
74 local_fiq_disable(); 68 local_fiq_disable();
75 69
76 /* 70 /*
@@ -128,26 +122,17 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
128 if (index > 0) 122 if (index > 0)
129 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); 123 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
130 124
131 getnstimeofday(&ts_postidle);
132 ts_idle = timespec_sub(ts_postidle, ts_preidle);
133
134 local_irq_enable();
135 local_fiq_enable(); 125 local_fiq_enable();
136 126
137 idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \
138 USEC_PER_SEC;
139
140 /* Update cpuidle counters */
141 dev->last_residency = idle_time;
142
143 return index; 127 return index;
144} 128}
145 129
146DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); 130DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
147 131
148struct cpuidle_driver omap4_idle_driver = { 132struct cpuidle_driver omap4_idle_driver = {
149 .name = "omap4_idle", 133 .name = "omap4_idle",
150 .owner = THIS_MODULE, 134 .owner = THIS_MODULE,
135 .en_core_tk_irqen = 1,
151}; 136};
152 137
153static inline void _fill_cstate(struct cpuidle_driver *drv, 138static inline void _fill_cstate(struct cpuidle_driver *drv,
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
index 1b2334277e85..ca23b202b02d 100644
--- a/arch/arm/mach-shmobile/cpuidle.c
+++ b/arch/arm/mach-shmobile/cpuidle.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <asm/system.h> 16#include <asm/system.h>
17#include <asm/cpuidle.h>
17#include <asm/io.h> 18#include <asm/io.h>
18 19
19static void shmobile_enter_wfi(void) 20static void shmobile_enter_wfi(void)
@@ -29,37 +30,19 @@ static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
29 struct cpuidle_driver *drv, 30 struct cpuidle_driver *drv,
30 int index) 31 int index)
31{ 32{
32 ktime_t before, after;
33
34 before = ktime_get();
35
36 local_irq_disable();
37 local_fiq_disable();
38
39 shmobile_cpuidle_modes[index](); 33 shmobile_cpuidle_modes[index]();
40 34
41 local_irq_enable();
42 local_fiq_enable();
43
44 after = ktime_get();
45 dev->last_residency = ktime_to_ns(ktime_sub(after, before)) >> 10;
46
47 return index; 35 return index;
48} 36}
49 37
50static struct cpuidle_device shmobile_cpuidle_dev; 38static struct cpuidle_device shmobile_cpuidle_dev;
51static struct cpuidle_driver shmobile_cpuidle_driver = { 39static struct cpuidle_driver shmobile_cpuidle_driver = {
52 .name = "shmobile_cpuidle", 40 .name = "shmobile_cpuidle",
53 .owner = THIS_MODULE, 41 .owner = THIS_MODULE,
54 .states[0] = { 42 .en_core_tk_irqen = 1,
55 .name = "C1", 43 .states[0] = ARM_CPUIDLE_WFI_STATE,
56 .desc = "WFI", 44 .safe_state_index = 0, /* C1 */
57 .exit_latency = 1, 45 .state_count = 1,
58 .target_residency = 1 * 2,
59 .flags = CPUIDLE_FLAG_TIME_VALID,
60 },
61 .safe_state_index = 0, /* C1 */
62 .state_count = 1,
63}; 46};
64 47
65void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); 48void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
index 6d62eb40e750..1ddc876d3b26 100644
--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -29,7 +29,6 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,
29 int index) 29 int index)
30{ 30{
31 unsigned long allowed_mode = SUSP_SH_SLEEP; 31 unsigned long allowed_mode = SUSP_SH_SLEEP;
32 ktime_t before, after;
33 int requested_state = index; 32 int requested_state = index;
34 int allowed_state; 33 int allowed_state;
35 int k; 34 int k;
@@ -47,19 +46,16 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,
47 */ 46 */
48 k = min_t(int, allowed_state, requested_state); 47 k = min_t(int, allowed_state, requested_state);
49 48
50 before = ktime_get();
51 sh_mobile_call_standby(cpuidle_mode[k]); 49 sh_mobile_call_standby(cpuidle_mode[k]);
52 after = ktime_get();
53
54 dev->last_residency = (int)ktime_to_ns(ktime_sub(after, before)) >> 10;
55 50
56 return k; 51 return k;
57} 52}
58 53
59static struct cpuidle_device cpuidle_dev; 54static struct cpuidle_device cpuidle_dev;
60static struct cpuidle_driver cpuidle_driver = { 55static struct cpuidle_driver cpuidle_driver = {
61 .name = "sh_idle", 56 .name = "sh_idle",
62 .owner = THIS_MODULE, 57 .owner = THIS_MODULE,
58 .en_core_tk_irqen = 1,
63}; 59};
64 60
65void sh_mobile_setup_cpuidle(void) 61void sh_mobile_setup_cpuidle(void)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index ce664f33ea8e..bbcc2c389ade 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -642,6 +642,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
642 kfree(buffer.pointer); 642 kfree(buffer.pointer);
643 buffer.length = ACPI_ALLOCATE_BUFFER; 643 buffer.length = ACPI_ALLOCATE_BUFFER;
644 buffer.pointer = NULL; 644 buffer.pointer = NULL;
645 lapic = NULL;
645 646
646 if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL)) 647 if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL))
647 goto out; 648 goto out;
@@ -650,7 +651,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
650 goto free_tmp_map; 651 goto free_tmp_map;
651 652
652 cpumask_copy(tmp_map, cpu_present_mask); 653 cpumask_copy(tmp_map, cpu_present_mask);
653 acpi_register_lapic(physid, lapic->lapic_flags & ACPI_MADT_ENABLED); 654 acpi_register_lapic(physid, ACPI_MADT_ENABLED);
654 655
655 /* 656 /*
656 * If mp_register_lapic successfully generates a new logical cpu 657 * If mp_register_lapic successfully generates a new logical cpu
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 66d250c00d11..93a2a0932b51 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -50,6 +50,7 @@
50#include <linux/tboot.h> 50#include <linux/tboot.h>
51#include <linux/stackprotector.h> 51#include <linux/stackprotector.h>
52#include <linux/gfp.h> 52#include <linux/gfp.h>
53#include <linux/cpuidle.h>
53 54
54#include <asm/acpi.h> 55#include <asm/acpi.h>
55#include <asm/desc.h> 56#include <asm/desc.h>
@@ -1422,7 +1423,8 @@ void native_play_dead(void)
1422 tboot_shutdown(TB_SHUTDOWN_WFS); 1423 tboot_shutdown(TB_SHUTDOWN_WFS);
1423 1424
1424 mwait_play_dead(); /* Only returns on failure */ 1425 mwait_play_dead(); /* Only returns on failure */
1425 hlt_play_dead(); 1426 if (cpuidle_play_dead())
1427 hlt_play_dead();
1426} 1428}
1427 1429
1428#else /* ... !CONFIG_HOTPLUG_CPU */ 1430#else /* ... !CONFIG_HOTPLUG_CPU */
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 7556913aba45..47768ff87343 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -384,6 +384,15 @@ config ACPI_CUSTOM_METHOD
384 load additional kernel modules after boot, this feature may be used 384 load additional kernel modules after boot, this feature may be used
385 to override that restriction). 385 to override that restriction).
386 386
387config ACPI_BGRT
388 tristate "Boottime Graphics Resource Table support"
389 default n
390 help
391 This driver adds support for exposing the ACPI Boottime Graphics
392 Resource Table, which allows the operating system to obtain
393 data from the firmware boot splash. It will appear under
394 /sys/firmware/acpi/bgrt/ .
395
387source "drivers/acpi/apei/Kconfig" 396source "drivers/acpi/apei/Kconfig"
388 397
389endif # ACPI 398endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 1567028d2038..47199e2a9130 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_ACPI_SBS) += sbs.o
62obj-$(CONFIG_ACPI_HED) += hed.o 62obj-$(CONFIG_ACPI_HED) += hed.o
63obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o 63obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
64obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o 64obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
65obj-$(CONFIG_ACPI_BGRT) += bgrt.o
65 66
66# processor has its own "processor." module_param namespace 67# processor has its own "processor." module_param namespace
67processor-y := processor_driver.o processor_throttling.o 68processor-y := processor_driver.o processor_throttling.o
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index a716fede4f25..ab513a972c95 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -74,8 +74,7 @@ acpi_status acpi_reset(void)
74 74
75 /* Check if the reset register is supported */ 75 /* Check if the reset register is supported */
76 76
77 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || 77 if (!reset_reg->address) {
78 !reset_reg->address) {
79 return_ACPI_STATUS(AE_NOT_EXIST); 78 return_ACPI_STATUS(AE_NOT_EXIST);
80 } 79 }
81 80
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index c5d870406f41..4c9c760db4a4 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -363,10 +363,6 @@ static void acpi_tb_convert_fadt(void)
363 u32 address32; 363 u32 address32;
364 u32 i; 364 u32 i;
365 365
366 /* Update the local FADT table header length */
367
368 acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
369
370 /* 366 /*
371 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. 367 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
372 * Later code will always use the X 64-bit field. Also, check for an 368 * Later code will always use the X 64-bit field. Also, check for an
@@ -408,6 +404,10 @@ static void acpi_tb_convert_fadt(void)
408 acpi_gbl_FADT.boot_flags = 0; 404 acpi_gbl_FADT.boot_flags = 0;
409 } 405 }
410 406
407 /* Update the local FADT table header length */
408
409 acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
410
411 /* 411 /*
412 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" 412 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
413 * generic address structures as necessary. Later code will always use 413 * generic address structures as necessary. Later code will always use
diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c
new file mode 100644
index 000000000000..8cf6c46e99fb
--- /dev/null
+++ b/drivers/acpi/bgrt.c
@@ -0,0 +1,175 @@
1/*
2 * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/device.h>
13#include <linux/sysfs.h>
14#include <acpi/acpi.h>
15#include <acpi/acpi_bus.h>
16
17static struct acpi_table_bgrt *bgrt_tab;
18static struct kobject *bgrt_kobj;
19
20struct bmp_header {
21 u16 id;
22 u32 size;
23} __attribute ((packed));
24
25static struct bmp_header bmp_header;
26
27static ssize_t show_version(struct device *dev,
28 struct device_attribute *attr, char *buf)
29{
30 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->version);
31}
32static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
33
34static ssize_t show_status(struct device *dev,
35 struct device_attribute *attr, char *buf)
36{
37 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->status);
38}
39static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
40
41static ssize_t show_type(struct device *dev,
42 struct device_attribute *attr, char *buf)
43{
44 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_type);
45}
46static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
47
48static ssize_t show_xoffset(struct device *dev,
49 struct device_attribute *attr, char *buf)
50{
51 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_x);
52}
53static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL);
54
55static ssize_t show_yoffset(struct device *dev,
56 struct device_attribute *attr, char *buf)
57{
58 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_y);
59}
60static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);
61
62static ssize_t show_image(struct file *file, struct kobject *kobj,
63 struct bin_attribute *attr, char *buf, loff_t off, size_t count)
64{
65 int size = attr->size;
66 void __iomem *image = attr->private;
67
68 if (off >= size) {
69 count = 0;
70 } else {
71 if (off + count > size)
72 count = size - off;
73
74 memcpy_fromio(buf, image+off, count);
75 }
76
77 return count;
78}
79
80static struct bin_attribute image_attr = {
81 .attr = {
82 .name = "image",
83 .mode = S_IRUGO,
84 },
85 .read = show_image,
86};
87
88static struct attribute *bgrt_attributes[] = {
89 &dev_attr_version.attr,
90 &dev_attr_status.attr,
91 &dev_attr_type.attr,
92 &dev_attr_xoffset.attr,
93 &dev_attr_yoffset.attr,
94 NULL,
95};
96
97static struct attribute_group bgrt_attribute_group = {
98 .attrs = bgrt_attributes,
99};
100
101static int __init bgrt_init(void)
102{
103 acpi_status status;
104 int ret;
105 void __iomem *bgrt;
106
107 if (acpi_disabled)
108 return -ENODEV;
109
110 status = acpi_get_table("BGRT", 0,
111 (struct acpi_table_header **)&bgrt_tab);
112
113 if (ACPI_FAILURE(status))
114 return -ENODEV;
115
116 sysfs_bin_attr_init(&image_attr);
117
118 bgrt = ioremap(bgrt_tab->image_address, sizeof(struct bmp_header));
119
120 if (!bgrt) {
121 ret = -EINVAL;
122 goto out_err;
123 }
124
125 memcpy_fromio(&bmp_header, bgrt, sizeof(bmp_header));
126 image_attr.size = bmp_header.size;
127 iounmap(bgrt);
128
129 image_attr.private = ioremap(bgrt_tab->image_address, image_attr.size);
130
131 if (!image_attr.private) {
132 ret = -EINVAL;
133 goto out_err;
134 }
135
136
137 bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
138 if (!bgrt_kobj) {
139 ret = -EINVAL;
140 goto out_iounmap;
141 }
142
143 ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
144 if (ret)
145 goto out_kobject;
146
147 ret = sysfs_create_bin_file(bgrt_kobj, &image_attr);
148 if (ret)
149 goto out_group;
150
151 return 0;
152
153out_group:
154 sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
155out_kobject:
156 kobject_put(bgrt_kobj);
157out_iounmap:
158 iounmap(image_attr.private);
159out_err:
160 return ret;
161}
162
163static void __exit bgrt_exit(void)
164{
165 iounmap(image_attr.private);
166 sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
167 sysfs_remove_bin_file(bgrt_kobj, &image_attr);
168}
169
170module_init(bgrt_init);
171module_exit(bgrt_exit);
172
173MODULE_AUTHOR("Matthew Garrett");
174MODULE_DESCRIPTION("BGRT boot graphic support");
175MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 9ecec98bc76e..3263b68cdfa3 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1010,6 +1010,7 @@ static int __init acpi_bus_init(void)
1010} 1010}
1011 1011
1012struct kobject *acpi_kobj; 1012struct kobject *acpi_kobj;
1013EXPORT_SYMBOL_GPL(acpi_kobj);
1013 1014
1014static int __init acpi_init(void) 1015static int __init acpi_init(void)
1015{ 1016{
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index b19a18dd994f..3268dcfbaa9b 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -812,10 +812,10 @@ static int acpi_ec_add(struct acpi_device *device)
812 first_ec = ec; 812 first_ec = ec;
813 device->driver_data = ec; 813 device->driver_data = ec;
814 814
815 WARN(!request_region(ec->data_addr, 1, "EC data"), 815 ret = !!request_region(ec->data_addr, 1, "EC data");
816 "Could not request EC data io port 0x%lx", ec->data_addr); 816 WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr);
817 WARN(!request_region(ec->command_addr, 1, "EC cmd"), 817 ret = !!request_region(ec->command_addr, 1, "EC cmd");
818 "Could not request EC cmd io port 0x%lx", ec->command_addr); 818 WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
819 819
820 pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", 820 pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
821 ec->gpe, ec->command_addr, ec->data_addr); 821 ec->gpe, ec->command_addr, ec->data_addr);
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
index 7a2035fa8c71..266bc58ce0ce 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -95,8 +95,8 @@ static int suspend_nvs_register(unsigned long start, unsigned long size)
95{ 95{
96 struct nvs_page *entry, *next; 96 struct nvs_page *entry, *next;
97 97
98 pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n", 98 pr_info("PM: Registering ACPI NVS region [mem %#010lx-%#010lx] (%ld bytes)\n",
99 start, size); 99 start, start + size - 1, size);
100 100
101 while (size > 0) { 101 while (size > 0) {
102 unsigned int nr_bytes; 102 unsigned int nr_bytes;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 07d426425b59..9fddb55764f3 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -347,7 +347,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
347 unsigned long pfn; 347 unsigned long pfn;
348 348
349 pfn = pg_off >> PAGE_SHIFT; 349 pfn = pg_off >> PAGE_SHIFT;
350 if (page_is_ram(pfn)) 350 if (should_use_kmap(pfn))
351 kunmap(pfn_to_page(pfn)); 351 kunmap(pfn_to_page(pfn));
352 else 352 else
353 iounmap(vaddr); 353 iounmap(vaddr);
@@ -604,7 +604,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
604 604
605 acpi_irq_handler = handler; 605 acpi_irq_handler = handler;
606 acpi_irq_context = context; 606 acpi_irq_context = context;
607 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { 607 if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi",
608 acpi_irq)) {
608 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); 609 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
609 acpi_irq_handler = NULL; 610 acpi_irq_handler = NULL;
610 return AE_NOT_ACQUIRED; 611 return AE_NOT_ACQUIRED;
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 8ae05ce18500..41de1355edcd 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -68,6 +68,7 @@
68#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 68#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
69#define ACPI_PROCESSOR_NOTIFY_POWER 0x81 69#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
70#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 70#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
71#define ACPI_PROCESSOR_DEVICE_HID "ACPI0007"
71 72
72#define ACPI_PROCESSOR_LIMIT_USER 0 73#define ACPI_PROCESSOR_LIMIT_USER 0
73#define ACPI_PROCESSOR_LIMIT_THERMAL 1 74#define ACPI_PROCESSOR_LIMIT_THERMAL 1
@@ -88,7 +89,7 @@ static int acpi_processor_start(struct acpi_processor *pr);
88 89
89static const struct acpi_device_id processor_device_ids[] = { 90static const struct acpi_device_id processor_device_ids[] = {
90 {ACPI_PROCESSOR_OBJECT_HID, 0}, 91 {ACPI_PROCESSOR_OBJECT_HID, 0},
91 {"ACPI0007", 0}, 92 {ACPI_PROCESSOR_DEVICE_HID, 0},
92 {"", 0}, 93 {"", 0},
93}; 94};
94MODULE_DEVICE_TABLE(acpi, processor_device_ids); 95MODULE_DEVICE_TABLE(acpi, processor_device_ids);
@@ -535,8 +536,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
535 return -ENOMEM; 536 return -ENOMEM;
536 537
537 if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { 538 if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
538 kfree(pr); 539 result = -ENOMEM;
539 return -ENOMEM; 540 goto err_free_pr;
540 } 541 }
541 542
542 pr->handle = device->handle; 543 pr->handle = device->handle;
@@ -576,7 +577,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
576 dev = get_cpu_device(pr->id); 577 dev = get_cpu_device(pr->id);
577 if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) { 578 if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) {
578 result = -EFAULT; 579 result = -EFAULT;
579 goto err_free_cpumask; 580 goto err_clear_processor;
580 } 581 }
581 582
582 /* 583 /*
@@ -594,9 +595,15 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
594 595
595err_remove_sysfs: 596err_remove_sysfs:
596 sysfs_remove_link(&device->dev.kobj, "sysdev"); 597 sysfs_remove_link(&device->dev.kobj, "sysdev");
598err_clear_processor:
599 /*
600 * processor_device_array is not cleared to allow checks for buggy BIOS
601 */
602 per_cpu(processors, pr->id) = NULL;
597err_free_cpumask: 603err_free_cpumask:
598 free_cpumask_var(pr->throttling.shared_cpu_map); 604 free_cpumask_var(pr->throttling.shared_cpu_map);
599 605err_free_pr:
606 kfree(pr);
600 return result; 607 return result;
601} 608}
602 609
@@ -741,20 +748,46 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
741 return; 748 return;
742} 749}
743 750
751static acpi_status is_processor_device(acpi_handle handle)
752{
753 struct acpi_device_info *info;
754 char *hid;
755 acpi_status status;
756
757 status = acpi_get_object_info(handle, &info);
758 if (ACPI_FAILURE(status))
759 return status;
760
761 if (info->type == ACPI_TYPE_PROCESSOR) {
762 kfree(info);
763 return AE_OK; /* found a processor object */
764 }
765
766 if (!(info->valid & ACPI_VALID_HID)) {
767 kfree(info);
768 return AE_ERROR;
769 }
770
771 hid = info->hardware_id.string;
772 if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) {
773 kfree(info);
774 return AE_ERROR;
775 }
776
777 kfree(info);
778 return AE_OK; /* found a processor device object */
779}
780
744static acpi_status 781static acpi_status
745processor_walk_namespace_cb(acpi_handle handle, 782processor_walk_namespace_cb(acpi_handle handle,
746 u32 lvl, void *context, void **rv) 783 u32 lvl, void *context, void **rv)
747{ 784{
748 acpi_status status; 785 acpi_status status;
749 int *action = context; 786 int *action = context;
750 acpi_object_type type = 0;
751 787
752 status = acpi_get_type(handle, &type); 788 status = is_processor_device(handle);
753 if (ACPI_FAILURE(status)) 789 if (ACPI_FAILURE(status))
754 return (AE_OK); 790 return AE_OK; /* not a processor; continue to walk */
755
756 if (type != ACPI_TYPE_PROCESSOR)
757 return (AE_OK);
758 791
759 switch (*action) { 792 switch (*action) {
760 case INSTALL_NOTIFY_HANDLER: 793 case INSTALL_NOTIFY_HANDLER:
@@ -772,7 +805,8 @@ processor_walk_namespace_cb(acpi_handle handle,
772 break; 805 break;
773 } 806 }
774 807
775 return (AE_OK); 808 /* found a processor; skip walking underneath */
809 return AE_CTRL_DEPTH;
776} 810}
777 811
778static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) 812static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
@@ -830,7 +864,7 @@ void acpi_processor_install_hotplug_notify(void)
830{ 864{
831#ifdef CONFIG_ACPI_HOTPLUG_CPU 865#ifdef CONFIG_ACPI_HOTPLUG_CPU
832 int action = INSTALL_NOTIFY_HANDLER; 866 int action = INSTALL_NOTIFY_HANDLER;
833 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, 867 acpi_walk_namespace(ACPI_TYPE_ANY,
834 ACPI_ROOT_OBJECT, 868 ACPI_ROOT_OBJECT,
835 ACPI_UINT32_MAX, 869 ACPI_UINT32_MAX,
836 processor_walk_namespace_cb, NULL, &action, NULL); 870 processor_walk_namespace_cb, NULL, &action, NULL);
@@ -843,7 +877,7 @@ void acpi_processor_uninstall_hotplug_notify(void)
843{ 877{
844#ifdef CONFIG_ACPI_HOTPLUG_CPU 878#ifdef CONFIG_ACPI_HOTPLUG_CPU
845 int action = UNINSTALL_NOTIFY_HANDLER; 879 int action = UNINSTALL_NOTIFY_HANDLER;
846 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, 880 acpi_walk_namespace(ACPI_TYPE_ANY,
847 ACPI_ROOT_OBJECT, 881 ACPI_ROOT_OBJECT,
848 ACPI_UINT32_MAX, 882 ACPI_UINT32_MAX,
849 processor_walk_namespace_cb, NULL, &action, NULL); 883 processor_walk_namespace_cb, NULL, &action, NULL);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 0e8e2de2ed3e..b3447f63e46b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -770,6 +770,35 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
770 return index; 770 return index;
771} 771}
772 772
773
774/**
775 * acpi_idle_play_dead - enters an ACPI state for long-term idle (i.e. off-lining)
776 * @dev: the target CPU
777 * @index: the index of suggested state
778 */
779static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
780{
781 struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
782 struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
783
784 ACPI_FLUSH_CPU_CACHE();
785
786 while (1) {
787
788 if (cx->entry_method == ACPI_CSTATE_HALT)
789 halt();
790 else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
791 inb(cx->address);
792 /* See comment in acpi_idle_do_entry() */
793 inl(acpi_gbl_FADT.xpm_timer_block.address);
794 } else
795 return -ENODEV;
796 }
797
798 /* Never reached */
799 return 0;
800}
801
773/** 802/**
774 * acpi_idle_enter_simple - enters an ACPI state without BM handling 803 * acpi_idle_enter_simple - enters an ACPI state without BM handling
775 * @dev: the target CPU 804 * @dev: the target CPU
@@ -1077,12 +1106,14 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
1077 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1106 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1078 1107
1079 state->enter = acpi_idle_enter_c1; 1108 state->enter = acpi_idle_enter_c1;
1109 state->enter_dead = acpi_idle_play_dead;
1080 drv->safe_state_index = count; 1110 drv->safe_state_index = count;
1081 break; 1111 break;
1082 1112
1083 case ACPI_STATE_C2: 1113 case ACPI_STATE_C2:
1084 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1114 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1085 state->enter = acpi_idle_enter_simple; 1115 state->enter = acpi_idle_enter_simple;
1116 state->enter_dead = acpi_idle_play_dead;
1086 drv->safe_state_index = count; 1117 drv->safe_state_index = count;
1087 break; 1118 break;
1088 1119
@@ -1159,8 +1190,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1159 * to make the code that updates C-States be called once. 1190 * to make the code that updates C-States be called once.
1160 */ 1191 */
1161 1192
1162 if (smp_processor_id() == 0 && 1193 if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) {
1163 cpuidle_get_driver() == &acpi_idle_driver) {
1164 1194
1165 cpuidle_pause_and_lock(); 1195 cpuidle_pause_and_lock();
1166 /* Protect against cpu-hotplug */ 1196 /* Protect against cpu-hotplug */
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 3b599abf2b40..641b5450a0db 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -57,6 +57,27 @@ ACPI_MODULE_NAME("processor_thermal");
57static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); 57static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg);
58static unsigned int acpi_thermal_cpufreq_is_init = 0; 58static unsigned int acpi_thermal_cpufreq_is_init = 0;
59 59
60#define reduction_pctg(cpu) \
61 per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu))
62
63/*
64 * Emulate "per package data" using per cpu data (which should really be
65 * provided elsewhere)
66 *
67 * Note we can lose a CPU on cpu hotunplug, in this case we forget the state
68 * temporarily. Fortunately that's not a big issue here (I hope)
69 */
70static int phys_package_first_cpu(int cpu)
71{
72 int i;
73 int id = topology_physical_package_id(cpu);
74
75 for_each_online_cpu(i)
76 if (topology_physical_package_id(i) == id)
77 return i;
78 return 0;
79}
80
60static int cpu_has_cpufreq(unsigned int cpu) 81static int cpu_has_cpufreq(unsigned int cpu)
61{ 82{
62 struct cpufreq_policy policy; 83 struct cpufreq_policy policy;
@@ -76,7 +97,7 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
76 97
77 max_freq = ( 98 max_freq = (
78 policy->cpuinfo.max_freq * 99 policy->cpuinfo.max_freq *
79 (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20) 100 (100 - reduction_pctg(policy->cpu) * 20)
80 ) / 100; 101 ) / 100;
81 102
82 cpufreq_verify_within_limits(policy, 0, max_freq); 103 cpufreq_verify_within_limits(policy, 0, max_freq);
@@ -102,16 +123,28 @@ static int cpufreq_get_cur_state(unsigned int cpu)
102 if (!cpu_has_cpufreq(cpu)) 123 if (!cpu_has_cpufreq(cpu))
103 return 0; 124 return 0;
104 125
105 return per_cpu(cpufreq_thermal_reduction_pctg, cpu); 126 return reduction_pctg(cpu);
106} 127}
107 128
108static int cpufreq_set_cur_state(unsigned int cpu, int state) 129static int cpufreq_set_cur_state(unsigned int cpu, int state)
109{ 130{
131 int i;
132
110 if (!cpu_has_cpufreq(cpu)) 133 if (!cpu_has_cpufreq(cpu))
111 return 0; 134 return 0;
112 135
113 per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state; 136 reduction_pctg(cpu) = state;
114 cpufreq_update_policy(cpu); 137
138 /*
139 * Update all the CPUs in the same package because they all
140 * contribute to the temperature and often share the same
141 * frequency.
142 */
143 for_each_online_cpu(i) {
144 if (topology_physical_package_id(i) ==
145 topology_physical_package_id(cpu))
146 cpufreq_update_policy(i);
147 }
115 return 0; 148 return 0;
116} 149}
117 150
@@ -119,10 +152,6 @@ void acpi_thermal_cpufreq_init(void)
119{ 152{
120 int i; 153 int i;
121 154
122 for (i = 0; i < nr_cpu_ids; i++)
123 if (cpu_present(i))
124 per_cpu(cpufreq_thermal_reduction_pctg, i) = 0;
125
126 i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, 155 i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block,
127 CPUFREQ_POLICY_NOTIFIER); 156 CPUFREQ_POLICY_NOTIFIER);
128 if (!i) 157 if (!i)
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 605a2954ef17..1d02b7b5ade0 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -769,7 +769,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr,
769 u64 *value) 769 u64 *value)
770{ 770{
771 u32 bit_width, bit_offset; 771 u32 bit_width, bit_offset;
772 u64 ptc_value; 772 u32 ptc_value;
773 u64 ptc_mask; 773 u64 ptc_mask;
774 struct acpi_processor_throttling *throttling; 774 struct acpi_processor_throttling *throttling;
775 int ret = -1; 775 int ret = -1;
@@ -777,12 +777,11 @@ static int acpi_read_throttling_status(struct acpi_processor *pr,
777 throttling = &pr->throttling; 777 throttling = &pr->throttling;
778 switch (throttling->status_register.space_id) { 778 switch (throttling->status_register.space_id) {
779 case ACPI_ADR_SPACE_SYSTEM_IO: 779 case ACPI_ADR_SPACE_SYSTEM_IO:
780 ptc_value = 0;
781 bit_width = throttling->status_register.bit_width; 780 bit_width = throttling->status_register.bit_width;
782 bit_offset = throttling->status_register.bit_offset; 781 bit_offset = throttling->status_register.bit_offset;
783 782
784 acpi_os_read_port((acpi_io_address) throttling->status_register. 783 acpi_os_read_port((acpi_io_address) throttling->status_register.
785 address, (u32 *) &ptc_value, 784 address, &ptc_value,
786 (u32) (bit_width + bit_offset)); 785 (u32) (bit_width + bit_offset));
787 ptc_mask = (1 << bit_width) - 1; 786 ptc_mask = (1 << bit_width) - 1;
788 *value = (u64) ((ptc_value >> bit_offset) & ptc_mask); 787 *value = (u64) ((ptc_value >> bit_offset) & ptc_mask);
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
index a6c77e8b37bd..c1d612435939 100644
--- a/drivers/acpi/reboot.c
+++ b/drivers/acpi/reboot.c
@@ -23,8 +23,7 @@ void acpi_reboot(void)
23 /* Is the reset register supported? The spec says we should be 23 /* Is the reset register supported? The spec says we should be
24 * checking the bit width and bit offset, but Windows ignores 24 * checking the bit width and bit offset, but Windows ignores
25 * these fields */ 25 * these fields */
26 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) 26 /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */
27 return;
28 27
29 reset_value = acpi_gbl_FADT.reset_value; 28 reset_value = acpi_gbl_FADT.reset_value;
30 29
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 8ab80bafe3f1..5d24a17aa854 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -880,7 +880,6 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
880 int j; 880 int j;
881 881
882 device->power.flags.power_resources = 1; 882 device->power.flags.power_resources = 1;
883 ps->flags.valid = 1;
884 for (j = 0; j < ps->resources.count; j++) 883 for (j = 0; j < ps->resources.count; j++)
885 acpi_bus_add_power_resource(ps->resources.handles[j]); 884 acpi_bus_add_power_resource(ps->resources.handles[j]);
886 } 885 }
@@ -888,10 +887,8 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
888 /* Evaluate "_PSx" to see if we can do explicit sets */ 887 /* Evaluate "_PSx" to see if we can do explicit sets */
889 object_name[2] = 'S'; 888 object_name[2] = 'S';
890 status = acpi_get_handle(device->handle, object_name, &handle); 889 status = acpi_get_handle(device->handle, object_name, &handle);
891 if (ACPI_SUCCESS(status)) { 890 if (ACPI_SUCCESS(status))
892 ps->flags.explicit_set = 1; 891 ps->flags.explicit_set = 1;
893 ps->flags.valid = 1;
894 }
895 892
896 /* State is valid if we have some power control */ 893 /* State is valid if we have some power control */
897 if (ps->resources.count || ps->flags.explicit_set) 894 if (ps->resources.count || ps->flags.explicit_set)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 48fbc647b178..7dbebea1ec31 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -941,13 +941,13 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)
941 if (!tz) 941 if (!tz)
942 return -EINVAL; 942 return -EINVAL;
943 943
944 /* Get temperature [_TMP] (required) */ 944 /* Get trip points [_CRT, _PSV, etc.] (required) */
945 result = acpi_thermal_get_temperature(tz); 945 result = acpi_thermal_get_trip_points(tz);
946 if (result) 946 if (result)
947 return result; 947 return result;
948 948
949 /* Get trip points [_CRT, _PSV, etc.] (required) */ 949 /* Get temperature [_TMP] (required) */
950 result = acpi_thermal_get_trip_points(tz); 950 result = acpi_thermal_get_temperature(tz);
951 if (result) 951 if (result)
952 return result; 952 return result;
953 953
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index eaef02afc7cf..9577b6fa2650 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -548,27 +548,27 @@ acpi_video_device_EDID(struct acpi_video_device *device,
548 * 1. The system BIOS should NOT automatically control the brightness 548 * 1. The system BIOS should NOT automatically control the brightness
549 * level of the LCD when the power changes from AC to DC. 549 * level of the LCD when the power changes from AC to DC.
550 * Return Value: 550 * Return Value:
551 * -1 wrong arg. 551 * -EINVAL wrong arg.
552 */ 552 */
553 553
554static int 554static int
555acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) 555acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
556{ 556{
557 u64 status = 0; 557 acpi_status status;
558 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 558 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
559 struct acpi_object_list args = { 1, &arg0 }; 559 struct acpi_object_list args = { 1, &arg0 };
560 560
561 561
562 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) { 562 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1)
563 status = -1; 563 return -EINVAL;
564 goto Failed;
565 }
566 arg0.integer.value = (lcd_flag << 2) | bios_flag; 564 arg0.integer.value = (lcd_flag << 2) | bios_flag;
567 video->dos_setting = arg0.integer.value; 565 video->dos_setting = arg0.integer.value;
568 acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL); 566 status = acpi_evaluate_object(video->device->handle, "_DOS",
567 &args, NULL);
568 if (ACPI_FAILURE(status))
569 return -EIO;
569 570
570 Failed: 571 return 0;
571 return status;
572} 572}
573 573
574/* 574/*
@@ -1343,15 +1343,17 @@ static int
1343acpi_video_bus_get_devices(struct acpi_video_bus *video, 1343acpi_video_bus_get_devices(struct acpi_video_bus *video,
1344 struct acpi_device *device) 1344 struct acpi_device *device)
1345{ 1345{
1346 int status = 0; 1346 int status;
1347 struct acpi_device *dev; 1347 struct acpi_device *dev;
1348 1348
1349 acpi_video_device_enumerate(video); 1349 status = acpi_video_device_enumerate(video);
1350 if (status)
1351 return status;
1350 1352
1351 list_for_each_entry(dev, &device->children, node) { 1353 list_for_each_entry(dev, &device->children, node) {
1352 1354
1353 status = acpi_video_bus_get_one_device(dev, video); 1355 status = acpi_video_bus_get_one_device(dev, video);
1354 if (ACPI_FAILURE(status)) { 1356 if (status) {
1355 printk(KERN_WARNING PREFIX 1357 printk(KERN_WARNING PREFIX
1356 "Can't attach device\n"); 1358 "Can't attach device\n");
1357 continue; 1359 continue;
@@ -1653,15 +1655,20 @@ static int acpi_video_bus_add(struct acpi_device *device)
1653 mutex_init(&video->device_list_lock); 1655 mutex_init(&video->device_list_lock);
1654 INIT_LIST_HEAD(&video->video_device_list); 1656 INIT_LIST_HEAD(&video->video_device_list);
1655 1657
1656 acpi_video_bus_get_devices(video, device); 1658 error = acpi_video_bus_get_devices(video, device);
1657 acpi_video_bus_start_devices(video); 1659 if (error)
1660 goto err_free_video;
1658 1661
1659 video->input = input = input_allocate_device(); 1662 video->input = input = input_allocate_device();
1660 if (!input) { 1663 if (!input) {
1661 error = -ENOMEM; 1664 error = -ENOMEM;
1662 goto err_stop_video; 1665 goto err_put_video;
1663 } 1666 }
1664 1667
1668 error = acpi_video_bus_start_devices(video);
1669 if (error)
1670 goto err_free_input_dev;
1671
1665 snprintf(video->phys, sizeof(video->phys), 1672 snprintf(video->phys, sizeof(video->phys),
1666 "%s/video/input0", acpi_device_hid(video->device)); 1673 "%s/video/input0", acpi_device_hid(video->device));
1667 1674
@@ -1682,7 +1689,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
1682 1689
1683 error = input_register_device(input); 1690 error = input_register_device(input);
1684 if (error) 1691 if (error)
1685 goto err_free_input_dev; 1692 goto err_stop_video;
1686 1693
1687 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", 1694 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
1688 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 1695 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
@@ -1692,14 +1699,19 @@ static int acpi_video_bus_add(struct acpi_device *device)
1692 1699
1693 video->pm_nb.notifier_call = acpi_video_resume; 1700 video->pm_nb.notifier_call = acpi_video_resume;
1694 video->pm_nb.priority = 0; 1701 video->pm_nb.priority = 0;
1695 register_pm_notifier(&video->pm_nb); 1702 error = register_pm_notifier(&video->pm_nb);
1703 if (error)
1704 goto err_unregister_input_dev;
1696 1705
1697 return 0; 1706 return 0;
1698 1707
1699 err_free_input_dev: 1708 err_unregister_input_dev:
1700 input_free_device(input); 1709 input_unregister_device(input);
1701 err_stop_video: 1710 err_stop_video:
1702 acpi_video_bus_stop_devices(video); 1711 acpi_video_bus_stop_devices(video);
1712 err_free_input_dev:
1713 input_free_device(input);
1714 err_put_video:
1703 acpi_video_bus_put_devices(video); 1715 acpi_video_bus_put_devices(video);
1704 kfree(video->attached_array); 1716 kfree(video->attached_array);
1705 err_free_video: 1717 err_free_video:
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 59f4261c753a..3e146b2ada4a 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -53,6 +53,52 @@ static void cpuidle_kick_cpus(void) {}
53 53
54static int __cpuidle_register_device(struct cpuidle_device *dev); 54static int __cpuidle_register_device(struct cpuidle_device *dev);
55 55
56static inline int cpuidle_enter(struct cpuidle_device *dev,
57 struct cpuidle_driver *drv, int index)
58{
59 struct cpuidle_state *target_state = &drv->states[index];
60 return target_state->enter(dev, drv, index);
61}
62
63static inline int cpuidle_enter_tk(struct cpuidle_device *dev,
64 struct cpuidle_driver *drv, int index)
65{
66 return cpuidle_wrap_enter(dev, drv, index, cpuidle_enter);
67}
68
69typedef int (*cpuidle_enter_t)(struct cpuidle_device *dev,
70 struct cpuidle_driver *drv, int index);
71
72static cpuidle_enter_t cpuidle_enter_ops;
73
74/**
75 * cpuidle_play_dead - cpu off-lining
76 *
77 * Only returns in case of an error
78 */
79int cpuidle_play_dead(void)
80{
81 struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
82 struct cpuidle_driver *drv = cpuidle_get_driver();
83 int i, dead_state = -1;
84 int power_usage = -1;
85
86 /* Find lowest-power state that supports long-term idle */
87 for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
88 struct cpuidle_state *s = &drv->states[i];
89
90 if (s->power_usage < power_usage && s->enter_dead) {
91 power_usage = s->power_usage;
92 dead_state = i;
93 }
94 }
95
96 if (dead_state != -1)
97 return drv->states[dead_state].enter_dead(dev, dead_state);
98
99 return -ENODEV;
100}
101
56/** 102/**
57 * cpuidle_idle_call - the main idle loop 103 * cpuidle_idle_call - the main idle loop
58 * 104 *
@@ -63,7 +109,6 @@ int cpuidle_idle_call(void)
63{ 109{
64 struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); 110 struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
65 struct cpuidle_driver *drv = cpuidle_get_driver(); 111 struct cpuidle_driver *drv = cpuidle_get_driver();
66 struct cpuidle_state *target_state;
67 int next_state, entered_state; 112 int next_state, entered_state;
68 113
69 if (off) 114 if (off)
@@ -92,12 +137,10 @@ int cpuidle_idle_call(void)
92 return 0; 137 return 0;
93 } 138 }
94 139
95 target_state = &drv->states[next_state];
96
97 trace_power_start(POWER_CSTATE, next_state, dev->cpu); 140 trace_power_start(POWER_CSTATE, next_state, dev->cpu);
98 trace_cpu_idle(next_state, dev->cpu); 141 trace_cpu_idle(next_state, dev->cpu);
99 142
100 entered_state = target_state->enter(dev, drv, next_state); 143 entered_state = cpuidle_enter_ops(dev, drv, next_state);
101 144
102 trace_power_end(dev->cpu); 145 trace_power_end(dev->cpu);
103 trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); 146 trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu);
@@ -110,6 +153,8 @@ int cpuidle_idle_call(void)
110 dev->states_usage[entered_state].time += 153 dev->states_usage[entered_state].time +=
111 (unsigned long long)dev->last_residency; 154 (unsigned long long)dev->last_residency;
112 dev->states_usage[entered_state].usage++; 155 dev->states_usage[entered_state].usage++;
156 } else {
157 dev->last_residency = 0;
113 } 158 }
114 159
115 /* give the governor an opportunity to reflect on the outcome */ 160 /* give the governor an opportunity to reflect on the outcome */
@@ -164,6 +209,37 @@ void cpuidle_resume_and_unlock(void)
164 209
165EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); 210EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
166 211
212/**
213 * cpuidle_wrap_enter - performs timekeeping and irqen around enter function
214 * @dev: pointer to a valid cpuidle_device object
215 * @drv: pointer to a valid cpuidle_driver object
216 * @index: index of the target cpuidle state.
217 */
218int cpuidle_wrap_enter(struct cpuidle_device *dev,
219 struct cpuidle_driver *drv, int index,
220 int (*enter)(struct cpuidle_device *dev,
221 struct cpuidle_driver *drv, int index))
222{
223 ktime_t time_start, time_end;
224 s64 diff;
225
226 time_start = ktime_get();
227
228 index = enter(dev, drv, index);
229
230 time_end = ktime_get();
231
232 local_irq_enable();
233
234 diff = ktime_to_us(ktime_sub(time_end, time_start));
235 if (diff > INT_MAX)
236 diff = INT_MAX;
237
238 dev->last_residency = (int) diff;
239
240 return index;
241}
242
167#ifdef CONFIG_ARCH_HAS_CPU_RELAX 243#ifdef CONFIG_ARCH_HAS_CPU_RELAX
168static int poll_idle(struct cpuidle_device *dev, 244static int poll_idle(struct cpuidle_device *dev,
169 struct cpuidle_driver *drv, int index) 245 struct cpuidle_driver *drv, int index)
@@ -197,6 +273,7 @@ static void poll_idle_init(struct cpuidle_driver *drv)
197 state->power_usage = -1; 273 state->power_usage = -1;
198 state->flags = 0; 274 state->flags = 0;
199 state->enter = poll_idle; 275 state->enter = poll_idle;
276 state->disable = 0;
200} 277}
201#else 278#else
202static void poll_idle_init(struct cpuidle_driver *drv) {} 279static void poll_idle_init(struct cpuidle_driver *drv) {}
@@ -212,13 +289,14 @@ static void poll_idle_init(struct cpuidle_driver *drv) {}
212int cpuidle_enable_device(struct cpuidle_device *dev) 289int cpuidle_enable_device(struct cpuidle_device *dev)
213{ 290{
214 int ret, i; 291 int ret, i;
292 struct cpuidle_driver *drv = cpuidle_get_driver();
215 293
216 if (dev->enabled) 294 if (dev->enabled)
217 return 0; 295 return 0;
218 if (!cpuidle_get_driver() || !cpuidle_curr_governor) 296 if (!drv || !cpuidle_curr_governor)
219 return -EIO; 297 return -EIO;
220 if (!dev->state_count) 298 if (!dev->state_count)
221 return -EINVAL; 299 dev->state_count = drv->state_count;
222 300
223 if (dev->registered == 0) { 301 if (dev->registered == 0) {
224 ret = __cpuidle_register_device(dev); 302 ret = __cpuidle_register_device(dev);
@@ -226,13 +304,16 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
226 return ret; 304 return ret;
227 } 305 }
228 306
229 poll_idle_init(cpuidle_get_driver()); 307 cpuidle_enter_ops = drv->en_core_tk_irqen ?
308 cpuidle_enter_tk : cpuidle_enter;
309
310 poll_idle_init(drv);
230 311
231 if ((ret = cpuidle_add_state_sysfs(dev))) 312 if ((ret = cpuidle_add_state_sysfs(dev)))
232 return ret; 313 return ret;
233 314
234 if (cpuidle_curr_governor->enable && 315 if (cpuidle_curr_governor->enable &&
235 (ret = cpuidle_curr_governor->enable(cpuidle_get_driver(), dev))) 316 (ret = cpuidle_curr_governor->enable(drv, dev)))
236 goto fail_sysfs; 317 goto fail_sysfs;
237 318
238 for (i = 0; i < dev->state_count; i++) { 319 for (i = 0; i < dev->state_count; i++) {
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 284d7af5a9c8..40cd3f3024df 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -47,7 +47,7 @@ static void __cpuidle_register_driver(struct cpuidle_driver *drv)
47 */ 47 */
48int cpuidle_register_driver(struct cpuidle_driver *drv) 48int cpuidle_register_driver(struct cpuidle_driver *drv)
49{ 49{
50 if (!drv) 50 if (!drv || !drv->state_count)
51 return -EINVAL; 51 return -EINVAL;
52 52
53 if (cpuidle_disabled()) 53 if (cpuidle_disabled())
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index ad0952601ae2..06335756ea14 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -236,7 +236,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
236{ 236{
237 struct menu_device *data = &__get_cpu_var(menu_devices); 237 struct menu_device *data = &__get_cpu_var(menu_devices);
238 int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); 238 int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
239 unsigned int power_usage = -1; 239 int power_usage = -1;
240 int i; 240 int i;
241 int multiplier; 241 int multiplier;
242 struct timespec t; 242 struct timespec t;
@@ -280,7 +280,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
280 * We want to default to C1 (hlt), not to busy polling 280 * We want to default to C1 (hlt), not to busy polling
281 * unless the timer is happening really really soon. 281 * unless the timer is happening really really soon.
282 */ 282 */
283 if (data->expected_us > 5) 283 if (data->expected_us > 5 &&
284 drv->states[CPUIDLE_DRIVER_STATE_START].disable == 0)
284 data->last_state_idx = CPUIDLE_DRIVER_STATE_START; 285 data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
285 286
286 /* 287 /*
@@ -290,6 +291,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
290 for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { 291 for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
291 struct cpuidle_state *s = &drv->states[i]; 292 struct cpuidle_state *s = &drv->states[i];
292 293
294 if (s->disable)
295 continue;
293 if (s->target_residency > data->predicted_us) 296 if (s->target_residency > data->predicted_us)
294 continue; 297 continue;
295 if (s->exit_latency > latency_req) 298 if (s->exit_latency > latency_req)
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
index 3fe41fe4851a..88032b4dc6d2 100644
--- a/drivers/cpuidle/sysfs.c
+++ b/drivers/cpuidle/sysfs.c
@@ -11,6 +11,7 @@
11#include <linux/sysfs.h> 11#include <linux/sysfs.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/cpu.h> 13#include <linux/cpu.h>
14#include <linux/capability.h>
14 15
15#include "cpuidle.h" 16#include "cpuidle.h"
16 17
@@ -222,6 +223,9 @@ struct cpuidle_state_attr {
222#define define_one_state_ro(_name, show) \ 223#define define_one_state_ro(_name, show) \
223static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL) 224static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
224 225
226#define define_one_state_rw(_name, show, store) \
227static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0644, show, store)
228
225#define define_show_state_function(_name) \ 229#define define_show_state_function(_name) \
226static ssize_t show_state_##_name(struct cpuidle_state *state, \ 230static ssize_t show_state_##_name(struct cpuidle_state *state, \
227 struct cpuidle_state_usage *state_usage, char *buf) \ 231 struct cpuidle_state_usage *state_usage, char *buf) \
@@ -229,6 +233,24 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \
229 return sprintf(buf, "%u\n", state->_name);\ 233 return sprintf(buf, "%u\n", state->_name);\
230} 234}
231 235
236#define define_store_state_function(_name) \
237static ssize_t store_state_##_name(struct cpuidle_state *state, \
238 const char *buf, size_t size) \
239{ \
240 long value; \
241 int err; \
242 if (!capable(CAP_SYS_ADMIN)) \
243 return -EPERM; \
244 err = kstrtol(buf, 0, &value); \
245 if (err) \
246 return err; \
247 if (value) \
248 state->disable = 1; \
249 else \
250 state->disable = 0; \
251 return size; \
252}
253
232#define define_show_state_ull_function(_name) \ 254#define define_show_state_ull_function(_name) \
233static ssize_t show_state_##_name(struct cpuidle_state *state, \ 255static ssize_t show_state_##_name(struct cpuidle_state *state, \
234 struct cpuidle_state_usage *state_usage, char *buf) \ 256 struct cpuidle_state_usage *state_usage, char *buf) \
@@ -251,6 +273,8 @@ define_show_state_ull_function(usage)
251define_show_state_ull_function(time) 273define_show_state_ull_function(time)
252define_show_state_str_function(name) 274define_show_state_str_function(name)
253define_show_state_str_function(desc) 275define_show_state_str_function(desc)
276define_show_state_function(disable)
277define_store_state_function(disable)
254 278
255define_one_state_ro(name, show_state_name); 279define_one_state_ro(name, show_state_name);
256define_one_state_ro(desc, show_state_desc); 280define_one_state_ro(desc, show_state_desc);
@@ -258,6 +282,7 @@ define_one_state_ro(latency, show_state_exit_latency);
258define_one_state_ro(power, show_state_power_usage); 282define_one_state_ro(power, show_state_power_usage);
259define_one_state_ro(usage, show_state_usage); 283define_one_state_ro(usage, show_state_usage);
260define_one_state_ro(time, show_state_time); 284define_one_state_ro(time, show_state_time);
285define_one_state_rw(disable, show_state_disable, store_state_disable);
261 286
262static struct attribute *cpuidle_state_default_attrs[] = { 287static struct attribute *cpuidle_state_default_attrs[] = {
263 &attr_name.attr, 288 &attr_name.attr,
@@ -266,6 +291,7 @@ static struct attribute *cpuidle_state_default_attrs[] = {
266 &attr_power.attr, 291 &attr_power.attr,
267 &attr_usage.attr, 292 &attr_usage.attr,
268 &attr_time.attr, 293 &attr_time.attr,
294 &attr_disable.attr,
269 NULL 295 NULL
270}; 296};
271 297
@@ -287,8 +313,22 @@ static ssize_t cpuidle_state_show(struct kobject * kobj,
287 return ret; 313 return ret;
288} 314}
289 315
316static ssize_t cpuidle_state_store(struct kobject *kobj,
317 struct attribute *attr, const char *buf, size_t size)
318{
319 int ret = -EIO;
320 struct cpuidle_state *state = kobj_to_state(kobj);
321 struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
322
323 if (cattr->store)
324 ret = cattr->store(state, buf, size);
325
326 return ret;
327}
328
290static const struct sysfs_ops cpuidle_state_sysfs_ops = { 329static const struct sysfs_ops cpuidle_state_sysfs_ops = {
291 .show = cpuidle_state_show, 330 .show = cpuidle_state_show,
331 .store = cpuidle_state_store,
292}; 332};
293 333
294static void cpuidle_state_sysfs_release(struct kobject *kobj) 334static void cpuidle_state_sysfs_release(struct kobject *kobj)
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 88a98cff5a44..f7ba316e0ed6 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -609,25 +609,16 @@ static bool mcp_exceeded(struct ips_driver *ips)
609 bool ret = false; 609 bool ret = false;
610 u32 temp_limit; 610 u32 temp_limit;
611 u32 avg_power; 611 u32 avg_power;
612 const char *msg = "MCP limit exceeded: ";
613 612
614 spin_lock_irqsave(&ips->turbo_status_lock, flags); 613 spin_lock_irqsave(&ips->turbo_status_lock, flags);
615 614
616 temp_limit = ips->mcp_temp_limit * 100; 615 temp_limit = ips->mcp_temp_limit * 100;
617 if (ips->mcp_avg_temp > temp_limit) { 616 if (ips->mcp_avg_temp > temp_limit)
618 dev_info(&ips->dev->dev,
619 "%sAvg temp %u, limit %u\n", msg, ips->mcp_avg_temp,
620 temp_limit);
621 ret = true; 617 ret = true;
622 }
623 618
624 avg_power = ips->cpu_avg_power + ips->mch_avg_power; 619 avg_power = ips->cpu_avg_power + ips->mch_avg_power;
625 if (avg_power > ips->mcp_power_limit) { 620 if (avg_power > ips->mcp_power_limit)
626 dev_info(&ips->dev->dev,
627 "%sAvg power %u, limit %u\n", msg, avg_power,
628 ips->mcp_power_limit);
629 ret = true; 621 ret = true;
630 }
631 622
632 spin_unlock_irqrestore(&ips->turbo_status_lock, flags); 623 spin_unlock_irqrestore(&ips->turbo_status_lock, flags);
633 624
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index b00c17612a89..d21e8f59c84e 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -321,9 +321,14 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp)
321{ 321{
322 struct acpi_device *acpi = to_acpi_device(dev); 322 struct acpi_device *acpi = to_acpi_device(dev);
323 struct pnp_dev *pnp = _pnp; 323 struct pnp_dev *pnp = _pnp;
324 struct device *physical_device;
325
326 physical_device = acpi_get_physical_device(acpi->handle);
327 if (physical_device)
328 put_device(physical_device);
324 329
325 /* true means it matched */ 330 /* true means it matched */
326 return !acpi_get_physical_device(acpi->handle) 331 return !physical_device
327 && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); 332 && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
328} 333}
329 334
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index f7f71b2d3101..514a691abea0 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -18,3 +18,11 @@ config THERMAL_HWMON
18 depends on THERMAL 18 depends on THERMAL
19 depends on HWMON=y || HWMON=THERMAL 19 depends on HWMON=y || HWMON=THERMAL
20 default y 20 default y
21
22config SPEAR_THERMAL
23 bool "SPEAr thermal sensor driver"
24 depends on THERMAL
25 depends on PLAT_SPEAR
26 help
27 Enable this to plug the SPEAr thermal sensor driver into the Linux
28 thermal framework
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 31108a01c22e..a9fff0bf4b14 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -3,3 +3,4 @@
3# 3#
4 4
5obj-$(CONFIG_THERMAL) += thermal_sys.o 5obj-$(CONFIG_THERMAL) += thermal_sys.o
6obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o \ No newline at end of file
diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
new file mode 100644
index 000000000000..c2e32df3b164
--- /dev/null
+++ b/drivers/thermal/spear_thermal.c
@@ -0,0 +1,206 @@
1/*
2 * SPEAr thermal driver.
3 *
4 * Copyright (C) 2011-2012 ST Microelectronics
5 * Author: Vincenzo Frascino <vincenzo.frascino@st.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/clk.h>
19#include <linux/device.h>
20#include <linux/err.h>
21#include <linux/io.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/platform_data/spear_thermal.h>
26#include <linux/thermal.h>
27
28#define MD_FACTOR 1000
29
30/* SPEAr Thermal Sensor Dev Structure */
31struct spear_thermal_dev {
32 /* pointer to base address of the thermal sensor */
33 void __iomem *thermal_base;
34 /* clk structure */
35 struct clk *clk;
36 /* pointer to thermal flags */
37 unsigned int flags;
38};
39
40static inline int thermal_get_temp(struct thermal_zone_device *thermal,
41 unsigned long *temp)
42{
43 struct spear_thermal_dev *stdev = thermal->devdata;
44
45 /*
46 * Data are ready to be read after 628 usec from POWERDOWN signal
47 * (PDN) = 1
48 */
49 *temp = (readl_relaxed(stdev->thermal_base) & 0x7F) * MD_FACTOR;
50 return 0;
51}
52
53static struct thermal_zone_device_ops ops = {
54 .get_temp = thermal_get_temp,
55};
56
57#ifdef CONFIG_PM
58static int spear_thermal_suspend(struct device *dev)
59{
60 struct platform_device *pdev = to_platform_device(dev);
61 struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev);
62 struct spear_thermal_dev *stdev = spear_thermal->devdata;
63 unsigned int actual_mask = 0;
64
65 /* Disable SPEAr Thermal Sensor */
66 actual_mask = readl_relaxed(stdev->thermal_base);
67 writel_relaxed(actual_mask & ~stdev->flags, stdev->thermal_base);
68
69 clk_disable(stdev->clk);
70 dev_info(dev, "Suspended.\n");
71
72 return 0;
73}
74
75static int spear_thermal_resume(struct device *dev)
76{
77 struct platform_device *pdev = to_platform_device(dev);
78 struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev);
79 struct spear_thermal_dev *stdev = spear_thermal->devdata;
80 unsigned int actual_mask = 0;
81 int ret = 0;
82
83 ret = clk_enable(stdev->clk);
84 if (ret) {
85 dev_err(&pdev->dev, "Can't enable clock\n");
86 return ret;
87 }
88
89 /* Enable SPEAr Thermal Sensor */
90 actual_mask = readl_relaxed(stdev->thermal_base);
91 writel_relaxed(actual_mask | stdev->flags, stdev->thermal_base);
92
93 dev_info(dev, "Resumed.\n");
94
95 return 0;
96}
97#endif
98
99static SIMPLE_DEV_PM_OPS(spear_thermal_pm_ops, spear_thermal_suspend,
100 spear_thermal_resume);
101
102static int spear_thermal_probe(struct platform_device *pdev)
103{
104 struct thermal_zone_device *spear_thermal = NULL;
105 struct spear_thermal_dev *stdev;
106 struct spear_thermal_pdata *pdata;
107 int ret = 0;
108 struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
109
110 if (!stres) {
111 dev_err(&pdev->dev, "memory resource missing\n");
112 return -ENODEV;
113 }
114
115 pdata = dev_get_platdata(&pdev->dev);
116 if (!pdata) {
117 dev_err(&pdev->dev, "platform data is NULL\n");
118 return -EINVAL;
119 }
120
121 stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL);
122 if (!stdev) {
123 dev_err(&pdev->dev, "kzalloc fail\n");
124 return -ENOMEM;
125 }
126
127 /* Enable thermal sensor */
128 stdev->thermal_base = devm_ioremap(&pdev->dev, stres->start,
129 resource_size(stres));
130 if (!stdev->thermal_base) {
131 dev_err(&pdev->dev, "ioremap failed\n");
132 return -ENOMEM;
133 }
134
135 stdev->clk = clk_get(&pdev->dev, NULL);
136 if (IS_ERR(stdev->clk)) {
137 dev_err(&pdev->dev, "Can't get clock\n");
138 return PTR_ERR(stdev->clk);
139 }
140
141 ret = clk_enable(stdev->clk);
142 if (ret) {
143 dev_err(&pdev->dev, "Can't enable clock\n");
144 goto put_clk;
145 }
146
147 stdev->flags = pdata->thermal_flags;
148 writel_relaxed(stdev->flags, stdev->thermal_base);
149
150 spear_thermal = thermal_zone_device_register("spear_thermal", 0,
151 stdev, &ops, 0, 0, 0, 0);
152 if (IS_ERR(spear_thermal)) {
153 dev_err(&pdev->dev, "thermal zone device is NULL\n");
154 ret = PTR_ERR(spear_thermal);
155 goto disable_clk;
156 }
157
158 platform_set_drvdata(pdev, spear_thermal);
159
160 dev_info(&spear_thermal->device, "Thermal Sensor Loaded at: 0x%p.\n",
161 stdev->thermal_base);
162
163 return 0;
164
165disable_clk:
166 clk_disable(stdev->clk);
167put_clk:
168 clk_put(stdev->clk);
169
170 return ret;
171}
172
173static int spear_thermal_exit(struct platform_device *pdev)
174{
175 unsigned int actual_mask = 0;
176 struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev);
177 struct spear_thermal_dev *stdev = spear_thermal->devdata;
178
179 thermal_zone_device_unregister(spear_thermal);
180 platform_set_drvdata(pdev, NULL);
181
182 /* Disable SPEAr Thermal Sensor */
183 actual_mask = readl_relaxed(stdev->thermal_base);
184 writel_relaxed(actual_mask & ~stdev->flags, stdev->thermal_base);
185
186 clk_disable(stdev->clk);
187 clk_put(stdev->clk);
188
189 return 0;
190}
191
192static struct platform_driver spear_thermal_driver = {
193 .probe = spear_thermal_probe,
194 .remove = spear_thermal_exit,
195 .driver = {
196 .name = "spear_thermal",
197 .owner = THIS_MODULE,
198 .pm = &spear_thermal_pm_ops,
199 },
200};
201
202module_platform_driver(spear_thermal_driver);
203
204MODULE_AUTHOR("Vincenzo Frascino <vincenzo.frascino@st.com>");
205MODULE_DESCRIPTION("SPEAr thermal driver");
206MODULE_LICENSE("GPL");
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 220ce7e31cf5..022bacb71a7e 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -23,6 +23,8 @@
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */ 24 */
25 25
26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
26#include <linux/module.h> 28#include <linux/module.h>
27#include <linux/device.h> 29#include <linux/device.h>
28#include <linux/err.h> 30#include <linux/err.h>
@@ -39,8 +41,6 @@ MODULE_AUTHOR("Zhang Rui");
39MODULE_DESCRIPTION("Generic thermal management sysfs support"); 41MODULE_DESCRIPTION("Generic thermal management sysfs support");
40MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
41 43
42#define PREFIX "Thermal: "
43
44struct thermal_cooling_device_instance { 44struct thermal_cooling_device_instance {
45 int id; 45 int id;
46 char name[THERMAL_NAME_LENGTH]; 46 char name[THERMAL_NAME_LENGTH];
@@ -60,13 +60,11 @@ static LIST_HEAD(thermal_tz_list);
60static LIST_HEAD(thermal_cdev_list); 60static LIST_HEAD(thermal_cdev_list);
61static DEFINE_MUTEX(thermal_list_lock); 61static DEFINE_MUTEX(thermal_list_lock);
62 62
63static unsigned int thermal_event_seqnum;
64
65static int get_idr(struct idr *idr, struct mutex *lock, int *id) 63static int get_idr(struct idr *idr, struct mutex *lock, int *id)
66{ 64{
67 int err; 65 int err;
68 66
69 again: 67again:
70 if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) 68 if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
71 return -ENOMEM; 69 return -ENOMEM;
72 70
@@ -152,9 +150,9 @@ mode_store(struct device *dev, struct device_attribute *attr,
152 if (!tz->ops->set_mode) 150 if (!tz->ops->set_mode)
153 return -EPERM; 151 return -EPERM;
154 152
155 if (!strncmp(buf, "enabled", sizeof("enabled"))) 153 if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
156 result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED); 154 result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
157 else if (!strncmp(buf, "disabled", sizeof("disabled"))) 155 else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
158 result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED); 156 result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
159 else 157 else
160 result = -EINVAL; 158 result = -EINVAL;
@@ -283,8 +281,7 @@ passive_show(struct device *dev, struct device_attribute *attr,
283static DEVICE_ATTR(type, 0444, type_show, NULL); 281static DEVICE_ATTR(type, 0444, type_show, NULL);
284static DEVICE_ATTR(temp, 0444, temp_show, NULL); 282static DEVICE_ATTR(temp, 0444, temp_show, NULL);
285static DEVICE_ATTR(mode, 0644, mode_show, mode_store); 283static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
286static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \ 284static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
287 passive_store);
288 285
289static struct device_attribute trip_point_attrs[] = { 286static struct device_attribute trip_point_attrs[] = {
290 __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), 287 __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
@@ -313,22 +310,6 @@ static struct device_attribute trip_point_attrs[] = {
313 __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL), 310 __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL),
314}; 311};
315 312
316#define TRIP_POINT_ATTR_ADD(_dev, _index, result) \
317do { \
318 result = device_create_file(_dev, \
319 &trip_point_attrs[_index * 2]); \
320 if (result) \
321 break; \
322 result = device_create_file(_dev, \
323 &trip_point_attrs[_index * 2 + 1]); \
324} while (0)
325
326#define TRIP_POINT_ATTR_REMOVE(_dev, _index) \
327do { \
328 device_remove_file(_dev, &trip_point_attrs[_index * 2]); \
329 device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \
330} while (0)
331
332/* sys I/F for cooling device */ 313/* sys I/F for cooling device */
333#define to_cooling_device(_dev) \ 314#define to_cooling_device(_dev) \
334 container_of(_dev, struct thermal_cooling_device, device) 315 container_of(_dev, struct thermal_cooling_device, device)
@@ -835,15 +816,14 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
835 return 0; 816 return 0;
836 817
837 device_remove_file(&tz->device, &dev->attr); 818 device_remove_file(&tz->device, &dev->attr);
838 remove_symbol_link: 819remove_symbol_link:
839 sysfs_remove_link(&tz->device.kobj, dev->name); 820 sysfs_remove_link(&tz->device.kobj, dev->name);
840 release_idr: 821release_idr:
841 release_idr(&tz->idr, &tz->lock, dev->id); 822 release_idr(&tz->idr, &tz->lock, dev->id);
842 free_mem: 823free_mem:
843 kfree(dev); 824 kfree(dev);
844 return result; 825 return result;
845} 826}
846
847EXPORT_SYMBOL(thermal_zone_bind_cooling_device); 827EXPORT_SYMBOL(thermal_zone_bind_cooling_device);
848 828
849/** 829/**
@@ -873,14 +853,13 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
873 853
874 return -ENODEV; 854 return -ENODEV;
875 855
876 unbind: 856unbind:
877 device_remove_file(&tz->device, &pos->attr); 857 device_remove_file(&tz->device, &pos->attr);
878 sysfs_remove_link(&tz->device.kobj, pos->name); 858 sysfs_remove_link(&tz->device.kobj, pos->name);
879 release_idr(&tz->idr, &tz->lock, pos->id); 859 release_idr(&tz->idr, &tz->lock, pos->id);
880 kfree(pos); 860 kfree(pos);
881 return 0; 861 return 0;
882} 862}
883
884EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); 863EXPORT_SYMBOL(thermal_zone_unbind_cooling_device);
885 864
886static void thermal_release(struct device *dev) 865static void thermal_release(struct device *dev)
@@ -888,7 +867,8 @@ static void thermal_release(struct device *dev)
888 struct thermal_zone_device *tz; 867 struct thermal_zone_device *tz;
889 struct thermal_cooling_device *cdev; 868 struct thermal_cooling_device *cdev;
890 869
891 if (!strncmp(dev_name(dev), "thermal_zone", sizeof "thermal_zone" - 1)) { 870 if (!strncmp(dev_name(dev), "thermal_zone",
871 sizeof("thermal_zone") - 1)) {
892 tz = to_thermal_zone(dev); 872 tz = to_thermal_zone(dev);
893 kfree(tz); 873 kfree(tz);
894 } else { 874 } else {
@@ -908,8 +888,9 @@ static struct class thermal_class = {
908 * @devdata: device private data. 888 * @devdata: device private data.
909 * @ops: standard thermal cooling devices callbacks. 889 * @ops: standard thermal cooling devices callbacks.
910 */ 890 */
911struct thermal_cooling_device *thermal_cooling_device_register( 891struct thermal_cooling_device *
912 char *type, void *devdata, const struct thermal_cooling_device_ops *ops) 892thermal_cooling_device_register(char *type, void *devdata,
893 const struct thermal_cooling_device_ops *ops)
913{ 894{
914 struct thermal_cooling_device *cdev; 895 struct thermal_cooling_device *cdev;
915 struct thermal_zone_device *pos; 896 struct thermal_zone_device *pos;
@@ -974,12 +955,11 @@ struct thermal_cooling_device *thermal_cooling_device_register(
974 if (!result) 955 if (!result)
975 return cdev; 956 return cdev;
976 957
977 unregister: 958unregister:
978 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); 959 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
979 device_unregister(&cdev->device); 960 device_unregister(&cdev->device);
980 return ERR_PTR(result); 961 return ERR_PTR(result);
981} 962}
982
983EXPORT_SYMBOL(thermal_cooling_device_register); 963EXPORT_SYMBOL(thermal_cooling_device_register);
984 964
985/** 965/**
@@ -1024,7 +1004,6 @@ void thermal_cooling_device_unregister(struct
1024 device_unregister(&cdev->device); 1004 device_unregister(&cdev->device);
1025 return; 1005 return;
1026} 1006}
1027
1028EXPORT_SYMBOL(thermal_cooling_device_unregister); 1007EXPORT_SYMBOL(thermal_cooling_device_unregister);
1029 1008
1030/** 1009/**
@@ -1044,8 +1023,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
1044 1023
1045 if (tz->ops->get_temp(tz, &temp)) { 1024 if (tz->ops->get_temp(tz, &temp)) {
1046 /* get_temp failed - retry it later */ 1025 /* get_temp failed - retry it later */
1047 printk(KERN_WARNING PREFIX "failed to read out thermal zone " 1026 pr_warn("failed to read out thermal zone %d\n", tz->id);
1048 "%d\n", tz->id);
1049 goto leave; 1027 goto leave;
1050 } 1028 }
1051 1029
@@ -1060,9 +1038,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
1060 ret = tz->ops->notify(tz, count, 1038 ret = tz->ops->notify(tz, count,
1061 trip_type); 1039 trip_type);
1062 if (!ret) { 1040 if (!ret) {
1063 printk(KERN_EMERG 1041 pr_emerg("Critical temperature reached (%ld C), shutting down\n",
1064 "Critical temperature reached (%ld C), shutting down.\n", 1042 temp/1000);
1065 temp/1000);
1066 orderly_poweroff(true); 1043 orderly_poweroff(true);
1067 } 1044 }
1068 } 1045 }
@@ -1100,7 +1077,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
1100 1077
1101 tz->last_temperature = temp; 1078 tz->last_temperature = temp;
1102 1079
1103 leave: 1080leave:
1104 if (tz->passive) 1081 if (tz->passive)
1105 thermal_zone_device_set_polling(tz, tz->passive_delay); 1082 thermal_zone_device_set_polling(tz, tz->passive_delay);
1106 else if (tz->polling_delay) 1083 else if (tz->polling_delay)
@@ -1199,7 +1176,12 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
1199 } 1176 }
1200 1177
1201 for (count = 0; count < trips; count++) { 1178 for (count = 0; count < trips; count++) {
1202 TRIP_POINT_ATTR_ADD(&tz->device, count, result); 1179 result = device_create_file(&tz->device,
1180 &trip_point_attrs[count * 2]);
1181 if (result)
1182 break;
1183 result = device_create_file(&tz->device,
1184 &trip_point_attrs[count * 2 + 1]);
1203 if (result) 1185 if (result)
1204 goto unregister; 1186 goto unregister;
1205 tz->ops->get_trip_type(tz, count, &trip_type); 1187 tz->ops->get_trip_type(tz, count, &trip_type);
@@ -1235,12 +1217,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
1235 if (!result) 1217 if (!result)
1236 return tz; 1218 return tz;
1237 1219
1238 unregister: 1220unregister:
1239 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1221 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1240 device_unregister(&tz->device); 1222 device_unregister(&tz->device);
1241 return ERR_PTR(result); 1223 return ERR_PTR(result);
1242} 1224}
1243
1244EXPORT_SYMBOL(thermal_zone_device_register); 1225EXPORT_SYMBOL(thermal_zone_device_register);
1245 1226
1246/** 1227/**
@@ -1279,9 +1260,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1279 if (tz->ops->get_mode) 1260 if (tz->ops->get_mode)
1280 device_remove_file(&tz->device, &dev_attr_mode); 1261 device_remove_file(&tz->device, &dev_attr_mode);
1281 1262
1282 for (count = 0; count < tz->trips; count++) 1263 for (count = 0; count < tz->trips; count++) {
1283 TRIP_POINT_ATTR_REMOVE(&tz->device, count); 1264 device_remove_file(&tz->device,
1284 1265 &trip_point_attrs[count * 2]);
1266 device_remove_file(&tz->device,
1267 &trip_point_attrs[count * 2 + 1]);
1268 }
1285 thermal_remove_hwmon_sysfs(tz); 1269 thermal_remove_hwmon_sysfs(tz);
1286 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1270 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1287 idr_destroy(&tz->idr); 1271 idr_destroy(&tz->idr);
@@ -1289,7 +1273,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1289 device_unregister(&tz->device); 1273 device_unregister(&tz->device);
1290 return; 1274 return;
1291} 1275}
1292
1293EXPORT_SYMBOL(thermal_zone_device_unregister); 1276EXPORT_SYMBOL(thermal_zone_device_unregister);
1294 1277
1295#ifdef CONFIG_NET 1278#ifdef CONFIG_NET
@@ -1312,10 +1295,11 @@ int thermal_generate_netlink_event(u32 orig, enum events event)
1312 void *msg_header; 1295 void *msg_header;
1313 int size; 1296 int size;
1314 int result; 1297 int result;
1298 static unsigned int thermal_event_seqnum;
1315 1299
1316 /* allocate memory */ 1300 /* allocate memory */
1317 size = nla_total_size(sizeof(struct thermal_genl_event)) + \ 1301 size = nla_total_size(sizeof(struct thermal_genl_event)) +
1318 nla_total_size(0); 1302 nla_total_size(0);
1319 1303
1320 skb = genlmsg_new(size, GFP_ATOMIC); 1304 skb = genlmsg_new(size, GFP_ATOMIC);
1321 if (!skb) 1305 if (!skb)
@@ -1331,8 +1315,8 @@ int thermal_generate_netlink_event(u32 orig, enum events event)
1331 } 1315 }
1332 1316
1333 /* fill the data */ 1317 /* fill the data */
1334 attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \ 1318 attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT,
1335 sizeof(struct thermal_genl_event)); 1319 sizeof(struct thermal_genl_event));
1336 1320
1337 if (!attr) { 1321 if (!attr) {
1338 nlmsg_free(skb); 1322 nlmsg_free(skb);
@@ -1359,7 +1343,7 @@ int thermal_generate_netlink_event(u32 orig, enum events event)
1359 1343
1360 result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); 1344 result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC);
1361 if (result) 1345 if (result)
1362 printk(KERN_INFO "failed to send netlink event:%d", result); 1346 pr_info("failed to send netlink event:%d\n", result);
1363 1347
1364 return result; 1348 return result;
1365} 1349}
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 712abcc205ae..6c26a3da0e03 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -15,6 +15,7 @@
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/kobject.h> 16#include <linux/kobject.h>
17#include <linux/completion.h> 17#include <linux/completion.h>
18#include <linux/hrtimer.h>
18 19
19#define CPUIDLE_STATE_MAX 8 20#define CPUIDLE_STATE_MAX 8
20#define CPUIDLE_NAME_LEN 16 21#define CPUIDLE_NAME_LEN 16
@@ -43,12 +44,15 @@ struct cpuidle_state {
43 44
44 unsigned int flags; 45 unsigned int flags;
45 unsigned int exit_latency; /* in US */ 46 unsigned int exit_latency; /* in US */
46 unsigned int power_usage; /* in mW */ 47 int power_usage; /* in mW */
47 unsigned int target_residency; /* in US */ 48 unsigned int target_residency; /* in US */
49 unsigned int disable;
48 50
49 int (*enter) (struct cpuidle_device *dev, 51 int (*enter) (struct cpuidle_device *dev,
50 struct cpuidle_driver *drv, 52 struct cpuidle_driver *drv,
51 int index); 53 int index);
54
55 int (*enter_dead) (struct cpuidle_device *dev, int index);
52}; 56};
53 57
54/* Idle State Flags */ 58/* Idle State Flags */
@@ -96,7 +100,6 @@ struct cpuidle_device {
96 struct list_head device_list; 100 struct list_head device_list;
97 struct kobject kobj; 101 struct kobject kobj;
98 struct completion kobj_unregister; 102 struct completion kobj_unregister;
99 void *governor_data;
100}; 103};
101 104
102DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); 105DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
@@ -118,10 +121,12 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
118 ****************************/ 121 ****************************/
119 122
120struct cpuidle_driver { 123struct cpuidle_driver {
121 char name[CPUIDLE_NAME_LEN]; 124 const char *name;
122 struct module *owner; 125 struct module *owner;
123 126
124 unsigned int power_specified:1; 127 unsigned int power_specified:1;
128 /* set to 1 to use the core cpuidle time keeping (for all states). */
129 unsigned int en_core_tk_irqen:1;
125 struct cpuidle_state states[CPUIDLE_STATE_MAX]; 130 struct cpuidle_state states[CPUIDLE_STATE_MAX];
126 int state_count; 131 int state_count;
127 int safe_state_index; 132 int safe_state_index;
@@ -140,6 +145,11 @@ extern void cpuidle_pause_and_lock(void);
140extern void cpuidle_resume_and_unlock(void); 145extern void cpuidle_resume_and_unlock(void);
141extern int cpuidle_enable_device(struct cpuidle_device *dev); 146extern int cpuidle_enable_device(struct cpuidle_device *dev);
142extern void cpuidle_disable_device(struct cpuidle_device *dev); 147extern void cpuidle_disable_device(struct cpuidle_device *dev);
148extern int cpuidle_wrap_enter(struct cpuidle_device *dev,
149 struct cpuidle_driver *drv, int index,
150 int (*enter)(struct cpuidle_device *dev,
151 struct cpuidle_driver *drv, int index));
152extern int cpuidle_play_dead(void);
143 153
144#else 154#else
145static inline void disable_cpuidle(void) { } 155static inline void disable_cpuidle(void) { }
@@ -157,6 +167,12 @@ static inline void cpuidle_resume_and_unlock(void) { }
157static inline int cpuidle_enable_device(struct cpuidle_device *dev) 167static inline int cpuidle_enable_device(struct cpuidle_device *dev)
158{return -ENODEV; } 168{return -ENODEV; }
159static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } 169static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
170static inline int cpuidle_wrap_enter(struct cpuidle_device *dev,
171 struct cpuidle_driver *drv, int index,
172 int (*enter)(struct cpuidle_device *dev,
173 struct cpuidle_driver *drv, int index))
174{ return -ENODEV; }
175static inline int cpuidle_play_dead(void) {return -ENODEV; }
160 176
161#endif 177#endif
162 178
diff --git a/include/linux/platform_data/spear_thermal.h b/include/linux/platform_data/spear_thermal.h
new file mode 100644
index 000000000000..724f2e1cbbcb
--- /dev/null
+++ b/include/linux/platform_data/spear_thermal.h
@@ -0,0 +1,26 @@
1/*
2 * SPEAr thermal driver platform data.
3 *
4 * Copyright (C) 2011-2012 ST Microelectronics
5 * Author: Vincenzo Frascino <vincenzo.frascino@st.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17#ifndef SPEAR_THERMAL_H
18#define SPEAR_THERMAL_H
19
20/* SPEAr Thermal Sensor Platform Data */
21struct spear_thermal_pdata {
22 /* flags used to enable thermal sensor */
23 unsigned int thermal_flags;
24};
25
26#endif /* SPEAR_THERMAL_H */
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 555c69a5592a..adf175f61496 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -4,11 +4,13 @@ turbostat \- Report processor frequency and idle statistics
4.SH SYNOPSIS 4.SH SYNOPSIS
5.ft B 5.ft B
6.B turbostat 6.B turbostat
7.RB [ "\-s" ]
7.RB [ "\-v" ] 8.RB [ "\-v" ]
8.RB [ "\-M MSR#" ] 9.RB [ "\-M MSR#" ]
9.RB command 10.RB command
10.br 11.br
11.B turbostat 12.B turbostat
13.RB [ "\-s" ]
12.RB [ "\-v" ] 14.RB [ "\-v" ]
13.RB [ "\-M MSR#" ] 15.RB [ "\-M MSR#" ]
14.RB [ "\-i interval_sec" ] 16.RB [ "\-i interval_sec" ]
@@ -25,6 +27,8 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs.
25on processors that additionally support C-state residency counters. 27on processors that additionally support C-state residency counters.
26 28
27.SS Options 29.SS Options
30The \fB-s\fP option prints only a 1-line summary for each sample interval.
31.PP
28The \fB-v\fP option increases verbosity. 32The \fB-v\fP option increases verbosity.
29.PP 33.PP
30The \fB-M MSR#\fP option dumps the specified MSR, 34The \fB-M MSR#\fP option dumps the specified MSR,
@@ -39,13 +43,14 @@ displays the statistics gathered since it was forked.
39.SH FIELD DESCRIPTIONS 43.SH FIELD DESCRIPTIONS
40.nf 44.nf
41\fBpk\fP processor package number. 45\fBpk\fP processor package number.
42\fBcr\fP processor core number. 46\fBcor\fP processor core number.
43\fBCPU\fP Linux CPU (logical processor) number. 47\fBCPU\fP Linux CPU (logical processor) number.
48Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology.
44\fB%c0\fP percent of the interval that the CPU retired instructions. 49\fB%c0\fP percent of the interval that the CPU retired instructions.
45\fBGHz\fP average clock rate while the CPU was in c0 state. 50\fBGHz\fP average clock rate while the CPU was in c0 state.
46\fBTSC\fP average GHz that the TSC ran during the entire interval. 51\fBTSC\fP average GHz that the TSC ran during the entire interval.
47\fB%c1, %c3, %c6\fP show the percentage residency in hardware core idle states. 52\fB%c1, %c3, %c6, %c7\fP show the percentage residency in hardware core idle states.
48\fB%pc3, %pc6\fP percentage residency in hardware package idle states. 53\fB%pc2, %pc3, %pc6, %pc7\fP percentage residency in hardware package idle states.
49.fi 54.fi
50.PP 55.PP
51.SH EXAMPLE 56.SH EXAMPLE
@@ -53,25 +58,37 @@ Without any parameters, turbostat prints out counters ever 5 seconds.
53(override interval with "-i sec" option, or specify a command 58(override interval with "-i sec" option, or specify a command
54for turbostat to fork). 59for turbostat to fork).
55 60
56The first row of statistics reflect the average for the entire system. 61The first row of statistics is a summary for the entire system.
62Note that the summary is a weighted average.
57Subsequent rows show per-CPU statistics. 63Subsequent rows show per-CPU statistics.
58 64
59.nf 65.nf
60[root@x980]# ./turbostat 66[root@x980]# ./turbostat
61cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 67cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6
62 0.04 1.62 3.38 0.11 0.00 99.85 0.00 95.07 68 0.60 1.63 3.38 2.91 0.00 96.49 0.00 76.64
63 0 0 0.04 1.62 3.38 0.06 0.00 99.90 0.00 95.07 69 0 0 0.59 1.62 3.38 4.51 0.00 94.90 0.00 76.64
64 0 6 0.02 1.62 3.38 0.08 0.00 99.90 0.00 95.07 70 0 6 1.13 1.64 3.38 3.97 0.00 94.90 0.00 76.64
65 1 2 0.10 1.62 3.38 0.29 0.00 99.61 0.00 95.07 71 1 2 0.08 1.62 3.38 0.07 0.00 99.85 0.00 76.64
66 1 8 0.11 1.62 3.38 0.28 0.00 99.61 0.00 95.07 72 1 8 0.03 1.62 3.38 0.12 0.00 99.85 0.00 76.64
67 2 4 0.01 1.62 3.38 0.01 0.00 99.98 0.00 95.07 73 2 4 0.01 1.62 3.38 0.06 0.00 99.93 0.00 76.64
68 2 10 0.01 1.61 3.38 0.02 0.00 99.98 0.00 95.07 74 2 10 0.04 1.62 3.38 0.02 0.00 99.93 0.00 76.64
69 8 1 0.07 1.62 3.38 0.15 0.00 99.78 0.00 95.07 75 8 1 2.85 1.62 3.38 11.71 0.00 85.44 0.00 76.64
70 8 7 0.03 1.62 3.38 0.19 0.00 99.78 0.00 95.07 76 8 7 1.98 1.62 3.38 12.58 0.00 85.44 0.00 76.64
71 9 3 0.01 1.62 3.38 0.02 0.00 99.98 0.00 95.07 77 9 3 0.36 1.62 3.38 0.71 0.00 98.93 0.00 76.64
72 9 9 0.01 1.62 3.38 0.02 0.00 99.98 0.00 95.07 78 9 9 0.09 1.62 3.38 0.98 0.00 98.93 0.00 76.64
73 10 5 0.01 1.62 3.38 0.13 0.00 99.86 0.00 95.07 79 10 5 0.03 1.62 3.38 0.09 0.00 99.87 0.00 76.64
74 10 11 0.08 1.62 3.38 0.05 0.00 99.86 0.00 95.07 80 10 11 0.07 1.62 3.38 0.06 0.00 99.87 0.00 76.64
81.fi
82.SH SUMMARY EXAMPLE
83The "-s" option prints the column headers just once,
84and then the one line system summary for each sample interval.
85
86.nf
87[root@x980]# ./turbostat -s
88 %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6
89 0.61 1.89 3.38 5.95 0.00 93.44 0.00 66.33
90 0.52 1.62 3.38 6.83 0.00 92.65 0.00 61.11
91 0.62 1.92 3.38 5.47 0.00 93.91 0.00 67.31
75.fi 92.fi
76.SH VERBOSE EXAMPLE 93.SH VERBOSE EXAMPLE
77The "-v" option adds verbosity to the output: 94The "-v" option adds verbosity to the output:
@@ -101,33 +118,33 @@ until ^C while the other CPUs are mostly idle:
101 118
102.nf 119.nf
103[root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null 120[root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null
104 121^C
105^Ccr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 122cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6
106 8.49 3.63 3.38 16.23 0.66 74.63 0.00 0.00 123 8.63 3.64 3.38 14.46 0.49 76.42 0.00 0.00
107 0 0 1.22 3.62 3.38 32.18 0.00 66.60 0.00 0.00 124 0 0 0.34 3.36 3.38 99.66 0.00 0.00 0.00 0.00
108 0 6 0.40 3.61 3.38 33.00 0.00 66.60 0.00 0.00 125 0 6 99.96 3.64 3.38 0.04 0.00 0.00 0.00 0.00
109 1 2 0.11 3.14 3.38 0.19 3.95 95.75 0.00 0.00 126 1 2 0.14 3.50 3.38 1.75 2.04 96.07 0.00 0.00
110 1 8 0.05 2.88 3.38 0.25 3.95 95.75 0.00 0.00 127 1 8 0.38 3.57 3.38 1.51 2.04 96.07 0.00 0.00
111 2 4 0.00 3.13 3.38 0.02 0.00 99.98 0.00 0.00 128 2 4 0.01 2.65 3.38 0.06 0.00 99.93 0.00 0.00
112 2 10 0.00 3.09 3.38 0.02 0.00 99.98 0.00 0.00 129 2 10 0.03 2.12 3.38 0.04 0.00 99.93 0.00 0.00
113 8 1 0.04 3.50 3.38 14.43 0.00 85.54 0.00 0.00 130 8 1 0.91 3.59 3.38 35.27 0.92 62.90 0.00 0.00
114 8 7 0.03 2.98 3.38 14.43 0.00 85.54 0.00 0.00 131 8 7 1.61 3.63 3.38 34.57 0.92 62.90 0.00 0.00
115 9 3 0.00 3.16 3.38 100.00 0.00 0.00 0.00 0.00 132 9 3 0.04 3.38 3.38 0.20 0.00 99.76 0.00 0.00
116 9 9 99.93 3.63 3.38 0.06 0.00 0.00 0.00 0.00 133 9 9 0.04 3.29 3.38 0.20 0.00 99.76 0.00 0.00
117 10 5 0.01 2.82 3.38 0.08 0.00 99.91 0.00 0.00 134 10 5 0.03 3.08 3.38 0.12 0.00 99.85 0.00 0.00
118 10 11 0.02 3.36 3.38 0.06 0.00 99.91 0.00 0.00 135 10 11 0.05 3.07 3.38 0.10 0.00 99.85 0.00 0.00
1196.950866 sec 1364.907015 sec
120 137
121.fi 138.fi
122Above the cycle soaker drives cpu9 up 3.6 Ghz turbo limit 139Above the cycle soaker drives cpu6 up 3.6 Ghz turbo limit
123while the other processors are generally in various states of idle. 140while the other processors are generally in various states of idle.
124 141
125Note that cpu3 is an HT sibling sharing core9 142Note that cpu0 is an HT sibling sharing core0
126with cpu9, and thus it is unable to get to an idle state 143with cpu6, and thus it is unable to get to an idle state
127deeper than c1 while cpu9 is busy. 144deeper than c1 while cpu6 is busy.
128 145
129Note that turbostat reports average GHz of 3.61, while 146Note that turbostat reports average GHz of 3.64, while
130the arithmetic average of the GHz column above is 3.24. 147the arithmetic average of the GHz column above is lower.
131This is a weighted average, where the weight is %c0. ie. it is the total number of 148This is a weighted average, where the weight is %c0. ie. it is the total number of
132un-halted cycles elapsed per time divided by the number of CPUs. 149un-halted cycles elapsed per time divided by the number of CPUs.
133.SH NOTES 150.SH NOTES
@@ -167,6 +184,6 @@ http://www.intel.com/products/processor/manuals/
167.SH "SEE ALSO" 184.SH "SEE ALSO"
168msr(4), vmstat(8) 185msr(4), vmstat(8)
169.PP 186.PP
170.SH AUTHORS 187.SH AUTHOR
171.nf 188.nf
172Written by Len Brown <len.brown@intel.com> 189Written by Len Brown <len.brown@intel.com>
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 310d3dd5e547..ab2f682fd44c 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -2,7 +2,7 @@
2 * turbostat -- show CPU frequency and C-state residency 2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors. 3 * on modern Intel turbo-capable processors.
4 * 4 *
5 * Copyright (c) 2010, Intel Corporation. 5 * Copyright (c) 2012 Intel Corporation.
6 * Len Brown <len.brown@intel.com> 6 * Len Brown <len.brown@intel.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
@@ -19,6 +19,7 @@
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20 */ 20 */
21 21
22#define _GNU_SOURCE
22#include <stdio.h> 23#include <stdio.h>
23#include <unistd.h> 24#include <unistd.h>
24#include <sys/types.h> 25#include <sys/types.h>
@@ -32,6 +33,7 @@
32#include <dirent.h> 33#include <dirent.h>
33#include <string.h> 34#include <string.h>
34#include <ctype.h> 35#include <ctype.h>
36#include <sched.h>
35 37
36#define MSR_TSC 0x10 38#define MSR_TSC 0x10
37#define MSR_NEHALEM_PLATFORM_INFO 0xCE 39#define MSR_NEHALEM_PLATFORM_INFO 0xCE
@@ -49,6 +51,7 @@
49char *proc_stat = "/proc/stat"; 51char *proc_stat = "/proc/stat";
50unsigned int interval_sec = 5; /* set with -i interval_sec */ 52unsigned int interval_sec = 5; /* set with -i interval_sec */
51unsigned int verbose; /* set with -v */ 53unsigned int verbose; /* set with -v */
54unsigned int summary_only; /* set with -s */
52unsigned int skip_c0; 55unsigned int skip_c0;
53unsigned int skip_c1; 56unsigned int skip_c1;
54unsigned int do_nhm_cstates; 57unsigned int do_nhm_cstates;
@@ -68,9 +71,10 @@ unsigned int show_cpu;
68int aperf_mperf_unstable; 71int aperf_mperf_unstable;
69int backwards_count; 72int backwards_count;
70char *progname; 73char *progname;
71int need_reinitialize;
72 74
73int num_cpus; 75int num_cpus;
76cpu_set_t *cpu_mask;
77size_t cpu_mask_size;
74 78
75struct counters { 79struct counters {
76 unsigned long long tsc; /* per thread */ 80 unsigned long long tsc; /* per thread */
@@ -99,44 +103,76 @@ struct timeval tv_even;
99struct timeval tv_odd; 103struct timeval tv_odd;
100struct timeval tv_delta; 104struct timeval tv_delta;
101 105
102unsigned long long get_msr(int cpu, off_t offset) 106/*
107 * cpu_mask_init(ncpus)
108 *
109 * allocate and clear cpu_mask
110 * set cpu_mask_size
111 */
112void cpu_mask_init(int ncpus)
113{
114 cpu_mask = CPU_ALLOC(ncpus);
115 if (cpu_mask == NULL) {
116 perror("CPU_ALLOC");
117 exit(3);
118 }
119 cpu_mask_size = CPU_ALLOC_SIZE(ncpus);
120 CPU_ZERO_S(cpu_mask_size, cpu_mask);
121}
122
123void cpu_mask_uninit()
124{
125 CPU_FREE(cpu_mask);
126 cpu_mask = NULL;
127 cpu_mask_size = 0;
128}
129
130int cpu_migrate(int cpu)
131{
132 CPU_ZERO_S(cpu_mask_size, cpu_mask);
133 CPU_SET_S(cpu, cpu_mask_size, cpu_mask);
134 if (sched_setaffinity(0, cpu_mask_size, cpu_mask) == -1)
135 return -1;
136 else
137 return 0;
138}
139
140int get_msr(int cpu, off_t offset, unsigned long long *msr)
103{ 141{
104 ssize_t retval; 142 ssize_t retval;
105 unsigned long long msr;
106 char pathname[32]; 143 char pathname[32];
107 int fd; 144 int fd;
108 145
109 sprintf(pathname, "/dev/cpu/%d/msr", cpu); 146 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
110 fd = open(pathname, O_RDONLY); 147 fd = open(pathname, O_RDONLY);
111 if (fd < 0) { 148 if (fd < 0)
112 perror(pathname); 149 return -1;
113 need_reinitialize = 1;
114 return 0;
115 }
116
117 retval = pread(fd, &msr, sizeof msr, offset);
118 if (retval != sizeof msr) {
119 fprintf(stderr, "cpu%d pread(..., 0x%zx) = %jd\n",
120 cpu, offset, retval);
121 exit(-2);
122 }
123 150
151 retval = pread(fd, msr, sizeof *msr, offset);
124 close(fd); 152 close(fd);
125 return msr; 153
154 if (retval != sizeof *msr)
155 return -1;
156
157 return 0;
126} 158}
127 159
128void print_header(void) 160void print_header(void)
129{ 161{
130 if (show_pkg) 162 if (show_pkg)
131 fprintf(stderr, "pk"); 163 fprintf(stderr, "pk");
164 if (show_pkg)
165 fprintf(stderr, " ");
132 if (show_core) 166 if (show_core)
133 fprintf(stderr, " cr"); 167 fprintf(stderr, "cor");
134 if (show_cpu) 168 if (show_cpu)
135 fprintf(stderr, " CPU"); 169 fprintf(stderr, " CPU");
170 if (show_pkg || show_core || show_cpu)
171 fprintf(stderr, " ");
136 if (do_nhm_cstates) 172 if (do_nhm_cstates)
137 fprintf(stderr, " %%c0 "); 173 fprintf(stderr, " %%c0");
138 if (has_aperf) 174 if (has_aperf)
139 fprintf(stderr, " GHz"); 175 fprintf(stderr, " GHz");
140 fprintf(stderr, " TSC"); 176 fprintf(stderr, " TSC");
141 if (do_nhm_cstates) 177 if (do_nhm_cstates)
142 fprintf(stderr, " %%c1"); 178 fprintf(stderr, " %%c1");
@@ -147,13 +183,13 @@ void print_header(void)
147 if (do_snb_cstates) 183 if (do_snb_cstates)
148 fprintf(stderr, " %%c7"); 184 fprintf(stderr, " %%c7");
149 if (do_snb_cstates) 185 if (do_snb_cstates)
150 fprintf(stderr, " %%pc2"); 186 fprintf(stderr, " %%pc2");
151 if (do_nhm_cstates) 187 if (do_nhm_cstates)
152 fprintf(stderr, " %%pc3"); 188 fprintf(stderr, " %%pc3");
153 if (do_nhm_cstates) 189 if (do_nhm_cstates)
154 fprintf(stderr, " %%pc6"); 190 fprintf(stderr, " %%pc6");
155 if (do_snb_cstates) 191 if (do_snb_cstates)
156 fprintf(stderr, " %%pc7"); 192 fprintf(stderr, " %%pc7");
157 if (extra_msr_offset) 193 if (extra_msr_offset)
158 fprintf(stderr, " MSR 0x%x ", extra_msr_offset); 194 fprintf(stderr, " MSR 0x%x ", extra_msr_offset);
159 195
@@ -187,6 +223,15 @@ void dump_list(struct counters *cnt)
187 dump_cnt(cnt); 223 dump_cnt(cnt);
188} 224}
189 225
226/*
227 * column formatting convention & formats
228 * package: "pk" 2 columns %2d
229 * core: "cor" 3 columns %3d
230 * CPU: "CPU" 3 columns %3d
231 * GHz: "GHz" 3 columns %3.2
232 * TSC: "TSC" 3 columns %3.2
233 * percentage " %pc3" %6.2
234 */
190void print_cnt(struct counters *p) 235void print_cnt(struct counters *p)
191{ 236{
192 double interval_float; 237 double interval_float;
@@ -196,39 +241,45 @@ void print_cnt(struct counters *p)
196 /* topology columns, print blanks on 1st (average) line */ 241 /* topology columns, print blanks on 1st (average) line */
197 if (p == cnt_average) { 242 if (p == cnt_average) {
198 if (show_pkg) 243 if (show_pkg)
244 fprintf(stderr, " ");
245 if (show_pkg && show_core)
199 fprintf(stderr, " "); 246 fprintf(stderr, " ");
200 if (show_core) 247 if (show_core)
201 fprintf(stderr, " "); 248 fprintf(stderr, " ");
202 if (show_cpu) 249 if (show_cpu)
203 fprintf(stderr, " "); 250 fprintf(stderr, " " " ");
204 } else { 251 } else {
205 if (show_pkg) 252 if (show_pkg)
206 fprintf(stderr, "%d", p->pkg); 253 fprintf(stderr, "%2d", p->pkg);
254 if (show_pkg && show_core)
255 fprintf(stderr, " ");
207 if (show_core) 256 if (show_core)
208 fprintf(stderr, "%4d", p->core); 257 fprintf(stderr, "%3d", p->core);
209 if (show_cpu) 258 if (show_cpu)
210 fprintf(stderr, "%4d", p->cpu); 259 fprintf(stderr, " %3d", p->cpu);
211 } 260 }
212 261
213 /* %c0 */ 262 /* %c0 */
214 if (do_nhm_cstates) { 263 if (do_nhm_cstates) {
264 if (show_pkg || show_core || show_cpu)
265 fprintf(stderr, " ");
215 if (!skip_c0) 266 if (!skip_c0)
216 fprintf(stderr, "%7.2f", 100.0 * p->mperf/p->tsc); 267 fprintf(stderr, "%6.2f", 100.0 * p->mperf/p->tsc);
217 else 268 else
218 fprintf(stderr, " ****"); 269 fprintf(stderr, " ****");
219 } 270 }
220 271
221 /* GHz */ 272 /* GHz */
222 if (has_aperf) { 273 if (has_aperf) {
223 if (!aperf_mperf_unstable) { 274 if (!aperf_mperf_unstable) {
224 fprintf(stderr, "%5.2f", 275 fprintf(stderr, " %3.2f",
225 1.0 * p->tsc / units * p->aperf / 276 1.0 * p->tsc / units * p->aperf /
226 p->mperf / interval_float); 277 p->mperf / interval_float);
227 } else { 278 } else {
228 if (p->aperf > p->tsc || p->mperf > p->tsc) { 279 if (p->aperf > p->tsc || p->mperf > p->tsc) {
229 fprintf(stderr, " ****"); 280 fprintf(stderr, " ***");
230 } else { 281 } else {
231 fprintf(stderr, "%4.1f*", 282 fprintf(stderr, "%3.1f*",
232 1.0 * p->tsc / 283 1.0 * p->tsc /
233 units * p->aperf / 284 units * p->aperf /
234 p->mperf / interval_float); 285 p->mperf / interval_float);
@@ -241,7 +292,7 @@ void print_cnt(struct counters *p)
241 292
242 if (do_nhm_cstates) { 293 if (do_nhm_cstates) {
243 if (!skip_c1) 294 if (!skip_c1)
244 fprintf(stderr, "%7.2f", 100.0 * p->c1/p->tsc); 295 fprintf(stderr, " %6.2f", 100.0 * p->c1/p->tsc);
245 else 296 else
246 fprintf(stderr, " ****"); 297 fprintf(stderr, " ****");
247 } 298 }
@@ -252,13 +303,13 @@ void print_cnt(struct counters *p)
252 if (do_snb_cstates) 303 if (do_snb_cstates)
253 fprintf(stderr, " %6.2f", 100.0 * p->c7/p->tsc); 304 fprintf(stderr, " %6.2f", 100.0 * p->c7/p->tsc);
254 if (do_snb_cstates) 305 if (do_snb_cstates)
255 fprintf(stderr, " %5.2f", 100.0 * p->pc2/p->tsc); 306 fprintf(stderr, " %6.2f", 100.0 * p->pc2/p->tsc);
256 if (do_nhm_cstates) 307 if (do_nhm_cstates)
257 fprintf(stderr, " %5.2f", 100.0 * p->pc3/p->tsc); 308 fprintf(stderr, " %6.2f", 100.0 * p->pc3/p->tsc);
258 if (do_nhm_cstates) 309 if (do_nhm_cstates)
259 fprintf(stderr, " %5.2f", 100.0 * p->pc6/p->tsc); 310 fprintf(stderr, " %6.2f", 100.0 * p->pc6/p->tsc);
260 if (do_snb_cstates) 311 if (do_snb_cstates)
261 fprintf(stderr, " %5.2f", 100.0 * p->pc7/p->tsc); 312 fprintf(stderr, " %6.2f", 100.0 * p->pc7/p->tsc);
262 if (extra_msr_offset) 313 if (extra_msr_offset)
263 fprintf(stderr, " 0x%016llx", p->extra_msr); 314 fprintf(stderr, " 0x%016llx", p->extra_msr);
264 putc('\n', stderr); 315 putc('\n', stderr);
@@ -267,12 +318,20 @@ void print_cnt(struct counters *p)
267void print_counters(struct counters *counters) 318void print_counters(struct counters *counters)
268{ 319{
269 struct counters *cnt; 320 struct counters *cnt;
321 static int printed;
322
270 323
271 print_header(); 324 if (!printed || !summary_only)
325 print_header();
272 326
273 if (num_cpus > 1) 327 if (num_cpus > 1)
274 print_cnt(cnt_average); 328 print_cnt(cnt_average);
275 329
330 printed = 1;
331
332 if (summary_only)
333 return;
334
276 for (cnt = counters; cnt != NULL; cnt = cnt->next) 335 for (cnt = counters; cnt != NULL; cnt = cnt->next)
277 print_cnt(cnt); 336 print_cnt(cnt);
278 337
@@ -440,31 +499,51 @@ void compute_average(struct counters *delta, struct counters *avg)
440 free(sum); 499 free(sum);
441} 500}
442 501
443void get_counters(struct counters *cnt) 502int get_counters(struct counters *cnt)
444{ 503{
445 for ( ; cnt; cnt = cnt->next) { 504 for ( ; cnt; cnt = cnt->next) {
446 cnt->tsc = get_msr(cnt->cpu, MSR_TSC); 505
447 if (do_nhm_cstates) 506 if (cpu_migrate(cnt->cpu))
448 cnt->c3 = get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY); 507 return -1;
449 if (do_nhm_cstates) 508
450 cnt->c6 = get_msr(cnt->cpu, MSR_CORE_C6_RESIDENCY); 509 if (get_msr(cnt->cpu, MSR_TSC, &cnt->tsc))
451 if (do_snb_cstates) 510 return -1;
452 cnt->c7 = get_msr(cnt->cpu, MSR_CORE_C7_RESIDENCY); 511
453 if (has_aperf) 512 if (has_aperf) {
454 cnt->aperf = get_msr(cnt->cpu, MSR_APERF); 513 if (get_msr(cnt->cpu, MSR_APERF, &cnt->aperf))
455 if (has_aperf) 514 return -1;
456 cnt->mperf = get_msr(cnt->cpu, MSR_MPERF); 515 if (get_msr(cnt->cpu, MSR_MPERF, &cnt->mperf))
457 if (do_snb_cstates) 516 return -1;
458 cnt->pc2 = get_msr(cnt->cpu, MSR_PKG_C2_RESIDENCY); 517 }
459 if (do_nhm_cstates) 518
460 cnt->pc3 = get_msr(cnt->cpu, MSR_PKG_C3_RESIDENCY); 519 if (do_nhm_cstates) {
461 if (do_nhm_cstates) 520 if (get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY, &cnt->c3))
462 cnt->pc6 = get_msr(cnt->cpu, MSR_PKG_C6_RESIDENCY); 521 return -1;
522 if (get_msr(cnt->cpu, MSR_CORE_C6_RESIDENCY, &cnt->c6))
523 return -1;
524 }
525
463 if (do_snb_cstates) 526 if (do_snb_cstates)
464 cnt->pc7 = get_msr(cnt->cpu, MSR_PKG_C7_RESIDENCY); 527 if (get_msr(cnt->cpu, MSR_CORE_C7_RESIDENCY, &cnt->c7))
528 return -1;
529
530 if (do_nhm_cstates) {
531 if (get_msr(cnt->cpu, MSR_PKG_C3_RESIDENCY, &cnt->pc3))
532 return -1;
533 if (get_msr(cnt->cpu, MSR_PKG_C6_RESIDENCY, &cnt->pc6))
534 return -1;
535 }
536 if (do_snb_cstates) {
537 if (get_msr(cnt->cpu, MSR_PKG_C2_RESIDENCY, &cnt->pc2))
538 return -1;
539 if (get_msr(cnt->cpu, MSR_PKG_C7_RESIDENCY, &cnt->pc7))
540 return -1;
541 }
465 if (extra_msr_offset) 542 if (extra_msr_offset)
466 cnt->extra_msr = get_msr(cnt->cpu, extra_msr_offset); 543 if (get_msr(cnt->cpu, extra_msr_offset, &cnt->extra_msr))
544 return -1;
467 } 545 }
546 return 0;
468} 547}
469 548
470void print_nehalem_info(void) 549void print_nehalem_info(void)
@@ -475,7 +554,7 @@ void print_nehalem_info(void)
475 if (!do_nehalem_platform_info) 554 if (!do_nehalem_platform_info)
476 return; 555 return;
477 556
478 msr = get_msr(0, MSR_NEHALEM_PLATFORM_INFO); 557 get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr);
479 558
480 ratio = (msr >> 40) & 0xFF; 559 ratio = (msr >> 40) & 0xFF;
481 fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n", 560 fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n",
@@ -491,7 +570,7 @@ void print_nehalem_info(void)
491 if (!do_nehalem_turbo_ratio_limit) 570 if (!do_nehalem_turbo_ratio_limit)
492 return; 571 return;
493 572
494 msr = get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT); 573 get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr);
495 574
496 ratio = (msr >> 24) & 0xFF; 575 ratio = (msr >> 24) & 0xFF;
497 if (ratio) 576 if (ratio)
@@ -557,7 +636,8 @@ void insert_counters(struct counters **list,
557 return; 636 return;
558 } 637 }
559 638
560 show_cpu = 1; /* there is more than one CPU */ 639 if (!summary_only)
640 show_cpu = 1; /* there is more than one CPU */
561 641
562 /* 642 /*
563 * insert on front of list. 643 * insert on front of list.
@@ -575,13 +655,15 @@ void insert_counters(struct counters **list,
575 655
576 while (prev->next && (prev->next->pkg < new->pkg)) { 656 while (prev->next && (prev->next->pkg < new->pkg)) {
577 prev = prev->next; 657 prev = prev->next;
578 show_pkg = 1; /* there is more than 1 package */ 658 if (!summary_only)
659 show_pkg = 1; /* there is more than 1 package */
579 } 660 }
580 661
581 while (prev->next && (prev->next->pkg == new->pkg) 662 while (prev->next && (prev->next->pkg == new->pkg)
582 && (prev->next->core < new->core)) { 663 && (prev->next->core < new->core)) {
583 prev = prev->next; 664 prev = prev->next;
584 show_core = 1; /* there is more than 1 core */ 665 if (!summary_only)
666 show_core = 1; /* there is more than 1 core */
585 } 667 }
586 668
587 while (prev->next && (prev->next->pkg == new->pkg) 669 while (prev->next && (prev->next->pkg == new->pkg)
@@ -681,7 +763,7 @@ int get_core_id(int cpu)
681} 763}
682 764
683/* 765/*
684 * run func(index, cpu) on every cpu in /proc/stat 766 * run func(pkg, core, cpu) on every cpu in /proc/stat
685 */ 767 */
686 768
687int for_all_cpus(void (func)(int, int, int)) 769int for_all_cpus(void (func)(int, int, int))
@@ -717,18 +799,18 @@ int for_all_cpus(void (func)(int, int, int))
717 799
718void re_initialize(void) 800void re_initialize(void)
719{ 801{
720 printf("turbostat: topology changed, re-initializing.\n");
721 free_all_counters(); 802 free_all_counters();
722 num_cpus = for_all_cpus(alloc_new_counters); 803 num_cpus = for_all_cpus(alloc_new_counters);
723 need_reinitialize = 0; 804 cpu_mask_uninit();
724 printf("num_cpus is now %d\n", num_cpus); 805 cpu_mask_init(num_cpus);
806 printf("turbostat: re-initialized with num_cpus %d\n", num_cpus);
725} 807}
726 808
727void dummy(int pkg, int core, int cpu) { return; } 809void dummy(int pkg, int core, int cpu) { return; }
728/* 810/*
729 * check to see if a cpu came on-line 811 * check to see if a cpu came on-line
730 */ 812 */
731void verify_num_cpus(void) 813int verify_num_cpus(void)
732{ 814{
733 int new_num_cpus; 815 int new_num_cpus;
734 816
@@ -738,8 +820,9 @@ void verify_num_cpus(void)
738 if (verbose) 820 if (verbose)
739 printf("num_cpus was %d, is now %d\n", 821 printf("num_cpus was %d, is now %d\n",
740 num_cpus, new_num_cpus); 822 num_cpus, new_num_cpus);
741 need_reinitialize = 1; 823 return -1;
742 } 824 }
825 return 0;
743} 826}
744 827
745void turbostat_loop() 828void turbostat_loop()
@@ -749,25 +832,25 @@ restart:
749 gettimeofday(&tv_even, (struct timezone *)NULL); 832 gettimeofday(&tv_even, (struct timezone *)NULL);
750 833
751 while (1) { 834 while (1) {
752 verify_num_cpus(); 835 if (verify_num_cpus()) {
753 if (need_reinitialize) {
754 re_initialize(); 836 re_initialize();
755 goto restart; 837 goto restart;
756 } 838 }
757 sleep(interval_sec); 839 sleep(interval_sec);
758 get_counters(cnt_odd); 840 if (get_counters(cnt_odd)) {
841 re_initialize();
842 goto restart;
843 }
759 gettimeofday(&tv_odd, (struct timezone *)NULL); 844 gettimeofday(&tv_odd, (struct timezone *)NULL);
760
761 compute_delta(cnt_odd, cnt_even, cnt_delta); 845 compute_delta(cnt_odd, cnt_even, cnt_delta);
762 timersub(&tv_odd, &tv_even, &tv_delta); 846 timersub(&tv_odd, &tv_even, &tv_delta);
763 compute_average(cnt_delta, cnt_average); 847 compute_average(cnt_delta, cnt_average);
764 print_counters(cnt_delta); 848 print_counters(cnt_delta);
765 if (need_reinitialize) { 849 sleep(interval_sec);
850 if (get_counters(cnt_even)) {
766 re_initialize(); 851 re_initialize();
767 goto restart; 852 goto restart;
768 } 853 }
769 sleep(interval_sec);
770 get_counters(cnt_even);
771 gettimeofday(&tv_even, (struct timezone *)NULL); 854 gettimeofday(&tv_even, (struct timezone *)NULL);
772 compute_delta(cnt_even, cnt_odd, cnt_delta); 855 compute_delta(cnt_even, cnt_odd, cnt_delta);
773 timersub(&tv_even, &tv_odd, &tv_delta); 856 timersub(&tv_even, &tv_odd, &tv_delta);
@@ -953,6 +1036,7 @@ void turbostat_init()
953 check_super_user(); 1036 check_super_user();
954 1037
955 num_cpus = for_all_cpus(alloc_new_counters); 1038 num_cpus = for_all_cpus(alloc_new_counters);
1039 cpu_mask_init(num_cpus);
956 1040
957 if (verbose) 1041 if (verbose)
958 print_nehalem_info(); 1042 print_nehalem_info();
@@ -1005,8 +1089,11 @@ void cmdline(int argc, char **argv)
1005 1089
1006 progname = argv[0]; 1090 progname = argv[0];
1007 1091
1008 while ((opt = getopt(argc, argv, "+vi:M:")) != -1) { 1092 while ((opt = getopt(argc, argv, "+svi:M:")) != -1) {
1009 switch (opt) { 1093 switch (opt) {
1094 case 's':
1095 summary_only++;
1096 break;
1010 case 'v': 1097 case 'v':
1011 verbose++; 1098 verbose++;
1012 break; 1099 break;