diff options
103 files changed, 3192 insertions, 1555 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 @@ | |||
1 | What: /sys/firmware/acpi/bgrt/ | ||
2 | Date: January 2012 | ||
3 | Contact: Matthew Garrett <mjg@redhat.com> | ||
4 | Description: | ||
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 | |||
1 | What: /sys/firmware/acpi/interrupts/ | 21 | What: /sys/firmware/acpi/interrupts/ |
2 | Date: February 2008 | 22 | Date: February 2008 |
3 | Contact: Len Brown <lenb@kernel.org> | 23 | Contact: Len Brown <lenb@kernel.org> |
diff --git a/Documentation/acpi/apei/einj.txt b/Documentation/acpi/apei/einj.txt index e7cc36397217..e20b6daaced4 100644 --- a/Documentation/acpi/apei/einj.txt +++ b/Documentation/acpi/apei/einj.txt | |||
@@ -53,6 +53,14 @@ directory apei/einj. The following files are provided. | |||
53 | This file is used to set the second error parameter value. Effect of | 53 | This file is used to set the second error parameter value. Effect of |
54 | parameter depends on error_type specified. | 54 | parameter depends on error_type specified. |
55 | 55 | ||
56 | - notrigger | ||
57 | The EINJ mechanism is a two step process. First inject the error, then | ||
58 | perform some actions to trigger it. Setting "notrigger" to 1 skips the | ||
59 | trigger phase, which *may* allow the user to cause the error in some other | ||
60 | context by a simple access to the cpu, memory location, or device that is | ||
61 | the target of the error injection. Whether this actually works depends | ||
62 | on what operations the BIOS actually includes in the trigger phase. | ||
63 | |||
56 | BIOS versions based in the ACPI 4.0 specification have limited options | 64 | BIOS versions based in the ACPI 4.0 specification have limited options |
57 | to control where the errors are injected. Your BIOS may support an | 65 | to control where the errors are injected. Your BIOS may support an |
58 | extension (enabled with the param_extension=1 module parameter, or | 66 | extension (enabled with the param_extension=1 module parameter, or |
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: |
37 | total 0 | 37 | total 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: |
46 | total 0 | 47 | total 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: |
55 | total 0 | 57 | total 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: |
64 | total 0 | 67 | total 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 | ||
5 | extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, | ||
6 | struct cpuidle_driver *drv, int index); | ||
7 | #else | ||
8 | static 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 8269d8928742..7b787d642af4 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -23,7 +23,7 @@ obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o | |||
23 | 23 | ||
24 | obj-$(CONFIG_LEDS) += leds.o | 24 | obj-$(CONFIG_LEDS) += leds.o |
25 | obj-$(CONFIG_OC_ETM) += etm.o | 25 | obj-$(CONFIG_OC_ETM) += etm.o |
26 | 26 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | |
27 | obj-$(CONFIG_ISA_DMA_API) += dma.o | 27 | obj-$(CONFIG_ISA_DMA_API) += dma.o |
28 | obj-$(CONFIG_FIQ) += fiq.o fiqasm.o | 28 | obj-$(CONFIG_FIQ) += fiq.o fiqasm.o |
29 | obj-$(CONFIG_MODULES) += armksyms.o module.o | 29 | obj-$(CONFIG_MODULES) += armksyms.o module.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 | |||
15 | int 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 555d956b3a57..ece1f9aefb47 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,61 +28,39 @@ | |||
27 | 28 | ||
28 | static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); | 29 | static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); |
29 | 30 | ||
30 | static 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 */ |
36 | static int at91_enter_idle(struct cpuidle_device *dev, | 32 | static 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; | 36 | at91_standby(); |
41 | int idle_time; | ||
42 | |||
43 | local_irq_disable(); | ||
44 | do_gettimeofday(&before); | ||
45 | if (index == 0) | ||
46 | /* Wait for interrupt state */ | ||
47 | cpu_do_idle(); | ||
48 | else if (index == 1) | ||
49 | at91_standby(); | ||
50 | 37 | ||
51 | do_gettimeofday(&after); | ||
52 | local_irq_enable(); | ||
53 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | ||
54 | (after.tv_usec - before.tv_usec); | ||
55 | |||
56 | dev->last_residency = idle_time; | ||
57 | return index; | 38 | return index; |
58 | } | 39 | } |
59 | 40 | ||
41 | static struct cpuidle_driver at91_idle_driver = { | ||
42 | .name = "at91_idle", | ||
43 | .owner = THIS_MODULE, | ||
44 | .en_core_tk_irqen = 1, | ||
45 | .states[0] = ARM_CPUIDLE_WFI_STATE, | ||
46 | .states[1] = { | ||
47 | .enter = at91_enter_idle, | ||
48 | .exit_latency = 10, | ||
49 | .target_residency = 100000, | ||
50 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
51 | .name = "RAM_SR", | ||
52 | .desc = "WFI and DDR Self Refresh", | ||
53 | }, | ||
54 | .state_count = AT91_MAX_STATES, | ||
55 | }; | ||
56 | |||
60 | /* Initialize CPU idle by registering the idle states */ | 57 | /* Initialize CPU idle by registering the idle states */ |
61 | static int at91_init_cpuidle(void) | 58 | static int at91_init_cpuidle(void) |
62 | { | 59 | { |
63 | struct cpuidle_device *device; | 60 | struct cpuidle_device *device; |
64 | struct cpuidle_driver *driver = &at91_idle_driver; | ||
65 | 61 | ||
66 | device = &per_cpu(at91_cpuidle_device, smp_processor_id()); | 62 | device = &per_cpu(at91_cpuidle_device, smp_processor_id()); |
67 | device->state_count = AT91_MAX_STATES; | 63 | device->state_count = AT91_MAX_STATES; |
68 | driver->state_count = AT91_MAX_STATES; | ||
69 | |||
70 | /* Wait for interrupt state */ | ||
71 | driver->states[0].enter = at91_enter_idle; | ||
72 | driver->states[0].exit_latency = 1; | ||
73 | driver->states[0].target_residency = 10000; | ||
74 | driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; | ||
75 | strcpy(driver->states[0].name, "WFI"); | ||
76 | strcpy(driver->states[0].desc, "Wait for interrupt"); | ||
77 | |||
78 | /* Wait for interrupt and RAM self refresh state */ | ||
79 | driver->states[1].enter = at91_enter_idle; | ||
80 | driver->states[1].exit_latency = 10; | ||
81 | driver->states[1].target_residency = 10000; | ||
82 | driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; | ||
83 | strcpy(driver->states[1].name, "RAM_SR"); | ||
84 | strcpy(driver->states[1].desc, "WFI and RAM Self Refresh"); | ||
85 | 64 | ||
86 | cpuidle_register_driver(&at91_idle_driver); | 65 | cpuidle_register_driver(&at91_idle_driver); |
87 | 66 | ||
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 */ | ||
35 | static 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 | ||
36 | static struct cpuidle_driver davinci_idle_driver = { | 57 | static 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 | ||
41 | static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); | 73 | static 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 */ | ||
81 | static 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 | |||
110 | static int __init davinci_cpuidle_probe(struct platform_device *pdev) | 112 | static 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 | ||
27 | static struct cpuidle_driver kirkwood_idle_driver = { | ||
28 | .name = "kirkwood_idle", | ||
29 | .owner = THIS_MODULE, | ||
30 | }; | ||
31 | |||
32 | static 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 */ |
35 | static int kirkwood_enter_idle(struct cpuidle_device *dev, | 29 | static 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 | ||
39 | static 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 | |||
55 | static 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 */ |
70 | static int kirkwood_init_cpuidle(void) | 58 | static 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 | /** | 90 | static 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 | */ | ||
99 | static 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 | ||
150 | return_sleep_time: | 135 | return_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 | */ | ||
151 | static 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 | ||
146 | DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); | 130 | DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); |
147 | 131 | ||
148 | struct cpuidle_driver omap4_idle_driver = { | 132 | struct 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 | ||
153 | static inline void _fill_cstate(struct cpuidle_driver *drv, | 138 | static 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 21b09b6455e4..7e6559105d40 100644 --- a/arch/arm/mach-shmobile/cpuidle.c +++ b/arch/arm/mach-shmobile/cpuidle.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/suspend.h> | 13 | #include <linux/suspend.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <asm/cpuidle.h> | ||
16 | #include <asm/io.h> | 17 | #include <asm/io.h> |
17 | 18 | ||
18 | static void shmobile_enter_wfi(void) | 19 | static void shmobile_enter_wfi(void) |
@@ -28,37 +29,19 @@ static int shmobile_cpuidle_enter(struct cpuidle_device *dev, | |||
28 | struct cpuidle_driver *drv, | 29 | struct cpuidle_driver *drv, |
29 | int index) | 30 | int index) |
30 | { | 31 | { |
31 | ktime_t before, after; | ||
32 | |||
33 | before = ktime_get(); | ||
34 | |||
35 | local_irq_disable(); | ||
36 | local_fiq_disable(); | ||
37 | |||
38 | shmobile_cpuidle_modes[index](); | 32 | shmobile_cpuidle_modes[index](); |
39 | 33 | ||
40 | local_irq_enable(); | ||
41 | local_fiq_enable(); | ||
42 | |||
43 | after = ktime_get(); | ||
44 | dev->last_residency = ktime_to_ns(ktime_sub(after, before)) >> 10; | ||
45 | |||
46 | return index; | 34 | return index; |
47 | } | 35 | } |
48 | 36 | ||
49 | static struct cpuidle_device shmobile_cpuidle_dev; | 37 | static struct cpuidle_device shmobile_cpuidle_dev; |
50 | static struct cpuidle_driver shmobile_cpuidle_driver = { | 38 | static struct cpuidle_driver shmobile_cpuidle_driver = { |
51 | .name = "shmobile_cpuidle", | 39 | .name = "shmobile_cpuidle", |
52 | .owner = THIS_MODULE, | 40 | .owner = THIS_MODULE, |
53 | .states[0] = { | 41 | .en_core_tk_irqen = 1, |
54 | .name = "C1", | 42 | .states[0] = ARM_CPUIDLE_WFI_STATE, |
55 | .desc = "WFI", | 43 | .safe_state_index = 0, /* C1 */ |
56 | .exit_latency = 1, | 44 | .state_count = 1, |
57 | .target_residency = 1 * 2, | ||
58 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
59 | }, | ||
60 | .safe_state_index = 0, /* C1 */ | ||
61 | .state_count = 1, | ||
62 | }; | 45 | }; |
63 | 46 | ||
64 | void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); | 47 | void (*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 | ||
59 | static struct cpuidle_device cpuidle_dev; | 54 | static struct cpuidle_device cpuidle_dev; |
60 | static struct cpuidle_driver cpuidle_driver = { | 55 | static 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 | ||
65 | void sh_mobile_setup_cpuidle(void) | 61 | void sh_mobile_setup_cpuidle(void) |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 0f42c2f44311..a415b1f44365 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 ce13315d48fb..6e1e406038c2 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> |
@@ -1404,7 +1405,8 @@ void native_play_dead(void) | |||
1404 | tboot_shutdown(TB_SHUTDOWN_WFS); | 1405 | tboot_shutdown(TB_SHUTDOWN_WFS); |
1405 | 1406 | ||
1406 | mwait_play_dead(); /* Only returns on failure */ | 1407 | mwait_play_dead(); /* Only returns on failure */ |
1407 | hlt_play_dead(); | 1408 | if (cpuidle_play_dead()) |
1409 | hlt_play_dead(); | ||
1408 | } | 1410 | } |
1409 | 1411 | ||
1410 | #else /* ... !CONFIG_HOTPLUG_CPU */ | 1412 | #else /* ... !CONFIG_HOTPLUG_CPU */ |
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index e2410e27f97e..6410744ac5cb 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c | |||
@@ -272,7 +272,7 @@ static void tboot_copy_fadt(const struct acpi_table_fadt *fadt) | |||
272 | offsetof(struct acpi_table_facs, firmware_waking_vector); | 272 | offsetof(struct acpi_table_facs, firmware_waking_vector); |
273 | } | 273 | } |
274 | 274 | ||
275 | void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) | 275 | static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) |
276 | { | 276 | { |
277 | static u32 acpi_shutdown_map[ACPI_S_STATE_COUNT] = { | 277 | static u32 acpi_shutdown_map[ACPI_S_STATE_COUNT] = { |
278 | /* S0,1,2: */ -1, -1, -1, | 278 | /* S0,1,2: */ -1, -1, -1, |
@@ -281,7 +281,7 @@ void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) | |||
281 | /* S5: */ TB_SHUTDOWN_S5 }; | 281 | /* S5: */ TB_SHUTDOWN_S5 }; |
282 | 282 | ||
283 | if (!tboot_enabled()) | 283 | if (!tboot_enabled()) |
284 | return; | 284 | return 0; |
285 | 285 | ||
286 | tboot_copy_fadt(&acpi_gbl_FADT); | 286 | tboot_copy_fadt(&acpi_gbl_FADT); |
287 | tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control; | 287 | tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control; |
@@ -292,10 +292,11 @@ void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) | |||
292 | if (sleep_state >= ACPI_S_STATE_COUNT || | 292 | if (sleep_state >= ACPI_S_STATE_COUNT || |
293 | acpi_shutdown_map[sleep_state] == -1) { | 293 | acpi_shutdown_map[sleep_state] == -1) { |
294 | pr_warning("unsupported sleep state 0x%x\n", sleep_state); | 294 | pr_warning("unsupported sleep state 0x%x\n", sleep_state); |
295 | return; | 295 | return -1; |
296 | } | 296 | } |
297 | 297 | ||
298 | tboot_shutdown(acpi_shutdown_map[sleep_state]); | 298 | tboot_shutdown(acpi_shutdown_map[sleep_state]); |
299 | return 0; | ||
299 | } | 300 | } |
300 | 301 | ||
301 | static atomic_t ap_wfs_count; | 302 | static atomic_t ap_wfs_count; |
@@ -345,6 +346,8 @@ static __init int tboot_late_init(void) | |||
345 | 346 | ||
346 | atomic_set(&ap_wfs_count, 0); | 347 | atomic_set(&ap_wfs_count, 0); |
347 | register_hotcpu_notifier(&tboot_cpu_notifier); | 348 | register_hotcpu_notifier(&tboot_cpu_notifier); |
349 | |||
350 | acpi_os_set_prepare_sleep(&tboot_sleep); | ||
348 | return 0; | 351 | return 0; |
349 | } | 352 | } |
350 | 353 | ||
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 | ||
387 | config 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 | |||
387 | source "drivers/acpi/apei/Kconfig" | 396 | source "drivers/acpi/apei/Kconfig" |
388 | 397 | ||
389 | endif # ACPI | 398 | endif # 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 | |||
62 | obj-$(CONFIG_ACPI_HED) += hed.o | 62 | obj-$(CONFIG_ACPI_HED) += hed.o |
63 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o | 63 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o |
64 | obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o | 64 | obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o |
65 | obj-$(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 |
67 | processor-y := processor_driver.o processor_throttling.o | 68 | processor-y := processor_driver.o processor_throttling.o |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 0ca208b6dcf0..793b8cc8e256 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -68,12 +68,14 @@ acpi-y += \ | |||
68 | 68 | ||
69 | acpi-y += \ | 69 | acpi-y += \ |
70 | hwacpi.o \ | 70 | hwacpi.o \ |
71 | hwesleep.o \ | ||
71 | hwgpe.o \ | 72 | hwgpe.o \ |
72 | hwpci.o \ | 73 | hwpci.o \ |
73 | hwregs.o \ | 74 | hwregs.o \ |
74 | hwsleep.o \ | 75 | hwsleep.o \ |
75 | hwvalid.o \ | 76 | hwvalid.o \ |
76 | hwxface.o | 77 | hwxface.o \ |
78 | hwxfsleep.o | ||
77 | 79 | ||
78 | acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o | 80 | acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o |
79 | 81 | ||
diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index a44bd424f9f4..8a7d51bfb3b3 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h | |||
@@ -51,7 +51,6 @@ | |||
51 | * | 51 | * |
52 | * Note: The order of these include files is important. | 52 | * Note: The order of these include files is important. |
53 | */ | 53 | */ |
54 | #include "acconfig.h" /* Global configuration constants */ | ||
55 | #include "acmacros.h" /* C macros */ | 54 | #include "acmacros.h" /* C macros */ |
56 | #include "aclocal.h" /* Internal data types */ | 55 | #include "aclocal.h" /* Internal data types */ |
57 | #include "acobject.h" /* ACPI internal object */ | 56 | #include "acobject.h" /* ACPI internal object */ |
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index deaa81979561..5e8abb07724f 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -111,7 +111,7 @@ acpi_status acpi_db_find_name_in_namespace(char *name_arg); | |||
111 | 111 | ||
112 | void acpi_db_set_scope(char *name); | 112 | void acpi_db_set_scope(char *name); |
113 | 113 | ||
114 | acpi_status acpi_db_sleep(char *object_arg); | 114 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_db_sleep(char *object_arg)) |
115 | 115 | ||
116 | void acpi_db_find_references(char *object_arg); | 116 | void acpi_db_find_references(char *object_arg); |
117 | 117 | ||
@@ -119,11 +119,13 @@ void acpi_db_display_locks(void); | |||
119 | 119 | ||
120 | void acpi_db_display_resources(char *object_arg); | 120 | void acpi_db_display_resources(char *object_arg); |
121 | 121 | ||
122 | void acpi_db_display_gpes(void); | 122 | ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_display_gpes(void)) |
123 | 123 | ||
124 | void acpi_db_check_integrity(void); | 124 | void acpi_db_check_integrity(void); |
125 | 125 | ||
126 | void acpi_db_generate_gpe(char *gpe_arg, char *block_arg); | 126 | ACPI_HW_DEPENDENT_RETURN_VOID(void |
127 | acpi_db_generate_gpe(char *gpe_arg, | ||
128 | char *block_arg)) | ||
127 | 129 | ||
128 | void acpi_db_check_predefined_names(void); | 130 | void acpi_db_check_predefined_names(void); |
129 | 131 | ||
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index c53caa521a30..d700f63e4701 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -69,11 +69,10 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node, | |||
69 | */ | 69 | */ |
70 | acpi_status acpi_ev_init_global_lock_handler(void); | 70 | acpi_status acpi_ev_init_global_lock_handler(void); |
71 | 71 | ||
72 | acpi_status acpi_ev_acquire_global_lock(u16 timeout); | 72 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status |
73 | 73 | acpi_ev_acquire_global_lock(u16 timeout)) | |
74 | acpi_status acpi_ev_release_global_lock(void); | 74 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_ev_release_global_lock(void)) |
75 | 75 | acpi_status acpi_ev_remove_global_lock_handler(void); | |
76 | acpi_status acpi_ev_remove_global_lock_handler(void); | ||
77 | 76 | ||
78 | /* | 77 | /* |
79 | * evgpe - Low-level GPE support | 78 | * evgpe - Low-level GPE support |
@@ -114,7 +113,9 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
114 | struct acpi_gpe_block_info *gpe_block, | 113 | struct acpi_gpe_block_info *gpe_block, |
115 | void *context); | 114 | void *context); |
116 | 115 | ||
117 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); | 116 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status |
117 | acpi_ev_delete_gpe_block(struct acpi_gpe_block_info | ||
118 | *gpe_block)) | ||
118 | 119 | ||
119 | u32 | 120 | u32 |
120 | acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | 121 | acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, |
@@ -126,9 +127,10 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
126 | */ | 127 | */ |
127 | acpi_status acpi_ev_gpe_initialize(void); | 128 | acpi_status acpi_ev_gpe_initialize(void); |
128 | 129 | ||
129 | void acpi_ev_update_gpes(acpi_owner_id table_owner_id); | 130 | ACPI_HW_DEPENDENT_RETURN_VOID(void |
131 | acpi_ev_update_gpes(acpi_owner_id table_owner_id)) | ||
130 | 132 | ||
131 | acpi_status | 133 | acpi_status |
132 | acpi_ev_match_gpe_method(acpi_handle obj_handle, | 134 | acpi_ev_match_gpe_method(acpi_handle obj_handle, |
133 | u32 level, void *context, void **return_value); | 135 | u32 level, void *context, void **return_value); |
134 | 136 | ||
@@ -237,6 +239,5 @@ acpi_status acpi_ev_remove_sci_handler(void); | |||
237 | 239 | ||
238 | u32 acpi_ev_initialize_sCI(u32 program_sCI); | 240 | u32 acpi_ev_initialize_sCI(u32 program_sCI); |
239 | 241 | ||
240 | void acpi_ev_terminate(void); | 242 | ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_ev_terminate(void)) |
241 | |||
242 | #endif /* __ACEVENTS_H__ */ | 243 | #endif /* __ACEVENTS_H__ */ |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 2853f7673f3b..4f7d3f57d05c 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -147,7 +147,7 @@ u8 acpi_gbl_system_awake_and_running; | |||
147 | */ | 147 | */ |
148 | u8 acpi_gbl_reduced_hardware; | 148 | u8 acpi_gbl_reduced_hardware; |
149 | 149 | ||
150 | #endif | 150 | #endif /* DEFINE_ACPI_GLOBALS */ |
151 | 151 | ||
152 | /* Do not disassemble buffers to resource descriptors */ | 152 | /* Do not disassemble buffers to resource descriptors */ |
153 | 153 | ||
@@ -184,8 +184,12 @@ ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; | |||
184 | * found in the RSDT/XSDT. | 184 | * found in the RSDT/XSDT. |
185 | */ | 185 | */ |
186 | ACPI_EXTERN struct acpi_table_list acpi_gbl_root_table_list; | 186 | ACPI_EXTERN struct acpi_table_list acpi_gbl_root_table_list; |
187 | |||
188 | #if (!ACPI_REDUCED_HARDWARE) | ||
187 | ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; | 189 | ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; |
188 | 190 | ||
191 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
192 | |||
189 | /* These addresses are calculated from the FADT Event Block addresses */ | 193 | /* These addresses are calculated from the FADT Event Block addresses */ |
190 | 194 | ||
191 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status; | 195 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status; |
@@ -397,10 +401,15 @@ ACPI_EXTERN struct acpi_fixed_event_handler | |||
397 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; | 401 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; |
398 | ACPI_EXTERN struct acpi_gpe_block_info | 402 | ACPI_EXTERN struct acpi_gpe_block_info |
399 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; | 403 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; |
404 | |||
405 | #if (!ACPI_REDUCED_HARDWARE) | ||
406 | |||
400 | ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; | 407 | ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; |
401 | ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler; | 408 | ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler; |
402 | ACPI_EXTERN void *acpi_gbl_global_event_handler_context; | 409 | ACPI_EXTERN void *acpi_gbl_global_event_handler_context; |
403 | 410 | ||
411 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
412 | |||
404 | /***************************************************************************** | 413 | /***************************************************************************** |
405 | * | 414 | * |
406 | * Debugger globals | 415 | * Debugger globals |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 677793e938f5..5ccb99ae3a6f 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -81,6 +81,26 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value); | |||
81 | acpi_status acpi_hw_clear_acpi_status(void); | 81 | acpi_status acpi_hw_clear_acpi_status(void); |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * hwsleep - sleep/wake support (Legacy sleep registers) | ||
85 | */ | ||
86 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags); | ||
87 | |||
88 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags); | ||
89 | |||
90 | acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags); | ||
91 | |||
92 | /* | ||
93 | * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers) | ||
94 | */ | ||
95 | void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument); | ||
96 | |||
97 | acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags); | ||
98 | |||
99 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags); | ||
100 | |||
101 | acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags); | ||
102 | |||
103 | /* | ||
84 | * hwvalid - Port I/O with validation | 104 | * hwvalid - Port I/O with validation |
85 | */ | 105 | */ |
86 | acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width); | 106 | acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width); |
@@ -128,16 +148,4 @@ acpi_status | |||
128 | acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, | 148 | acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, |
129 | acpi_handle root_pci_device, acpi_handle pci_region); | 149 | acpi_handle root_pci_device, acpi_handle pci_region); |
130 | 150 | ||
131 | #ifdef ACPI_FUTURE_USAGE | ||
132 | /* | ||
133 | * hwtimer - ACPI Timer prototypes | ||
134 | */ | ||
135 | acpi_status acpi_get_timer_resolution(u32 * resolution); | ||
136 | |||
137 | acpi_status acpi_get_timer(u32 * ticks); | ||
138 | |||
139 | acpi_status | ||
140 | acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed); | ||
141 | #endif /* ACPI_FUTURE_USAGE */ | ||
142 | |||
143 | #endif /* __ACHWARE_H__ */ | 151 | #endif /* __ACHWARE_H__ */ |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 3f24068837d5..e3922ca20e7f 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -370,6 +370,7 @@ struct acpi_predefined_data { | |||
370 | /* Defines for Flags field above */ | 370 | /* Defines for Flags field above */ |
371 | 371 | ||
372 | #define ACPI_OBJECT_REPAIRED 1 | 372 | #define ACPI_OBJECT_REPAIRED 1 |
373 | #define ACPI_OBJECT_WRAPPED 2 | ||
373 | 374 | ||
374 | /* | 375 | /* |
375 | * Bitmapped return value types | 376 | * Bitmapped return value types |
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index ef338a96f5b2..f119f473f71a 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -516,6 +516,12 @@ | |||
516 | 516 | ||
517 | #endif /* ACPI_DEBUG_OUTPUT */ | 517 | #endif /* ACPI_DEBUG_OUTPUT */ |
518 | 518 | ||
519 | #if (!ACPI_REDUCED_HARDWARE) | ||
520 | #define ACPI_HW_OPTIONAL_FUNCTION(addr) addr | ||
521 | #else | ||
522 | #define ACPI_HW_OPTIONAL_FUNCTION(addr) NULL | ||
523 | #endif | ||
524 | |||
519 | /* | 525 | /* |
520 | * Some code only gets executed when the debugger is built in. | 526 | * Some code only gets executed when the debugger is built in. |
521 | * Note that this is entirely independent of whether the | 527 | * Note that this is entirely independent of whether the |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 2c9e0f049523..9b19d4b86424 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -283,8 +283,9 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, | |||
283 | union acpi_operand_object **return_object_ptr); | 283 | union acpi_operand_object **return_object_ptr); |
284 | 284 | ||
285 | acpi_status | 285 | acpi_status |
286 | acpi_ns_repair_package_list(struct acpi_predefined_data *data, | 286 | acpi_ns_wrap_with_package(struct acpi_predefined_data *data, |
287 | union acpi_operand_object **obj_desc_ptr); | 287 | union acpi_operand_object *original_object, |
288 | union acpi_operand_object **obj_desc_ptr); | ||
288 | 289 | ||
289 | acpi_status | 290 | acpi_status |
290 | acpi_ns_repair_null_element(struct acpi_predefined_data *data, | 291 | acpi_ns_repair_null_element(struct acpi_predefined_data *data, |
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index d5bec304c823..6712965ba8ae 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -67,6 +67,11 @@ acpi_status acpi_tb_resize_root_table_list(void); | |||
67 | 67 | ||
68 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); | 68 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); |
69 | 69 | ||
70 | struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | ||
71 | *table_header, | ||
72 | struct acpi_table_desc | ||
73 | *table_desc); | ||
74 | |||
70 | acpi_status | 75 | acpi_status |
71 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); | 76 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); |
72 | 77 | ||
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index 6729ebe2f1e6..07e4dc44f81c 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | #define _COMPONENT ACPI_EVENTS | 48 | #define _COMPONENT ACPI_EVENTS |
49 | ACPI_MODULE_NAME("evevent") | 49 | ACPI_MODULE_NAME("evevent") |
50 | 50 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | |
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static acpi_status acpi_ev_fixed_event_initialize(void); | 52 | static acpi_status acpi_ev_fixed_event_initialize(void); |
53 | 53 | ||
@@ -291,3 +291,5 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) | |||
291 | return ((acpi_gbl_fixed_event_handlers[event]. | 291 | return ((acpi_gbl_fixed_event_handlers[event]. |
292 | handler) (acpi_gbl_fixed_event_handlers[event].context)); | 292 | handler) (acpi_gbl_fixed_event_handlers[event].context)); |
293 | } | 293 | } |
294 | |||
295 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c index 5e5683cb1f0d..cfeab38795d8 100644 --- a/drivers/acpi/acpica/evglock.c +++ b/drivers/acpi/acpica/evglock.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evglock") | 50 | ACPI_MODULE_NAME("evglock") |
51 | 51 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | |
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static u32 acpi_ev_global_lock_handler(void *context); | 53 | static u32 acpi_ev_global_lock_handler(void *context); |
54 | 54 | ||
@@ -339,3 +339,5 @@ acpi_status acpi_ev_release_global_lock(void) | |||
339 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); | 339 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); |
340 | return_ACPI_STATUS(status); | 340 | return_ACPI_STATUS(status); |
341 | } | 341 | } |
342 | |||
343 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 9e88cb6fb25e..8ba0e5f17091 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evgpe") | 50 | ACPI_MODULE_NAME("evgpe") |
51 | 51 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | |
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); | 53 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); |
54 | 54 | ||
@@ -766,3 +766,5 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
766 | 766 | ||
767 | return_UINT32(ACPI_INTERRUPT_HANDLED); | 767 | return_UINT32(ACPI_INTERRUPT_HANDLED); |
768 | } | 768 | } |
769 | |||
770 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index be75339cd5dd..23a3ca86b2eb 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evgpeblk") | 50 | ACPI_MODULE_NAME("evgpeblk") |
51 | 51 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | |
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static acpi_status | 53 | static acpi_status |
54 | acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, | 54 | acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, |
@@ -504,3 +504,5 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
504 | 504 | ||
505 | return_ACPI_STATUS(AE_OK); | 505 | return_ACPI_STATUS(AE_OK); |
506 | } | 506 | } |
507 | |||
508 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index adf7494da9db..da0add858f81 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evgpeinit") | 50 | ACPI_MODULE_NAME("evgpeinit") |
51 | 51 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | |
52 | /* | 52 | /* |
53 | * Note: History of _PRW support in ACPICA | 53 | * Note: History of _PRW support in ACPICA |
54 | * | 54 | * |
@@ -440,3 +440,5 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
440 | name, gpe_number)); | 440 | name, gpe_number)); |
441 | return_ACPI_STATUS(AE_OK); | 441 | return_ACPI_STATUS(AE_OK); |
442 | } | 442 | } |
443 | |||
444 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index 25073932aa10..3c43796b8361 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #define _COMPONENT ACPI_EVENTS | 48 | #define _COMPONENT ACPI_EVENTS |
49 | ACPI_MODULE_NAME("evgpeutil") | 49 | ACPI_MODULE_NAME("evgpeutil") |
50 | 50 | ||
51 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
51 | /******************************************************************************* | 52 | /******************************************************************************* |
52 | * | 53 | * |
53 | * FUNCTION: acpi_ev_walk_gpe_list | 54 | * FUNCTION: acpi_ev_walk_gpe_list |
@@ -374,3 +375,5 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
374 | 375 | ||
375 | return_ACPI_STATUS(AE_OK); | 376 | return_ACPI_STATUS(AE_OK); |
376 | } | 377 | } |
378 | |||
379 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 84966f416463..51ef9f5e002d 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -108,27 +108,30 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
108 | ACPI_FUNCTION_NAME(ev_queue_notify_request); | 108 | ACPI_FUNCTION_NAME(ev_queue_notify_request); |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * For value 3 (Ejection Request), some device method may need to be run. | 111 | * For value 0x03 (Ejection Request), may need to run a device method. |
112 | * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need | 112 | * For value 0x02 (Device Wake), if _PRW exists, may need to run |
113 | * to be run. | 113 | * the _PS0 method. |
114 | * For value 0x80 (Status Change) on the power button or sleep button, | 114 | * For value 0x80 (Status Change) on the power button or sleep button, |
115 | * initiate soft-off or sleep operation? | 115 | * initiate soft-off or sleep operation. |
116 | * | ||
117 | * For all cases, simply dispatch the notify to the handler. | ||
116 | */ | 118 | */ |
117 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 119 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
118 | "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n", | 120 | "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", |
119 | acpi_ut_get_node_name(node), node, notify_value, | 121 | acpi_ut_get_node_name(node), |
120 | acpi_ut_get_notify_name(notify_value))); | 122 | acpi_ut_get_type_name(node->type), notify_value, |
123 | acpi_ut_get_notify_name(notify_value), node)); | ||
121 | 124 | ||
122 | /* Get the notify object attached to the NS Node */ | 125 | /* Get the notify object attached to the NS Node */ |
123 | 126 | ||
124 | obj_desc = acpi_ns_get_attached_object(node); | 127 | obj_desc = acpi_ns_get_attached_object(node); |
125 | if (obj_desc) { | 128 | if (obj_desc) { |
126 | 129 | ||
127 | /* We have the notify object, Get the right handler */ | 130 | /* We have the notify object, Get the correct handler */ |
128 | 131 | ||
129 | switch (node->type) { | 132 | switch (node->type) { |
130 | 133 | ||
131 | /* Notify allowed only on these types */ | 134 | /* Notify is allowed only on these types */ |
132 | 135 | ||
133 | case ACPI_TYPE_DEVICE: | 136 | case ACPI_TYPE_DEVICE: |
134 | case ACPI_TYPE_THERMAL: | 137 | case ACPI_TYPE_THERMAL: |
@@ -152,7 +155,7 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
152 | } | 155 | } |
153 | 156 | ||
154 | /* | 157 | /* |
155 | * If there is any handler to run, schedule the dispatcher. | 158 | * If there is a handler to run, schedule the dispatcher. |
156 | * Check for: | 159 | * Check for: |
157 | * 1) Global system notify handler | 160 | * 1) Global system notify handler |
158 | * 2) Global device notify handler | 161 | * 2) Global device notify handler |
@@ -270,6 +273,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
270 | acpi_ut_delete_generic_state(notify_info); | 273 | acpi_ut_delete_generic_state(notify_info); |
271 | } | 274 | } |
272 | 275 | ||
276 | #if (!ACPI_REDUCED_HARDWARE) | ||
273 | /****************************************************************************** | 277 | /****************************************************************************** |
274 | * | 278 | * |
275 | * FUNCTION: acpi_ev_terminate | 279 | * FUNCTION: acpi_ev_terminate |
@@ -338,3 +342,5 @@ void acpi_ev_terminate(void) | |||
338 | } | 342 | } |
339 | return_VOID; | 343 | return_VOID; |
340 | } | 344 | } |
345 | |||
346 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 26065c612e76..6a57aa2d70d1 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evsci") | 50 | ACPI_MODULE_NAME("evsci") |
51 | 51 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | |
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context); | 53 | static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context); |
54 | 54 | ||
@@ -181,3 +181,5 @@ acpi_status acpi_ev_remove_sci_handler(void) | |||
181 | 181 | ||
182 | return_ACPI_STATUS(status); | 182 | return_ACPI_STATUS(status); |
183 | } | 183 | } |
184 | |||
185 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 61944e89565a..44bef5744ebb 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -51,222 +51,6 @@ | |||
51 | #define _COMPONENT ACPI_EVENTS | 51 | #define _COMPONENT ACPI_EVENTS |
52 | ACPI_MODULE_NAME("evxface") | 52 | ACPI_MODULE_NAME("evxface") |
53 | 53 | ||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_install_exception_handler | ||
57 | * | ||
58 | * PARAMETERS: Handler - Pointer to the handler function for the | ||
59 | * event | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Saves the pointer to the handler function | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | #ifdef ACPI_FUTURE_USAGE | ||
67 | acpi_status acpi_install_exception_handler(acpi_exception_handler handler) | ||
68 | { | ||
69 | acpi_status status; | ||
70 | |||
71 | ACPI_FUNCTION_TRACE(acpi_install_exception_handler); | ||
72 | |||
73 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
74 | if (ACPI_FAILURE(status)) { | ||
75 | return_ACPI_STATUS(status); | ||
76 | } | ||
77 | |||
78 | /* Don't allow two handlers. */ | ||
79 | |||
80 | if (acpi_gbl_exception_handler) { | ||
81 | status = AE_ALREADY_EXISTS; | ||
82 | goto cleanup; | ||
83 | } | ||
84 | |||
85 | /* Install the handler */ | ||
86 | |||
87 | acpi_gbl_exception_handler = handler; | ||
88 | |||
89 | cleanup: | ||
90 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
91 | return_ACPI_STATUS(status); | ||
92 | } | ||
93 | |||
94 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) | ||
95 | #endif /* ACPI_FUTURE_USAGE */ | ||
96 | |||
97 | /******************************************************************************* | ||
98 | * | ||
99 | * FUNCTION: acpi_install_global_event_handler | ||
100 | * | ||
101 | * PARAMETERS: Handler - Pointer to the global event handler function | ||
102 | * Context - Value passed to the handler on each event | ||
103 | * | ||
104 | * RETURN: Status | ||
105 | * | ||
106 | * DESCRIPTION: Saves the pointer to the handler function. The global handler | ||
107 | * is invoked upon each incoming GPE and Fixed Event. It is | ||
108 | * invoked at interrupt level at the time of the event dispatch. | ||
109 | * Can be used to update event counters, etc. | ||
110 | * | ||
111 | ******************************************************************************/ | ||
112 | acpi_status | ||
113 | acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context) | ||
114 | { | ||
115 | acpi_status status; | ||
116 | |||
117 | ACPI_FUNCTION_TRACE(acpi_install_global_event_handler); | ||
118 | |||
119 | /* Parameter validation */ | ||
120 | |||
121 | if (!handler) { | ||
122 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
123 | } | ||
124 | |||
125 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
126 | if (ACPI_FAILURE(status)) { | ||
127 | return_ACPI_STATUS(status); | ||
128 | } | ||
129 | |||
130 | /* Don't allow two handlers. */ | ||
131 | |||
132 | if (acpi_gbl_global_event_handler) { | ||
133 | status = AE_ALREADY_EXISTS; | ||
134 | goto cleanup; | ||
135 | } | ||
136 | |||
137 | acpi_gbl_global_event_handler = handler; | ||
138 | acpi_gbl_global_event_handler_context = context; | ||
139 | |||
140 | cleanup: | ||
141 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
142 | return_ACPI_STATUS(status); | ||
143 | } | ||
144 | |||
145 | ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler) | ||
146 | |||
147 | /******************************************************************************* | ||
148 | * | ||
149 | * FUNCTION: acpi_install_fixed_event_handler | ||
150 | * | ||
151 | * PARAMETERS: Event - Event type to enable. | ||
152 | * Handler - Pointer to the handler function for the | ||
153 | * event | ||
154 | * Context - Value passed to the handler on each GPE | ||
155 | * | ||
156 | * RETURN: Status | ||
157 | * | ||
158 | * DESCRIPTION: Saves the pointer to the handler function and then enables the | ||
159 | * event. | ||
160 | * | ||
161 | ******************************************************************************/ | ||
162 | acpi_status | ||
163 | acpi_install_fixed_event_handler(u32 event, | ||
164 | acpi_event_handler handler, void *context) | ||
165 | { | ||
166 | acpi_status status; | ||
167 | |||
168 | ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler); | ||
169 | |||
170 | /* Parameter validation */ | ||
171 | |||
172 | if (event > ACPI_EVENT_MAX) { | ||
173 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
174 | } | ||
175 | |||
176 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
177 | if (ACPI_FAILURE(status)) { | ||
178 | return_ACPI_STATUS(status); | ||
179 | } | ||
180 | |||
181 | /* Don't allow two handlers. */ | ||
182 | |||
183 | if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { | ||
184 | status = AE_ALREADY_EXISTS; | ||
185 | goto cleanup; | ||
186 | } | ||
187 | |||
188 | /* Install the handler before enabling the event */ | ||
189 | |||
190 | acpi_gbl_fixed_event_handlers[event].handler = handler; | ||
191 | acpi_gbl_fixed_event_handlers[event].context = context; | ||
192 | |||
193 | status = acpi_clear_event(event); | ||
194 | if (ACPI_SUCCESS(status)) | ||
195 | status = acpi_enable_event(event, 0); | ||
196 | if (ACPI_FAILURE(status)) { | ||
197 | ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X", | ||
198 | event)); | ||
199 | |||
200 | /* Remove the handler */ | ||
201 | |||
202 | acpi_gbl_fixed_event_handlers[event].handler = NULL; | ||
203 | acpi_gbl_fixed_event_handlers[event].context = NULL; | ||
204 | } else { | ||
205 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
206 | "Enabled fixed event %X, Handler=%p\n", event, | ||
207 | handler)); | ||
208 | } | ||
209 | |||
210 | cleanup: | ||
211 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
212 | return_ACPI_STATUS(status); | ||
213 | } | ||
214 | |||
215 | ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler) | ||
216 | |||
217 | /******************************************************************************* | ||
218 | * | ||
219 | * FUNCTION: acpi_remove_fixed_event_handler | ||
220 | * | ||
221 | * PARAMETERS: Event - Event type to disable. | ||
222 | * Handler - Address of the handler | ||
223 | * | ||
224 | * RETURN: Status | ||
225 | * | ||
226 | * DESCRIPTION: Disables the event and unregisters the event handler. | ||
227 | * | ||
228 | ******************************************************************************/ | ||
229 | acpi_status | ||
230 | acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) | ||
231 | { | ||
232 | acpi_status status = AE_OK; | ||
233 | |||
234 | ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler); | ||
235 | |||
236 | /* Parameter validation */ | ||
237 | |||
238 | if (event > ACPI_EVENT_MAX) { | ||
239 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
240 | } | ||
241 | |||
242 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
243 | if (ACPI_FAILURE(status)) { | ||
244 | return_ACPI_STATUS(status); | ||
245 | } | ||
246 | |||
247 | /* Disable the event before removing the handler */ | ||
248 | |||
249 | status = acpi_disable_event(event, 0); | ||
250 | |||
251 | /* Always Remove the handler */ | ||
252 | |||
253 | acpi_gbl_fixed_event_handlers[event].handler = NULL; | ||
254 | acpi_gbl_fixed_event_handlers[event].context = NULL; | ||
255 | |||
256 | if (ACPI_FAILURE(status)) { | ||
257 | ACPI_WARNING((AE_INFO, | ||
258 | "Could not write to fixed event enable register 0x%X", | ||
259 | event)); | ||
260 | } else { | ||
261 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n", | ||
262 | event)); | ||
263 | } | ||
264 | |||
265 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
266 | return_ACPI_STATUS(status); | ||
267 | } | ||
268 | |||
269 | ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler) | ||
270 | 54 | ||
271 | /******************************************************************************* | 55 | /******************************************************************************* |
272 | * | 56 | * |
@@ -334,6 +118,7 @@ acpi_add_handler_object(struct acpi_object_notify_handler *parent_obj, | |||
334 | return AE_OK; | 118 | return AE_OK; |
335 | } | 119 | } |
336 | 120 | ||
121 | |||
337 | /******************************************************************************* | 122 | /******************************************************************************* |
338 | * | 123 | * |
339 | * FUNCTION: acpi_install_notify_handler | 124 | * FUNCTION: acpi_install_notify_handler |
@@ -705,6 +490,224 @@ ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler) | |||
705 | 490 | ||
706 | /******************************************************************************* | 491 | /******************************************************************************* |
707 | * | 492 | * |
493 | * FUNCTION: acpi_install_exception_handler | ||
494 | * | ||
495 | * PARAMETERS: Handler - Pointer to the handler function for the | ||
496 | * event | ||
497 | * | ||
498 | * RETURN: Status | ||
499 | * | ||
500 | * DESCRIPTION: Saves the pointer to the handler function | ||
501 | * | ||
502 | ******************************************************************************/ | ||
503 | #ifdef ACPI_FUTURE_USAGE | ||
504 | acpi_status acpi_install_exception_handler(acpi_exception_handler handler) | ||
505 | { | ||
506 | acpi_status status; | ||
507 | |||
508 | ACPI_FUNCTION_TRACE(acpi_install_exception_handler); | ||
509 | |||
510 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
511 | if (ACPI_FAILURE(status)) { | ||
512 | return_ACPI_STATUS(status); | ||
513 | } | ||
514 | |||
515 | /* Don't allow two handlers. */ | ||
516 | |||
517 | if (acpi_gbl_exception_handler) { | ||
518 | status = AE_ALREADY_EXISTS; | ||
519 | goto cleanup; | ||
520 | } | ||
521 | |||
522 | /* Install the handler */ | ||
523 | |||
524 | acpi_gbl_exception_handler = handler; | ||
525 | |||
526 | cleanup: | ||
527 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
528 | return_ACPI_STATUS(status); | ||
529 | } | ||
530 | |||
531 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) | ||
532 | #endif /* ACPI_FUTURE_USAGE */ | ||
533 | |||
534 | #if (!ACPI_REDUCED_HARDWARE) | ||
535 | /******************************************************************************* | ||
536 | * | ||
537 | * FUNCTION: acpi_install_global_event_handler | ||
538 | * | ||
539 | * PARAMETERS: Handler - Pointer to the global event handler function | ||
540 | * Context - Value passed to the handler on each event | ||
541 | * | ||
542 | * RETURN: Status | ||
543 | * | ||
544 | * DESCRIPTION: Saves the pointer to the handler function. The global handler | ||
545 | * is invoked upon each incoming GPE and Fixed Event. It is | ||
546 | * invoked at interrupt level at the time of the event dispatch. | ||
547 | * Can be used to update event counters, etc. | ||
548 | * | ||
549 | ******************************************************************************/ | ||
550 | acpi_status | ||
551 | acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context) | ||
552 | { | ||
553 | acpi_status status; | ||
554 | |||
555 | ACPI_FUNCTION_TRACE(acpi_install_global_event_handler); | ||
556 | |||
557 | /* Parameter validation */ | ||
558 | |||
559 | if (!handler) { | ||
560 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
561 | } | ||
562 | |||
563 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
564 | if (ACPI_FAILURE(status)) { | ||
565 | return_ACPI_STATUS(status); | ||
566 | } | ||
567 | |||
568 | /* Don't allow two handlers. */ | ||
569 | |||
570 | if (acpi_gbl_global_event_handler) { | ||
571 | status = AE_ALREADY_EXISTS; | ||
572 | goto cleanup; | ||
573 | } | ||
574 | |||
575 | acpi_gbl_global_event_handler = handler; | ||
576 | acpi_gbl_global_event_handler_context = context; | ||
577 | |||
578 | cleanup: | ||
579 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
580 | return_ACPI_STATUS(status); | ||
581 | } | ||
582 | |||
583 | ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler) | ||
584 | |||
585 | /******************************************************************************* | ||
586 | * | ||
587 | * FUNCTION: acpi_install_fixed_event_handler | ||
588 | * | ||
589 | * PARAMETERS: Event - Event type to enable. | ||
590 | * Handler - Pointer to the handler function for the | ||
591 | * event | ||
592 | * Context - Value passed to the handler on each GPE | ||
593 | * | ||
594 | * RETURN: Status | ||
595 | * | ||
596 | * DESCRIPTION: Saves the pointer to the handler function and then enables the | ||
597 | * event. | ||
598 | * | ||
599 | ******************************************************************************/ | ||
600 | acpi_status | ||
601 | acpi_install_fixed_event_handler(u32 event, | ||
602 | acpi_event_handler handler, void *context) | ||
603 | { | ||
604 | acpi_status status; | ||
605 | |||
606 | ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler); | ||
607 | |||
608 | /* Parameter validation */ | ||
609 | |||
610 | if (event > ACPI_EVENT_MAX) { | ||
611 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
612 | } | ||
613 | |||
614 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
615 | if (ACPI_FAILURE(status)) { | ||
616 | return_ACPI_STATUS(status); | ||
617 | } | ||
618 | |||
619 | /* Don't allow two handlers. */ | ||
620 | |||
621 | if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { | ||
622 | status = AE_ALREADY_EXISTS; | ||
623 | goto cleanup; | ||
624 | } | ||
625 | |||
626 | /* Install the handler before enabling the event */ | ||
627 | |||
628 | acpi_gbl_fixed_event_handlers[event].handler = handler; | ||
629 | acpi_gbl_fixed_event_handlers[event].context = context; | ||
630 | |||
631 | status = acpi_clear_event(event); | ||
632 | if (ACPI_SUCCESS(status)) | ||
633 | status = acpi_enable_event(event, 0); | ||
634 | if (ACPI_FAILURE(status)) { | ||
635 | ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X", | ||
636 | event)); | ||
637 | |||
638 | /* Remove the handler */ | ||
639 | |||
640 | acpi_gbl_fixed_event_handlers[event].handler = NULL; | ||
641 | acpi_gbl_fixed_event_handlers[event].context = NULL; | ||
642 | } else { | ||
643 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
644 | "Enabled fixed event %X, Handler=%p\n", event, | ||
645 | handler)); | ||
646 | } | ||
647 | |||
648 | cleanup: | ||
649 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
650 | return_ACPI_STATUS(status); | ||
651 | } | ||
652 | |||
653 | ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler) | ||
654 | |||
655 | /******************************************************************************* | ||
656 | * | ||
657 | * FUNCTION: acpi_remove_fixed_event_handler | ||
658 | * | ||
659 | * PARAMETERS: Event - Event type to disable. | ||
660 | * Handler - Address of the handler | ||
661 | * | ||
662 | * RETURN: Status | ||
663 | * | ||
664 | * DESCRIPTION: Disables the event and unregisters the event handler. | ||
665 | * | ||
666 | ******************************************************************************/ | ||
667 | acpi_status | ||
668 | acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) | ||
669 | { | ||
670 | acpi_status status = AE_OK; | ||
671 | |||
672 | ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler); | ||
673 | |||
674 | /* Parameter validation */ | ||
675 | |||
676 | if (event > ACPI_EVENT_MAX) { | ||
677 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
678 | } | ||
679 | |||
680 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
681 | if (ACPI_FAILURE(status)) { | ||
682 | return_ACPI_STATUS(status); | ||
683 | } | ||
684 | |||
685 | /* Disable the event before removing the handler */ | ||
686 | |||
687 | status = acpi_disable_event(event, 0); | ||
688 | |||
689 | /* Always Remove the handler */ | ||
690 | |||
691 | acpi_gbl_fixed_event_handlers[event].handler = NULL; | ||
692 | acpi_gbl_fixed_event_handlers[event].context = NULL; | ||
693 | |||
694 | if (ACPI_FAILURE(status)) { | ||
695 | ACPI_WARNING((AE_INFO, | ||
696 | "Could not write to fixed event enable register 0x%X", | ||
697 | event)); | ||
698 | } else { | ||
699 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n", | ||
700 | event)); | ||
701 | } | ||
702 | |||
703 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
704 | return_ACPI_STATUS(status); | ||
705 | } | ||
706 | |||
707 | ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler) | ||
708 | |||
709 | /******************************************************************************* | ||
710 | * | ||
708 | * FUNCTION: acpi_install_gpe_handler | 711 | * FUNCTION: acpi_install_gpe_handler |
709 | * | 712 | * |
710 | * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT | 713 | * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT |
@@ -984,3 +987,4 @@ acpi_status acpi_release_global_lock(u32 handle) | |||
984 | } | 987 | } |
985 | 988 | ||
986 | ACPI_EXPORT_SYMBOL(acpi_release_global_lock) | 989 | ACPI_EXPORT_SYMBOL(acpi_release_global_lock) |
990 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 1768bbec1002..77cee5a5e891 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evxfevnt") | 50 | ACPI_MODULE_NAME("evxfevnt") |
51 | 51 | ||
52 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
52 | /******************************************************************************* | 53 | /******************************************************************************* |
53 | * | 54 | * |
54 | * FUNCTION: acpi_enable | 55 | * FUNCTION: acpi_enable |
@@ -352,3 +353,4 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) | |||
352 | } | 353 | } |
353 | 354 | ||
354 | ACPI_EXPORT_SYMBOL(acpi_get_event_status) | 355 | ACPI_EXPORT_SYMBOL(acpi_get_event_status) |
356 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 33388fd69df4..86f9b343ebd4 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #define _COMPONENT ACPI_EVENTS | 50 | #define _COMPONENT ACPI_EVENTS |
51 | ACPI_MODULE_NAME("evxfgpe") | 51 | ACPI_MODULE_NAME("evxfgpe") |
52 | 52 | ||
53 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
53 | /****************************************************************************** | 54 | /****************************************************************************** |
54 | * | 55 | * |
55 | * FUNCTION: acpi_update_all_gpes | 56 | * FUNCTION: acpi_update_all_gpes |
@@ -695,3 +696,4 @@ acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) | |||
695 | } | 696 | } |
696 | 697 | ||
697 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | 698 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) |
699 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index d21ec5f0b3a9..d0b9ed5df97e 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #define _COMPONENT ACPI_HARDWARE | 48 | #define _COMPONENT ACPI_HARDWARE |
49 | ACPI_MODULE_NAME("hwacpi") | 49 | ACPI_MODULE_NAME("hwacpi") |
50 | 50 | ||
51 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
51 | /****************************************************************************** | 52 | /****************************************************************************** |
52 | * | 53 | * |
53 | * FUNCTION: acpi_hw_set_mode | 54 | * FUNCTION: acpi_hw_set_mode |
@@ -166,3 +167,5 @@ u32 acpi_hw_get_mode(void) | |||
166 | return_UINT32(ACPI_SYS_MODE_LEGACY); | 167 | return_UINT32(ACPI_SYS_MODE_LEGACY); |
167 | } | 168 | } |
168 | } | 169 | } |
170 | |||
171 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c new file mode 100644 index 000000000000..29e859293edd --- /dev/null +++ b/drivers/acpi/acpica/hwesleep.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the | ||
4 | * extended FADT-V5 sleep registers. | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2012, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include "accommon.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_HARDWARE | ||
49 | ACPI_MODULE_NAME("hwesleep") | ||
50 | |||
51 | /******************************************************************************* | ||
52 | * | ||
53 | * FUNCTION: acpi_hw_execute_sleep_method | ||
54 | * | ||
55 | * PARAMETERS: method_pathname - Pathname of method to execute | ||
56 | * integer_argument - Argument to pass to the method | ||
57 | * | ||
58 | * RETURN: None | ||
59 | * | ||
60 | * DESCRIPTION: Execute a sleep/wake related method with one integer argument | ||
61 | * and no return value. | ||
62 | * | ||
63 | ******************************************************************************/ | ||
64 | void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument) | ||
65 | { | ||
66 | struct acpi_object_list arg_list; | ||
67 | union acpi_object arg; | ||
68 | acpi_status status; | ||
69 | |||
70 | ACPI_FUNCTION_TRACE(hw_execute_sleep_method); | ||
71 | |||
72 | /* One argument, integer_argument; No return value expected */ | ||
73 | |||
74 | arg_list.count = 1; | ||
75 | arg_list.pointer = &arg; | ||
76 | arg.type = ACPI_TYPE_INTEGER; | ||
77 | arg.integer.value = (u64)integer_argument; | ||
78 | |||
79 | status = acpi_evaluate_object(NULL, method_pathname, &arg_list, NULL); | ||
80 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
81 | ACPI_EXCEPTION((AE_INFO, status, "While executing method %s", | ||
82 | method_pathname)); | ||
83 | } | ||
84 | |||
85 | return_VOID; | ||
86 | } | ||
87 | |||
88 | /******************************************************************************* | ||
89 | * | ||
90 | * FUNCTION: acpi_hw_extended_sleep | ||
91 | * | ||
92 | * PARAMETERS: sleep_state - Which sleep state to enter | ||
93 | * Flags - ACPI_EXECUTE_GTS to run optional method | ||
94 | * | ||
95 | * RETURN: Status | ||
96 | * | ||
97 | * DESCRIPTION: Enter a system sleep state via the extended FADT sleep | ||
98 | * registers (V5 FADT). | ||
99 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | ||
100 | * | ||
101 | ******************************************************************************/ | ||
102 | |||
103 | acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | ||
104 | { | ||
105 | acpi_status status; | ||
106 | u8 sleep_type_value; | ||
107 | u64 sleep_status; | ||
108 | |||
109 | ACPI_FUNCTION_TRACE(hw_extended_sleep); | ||
110 | |||
111 | /* Extended sleep registers must be valid */ | ||
112 | |||
113 | if (!acpi_gbl_FADT.sleep_control.address || | ||
114 | !acpi_gbl_FADT.sleep_status.address) { | ||
115 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
116 | } | ||
117 | |||
118 | /* Clear wake status (WAK_STS) */ | ||
119 | |||
120 | status = acpi_write(ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status); | ||
121 | if (ACPI_FAILURE(status)) { | ||
122 | return_ACPI_STATUS(status); | ||
123 | } | ||
124 | |||
125 | acpi_gbl_system_awake_and_running = FALSE; | ||
126 | |||
127 | /* Optionally execute _GTS (Going To Sleep) */ | ||
128 | |||
129 | if (flags & ACPI_EXECUTE_GTS) { | ||
130 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); | ||
131 | } | ||
132 | |||
133 | /* Flush caches, as per ACPI specification */ | ||
134 | |||
135 | ACPI_FLUSH_CPU_CACHE(); | ||
136 | |||
137 | /* | ||
138 | * Set the SLP_TYP and SLP_EN bits. | ||
139 | * | ||
140 | * Note: We only use the first value returned by the \_Sx method | ||
141 | * (acpi_gbl_sleep_type_a) - As per ACPI specification. | ||
142 | */ | ||
143 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | ||
144 | "Entering sleep state [S%u]\n", sleep_state)); | ||
145 | |||
146 | sleep_type_value = | ||
147 | ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) & | ||
148 | ACPI_X_SLEEP_TYPE_MASK); | ||
149 | |||
150 | status = acpi_write((sleep_type_value | ACPI_X_SLEEP_ENABLE), | ||
151 | &acpi_gbl_FADT.sleep_control); | ||
152 | if (ACPI_FAILURE(status)) { | ||
153 | return_ACPI_STATUS(status); | ||
154 | } | ||
155 | |||
156 | /* Wait for transition back to Working State */ | ||
157 | |||
158 | do { | ||
159 | status = acpi_read(&sleep_status, &acpi_gbl_FADT.sleep_status); | ||
160 | if (ACPI_FAILURE(status)) { | ||
161 | return_ACPI_STATUS(status); | ||
162 | } | ||
163 | |||
164 | } while (!(((u8)sleep_status) & ACPI_X_WAKE_STATUS)); | ||
165 | |||
166 | return_ACPI_STATUS(AE_OK); | ||
167 | } | ||
168 | |||
169 | /******************************************************************************* | ||
170 | * | ||
171 | * FUNCTION: acpi_hw_extended_wake_prep | ||
172 | * | ||
173 | * PARAMETERS: sleep_state - Which sleep state we just exited | ||
174 | * Flags - ACPI_EXECUTE_BFS to run optional method | ||
175 | * | ||
176 | * RETURN: Status | ||
177 | * | ||
178 | * DESCRIPTION: Perform first part of OS-independent ACPI cleanup after | ||
179 | * a sleep. Called with interrupts ENABLED. | ||
180 | * | ||
181 | ******************************************************************************/ | ||
182 | |||
183 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) | ||
184 | { | ||
185 | acpi_status status; | ||
186 | u8 sleep_type_value; | ||
187 | |||
188 | ACPI_FUNCTION_TRACE(hw_extended_wake_prep); | ||
189 | |||
190 | status = acpi_get_sleep_type_data(ACPI_STATE_S0, | ||
191 | &acpi_gbl_sleep_type_a, | ||
192 | &acpi_gbl_sleep_type_b); | ||
193 | if (ACPI_SUCCESS(status)) { | ||
194 | sleep_type_value = | ||
195 | ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) & | ||
196 | ACPI_X_SLEEP_TYPE_MASK); | ||
197 | |||
198 | (void)acpi_write((sleep_type_value | ACPI_X_SLEEP_ENABLE), | ||
199 | &acpi_gbl_FADT.sleep_control); | ||
200 | } | ||
201 | |||
202 | /* Optionally execute _BFS (Back From Sleep) */ | ||
203 | |||
204 | if (flags & ACPI_EXECUTE_BFS) { | ||
205 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); | ||
206 | } | ||
207 | return_ACPI_STATUS(AE_OK); | ||
208 | } | ||
209 | |||
210 | /******************************************************************************* | ||
211 | * | ||
212 | * FUNCTION: acpi_hw_extended_wake | ||
213 | * | ||
214 | * PARAMETERS: sleep_state - Which sleep state we just exited | ||
215 | * Flags - Reserved, set to zero | ||
216 | * | ||
217 | * RETURN: Status | ||
218 | * | ||
219 | * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep | ||
220 | * Called with interrupts ENABLED. | ||
221 | * | ||
222 | ******************************************************************************/ | ||
223 | |||
224 | acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags) | ||
225 | { | ||
226 | ACPI_FUNCTION_TRACE(hw_extended_wake); | ||
227 | |||
228 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ | ||
229 | |||
230 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; | ||
231 | |||
232 | /* Execute the wake methods */ | ||
233 | |||
234 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING); | ||
235 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state); | ||
236 | |||
237 | /* | ||
238 | * Some BIOS code assumes that WAK_STS will be cleared on resume | ||
239 | * and use it to determine whether the system is rebooting or | ||
240 | * resuming. Clear WAK_STS for compatibility. | ||
241 | */ | ||
242 | (void)acpi_write(ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status); | ||
243 | acpi_gbl_system_awake_and_running = TRUE; | ||
244 | |||
245 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); | ||
246 | return_ACPI_STATUS(AE_OK); | ||
247 | } | ||
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 1a6894afef79..25bd28c4ae8d 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define _COMPONENT ACPI_HARDWARE | 49 | #define _COMPONENT ACPI_HARDWARE |
50 | ACPI_MODULE_NAME("hwgpe") | 50 | ACPI_MODULE_NAME("hwgpe") |
51 | 51 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | |
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static acpi_status | 53 | static acpi_status |
54 | acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 54 | acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
@@ -479,3 +479,5 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void) | |||
479 | status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL); | 479 | status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL); |
480 | return_ACPI_STATUS(status); | 480 | return_ACPI_STATUS(status); |
481 | } | 481 | } |
482 | |||
483 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 4ea4eeb51bfd..6b6c83b87b52 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #define _COMPONENT ACPI_HARDWARE | 51 | #define _COMPONENT ACPI_HARDWARE |
52 | ACPI_MODULE_NAME("hwregs") | 52 | ACPI_MODULE_NAME("hwregs") |
53 | 53 | ||
54 | #if (!ACPI_REDUCED_HARDWARE) | ||
54 | /* Local Prototypes */ | 55 | /* Local Prototypes */ |
55 | static acpi_status | 56 | static acpi_status |
56 | acpi_hw_read_multiple(u32 *value, | 57 | acpi_hw_read_multiple(u32 *value, |
@@ -62,6 +63,8 @@ acpi_hw_write_multiple(u32 value, | |||
62 | struct acpi_generic_address *register_a, | 63 | struct acpi_generic_address *register_a, |
63 | struct acpi_generic_address *register_b); | 64 | struct acpi_generic_address *register_b); |
64 | 65 | ||
66 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
67 | |||
65 | /****************************************************************************** | 68 | /****************************************************************************** |
66 | * | 69 | * |
67 | * FUNCTION: acpi_hw_validate_register | 70 | * FUNCTION: acpi_hw_validate_register |
@@ -154,6 +157,7 @@ acpi_hw_validate_register(struct acpi_generic_address *reg, | |||
154 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | 157 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) |
155 | { | 158 | { |
156 | u64 address; | 159 | u64 address; |
160 | u64 value64; | ||
157 | acpi_status status; | 161 | acpi_status status; |
158 | 162 | ||
159 | ACPI_FUNCTION_NAME(hw_read); | 163 | ACPI_FUNCTION_NAME(hw_read); |
@@ -175,7 +179,9 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
175 | */ | 179 | */ |
176 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 180 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
177 | status = acpi_os_read_memory((acpi_physical_address) | 181 | status = acpi_os_read_memory((acpi_physical_address) |
178 | address, value, reg->bit_width); | 182 | address, &value64, reg->bit_width); |
183 | |||
184 | *value = (u32)value64; | ||
179 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | 185 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
180 | 186 | ||
181 | status = acpi_hw_read_port((acpi_io_address) | 187 | status = acpi_hw_read_port((acpi_io_address) |
@@ -225,7 +231,8 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
225 | */ | 231 | */ |
226 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 232 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
227 | status = acpi_os_write_memory((acpi_physical_address) | 233 | status = acpi_os_write_memory((acpi_physical_address) |
228 | address, value, reg->bit_width); | 234 | address, (u64)value, |
235 | reg->bit_width); | ||
229 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | 236 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
230 | 237 | ||
231 | status = acpi_hw_write_port((acpi_io_address) | 238 | status = acpi_hw_write_port((acpi_io_address) |
@@ -240,6 +247,7 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
240 | return (status); | 247 | return (status); |
241 | } | 248 | } |
242 | 249 | ||
250 | #if (!ACPI_REDUCED_HARDWARE) | ||
243 | /******************************************************************************* | 251 | /******************************************************************************* |
244 | * | 252 | * |
245 | * FUNCTION: acpi_hw_clear_acpi_status | 253 | * FUNCTION: acpi_hw_clear_acpi_status |
@@ -285,7 +293,7 @@ exit: | |||
285 | 293 | ||
286 | /******************************************************************************* | 294 | /******************************************************************************* |
287 | * | 295 | * |
288 | * FUNCTION: acpi_hw_get_register_bit_mask | 296 | * FUNCTION: acpi_hw_get_bit_register_info |
289 | * | 297 | * |
290 | * PARAMETERS: register_id - Index of ACPI Register to access | 298 | * PARAMETERS: register_id - Index of ACPI Register to access |
291 | * | 299 | * |
@@ -658,3 +666,5 @@ acpi_hw_write_multiple(u32 value, | |||
658 | 666 | ||
659 | return (status); | 667 | return (status); |
660 | } | 668 | } |
669 | |||
670 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 3c4a922a9fc2..0ed85cac3231 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -1,7 +1,7 @@ | |||
1 | |||
2 | /****************************************************************************** | 1 | /****************************************************************************** |
3 | * | 2 | * |
4 | * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface | 3 | * Name: hwsleep.c - ACPI Hardware Sleep/Wake Support functions for the |
4 | * original/legacy sleep/PM registers. | ||
5 | * | 5 | * |
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
@@ -43,213 +43,37 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include <linux/acpi.h> | ||
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "actables.h" | ||
48 | #include <linux/tboot.h> | ||
49 | #include <linux/module.h> | 48 | #include <linux/module.h> |
50 | 49 | ||
51 | #define _COMPONENT ACPI_HARDWARE | 50 | #define _COMPONENT ACPI_HARDWARE |
52 | ACPI_MODULE_NAME("hwsleep") | 51 | ACPI_MODULE_NAME("hwsleep") |
53 | 52 | ||
53 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
54 | /******************************************************************************* | 54 | /******************************************************************************* |
55 | * | 55 | * |
56 | * FUNCTION: acpi_set_firmware_waking_vector | 56 | * FUNCTION: acpi_hw_legacy_sleep |
57 | * | ||
58 | * PARAMETERS: physical_address - 32-bit physical address of ACPI real mode | ||
59 | * entry point. | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | acpi_status | ||
67 | acpi_set_firmware_waking_vector(u32 physical_address) | ||
68 | { | ||
69 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); | ||
70 | |||
71 | |||
72 | /* | ||
73 | * According to the ACPI specification 2.0c and later, the 64-bit | ||
74 | * waking vector should be cleared and the 32-bit waking vector should | ||
75 | * be used, unless we want the wake-up code to be called by the BIOS in | ||
76 | * Protected Mode. Some systems (for example HP dv5-1004nr) are known | ||
77 | * to fail to resume if the 64-bit vector is used. | ||
78 | */ | ||
79 | |||
80 | /* Set the 32-bit vector */ | ||
81 | |||
82 | acpi_gbl_FACS->firmware_waking_vector = physical_address; | ||
83 | |||
84 | /* Clear the 64-bit vector if it exists */ | ||
85 | |||
86 | if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) { | ||
87 | acpi_gbl_FACS->xfirmware_waking_vector = 0; | ||
88 | } | ||
89 | |||
90 | return_ACPI_STATUS(AE_OK); | ||
91 | } | ||
92 | |||
93 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) | ||
94 | |||
95 | #if ACPI_MACHINE_WIDTH == 64 | ||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * FUNCTION: acpi_set_firmware_waking_vector64 | ||
99 | * | ||
100 | * PARAMETERS: physical_address - 64-bit physical address of ACPI protected | ||
101 | * mode entry point. | ||
102 | * | ||
103 | * RETURN: Status | ||
104 | * | ||
105 | * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if | ||
106 | * it exists in the table. This function is intended for use with | ||
107 | * 64-bit host operating systems. | ||
108 | * | ||
109 | ******************************************************************************/ | ||
110 | acpi_status | ||
111 | acpi_set_firmware_waking_vector64(u64 physical_address) | ||
112 | { | ||
113 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64); | ||
114 | |||
115 | |||
116 | /* Determine if the 64-bit vector actually exists */ | ||
117 | |||
118 | if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) { | ||
119 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
120 | } | ||
121 | |||
122 | /* Clear 32-bit vector, set the 64-bit X_ vector */ | ||
123 | |||
124 | acpi_gbl_FACS->firmware_waking_vector = 0; | ||
125 | acpi_gbl_FACS->xfirmware_waking_vector = physical_address; | ||
126 | |||
127 | return_ACPI_STATUS(AE_OK); | ||
128 | } | ||
129 | |||
130 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) | ||
131 | #endif | ||
132 | |||
133 | /******************************************************************************* | ||
134 | * | ||
135 | * FUNCTION: acpi_enter_sleep_state_prep | ||
136 | * | ||
137 | * PARAMETERS: sleep_state - Which sleep state to enter | ||
138 | * | ||
139 | * RETURN: Status | ||
140 | * | ||
141 | * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) | ||
142 | * This function must execute with interrupts enabled. | ||
143 | * We break sleeping into 2 stages so that OSPM can handle | ||
144 | * various OS-specific tasks between the two steps. | ||
145 | * | ||
146 | ******************************************************************************/ | ||
147 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | ||
148 | { | ||
149 | acpi_status status; | ||
150 | struct acpi_object_list arg_list; | ||
151 | union acpi_object arg; | ||
152 | |||
153 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); | ||
154 | |||
155 | /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */ | ||
156 | |||
157 | status = acpi_get_sleep_type_data(sleep_state, | ||
158 | &acpi_gbl_sleep_type_a, | ||
159 | &acpi_gbl_sleep_type_b); | ||
160 | if (ACPI_FAILURE(status)) { | ||
161 | return_ACPI_STATUS(status); | ||
162 | } | ||
163 | |||
164 | /* Setup parameter object */ | ||
165 | |||
166 | arg_list.count = 1; | ||
167 | arg_list.pointer = &arg; | ||
168 | |||
169 | arg.type = ACPI_TYPE_INTEGER; | ||
170 | arg.integer.value = sleep_state; | ||
171 | |||
172 | /* Run the _PTS method */ | ||
173 | |||
174 | status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); | ||
175 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
176 | return_ACPI_STATUS(status); | ||
177 | } | ||
178 | |||
179 | /* Setup the argument to _SST */ | ||
180 | |||
181 | switch (sleep_state) { | ||
182 | case ACPI_STATE_S0: | ||
183 | arg.integer.value = ACPI_SST_WORKING; | ||
184 | break; | ||
185 | |||
186 | case ACPI_STATE_S1: | ||
187 | case ACPI_STATE_S2: | ||
188 | case ACPI_STATE_S3: | ||
189 | arg.integer.value = ACPI_SST_SLEEPING; | ||
190 | break; | ||
191 | |||
192 | case ACPI_STATE_S4: | ||
193 | arg.integer.value = ACPI_SST_SLEEP_CONTEXT; | ||
194 | break; | ||
195 | |||
196 | default: | ||
197 | arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */ | ||
198 | break; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * Set the system indicators to show the desired sleep state. | ||
203 | * _SST is an optional method (return no error if not found) | ||
204 | */ | ||
205 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | ||
206 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
207 | ACPI_EXCEPTION((AE_INFO, status, | ||
208 | "While executing method _SST")); | ||
209 | } | ||
210 | |||
211 | return_ACPI_STATUS(AE_OK); | ||
212 | } | ||
213 | |||
214 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | ||
215 | |||
216 | static unsigned int gts, bfs; | ||
217 | module_param(gts, uint, 0644); | ||
218 | module_param(bfs, uint, 0644); | ||
219 | MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); | ||
220 | MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); | ||
221 | |||
222 | /******************************************************************************* | ||
223 | * | ||
224 | * FUNCTION: acpi_enter_sleep_state | ||
225 | * | 57 | * |
226 | * PARAMETERS: sleep_state - Which sleep state to enter | 58 | * PARAMETERS: sleep_state - Which sleep state to enter |
59 | * Flags - ACPI_EXECUTE_GTS to run optional method | ||
227 | * | 60 | * |
228 | * RETURN: Status | 61 | * RETURN: Status |
229 | * | 62 | * |
230 | * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) | 63 | * DESCRIPTION: Enter a system sleep state via the legacy FADT PM registers |
231 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 64 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
232 | * | 65 | * |
233 | ******************************************************************************/ | 66 | ******************************************************************************/ |
234 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | 67 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) |
235 | { | 68 | { |
236 | u32 pm1a_control; | ||
237 | u32 pm1b_control; | ||
238 | struct acpi_bit_register_info *sleep_type_reg_info; | 69 | struct acpi_bit_register_info *sleep_type_reg_info; |
239 | struct acpi_bit_register_info *sleep_enable_reg_info; | 70 | struct acpi_bit_register_info *sleep_enable_reg_info; |
71 | u32 pm1a_control; | ||
72 | u32 pm1b_control; | ||
240 | u32 in_value; | 73 | u32 in_value; |
241 | struct acpi_object_list arg_list; | ||
242 | union acpi_object arg; | ||
243 | acpi_status status; | 74 | acpi_status status; |
244 | 75 | ||
245 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); | 76 | ACPI_FUNCTION_TRACE(hw_legacy_sleep); |
246 | |||
247 | if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || | ||
248 | (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { | ||
249 | ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X", | ||
250 | acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b)); | ||
251 | return_ACPI_STATUS(AE_AML_OPERAND_VALUE); | ||
252 | } | ||
253 | 77 | ||
254 | sleep_type_reg_info = | 78 | sleep_type_reg_info = |
255 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE); | 79 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE); |
@@ -271,6 +95,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
271 | return_ACPI_STATUS(status); | 95 | return_ACPI_STATUS(status); |
272 | } | 96 | } |
273 | 97 | ||
98 | if (sleep_state != ACPI_STATE_S5) { | ||
99 | /* | ||
100 | * Disable BM arbitration. This feature is contained within an | ||
101 | * optional register (PM2 Control), so ignore a BAD_ADDRESS | ||
102 | * exception. | ||
103 | */ | ||
104 | status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); | ||
105 | if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { | ||
106 | return_ACPI_STATUS(status); | ||
107 | } | ||
108 | } | ||
109 | |||
274 | /* | 110 | /* |
275 | * 1) Disable/Clear all GPEs | 111 | * 1) Disable/Clear all GPEs |
276 | * 2) Enable all wakeup GPEs | 112 | * 2) Enable all wakeup GPEs |
@@ -286,18 +122,10 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
286 | return_ACPI_STATUS(status); | 122 | return_ACPI_STATUS(status); |
287 | } | 123 | } |
288 | 124 | ||
289 | if (gts) { | 125 | /* Optionally execute _GTS (Going To Sleep) */ |
290 | /* Execute the _GTS method */ | ||
291 | |||
292 | arg_list.count = 1; | ||
293 | arg_list.pointer = &arg; | ||
294 | arg.type = ACPI_TYPE_INTEGER; | ||
295 | arg.integer.value = sleep_state; | ||
296 | 126 | ||
297 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); | 127 | if (flags & ACPI_EXECUTE_GTS) { |
298 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 128 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); |
299 | return_ACPI_STATUS(status); | ||
300 | } | ||
301 | } | 129 | } |
302 | 130 | ||
303 | /* Get current value of PM1A control */ | 131 | /* Get current value of PM1A control */ |
@@ -344,8 +172,12 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
344 | 172 | ||
345 | ACPI_FLUSH_CPU_CACHE(); | 173 | ACPI_FLUSH_CPU_CACHE(); |
346 | 174 | ||
347 | tboot_sleep(sleep_state, pm1a_control, pm1b_control); | 175 | status = acpi_os_prepare_sleep(sleep_state, pm1a_control, |
348 | 176 | pm1b_control); | |
177 | if (ACPI_SKIP(status)) | ||
178 | return_ACPI_STATUS(AE_OK); | ||
179 | if (ACPI_FAILURE(status)) | ||
180 | return_ACPI_STATUS(status); | ||
349 | /* Write #2: Write both SLP_TYP + SLP_EN */ | 181 | /* Write #2: Write both SLP_TYP + SLP_EN */ |
350 | 182 | ||
351 | status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); | 183 | status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); |
@@ -375,114 +207,44 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
375 | } | 207 | } |
376 | } | 208 | } |
377 | 209 | ||
378 | /* Wait until we enter sleep state */ | 210 | /* Wait for transition back to Working State */ |
379 | |||
380 | do { | ||
381 | status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, | ||
382 | &in_value); | ||
383 | if (ACPI_FAILURE(status)) { | ||
384 | return_ACPI_STATUS(status); | ||
385 | } | ||
386 | |||
387 | /* Spin until we wake */ | ||
388 | |||
389 | } while (!in_value); | ||
390 | |||
391 | return_ACPI_STATUS(AE_OK); | ||
392 | } | ||
393 | |||
394 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) | ||
395 | |||
396 | /******************************************************************************* | ||
397 | * | ||
398 | * FUNCTION: acpi_enter_sleep_state_s4bios | ||
399 | * | ||
400 | * PARAMETERS: None | ||
401 | * | ||
402 | * RETURN: Status | ||
403 | * | ||
404 | * DESCRIPTION: Perform a S4 bios request. | ||
405 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | ||
406 | * | ||
407 | ******************************************************************************/ | ||
408 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | ||
409 | { | ||
410 | u32 in_value; | ||
411 | acpi_status status; | ||
412 | |||
413 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); | ||
414 | |||
415 | /* Clear the wake status bit (PM1) */ | ||
416 | |||
417 | status = | ||
418 | acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS); | ||
419 | if (ACPI_FAILURE(status)) { | ||
420 | return_ACPI_STATUS(status); | ||
421 | } | ||
422 | |||
423 | status = acpi_hw_clear_acpi_status(); | ||
424 | if (ACPI_FAILURE(status)) { | ||
425 | return_ACPI_STATUS(status); | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * 1) Disable/Clear all GPEs | ||
430 | * 2) Enable all wakeup GPEs | ||
431 | */ | ||
432 | status = acpi_hw_disable_all_gpes(); | ||
433 | if (ACPI_FAILURE(status)) { | ||
434 | return_ACPI_STATUS(status); | ||
435 | } | ||
436 | acpi_gbl_system_awake_and_running = FALSE; | ||
437 | |||
438 | status = acpi_hw_enable_all_wakeup_gpes(); | ||
439 | if (ACPI_FAILURE(status)) { | ||
440 | return_ACPI_STATUS(status); | ||
441 | } | ||
442 | |||
443 | ACPI_FLUSH_CPU_CACHE(); | ||
444 | |||
445 | status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, | ||
446 | (u32) acpi_gbl_FADT.S4bios_request, 8); | ||
447 | 211 | ||
448 | do { | 212 | do { |
449 | acpi_os_stall(1000); | ||
450 | status = | 213 | status = |
451 | acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value); | 214 | acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value); |
452 | if (ACPI_FAILURE(status)) { | 215 | if (ACPI_FAILURE(status)) { |
453 | return_ACPI_STATUS(status); | 216 | return_ACPI_STATUS(status); |
454 | } | 217 | } |
218 | |||
455 | } while (!in_value); | 219 | } while (!in_value); |
456 | 220 | ||
457 | return_ACPI_STATUS(AE_OK); | 221 | return_ACPI_STATUS(AE_OK); |
458 | } | 222 | } |
459 | 223 | ||
460 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) | ||
461 | |||
462 | /******************************************************************************* | 224 | /******************************************************************************* |
463 | * | 225 | * |
464 | * FUNCTION: acpi_leave_sleep_state_prep | 226 | * FUNCTION: acpi_hw_legacy_wake_prep |
465 | * | 227 | * |
466 | * PARAMETERS: sleep_state - Which sleep state we are exiting | 228 | * PARAMETERS: sleep_state - Which sleep state we just exited |
229 | * Flags - ACPI_EXECUTE_BFS to run optional method | ||
467 | * | 230 | * |
468 | * RETURN: Status | 231 | * RETURN: Status |
469 | * | 232 | * |
470 | * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a | 233 | * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a |
471 | * sleep. | 234 | * sleep. |
472 | * Called with interrupts DISABLED. | 235 | * Called with interrupts ENABLED. |
473 | * | 236 | * |
474 | ******************************************************************************/ | 237 | ******************************************************************************/ |
475 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) | 238 | |
239 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | ||
476 | { | 240 | { |
477 | struct acpi_object_list arg_list; | ||
478 | union acpi_object arg; | ||
479 | acpi_status status; | 241 | acpi_status status; |
480 | struct acpi_bit_register_info *sleep_type_reg_info; | 242 | struct acpi_bit_register_info *sleep_type_reg_info; |
481 | struct acpi_bit_register_info *sleep_enable_reg_info; | 243 | struct acpi_bit_register_info *sleep_enable_reg_info; |
482 | u32 pm1a_control; | 244 | u32 pm1a_control; |
483 | u32 pm1b_control; | 245 | u32 pm1b_control; |
484 | 246 | ||
485 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); | 247 | ACPI_FUNCTION_TRACE(hw_legacy_wake_prep); |
486 | 248 | ||
487 | /* | 249 | /* |
488 | * Set SLP_TYPE and SLP_EN to state S0. | 250 | * Set SLP_TYPE and SLP_EN to state S0. |
@@ -525,27 +287,20 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) | |||
525 | } | 287 | } |
526 | } | 288 | } |
527 | 289 | ||
528 | if (bfs) { | 290 | /* Optionally execute _BFS (Back From Sleep) */ |
529 | /* Execute the _BFS method */ | ||
530 | 291 | ||
531 | arg_list.count = 1; | 292 | if (flags & ACPI_EXECUTE_BFS) { |
532 | arg_list.pointer = &arg; | 293 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); |
533 | arg.type = ACPI_TYPE_INTEGER; | ||
534 | arg.integer.value = sleep_state; | ||
535 | |||
536 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); | ||
537 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
538 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); | ||
539 | } | ||
540 | } | 294 | } |
541 | return_ACPI_STATUS(status); | 295 | return_ACPI_STATUS(status); |
542 | } | 296 | } |
543 | 297 | ||
544 | /******************************************************************************* | 298 | /******************************************************************************* |
545 | * | 299 | * |
546 | * FUNCTION: acpi_leave_sleep_state | 300 | * FUNCTION: acpi_hw_legacy_wake |
547 | * | 301 | * |
548 | * PARAMETERS: sleep_state - Which sleep state we just exited | 302 | * PARAMETERS: sleep_state - Which sleep state we just exited |
303 | * Flags - Reserved, set to zero | ||
549 | * | 304 | * |
550 | * RETURN: Status | 305 | * RETURN: Status |
551 | * | 306 | * |
@@ -553,31 +308,17 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) | |||
553 | * Called with interrupts ENABLED. | 308 | * Called with interrupts ENABLED. |
554 | * | 309 | * |
555 | ******************************************************************************/ | 310 | ******************************************************************************/ |
556 | acpi_status acpi_leave_sleep_state(u8 sleep_state) | 311 | |
312 | acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) | ||
557 | { | 313 | { |
558 | struct acpi_object_list arg_list; | ||
559 | union acpi_object arg; | ||
560 | acpi_status status; | 314 | acpi_status status; |
561 | 315 | ||
562 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | 316 | ACPI_FUNCTION_TRACE(hw_legacy_wake); |
563 | 317 | ||
564 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ | 318 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ |
565 | 319 | ||
566 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; | 320 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; |
567 | 321 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING); | |
568 | /* Setup parameter object */ | ||
569 | |||
570 | arg_list.count = 1; | ||
571 | arg_list.pointer = &arg; | ||
572 | arg.type = ACPI_TYPE_INTEGER; | ||
573 | |||
574 | /* Ignore any errors from these methods */ | ||
575 | |||
576 | arg.integer.value = ACPI_SST_WAKING; | ||
577 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | ||
578 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
579 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); | ||
580 | } | ||
581 | 322 | ||
582 | /* | 323 | /* |
583 | * GPEs must be enabled before _WAK is called as GPEs | 324 | * GPEs must be enabled before _WAK is called as GPEs |
@@ -591,46 +332,50 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
591 | if (ACPI_FAILURE(status)) { | 332 | if (ACPI_FAILURE(status)) { |
592 | return_ACPI_STATUS(status); | 333 | return_ACPI_STATUS(status); |
593 | } | 334 | } |
335 | |||
594 | status = acpi_hw_enable_all_runtime_gpes(); | 336 | status = acpi_hw_enable_all_runtime_gpes(); |
595 | if (ACPI_FAILURE(status)) { | 337 | if (ACPI_FAILURE(status)) { |
596 | return_ACPI_STATUS(status); | 338 | return_ACPI_STATUS(status); |
597 | } | 339 | } |
598 | 340 | ||
599 | arg.integer.value = sleep_state; | 341 | /* |
600 | status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); | 342 | * Now we can execute _WAK, etc. Some machines require that the GPEs |
601 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 343 | * are enabled before the wake methods are executed. |
602 | ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); | 344 | */ |
603 | } | 345 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state); |
604 | /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ | ||
605 | 346 | ||
606 | /* | 347 | /* |
607 | * Some BIOSes assume that WAK_STS will be cleared on resume and use | 348 | * Some BIOS code assumes that WAK_STS will be cleared on resume |
608 | * it to determine whether the system is rebooting or resuming. Clear | 349 | * and use it to determine whether the system is rebooting or |
609 | * it for compatibility. | 350 | * resuming. Clear WAK_STS for compatibility. |
610 | */ | 351 | */ |
611 | acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1); | 352 | acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1); |
612 | |||
613 | acpi_gbl_system_awake_and_running = TRUE; | 353 | acpi_gbl_system_awake_and_running = TRUE; |
614 | 354 | ||
615 | /* Enable power button */ | 355 | /* Enable power button */ |
616 | 356 | ||
617 | (void) | 357 | (void) |
618 | acpi_write_bit_register(acpi_gbl_fixed_event_info | 358 | acpi_write_bit_register(acpi_gbl_fixed_event_info |
619 | [ACPI_EVENT_POWER_BUTTON]. | 359 | [ACPI_EVENT_POWER_BUTTON]. |
620 | enable_register_id, ACPI_ENABLE_EVENT); | 360 | enable_register_id, ACPI_ENABLE_EVENT); |
621 | 361 | ||
622 | (void) | 362 | (void) |
623 | acpi_write_bit_register(acpi_gbl_fixed_event_info | 363 | acpi_write_bit_register(acpi_gbl_fixed_event_info |
624 | [ACPI_EVENT_POWER_BUTTON]. | 364 | [ACPI_EVENT_POWER_BUTTON]. |
625 | status_register_id, ACPI_CLEAR_STATUS); | 365 | status_register_id, ACPI_CLEAR_STATUS); |
626 | 366 | ||
627 | arg.integer.value = ACPI_SST_WORKING; | 367 | /* |
628 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | 368 | * Enable BM arbitration. This feature is contained within an |
629 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 369 | * optional register (PM2 Control), so ignore a BAD_ADDRESS |
630 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); | 370 | * exception. |
371 | */ | ||
372 | status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); | ||
373 | if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { | ||
374 | return_ACPI_STATUS(status); | ||
631 | } | 375 | } |
632 | 376 | ||
377 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); | ||
633 | return_ACPI_STATUS(status); | 378 | return_ACPI_STATUS(status); |
634 | } | 379 | } |
635 | 380 | ||
636 | ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state) | 381 | #endif /* !ACPI_REDUCED_HARDWARE */ |
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index d4973d9da9f1..f1b2c3b94cac 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #define _COMPONENT ACPI_HARDWARE | 49 | #define _COMPONENT ACPI_HARDWARE |
50 | ACPI_MODULE_NAME("hwtimer") | 50 | ACPI_MODULE_NAME("hwtimer") |
51 | 51 | ||
52 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
52 | /****************************************************************************** | 53 | /****************************************************************************** |
53 | * | 54 | * |
54 | * FUNCTION: acpi_get_timer_resolution | 55 | * FUNCTION: acpi_get_timer_resolution |
@@ -187,3 +188,4 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) | |||
187 | } | 188 | } |
188 | 189 | ||
189 | ACPI_EXPORT_SYMBOL(acpi_get_timer_duration) | 190 | ACPI_EXPORT_SYMBOL(acpi_get_timer_duration) |
191 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 9d38eb6c0d0b..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 | ||
@@ -138,11 +137,6 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
138 | return (status); | 137 | return (status); |
139 | } | 138 | } |
140 | 139 | ||
141 | width = reg->bit_width; | ||
142 | if (width == 64) { | ||
143 | width = 32; /* Break into two 32-bit transfers */ | ||
144 | } | ||
145 | |||
146 | /* Initialize entire 64-bit return value to zero */ | 140 | /* Initialize entire 64-bit return value to zero */ |
147 | 141 | ||
148 | *return_value = 0; | 142 | *return_value = 0; |
@@ -154,24 +148,17 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
154 | */ | 148 | */ |
155 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 149 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
156 | status = acpi_os_read_memory((acpi_physical_address) | 150 | status = acpi_os_read_memory((acpi_physical_address) |
157 | address, &value, width); | 151 | address, return_value, |
152 | reg->bit_width); | ||
158 | if (ACPI_FAILURE(status)) { | 153 | if (ACPI_FAILURE(status)) { |
159 | return (status); | 154 | return (status); |
160 | } | 155 | } |
161 | *return_value = value; | 156 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
162 | |||
163 | if (reg->bit_width == 64) { | ||
164 | |||
165 | /* Read the top 32 bits */ | ||
166 | 157 | ||
167 | status = acpi_os_read_memory((acpi_physical_address) | 158 | width = reg->bit_width; |
168 | (address + 4), &value, 32); | 159 | if (width == 64) { |
169 | if (ACPI_FAILURE(status)) { | 160 | width = 32; /* Break into two 32-bit transfers */ |
170 | return (status); | ||
171 | } | ||
172 | *return_value |= ((u64)value << 32); | ||
173 | } | 161 | } |
174 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
175 | 162 | ||
176 | status = acpi_hw_read_port((acpi_io_address) | 163 | status = acpi_hw_read_port((acpi_io_address) |
177 | address, &value, width); | 164 | address, &value, width); |
@@ -231,32 +218,22 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) | |||
231 | return (status); | 218 | return (status); |
232 | } | 219 | } |
233 | 220 | ||
234 | width = reg->bit_width; | ||
235 | if (width == 64) { | ||
236 | width = 32; /* Break into two 32-bit transfers */ | ||
237 | } | ||
238 | |||
239 | /* | 221 | /* |
240 | * Two address spaces supported: Memory or IO. PCI_Config is | 222 | * Two address spaces supported: Memory or IO. PCI_Config is |
241 | * not supported here because the GAS structure is insufficient | 223 | * not supported here because the GAS structure is insufficient |
242 | */ | 224 | */ |
243 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 225 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
244 | status = acpi_os_write_memory((acpi_physical_address) | 226 | status = acpi_os_write_memory((acpi_physical_address) |
245 | address, ACPI_LODWORD(value), | 227 | address, value, reg->bit_width); |
246 | width); | ||
247 | if (ACPI_FAILURE(status)) { | 228 | if (ACPI_FAILURE(status)) { |
248 | return (status); | 229 | return (status); |
249 | } | 230 | } |
231 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
250 | 232 | ||
251 | if (reg->bit_width == 64) { | 233 | width = reg->bit_width; |
252 | status = acpi_os_write_memory((acpi_physical_address) | 234 | if (width == 64) { |
253 | (address + 4), | 235 | width = 32; /* Break into two 32-bit transfers */ |
254 | ACPI_HIDWORD(value), 32); | ||
255 | if (ACPI_FAILURE(status)) { | ||
256 | return (status); | ||
257 | } | ||
258 | } | 236 | } |
259 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
260 | 237 | ||
261 | status = acpi_hw_write_port((acpi_io_address) | 238 | status = acpi_hw_write_port((acpi_io_address) |
262 | address, ACPI_LODWORD(value), | 239 | address, ACPI_LODWORD(value), |
@@ -286,6 +263,7 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) | |||
286 | 263 | ||
287 | ACPI_EXPORT_SYMBOL(acpi_write) | 264 | ACPI_EXPORT_SYMBOL(acpi_write) |
288 | 265 | ||
266 | #if (!ACPI_REDUCED_HARDWARE) | ||
289 | /******************************************************************************* | 267 | /******************************************************************************* |
290 | * | 268 | * |
291 | * FUNCTION: acpi_read_bit_register | 269 | * FUNCTION: acpi_read_bit_register |
@@ -453,7 +431,7 @@ unlock_and_exit: | |||
453 | } | 431 | } |
454 | 432 | ||
455 | ACPI_EXPORT_SYMBOL(acpi_write_bit_register) | 433 | ACPI_EXPORT_SYMBOL(acpi_write_bit_register) |
456 | 434 | #endif /* !ACPI_REDUCED_HARDWARE */ | |
457 | /******************************************************************************* | 435 | /******************************************************************************* |
458 | * | 436 | * |
459 | * FUNCTION: acpi_get_sleep_type_data | 437 | * FUNCTION: acpi_get_sleep_type_data |
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c new file mode 100644 index 000000000000..762d059bb508 --- /dev/null +++ b/drivers/acpi/acpica/hwxfsleep.c | |||
@@ -0,0 +1,431 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Name: hwxfsleep.c - ACPI Hardware Sleep/Wake External Interfaces | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2012, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include <linux/module.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_HARDWARE | ||
49 | ACPI_MODULE_NAME("hwxfsleep") | ||
50 | |||
51 | /* Local prototypes */ | ||
52 | static acpi_status | ||
53 | acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id); | ||
54 | |||
55 | /* | ||
56 | * Dispatch table used to efficiently branch to the various sleep | ||
57 | * functions. | ||
58 | */ | ||
59 | #define ACPI_SLEEP_FUNCTION_ID 0 | ||
60 | #define ACPI_WAKE_PREP_FUNCTION_ID 1 | ||
61 | #define ACPI_WAKE_FUNCTION_ID 2 | ||
62 | |||
63 | /* Legacy functions are optional, based upon ACPI_REDUCED_HARDWARE */ | ||
64 | |||
65 | static struct acpi_sleep_functions acpi_sleep_dispatch[] = { | ||
66 | {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_sleep), | ||
67 | acpi_hw_extended_sleep}, | ||
68 | {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_wake_prep), | ||
69 | acpi_hw_extended_wake_prep}, | ||
70 | {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_wake), acpi_hw_extended_wake} | ||
71 | }; | ||
72 | |||
73 | /* | ||
74 | * These functions are removed for the ACPI_REDUCED_HARDWARE case: | ||
75 | * acpi_set_firmware_waking_vector | ||
76 | * acpi_set_firmware_waking_vector64 | ||
77 | * acpi_enter_sleep_state_s4bios | ||
78 | */ | ||
79 | |||
80 | #if (!ACPI_REDUCED_HARDWARE) | ||
81 | /******************************************************************************* | ||
82 | * | ||
83 | * FUNCTION: acpi_set_firmware_waking_vector | ||
84 | * | ||
85 | * PARAMETERS: physical_address - 32-bit physical address of ACPI real mode | ||
86 | * entry point. | ||
87 | * | ||
88 | * RETURN: Status | ||
89 | * | ||
90 | * DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS | ||
91 | * | ||
92 | ******************************************************************************/ | ||
93 | |||
94 | acpi_status acpi_set_firmware_waking_vector(u32 physical_address) | ||
95 | { | ||
96 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); | ||
97 | |||
98 | |||
99 | /* | ||
100 | * According to the ACPI specification 2.0c and later, the 64-bit | ||
101 | * waking vector should be cleared and the 32-bit waking vector should | ||
102 | * be used, unless we want the wake-up code to be called by the BIOS in | ||
103 | * Protected Mode. Some systems (for example HP dv5-1004nr) are known | ||
104 | * to fail to resume if the 64-bit vector is used. | ||
105 | */ | ||
106 | |||
107 | /* Set the 32-bit vector */ | ||
108 | |||
109 | acpi_gbl_FACS->firmware_waking_vector = physical_address; | ||
110 | |||
111 | /* Clear the 64-bit vector if it exists */ | ||
112 | |||
113 | if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) { | ||
114 | acpi_gbl_FACS->xfirmware_waking_vector = 0; | ||
115 | } | ||
116 | |||
117 | return_ACPI_STATUS(AE_OK); | ||
118 | } | ||
119 | |||
120 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) | ||
121 | |||
122 | #if ACPI_MACHINE_WIDTH == 64 | ||
123 | /******************************************************************************* | ||
124 | * | ||
125 | * FUNCTION: acpi_set_firmware_waking_vector64 | ||
126 | * | ||
127 | * PARAMETERS: physical_address - 64-bit physical address of ACPI protected | ||
128 | * mode entry point. | ||
129 | * | ||
130 | * RETURN: Status | ||
131 | * | ||
132 | * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if | ||
133 | * it exists in the table. This function is intended for use with | ||
134 | * 64-bit host operating systems. | ||
135 | * | ||
136 | ******************************************************************************/ | ||
137 | acpi_status acpi_set_firmware_waking_vector64(u64 physical_address) | ||
138 | { | ||
139 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64); | ||
140 | |||
141 | |||
142 | /* Determine if the 64-bit vector actually exists */ | ||
143 | |||
144 | if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) { | ||
145 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
146 | } | ||
147 | |||
148 | /* Clear 32-bit vector, set the 64-bit X_ vector */ | ||
149 | |||
150 | acpi_gbl_FACS->firmware_waking_vector = 0; | ||
151 | acpi_gbl_FACS->xfirmware_waking_vector = physical_address; | ||
152 | return_ACPI_STATUS(AE_OK); | ||
153 | } | ||
154 | |||
155 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) | ||
156 | #endif | ||
157 | |||
158 | /******************************************************************************* | ||
159 | * | ||
160 | * FUNCTION: acpi_enter_sleep_state_s4bios | ||
161 | * | ||
162 | * PARAMETERS: None | ||
163 | * | ||
164 | * RETURN: Status | ||
165 | * | ||
166 | * DESCRIPTION: Perform a S4 bios request. | ||
167 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | ||
168 | * | ||
169 | ******************************************************************************/ | ||
170 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | ||
171 | { | ||
172 | u32 in_value; | ||
173 | acpi_status status; | ||
174 | |||
175 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); | ||
176 | |||
177 | /* Clear the wake status bit (PM1) */ | ||
178 | |||
179 | status = | ||
180 | acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS); | ||
181 | if (ACPI_FAILURE(status)) { | ||
182 | return_ACPI_STATUS(status); | ||
183 | } | ||
184 | |||
185 | status = acpi_hw_clear_acpi_status(); | ||
186 | if (ACPI_FAILURE(status)) { | ||
187 | return_ACPI_STATUS(status); | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * 1) Disable/Clear all GPEs | ||
192 | * 2) Enable all wakeup GPEs | ||
193 | */ | ||
194 | status = acpi_hw_disable_all_gpes(); | ||
195 | if (ACPI_FAILURE(status)) { | ||
196 | return_ACPI_STATUS(status); | ||
197 | } | ||
198 | acpi_gbl_system_awake_and_running = FALSE; | ||
199 | |||
200 | status = acpi_hw_enable_all_wakeup_gpes(); | ||
201 | if (ACPI_FAILURE(status)) { | ||
202 | return_ACPI_STATUS(status); | ||
203 | } | ||
204 | |||
205 | ACPI_FLUSH_CPU_CACHE(); | ||
206 | |||
207 | status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, | ||
208 | (u32)acpi_gbl_FADT.S4bios_request, 8); | ||
209 | |||
210 | do { | ||
211 | acpi_os_stall(1000); | ||
212 | status = | ||
213 | acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value); | ||
214 | if (ACPI_FAILURE(status)) { | ||
215 | return_ACPI_STATUS(status); | ||
216 | } | ||
217 | } while (!in_value); | ||
218 | |||
219 | return_ACPI_STATUS(AE_OK); | ||
220 | } | ||
221 | |||
222 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) | ||
223 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
224 | /******************************************************************************* | ||
225 | * | ||
226 | * FUNCTION: acpi_hw_sleep_dispatch | ||
227 | * | ||
228 | * PARAMETERS: sleep_state - Which sleep state to enter/exit | ||
229 | * function_id - Sleep, wake_prep, or Wake | ||
230 | * | ||
231 | * RETURN: Status from the invoked sleep handling function. | ||
232 | * | ||
233 | * DESCRIPTION: Dispatch a sleep/wake request to the appropriate handling | ||
234 | * function. | ||
235 | * | ||
236 | ******************************************************************************/ | ||
237 | static acpi_status | ||
238 | acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) | ||
239 | { | ||
240 | acpi_status status; | ||
241 | struct acpi_sleep_functions *sleep_functions = | ||
242 | &acpi_sleep_dispatch[function_id]; | ||
243 | |||
244 | #if (!ACPI_REDUCED_HARDWARE) | ||
245 | |||
246 | /* | ||
247 | * If the Hardware Reduced flag is set (from the FADT), we must | ||
248 | * use the extended sleep registers | ||
249 | */ | ||
250 | if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) { | ||
251 | status = sleep_functions->extended_function(sleep_state, flags); | ||
252 | } else { | ||
253 | /* Legacy sleep */ | ||
254 | |||
255 | status = sleep_functions->legacy_function(sleep_state, flags); | ||
256 | } | ||
257 | |||
258 | return (status); | ||
259 | |||
260 | #else | ||
261 | /* | ||
262 | * For the case where reduced-hardware-only code is being generated, | ||
263 | * we know that only the extended sleep registers are available | ||
264 | */ | ||
265 | status = sleep_functions->extended_function(sleep_state, flags); | ||
266 | return (status); | ||
267 | |||
268 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
269 | } | ||
270 | |||
271 | /******************************************************************************* | ||
272 | * | ||
273 | * FUNCTION: acpi_enter_sleep_state_prep | ||
274 | * | ||
275 | * PARAMETERS: sleep_state - Which sleep state to enter | ||
276 | * | ||
277 | * RETURN: Status | ||
278 | * | ||
279 | * DESCRIPTION: Prepare to enter a system sleep state. | ||
280 | * This function must execute with interrupts enabled. | ||
281 | * We break sleeping into 2 stages so that OSPM can handle | ||
282 | * various OS-specific tasks between the two steps. | ||
283 | * | ||
284 | ******************************************************************************/ | ||
285 | |||
286 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | ||
287 | { | ||
288 | acpi_status status; | ||
289 | struct acpi_object_list arg_list; | ||
290 | union acpi_object arg; | ||
291 | u32 sst_value; | ||
292 | |||
293 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); | ||
294 | |||
295 | status = acpi_get_sleep_type_data(sleep_state, | ||
296 | &acpi_gbl_sleep_type_a, | ||
297 | &acpi_gbl_sleep_type_b); | ||
298 | if (ACPI_FAILURE(status)) { | ||
299 | return_ACPI_STATUS(status); | ||
300 | } | ||
301 | |||
302 | /* Execute the _PTS method (Prepare To Sleep) */ | ||
303 | |||
304 | arg_list.count = 1; | ||
305 | arg_list.pointer = &arg; | ||
306 | arg.type = ACPI_TYPE_INTEGER; | ||
307 | arg.integer.value = sleep_state; | ||
308 | |||
309 | status = | ||
310 | acpi_evaluate_object(NULL, METHOD_PATHNAME__PTS, &arg_list, NULL); | ||
311 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
312 | return_ACPI_STATUS(status); | ||
313 | } | ||
314 | |||
315 | /* Setup the argument to the _SST method (System STatus) */ | ||
316 | |||
317 | switch (sleep_state) { | ||
318 | case ACPI_STATE_S0: | ||
319 | sst_value = ACPI_SST_WORKING; | ||
320 | break; | ||
321 | |||
322 | case ACPI_STATE_S1: | ||
323 | case ACPI_STATE_S2: | ||
324 | case ACPI_STATE_S3: | ||
325 | sst_value = ACPI_SST_SLEEPING; | ||
326 | break; | ||
327 | |||
328 | case ACPI_STATE_S4: | ||
329 | sst_value = ACPI_SST_SLEEP_CONTEXT; | ||
330 | break; | ||
331 | |||
332 | default: | ||
333 | sst_value = ACPI_SST_INDICATOR_OFF; /* Default is off */ | ||
334 | break; | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * Set the system indicators to show the desired sleep state. | ||
339 | * _SST is an optional method (return no error if not found) | ||
340 | */ | ||
341 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, sst_value); | ||
342 | return_ACPI_STATUS(AE_OK); | ||
343 | } | ||
344 | |||
345 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | ||
346 | |||
347 | /******************************************************************************* | ||
348 | * | ||
349 | * FUNCTION: acpi_enter_sleep_state | ||
350 | * | ||
351 | * PARAMETERS: sleep_state - Which sleep state to enter | ||
352 | * Flags - ACPI_EXECUTE_GTS to run optional method | ||
353 | * | ||
354 | * RETURN: Status | ||
355 | * | ||
356 | * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) | ||
357 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | ||
358 | * | ||
359 | ******************************************************************************/ | ||
360 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags) | ||
361 | { | ||
362 | acpi_status status; | ||
363 | |||
364 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); | ||
365 | |||
366 | if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || | ||
367 | (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { | ||
368 | ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X", | ||
369 | acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b)); | ||
370 | return_ACPI_STATUS(AE_AML_OPERAND_VALUE); | ||
371 | } | ||
372 | |||
373 | status = | ||
374 | acpi_hw_sleep_dispatch(sleep_state, flags, ACPI_SLEEP_FUNCTION_ID); | ||
375 | return_ACPI_STATUS(status); | ||
376 | } | ||
377 | |||
378 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) | ||
379 | |||
380 | /******************************************************************************* | ||
381 | * | ||
382 | * FUNCTION: acpi_leave_sleep_state_prep | ||
383 | * | ||
384 | * PARAMETERS: sleep_state - Which sleep state we are exiting | ||
385 | * Flags - ACPI_EXECUTE_BFS to run optional method | ||
386 | * | ||
387 | * RETURN: Status | ||
388 | * | ||
389 | * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a | ||
390 | * sleep. | ||
391 | * Called with interrupts DISABLED. | ||
392 | * | ||
393 | ******************************************************************************/ | ||
394 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags) | ||
395 | { | ||
396 | acpi_status status; | ||
397 | |||
398 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); | ||
399 | |||
400 | status = | ||
401 | acpi_hw_sleep_dispatch(sleep_state, flags, | ||
402 | ACPI_WAKE_PREP_FUNCTION_ID); | ||
403 | return_ACPI_STATUS(status); | ||
404 | } | ||
405 | |||
406 | ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state_prep) | ||
407 | |||
408 | /******************************************************************************* | ||
409 | * | ||
410 | * FUNCTION: acpi_leave_sleep_state | ||
411 | * | ||
412 | * PARAMETERS: sleep_state - Which sleep state we are exiting | ||
413 | * | ||
414 | * RETURN: Status | ||
415 | * | ||
416 | * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep | ||
417 | * Called with interrupts ENABLED. | ||
418 | * | ||
419 | ******************************************************************************/ | ||
420 | acpi_status acpi_leave_sleep_state(u8 sleep_state) | ||
421 | { | ||
422 | acpi_status status; | ||
423 | |||
424 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | ||
425 | |||
426 | |||
427 | status = acpi_hw_sleep_dispatch(sleep_state, 0, ACPI_WAKE_FUNCTION_ID); | ||
428 | return_ACPI_STATUS(status); | ||
429 | } | ||
430 | |||
431 | ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state) | ||
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index b7f2b3be79ac..3f7f3f6e7dd5 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -242,7 +242,20 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
242 | 242 | ||
243 | if (!obj_desc) { | 243 | if (!obj_desc) { |
244 | 244 | ||
245 | /* No attached object, we are done */ | 245 | /* No attached object. Some types should always have an object */ |
246 | |||
247 | switch (type) { | ||
248 | case ACPI_TYPE_INTEGER: | ||
249 | case ACPI_TYPE_PACKAGE: | ||
250 | case ACPI_TYPE_BUFFER: | ||
251 | case ACPI_TYPE_STRING: | ||
252 | case ACPI_TYPE_METHOD: | ||
253 | acpi_os_printf("<No attached object>"); | ||
254 | break; | ||
255 | |||
256 | default: | ||
257 | break; | ||
258 | } | ||
246 | 259 | ||
247 | acpi_os_printf("\n"); | 260 | acpi_os_printf("\n"); |
248 | return (AE_OK); | 261 | return (AE_OK); |
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 30ea5bc53a78..3b5acb0eb406 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c | |||
@@ -121,7 +121,7 @@ void acpi_ns_dump_root_devices(void) | |||
121 | return; | 121 | return; |
122 | } | 122 | } |
123 | 123 | ||
124 | status = acpi_get_handle(NULL, ACPI_NS_SYSTEM_BUS, &sys_bus_handle); | 124 | status = acpi_get_handle(NULL, METHOD_NAME__SB_, &sys_bus_handle); |
125 | if (ACPI_FAILURE(status)) { | 125 | if (ACPI_FAILURE(status)) { |
126 | return; | 126 | return; |
127 | } | 127 | } |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index bbe46a447d34..23ce09686418 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -638,8 +638,8 @@ acpi_ns_check_package(struct acpi_predefined_data *data, | |||
638 | /* Create the new outer package and populate it */ | 638 | /* Create the new outer package and populate it */ |
639 | 639 | ||
640 | status = | 640 | status = |
641 | acpi_ns_repair_package_list(data, | 641 | acpi_ns_wrap_with_package(data, *elements, |
642 | return_object_ptr); | 642 | return_object_ptr); |
643 | if (ACPI_FAILURE(status)) { | 643 | if (ACPI_FAILURE(status)) { |
644 | return (status); | 644 | return (status); |
645 | } | 645 | } |
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 9c35d20eb52b..5519a64a353f 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -71,11 +71,10 @@ ACPI_MODULE_NAME("nsrepair") | |||
71 | * Buffer -> String | 71 | * Buffer -> String |
72 | * Buffer -> Package of Integers | 72 | * Buffer -> Package of Integers |
73 | * Package -> Package of one Package | 73 | * Package -> Package of one Package |
74 | * An incorrect standalone object is wrapped with required outer package | ||
74 | * | 75 | * |
75 | * Additional possible repairs: | 76 | * Additional possible repairs: |
76 | * | ||
77 | * Required package elements that are NULL replaced by Integer/String/Buffer | 77 | * Required package elements that are NULL replaced by Integer/String/Buffer |
78 | * Incorrect standalone package wrapped with required outer package | ||
79 | * | 78 | * |
80 | ******************************************************************************/ | 79 | ******************************************************************************/ |
81 | /* Local prototypes */ | 80 | /* Local prototypes */ |
@@ -91,10 +90,6 @@ static acpi_status | |||
91 | acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, | 90 | acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, |
92 | union acpi_operand_object **return_object); | 91 | union acpi_operand_object **return_object); |
93 | 92 | ||
94 | static acpi_status | ||
95 | acpi_ns_convert_to_package(union acpi_operand_object *original_object, | ||
96 | union acpi_operand_object **return_object); | ||
97 | |||
98 | /******************************************************************************* | 93 | /******************************************************************************* |
99 | * | 94 | * |
100 | * FUNCTION: acpi_ns_repair_object | 95 | * FUNCTION: acpi_ns_repair_object |
@@ -151,9 +146,24 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, | |||
151 | } | 146 | } |
152 | } | 147 | } |
153 | if (expected_btypes & ACPI_RTYPE_PACKAGE) { | 148 | if (expected_btypes & ACPI_RTYPE_PACKAGE) { |
154 | status = acpi_ns_convert_to_package(return_object, &new_object); | 149 | /* |
150 | * A package is expected. We will wrap the existing object with a | ||
151 | * new package object. It is often the case that if a variable-length | ||
152 | * package is required, but there is only a single object needed, the | ||
153 | * BIOS will return that object instead of wrapping it with a Package | ||
154 | * object. Note: after the wrapping, the package will be validated | ||
155 | * for correct contents (expected object type or types). | ||
156 | */ | ||
157 | status = | ||
158 | acpi_ns_wrap_with_package(data, return_object, &new_object); | ||
155 | if (ACPI_SUCCESS(status)) { | 159 | if (ACPI_SUCCESS(status)) { |
156 | goto object_repaired; | 160 | /* |
161 | * The original object just had its reference count | ||
162 | * incremented for being inserted into the new package. | ||
163 | */ | ||
164 | *return_object_ptr = new_object; /* New Package object */ | ||
165 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
166 | return (AE_OK); | ||
157 | } | 167 | } |
158 | } | 168 | } |
159 | 169 | ||
@@ -165,22 +175,27 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, | |||
165 | 175 | ||
166 | /* Object was successfully repaired */ | 176 | /* Object was successfully repaired */ |
167 | 177 | ||
168 | /* | ||
169 | * If the original object is a package element, we need to: | ||
170 | * 1. Set the reference count of the new object to match the | ||
171 | * reference count of the old object. | ||
172 | * 2. Decrement the reference count of the original object. | ||
173 | */ | ||
174 | if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { | 178 | if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { |
175 | new_object->common.reference_count = | 179 | /* |
176 | return_object->common.reference_count; | 180 | * The original object is a package element. We need to |
181 | * decrement the reference count of the original object, | ||
182 | * for removing it from the package. | ||
183 | * | ||
184 | * However, if the original object was just wrapped with a | ||
185 | * package object as part of the repair, we don't need to | ||
186 | * change the reference count. | ||
187 | */ | ||
188 | if (!(data->flags & ACPI_OBJECT_WRAPPED)) { | ||
189 | new_object->common.reference_count = | ||
190 | return_object->common.reference_count; | ||
177 | 191 | ||
178 | if (return_object->common.reference_count > 1) { | 192 | if (return_object->common.reference_count > 1) { |
179 | return_object->common.reference_count--; | 193 | return_object->common.reference_count--; |
194 | } | ||
180 | } | 195 | } |
181 | 196 | ||
182 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | 197 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, |
183 | "%s: Converted %s to expected %s at index %u\n", | 198 | "%s: Converted %s to expected %s at Package index %u\n", |
184 | data->pathname, | 199 | data->pathname, |
185 | acpi_ut_get_object_type_name(return_object), | 200 | acpi_ut_get_object_type_name(return_object), |
186 | acpi_ut_get_object_type_name(new_object), | 201 | acpi_ut_get_object_type_name(new_object), |
@@ -453,65 +468,6 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, | |||
453 | 468 | ||
454 | /******************************************************************************* | 469 | /******************************************************************************* |
455 | * | 470 | * |
456 | * FUNCTION: acpi_ns_convert_to_package | ||
457 | * | ||
458 | * PARAMETERS: original_object - Object to be converted | ||
459 | * return_object - Where the new converted object is returned | ||
460 | * | ||
461 | * RETURN: Status. AE_OK if conversion was successful. | ||
462 | * | ||
463 | * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of | ||
464 | * the buffer is converted to a single integer package element. | ||
465 | * | ||
466 | ******************************************************************************/ | ||
467 | |||
468 | static acpi_status | ||
469 | acpi_ns_convert_to_package(union acpi_operand_object *original_object, | ||
470 | union acpi_operand_object **return_object) | ||
471 | { | ||
472 | union acpi_operand_object *new_object; | ||
473 | union acpi_operand_object **elements; | ||
474 | u32 length; | ||
475 | u8 *buffer; | ||
476 | |||
477 | switch (original_object->common.type) { | ||
478 | case ACPI_TYPE_BUFFER: | ||
479 | |||
480 | /* Buffer-to-Package conversion */ | ||
481 | |||
482 | length = original_object->buffer.length; | ||
483 | new_object = acpi_ut_create_package_object(length); | ||
484 | if (!new_object) { | ||
485 | return (AE_NO_MEMORY); | ||
486 | } | ||
487 | |||
488 | /* Convert each buffer byte to an integer package element */ | ||
489 | |||
490 | elements = new_object->package.elements; | ||
491 | buffer = original_object->buffer.pointer; | ||
492 | |||
493 | while (length--) { | ||
494 | *elements = | ||
495 | acpi_ut_create_integer_object((u64) *buffer); | ||
496 | if (!*elements) { | ||
497 | acpi_ut_remove_reference(new_object); | ||
498 | return (AE_NO_MEMORY); | ||
499 | } | ||
500 | elements++; | ||
501 | buffer++; | ||
502 | } | ||
503 | break; | ||
504 | |||
505 | default: | ||
506 | return (AE_AML_OPERAND_TYPE); | ||
507 | } | ||
508 | |||
509 | *return_object = new_object; | ||
510 | return (AE_OK); | ||
511 | } | ||
512 | |||
513 | /******************************************************************************* | ||
514 | * | ||
515 | * FUNCTION: acpi_ns_repair_null_element | 471 | * FUNCTION: acpi_ns_repair_null_element |
516 | * | 472 | * |
517 | * PARAMETERS: Data - Pointer to validation data structure | 473 | * PARAMETERS: Data - Pointer to validation data structure |
@@ -677,55 +633,56 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, | |||
677 | 633 | ||
678 | /******************************************************************************* | 634 | /******************************************************************************* |
679 | * | 635 | * |
680 | * FUNCTION: acpi_ns_repair_package_list | 636 | * FUNCTION: acpi_ns_wrap_with_package |
681 | * | 637 | * |
682 | * PARAMETERS: Data - Pointer to validation data structure | 638 | * PARAMETERS: Data - Pointer to validation data structure |
683 | * obj_desc_ptr - Pointer to the object to repair. The new | 639 | * original_object - Pointer to the object to repair. |
684 | * package object is returned here, | 640 | * obj_desc_ptr - The new package object is returned here |
685 | * overwriting the old object. | ||
686 | * | 641 | * |
687 | * RETURN: Status, new object in *obj_desc_ptr | 642 | * RETURN: Status, new object in *obj_desc_ptr |
688 | * | 643 | * |
689 | * DESCRIPTION: Repair a common problem with objects that are defined to return | 644 | * DESCRIPTION: Repair a common problem with objects that are defined to |
690 | * a variable-length Package of Packages. If the variable-length | 645 | * return a variable-length Package of sub-objects. If there is |
691 | * is one, some BIOS code mistakenly simply declares a single | 646 | * only one sub-object, some BIOS code mistakenly simply declares |
692 | * Package instead of a Package with one sub-Package. This | 647 | * the single object instead of a Package with one sub-object. |
693 | * function attempts to repair this error by wrapping a Package | 648 | * This function attempts to repair this error by wrapping a |
694 | * object around the original Package, creating the correct | 649 | * Package object around the original object, creating the |
695 | * Package with one sub-Package. | 650 | * correct and expected Package with one sub-object. |
696 | * | 651 | * |
697 | * Names that can be repaired in this manner include: | 652 | * Names that can be repaired in this manner include: |
698 | * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS | 653 | * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, |
654 | * _BCL, _DOD, _FIX, _Sx | ||
699 | * | 655 | * |
700 | ******************************************************************************/ | 656 | ******************************************************************************/ |
701 | 657 | ||
702 | acpi_status | 658 | acpi_status |
703 | acpi_ns_repair_package_list(struct acpi_predefined_data *data, | 659 | acpi_ns_wrap_with_package(struct acpi_predefined_data *data, |
704 | union acpi_operand_object **obj_desc_ptr) | 660 | union acpi_operand_object *original_object, |
661 | union acpi_operand_object **obj_desc_ptr) | ||
705 | { | 662 | { |
706 | union acpi_operand_object *pkg_obj_desc; | 663 | union acpi_operand_object *pkg_obj_desc; |
707 | 664 | ||
708 | ACPI_FUNCTION_NAME(ns_repair_package_list); | 665 | ACPI_FUNCTION_NAME(ns_wrap_with_package); |
709 | 666 | ||
710 | /* | 667 | /* |
711 | * Create the new outer package and populate it. The new package will | 668 | * Create the new outer package and populate it. The new package will |
712 | * have a single element, the lone subpackage. | 669 | * have a single element, the lone sub-object. |
713 | */ | 670 | */ |
714 | pkg_obj_desc = acpi_ut_create_package_object(1); | 671 | pkg_obj_desc = acpi_ut_create_package_object(1); |
715 | if (!pkg_obj_desc) { | 672 | if (!pkg_obj_desc) { |
716 | return (AE_NO_MEMORY); | 673 | return (AE_NO_MEMORY); |
717 | } | 674 | } |
718 | 675 | ||
719 | pkg_obj_desc->package.elements[0] = *obj_desc_ptr; | 676 | pkg_obj_desc->package.elements[0] = original_object; |
677 | |||
678 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | ||
679 | "%s: Wrapped %s with expected Package object\n", | ||
680 | data->pathname, | ||
681 | acpi_ut_get_object_type_name(original_object))); | ||
720 | 682 | ||
721 | /* Return the new object in the object pointer */ | 683 | /* Return the new object in the object pointer */ |
722 | 684 | ||
723 | *obj_desc_ptr = pkg_obj_desc; | 685 | *obj_desc_ptr = pkg_obj_desc; |
724 | data->flags |= ACPI_OBJECT_REPAIRED; | 686 | data->flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; |
725 | |||
726 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | ||
727 | "%s: Repaired incorrectly formed Package\n", | ||
728 | data->pathname)); | ||
729 | |||
730 | return (AE_OK); | 687 | return (AE_OK); |
731 | } | 688 | } |
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index a535b7afda5c..75113759f69d 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -341,7 +341,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) | |||
341 | 341 | ||
342 | if (!acpi_ns_valid_path_separator(*external_name) && | 342 | if (!acpi_ns_valid_path_separator(*external_name) && |
343 | (*external_name != 0)) { | 343 | (*external_name != 0)) { |
344 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 344 | return_ACPI_STATUS(AE_BAD_PATHNAME); |
345 | } | 345 | } |
346 | 346 | ||
347 | /* Move on the next segment */ | 347 | /* Move on the next segment */ |
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/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 1aecf7baa4e0..c03500b4cc7a 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -114,7 +114,6 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
114 | { | 114 | { |
115 | u32 i; | 115 | u32 i; |
116 | acpi_status status = AE_OK; | 116 | acpi_status status = AE_OK; |
117 | struct acpi_table_header *override_table = NULL; | ||
118 | 117 | ||
119 | ACPI_FUNCTION_TRACE(tb_add_table); | 118 | ACPI_FUNCTION_TRACE(tb_add_table); |
120 | 119 | ||
@@ -224,25 +223,10 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
224 | /* | 223 | /* |
225 | * ACPI Table Override: | 224 | * ACPI Table Override: |
226 | * Allow the host to override dynamically loaded tables. | 225 | * Allow the host to override dynamically loaded tables. |
226 | * NOTE: the table is fully mapped at this point, and the mapping will | ||
227 | * be deleted by tb_table_override if the table is actually overridden. | ||
227 | */ | 228 | */ |
228 | status = acpi_os_table_override(table_desc->pointer, &override_table); | 229 | (void)acpi_tb_table_override(table_desc->pointer, table_desc); |
229 | if (ACPI_SUCCESS(status) && override_table) { | ||
230 | ACPI_INFO((AE_INFO, | ||
231 | "%4.4s @ 0x%p Table override, replaced with:", | ||
232 | table_desc->pointer->signature, | ||
233 | ACPI_CAST_PTR(void, table_desc->address))); | ||
234 | |||
235 | /* We can delete the table that was passed as a parameter */ | ||
236 | |||
237 | acpi_tb_delete_table(table_desc); | ||
238 | |||
239 | /* Setup descriptor for the new table */ | ||
240 | |||
241 | table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table); | ||
242 | table_desc->pointer = override_table; | ||
243 | table_desc->length = override_table->length; | ||
244 | table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE; | ||
245 | } | ||
246 | 230 | ||
247 | /* Add the table to the global root table list */ | 231 | /* Add the table to the global root table list */ |
248 | 232 | ||
@@ -263,6 +247,95 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
263 | 247 | ||
264 | /******************************************************************************* | 248 | /******************************************************************************* |
265 | * | 249 | * |
250 | * FUNCTION: acpi_tb_table_override | ||
251 | * | ||
252 | * PARAMETERS: table_header - Header for the original table | ||
253 | * table_desc - Table descriptor initialized for the | ||
254 | * original table. May or may not be mapped. | ||
255 | * | ||
256 | * RETURN: Pointer to the entire new table. NULL if table not overridden. | ||
257 | * If overridden, installs the new table within the input table | ||
258 | * descriptor. | ||
259 | * | ||
260 | * DESCRIPTION: Attempt table override by calling the OSL override functions. | ||
261 | * Note: If the table is overridden, then the entire new table | ||
262 | * is mapped and returned by this function. | ||
263 | * | ||
264 | ******************************************************************************/ | ||
265 | |||
266 | struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | ||
267 | *table_header, | ||
268 | struct acpi_table_desc | ||
269 | *table_desc) | ||
270 | { | ||
271 | acpi_status status; | ||
272 | struct acpi_table_header *new_table = NULL; | ||
273 | acpi_physical_address new_address = 0; | ||
274 | u32 new_table_length = 0; | ||
275 | u8 new_flags; | ||
276 | char *override_type; | ||
277 | |||
278 | /* (1) Attempt logical override (returns a logical address) */ | ||
279 | |||
280 | status = acpi_os_table_override(table_header, &new_table); | ||
281 | if (ACPI_SUCCESS(status) && new_table) { | ||
282 | new_address = ACPI_PTR_TO_PHYSADDR(new_table); | ||
283 | new_table_length = new_table->length; | ||
284 | new_flags = ACPI_TABLE_ORIGIN_OVERRIDE; | ||
285 | override_type = "Logical"; | ||
286 | goto finish_override; | ||
287 | } | ||
288 | |||
289 | /* (2) Attempt physical override (returns a physical address) */ | ||
290 | |||
291 | status = acpi_os_physical_table_override(table_header, | ||
292 | &new_address, | ||
293 | &new_table_length); | ||
294 | if (ACPI_SUCCESS(status) && new_address && new_table_length) { | ||
295 | |||
296 | /* Map the entire new table */ | ||
297 | |||
298 | new_table = acpi_os_map_memory(new_address, new_table_length); | ||
299 | if (!new_table) { | ||
300 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, | ||
301 | "%4.4s %p Attempted physical table override failed", | ||
302 | table_header->signature, | ||
303 | ACPI_CAST_PTR(void, | ||
304 | table_desc->address))); | ||
305 | return (NULL); | ||
306 | } | ||
307 | |||
308 | override_type = "Physical"; | ||
309 | new_flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
310 | goto finish_override; | ||
311 | } | ||
312 | |||
313 | return (NULL); /* There was no override */ | ||
314 | |||
315 | finish_override: | ||
316 | |||
317 | ACPI_INFO((AE_INFO, | ||
318 | "%4.4s %p %s table override, new table: %p", | ||
319 | table_header->signature, | ||
320 | ACPI_CAST_PTR(void, table_desc->address), | ||
321 | override_type, new_table)); | ||
322 | |||
323 | /* We can now unmap/delete the original table (if fully mapped) */ | ||
324 | |||
325 | acpi_tb_delete_table(table_desc); | ||
326 | |||
327 | /* Setup descriptor for the new table */ | ||
328 | |||
329 | table_desc->address = new_address; | ||
330 | table_desc->pointer = new_table; | ||
331 | table_desc->length = new_table_length; | ||
332 | table_desc->flags = new_flags; | ||
333 | |||
334 | return (new_table); | ||
335 | } | ||
336 | |||
337 | /******************************************************************************* | ||
338 | * | ||
266 | * FUNCTION: acpi_tb_resize_root_table_list | 339 | * FUNCTION: acpi_tb_resize_root_table_list |
267 | * | 340 | * |
268 | * PARAMETERS: None | 341 | * PARAMETERS: None |
@@ -396,7 +469,11 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc) | |||
396 | case ACPI_TABLE_ORIGIN_ALLOCATED: | 469 | case ACPI_TABLE_ORIGIN_ALLOCATED: |
397 | ACPI_FREE(table_desc->pointer); | 470 | ACPI_FREE(table_desc->pointer); |
398 | break; | 471 | break; |
399 | default:; | 472 | |
473 | /* Not mapped or allocated, there is nothing we can do */ | ||
474 | |||
475 | default: | ||
476 | return; | ||
400 | } | 477 | } |
401 | 478 | ||
402 | table_desc->pointer = NULL; | 479 | table_desc->pointer = NULL; |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 09ca39e14337..0a706cac37de 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -118,6 +118,7 @@ acpi_tb_check_xsdt(acpi_physical_address address) | |||
118 | return AE_OK; | 118 | return AE_OK; |
119 | } | 119 | } |
120 | 120 | ||
121 | #if (!ACPI_REDUCED_HARDWARE) | ||
121 | /******************************************************************************* | 122 | /******************************************************************************* |
122 | * | 123 | * |
123 | * FUNCTION: acpi_tb_initialize_facs | 124 | * FUNCTION: acpi_tb_initialize_facs |
@@ -148,6 +149,7 @@ acpi_status acpi_tb_initialize_facs(void) | |||
148 | &acpi_gbl_FACS)); | 149 | &acpi_gbl_FACS)); |
149 | return status; | 150 | return status; |
150 | } | 151 | } |
152 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
151 | 153 | ||
152 | /******************************************************************************* | 154 | /******************************************************************************* |
153 | * | 155 | * |
@@ -444,7 +446,7 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
444 | * RETURN: None | 446 | * RETURN: None |
445 | * | 447 | * |
446 | * DESCRIPTION: Install an ACPI table into the global data structure. The | 448 | * DESCRIPTION: Install an ACPI table into the global data structure. The |
447 | * table override mechanism is implemented here to allow the host | 449 | * table override mechanism is called to allow the host |
448 | * OS to replace any table before it is installed in the root | 450 | * OS to replace any table before it is installed in the root |
449 | * table array. | 451 | * table array. |
450 | * | 452 | * |
@@ -454,11 +456,9 @@ void | |||
454 | acpi_tb_install_table(acpi_physical_address address, | 456 | acpi_tb_install_table(acpi_physical_address address, |
455 | char *signature, u32 table_index) | 457 | char *signature, u32 table_index) |
456 | { | 458 | { |
457 | u8 flags; | 459 | struct acpi_table_header *table; |
458 | acpi_status status; | 460 | struct acpi_table_header *final_table; |
459 | struct acpi_table_header *table_to_install; | 461 | struct acpi_table_desc *table_desc; |
460 | struct acpi_table_header *mapped_table; | ||
461 | struct acpi_table_header *override_table = NULL; | ||
462 | 462 | ||
463 | if (!address) { | 463 | if (!address) { |
464 | ACPI_ERROR((AE_INFO, | 464 | ACPI_ERROR((AE_INFO, |
@@ -469,69 +469,78 @@ acpi_tb_install_table(acpi_physical_address address, | |||
469 | 469 | ||
470 | /* Map just the table header */ | 470 | /* Map just the table header */ |
471 | 471 | ||
472 | mapped_table = | 472 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); |
473 | acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | 473 | if (!table) { |
474 | if (!mapped_table) { | 474 | ACPI_ERROR((AE_INFO, |
475 | "Could not map memory for table [%s] at %p", | ||
476 | signature, ACPI_CAST_PTR(void, address))); | ||
475 | return; | 477 | return; |
476 | } | 478 | } |
477 | 479 | ||
478 | /* If a particular signature is expected (DSDT/FACS), it must match */ | 480 | /* If a particular signature is expected (DSDT/FACS), it must match */ |
479 | 481 | ||
480 | if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) { | 482 | if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { |
481 | ACPI_ERROR((AE_INFO, | 483 | ACPI_ERROR((AE_INFO, |
482 | "Invalid signature 0x%X for ACPI table, expected [%s]", | 484 | "Invalid signature 0x%X for ACPI table, expected [%s]", |
483 | *ACPI_CAST_PTR(u32, mapped_table->signature), | 485 | *ACPI_CAST_PTR(u32, table->signature), signature)); |
484 | signature)); | ||
485 | goto unmap_and_exit; | 486 | goto unmap_and_exit; |
486 | } | 487 | } |
487 | 488 | ||
488 | /* | 489 | /* |
490 | * Initialize the table entry. Set the pointer to NULL, since the | ||
491 | * table is not fully mapped at this time. | ||
492 | */ | ||
493 | table_desc = &acpi_gbl_root_table_list.tables[table_index]; | ||
494 | |||
495 | table_desc->address = address; | ||
496 | table_desc->pointer = NULL; | ||
497 | table_desc->length = table->length; | ||
498 | table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
499 | ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); | ||
500 | |||
501 | /* | ||
489 | * ACPI Table Override: | 502 | * ACPI Table Override: |
490 | * | 503 | * |
491 | * Before we install the table, let the host OS override it with a new | 504 | * Before we install the table, let the host OS override it with a new |
492 | * one if desired. Any table within the RSDT/XSDT can be replaced, | 505 | * one if desired. Any table within the RSDT/XSDT can be replaced, |
493 | * including the DSDT which is pointed to by the FADT. | 506 | * including the DSDT which is pointed to by the FADT. |
507 | * | ||
508 | * NOTE: If the table is overridden, then final_table will contain a | ||
509 | * mapped pointer to the full new table. If the table is not overridden, | ||
510 | * or if there has been a physical override, then the table will be | ||
511 | * fully mapped later (in verify table). In any case, we must | ||
512 | * unmap the header that was mapped above. | ||
494 | */ | 513 | */ |
495 | status = acpi_os_table_override(mapped_table, &override_table); | 514 | final_table = acpi_tb_table_override(table, table_desc); |
496 | if (ACPI_SUCCESS(status) && override_table) { | 515 | if (!final_table) { |
497 | ACPI_INFO((AE_INFO, | 516 | final_table = table; /* There was no override */ |
498 | "%4.4s @ 0x%p Table override, replaced with:", | ||
499 | mapped_table->signature, ACPI_CAST_PTR(void, | ||
500 | address))); | ||
501 | |||
502 | acpi_gbl_root_table_list.tables[table_index].pointer = | ||
503 | override_table; | ||
504 | address = ACPI_PTR_TO_PHYSADDR(override_table); | ||
505 | |||
506 | table_to_install = override_table; | ||
507 | flags = ACPI_TABLE_ORIGIN_OVERRIDE; | ||
508 | } else { | ||
509 | table_to_install = mapped_table; | ||
510 | flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
511 | } | 517 | } |
512 | 518 | ||
513 | /* Initialize the table entry */ | 519 | acpi_tb_print_table_header(table_desc->address, final_table); |
514 | 520 | ||
515 | acpi_gbl_root_table_list.tables[table_index].address = address; | 521 | /* Set the global integer width (based upon revision of the DSDT) */ |
516 | acpi_gbl_root_table_list.tables[table_index].length = | ||
517 | table_to_install->length; | ||
518 | acpi_gbl_root_table_list.tables[table_index].flags = flags; | ||
519 | |||
520 | ACPI_MOVE_32_TO_32(& | ||
521 | (acpi_gbl_root_table_list.tables[table_index]. | ||
522 | signature), table_to_install->signature); | ||
523 | |||
524 | acpi_tb_print_table_header(address, table_to_install); | ||
525 | 522 | ||
526 | if (table_index == ACPI_TABLE_INDEX_DSDT) { | 523 | if (table_index == ACPI_TABLE_INDEX_DSDT) { |
524 | acpi_ut_set_integer_width(final_table->revision); | ||
525 | } | ||
527 | 526 | ||
528 | /* Global integer width is based upon revision of the DSDT */ | 527 | /* |
529 | 528 | * If we have a physical override during this early loading of the ACPI | |
530 | acpi_ut_set_integer_width(table_to_install->revision); | 529 | * tables, unmap the table for now. It will be mapped again later when |
530 | * it is actually used. This supports very early loading of ACPI tables, | ||
531 | * before virtual memory is fully initialized and running within the | ||
532 | * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE | ||
533 | * flag set and will not be deleted below. | ||
534 | */ | ||
535 | if (final_table != table) { | ||
536 | acpi_tb_delete_table(table_desc); | ||
531 | } | 537 | } |
532 | 538 | ||
533 | unmap_and_exit: | 539 | unmap_and_exit: |
534 | acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header)); | 540 | |
541 | /* Always unmap the table header that we mapped above */ | ||
542 | |||
543 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
535 | } | 544 | } |
536 | 545 | ||
537 | /******************************************************************************* | 546 | /******************************************************************************* |
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index d42ede5260c7..684849949bf3 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -497,19 +497,20 @@ char *acpi_ut_get_mutex_name(u32 mutex_id) | |||
497 | 497 | ||
498 | /* Names for Notify() values, used for debug output */ | 498 | /* Names for Notify() values, used for debug output */ |
499 | 499 | ||
500 | static const char *acpi_gbl_notify_value_names[] = { | 500 | static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { |
501 | "Bus Check", | 501 | /* 00 */ "Bus Check", |
502 | "Device Check", | 502 | /* 01 */ "Device Check", |
503 | "Device Wake", | 503 | /* 02 */ "Device Wake", |
504 | "Eject Request", | 504 | /* 03 */ "Eject Request", |
505 | "Device Check Light", | 505 | /* 04 */ "Device Check Light", |
506 | "Frequency Mismatch", | 506 | /* 05 */ "Frequency Mismatch", |
507 | "Bus Mode Mismatch", | 507 | /* 06 */ "Bus Mode Mismatch", |
508 | "Power Fault", | 508 | /* 07 */ "Power Fault", |
509 | "Capabilities Check", | 509 | /* 08 */ "Capabilities Check", |
510 | "Device PLD Check", | 510 | /* 09 */ "Device PLD Check", |
511 | "Reserved", | 511 | /* 10 */ "Reserved", |
512 | "System Locality Update" | 512 | /* 11 */ "System Locality Update", |
513 | /* 12 */ "Shutdown Request" | ||
513 | }; | 514 | }; |
514 | 515 | ||
515 | const char *acpi_ut_get_notify_name(u32 notify_value) | 516 | const char *acpi_ut_get_notify_name(u32 notify_value) |
@@ -519,9 +520,10 @@ const char *acpi_ut_get_notify_name(u32 notify_value) | |||
519 | return (acpi_gbl_notify_value_names[notify_value]); | 520 | return (acpi_gbl_notify_value_names[notify_value]); |
520 | } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | 521 | } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { |
521 | return ("Reserved"); | 522 | return ("Reserved"); |
522 | } else { /* Greater or equal to 0x80 */ | 523 | } else if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { |
523 | 524 | return ("Device Specific"); | |
524 | return ("**Device Specific**"); | 525 | } else { |
526 | return ("Hardware Specific"); | ||
525 | } | 527 | } |
526 | } | 528 | } |
527 | #endif | 529 | #endif |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 4153584cf526..90f53b42eca9 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -140,6 +140,7 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { | |||
140 | {NULL, ACPI_TYPE_ANY, NULL} | 140 | {NULL, ACPI_TYPE_ANY, NULL} |
141 | }; | 141 | }; |
142 | 142 | ||
143 | #if (!ACPI_REDUCED_HARDWARE) | ||
143 | /****************************************************************************** | 144 | /****************************************************************************** |
144 | * | 145 | * |
145 | * Event and Hardware globals | 146 | * Event and Hardware globals |
@@ -236,6 +237,7 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = | |||
236 | ACPI_BITMASK_RT_CLOCK_STATUS, | 237 | ACPI_BITMASK_RT_CLOCK_STATUS, |
237 | ACPI_BITMASK_RT_CLOCK_ENABLE}, | 238 | ACPI_BITMASK_RT_CLOCK_ENABLE}, |
238 | }; | 239 | }; |
240 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
239 | 241 | ||
240 | /******************************************************************************* | 242 | /******************************************************************************* |
241 | * | 243 | * |
@@ -286,6 +288,8 @@ acpi_status acpi_ut_init_globals(void) | |||
286 | 288 | ||
287 | acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; | 289 | acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; |
288 | 290 | ||
291 | #if (!ACPI_REDUCED_HARDWARE) | ||
292 | |||
289 | /* GPE support */ | 293 | /* GPE support */ |
290 | 294 | ||
291 | acpi_gbl_gpe_xrupt_list_head = NULL; | 295 | acpi_gbl_gpe_xrupt_list_head = NULL; |
@@ -294,6 +298,10 @@ acpi_status acpi_ut_init_globals(void) | |||
294 | acpi_current_gpe_count = 0; | 298 | acpi_current_gpe_count = 0; |
295 | acpi_gbl_all_gpes_initialized = FALSE; | 299 | acpi_gbl_all_gpes_initialized = FALSE; |
296 | 300 | ||
301 | acpi_gbl_global_event_handler = NULL; | ||
302 | |||
303 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
304 | |||
297 | /* Global handlers */ | 305 | /* Global handlers */ |
298 | 306 | ||
299 | acpi_gbl_system_notify.handler = NULL; | 307 | acpi_gbl_system_notify.handler = NULL; |
@@ -302,7 +310,6 @@ acpi_status acpi_ut_init_globals(void) | |||
302 | acpi_gbl_init_handler = NULL; | 310 | acpi_gbl_init_handler = NULL; |
303 | acpi_gbl_table_handler = NULL; | 311 | acpi_gbl_table_handler = NULL; |
304 | acpi_gbl_interface_handler = NULL; | 312 | acpi_gbl_interface_handler = NULL; |
305 | acpi_gbl_global_event_handler = NULL; | ||
306 | 313 | ||
307 | /* Global Lock support */ | 314 | /* Global Lock support */ |
308 | 315 | ||
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 8359c0c5dc98..246798e4c938 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c | |||
@@ -53,27 +53,35 @@ ACPI_MODULE_NAME("utinit") | |||
53 | /* Local prototypes */ | 53 | /* Local prototypes */ |
54 | static void acpi_ut_terminate(void); | 54 | static void acpi_ut_terminate(void); |
55 | 55 | ||
56 | #if (!ACPI_REDUCED_HARDWARE) | ||
57 | |||
58 | static void acpi_ut_free_gpe_lists(void); | ||
59 | |||
60 | #else | ||
61 | |||
62 | #define acpi_ut_free_gpe_lists() | ||
63 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
64 | |||
65 | #if (!ACPI_REDUCED_HARDWARE) | ||
56 | /****************************************************************************** | 66 | /****************************************************************************** |
57 | * | 67 | * |
58 | * FUNCTION: acpi_ut_terminate | 68 | * FUNCTION: acpi_ut_free_gpe_lists |
59 | * | 69 | * |
60 | * PARAMETERS: none | 70 | * PARAMETERS: none |
61 | * | 71 | * |
62 | * RETURN: none | 72 | * RETURN: none |
63 | * | 73 | * |
64 | * DESCRIPTION: Free global memory | 74 | * DESCRIPTION: Free global GPE lists |
65 | * | 75 | * |
66 | ******************************************************************************/ | 76 | ******************************************************************************/ |
67 | 77 | ||
68 | static void acpi_ut_terminate(void) | 78 | static void acpi_ut_free_gpe_lists(void) |
69 | { | 79 | { |
70 | struct acpi_gpe_block_info *gpe_block; | 80 | struct acpi_gpe_block_info *gpe_block; |
71 | struct acpi_gpe_block_info *next_gpe_block; | 81 | struct acpi_gpe_block_info *next_gpe_block; |
72 | struct acpi_gpe_xrupt_info *gpe_xrupt_info; | 82 | struct acpi_gpe_xrupt_info *gpe_xrupt_info; |
73 | struct acpi_gpe_xrupt_info *next_gpe_xrupt_info; | 83 | struct acpi_gpe_xrupt_info *next_gpe_xrupt_info; |
74 | 84 | ||
75 | ACPI_FUNCTION_TRACE(ut_terminate); | ||
76 | |||
77 | /* Free global GPE blocks and related info structures */ | 85 | /* Free global GPE blocks and related info structures */ |
78 | 86 | ||
79 | gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; | 87 | gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; |
@@ -91,7 +99,26 @@ static void acpi_ut_terminate(void) | |||
91 | ACPI_FREE(gpe_xrupt_info); | 99 | ACPI_FREE(gpe_xrupt_info); |
92 | gpe_xrupt_info = next_gpe_xrupt_info; | 100 | gpe_xrupt_info = next_gpe_xrupt_info; |
93 | } | 101 | } |
102 | } | ||
103 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
104 | |||
105 | /****************************************************************************** | ||
106 | * | ||
107 | * FUNCTION: acpi_ut_terminate | ||
108 | * | ||
109 | * PARAMETERS: none | ||
110 | * | ||
111 | * RETURN: none | ||
112 | * | ||
113 | * DESCRIPTION: Free global memory | ||
114 | * | ||
115 | ******************************************************************************/ | ||
116 | |||
117 | static void acpi_ut_terminate(void) | ||
118 | { | ||
119 | ACPI_FUNCTION_TRACE(ut_terminate); | ||
94 | 120 | ||
121 | acpi_ut_free_gpe_lists(); | ||
95 | acpi_ut_delete_address_lists(); | 122 | acpi_ut_delete_address_lists(); |
96 | return_VOID; | 123 | return_VOID; |
97 | } | 124 | } |
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 644e8c8ebc4b..afa94f51ff0b 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -145,6 +145,8 @@ acpi_status acpi_enable_subsystem(u32 flags) | |||
145 | 145 | ||
146 | ACPI_FUNCTION_TRACE(acpi_enable_subsystem); | 146 | ACPI_FUNCTION_TRACE(acpi_enable_subsystem); |
147 | 147 | ||
148 | #if (!ACPI_REDUCED_HARDWARE) | ||
149 | |||
148 | /* Enable ACPI mode */ | 150 | /* Enable ACPI mode */ |
149 | 151 | ||
150 | if (!(flags & ACPI_NO_ACPI_ENABLE)) { | 152 | if (!(flags & ACPI_NO_ACPI_ENABLE)) { |
@@ -169,6 +171,7 @@ acpi_status acpi_enable_subsystem(u32 flags) | |||
169 | ACPI_WARNING((AE_INFO, "Could not map the FACS table")); | 171 | ACPI_WARNING((AE_INFO, "Could not map the FACS table")); |
170 | return_ACPI_STATUS(status); | 172 | return_ACPI_STATUS(status); |
171 | } | 173 | } |
174 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
172 | 175 | ||
173 | /* | 176 | /* |
174 | * Install the default op_region handlers. These are installed unless | 177 | * Install the default op_region handlers. These are installed unless |
@@ -184,7 +187,7 @@ acpi_status acpi_enable_subsystem(u32 flags) | |||
184 | return_ACPI_STATUS(status); | 187 | return_ACPI_STATUS(status); |
185 | } | 188 | } |
186 | } | 189 | } |
187 | 190 | #if (!ACPI_REDUCED_HARDWARE) | |
188 | /* | 191 | /* |
189 | * Initialize ACPI Event handling (Fixed and General Purpose) | 192 | * Initialize ACPI Event handling (Fixed and General Purpose) |
190 | * | 193 | * |
@@ -220,6 +223,7 @@ acpi_status acpi_enable_subsystem(u32 flags) | |||
220 | return_ACPI_STATUS(status); | 223 | return_ACPI_STATUS(status); |
221 | } | 224 | } |
222 | } | 225 | } |
226 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
223 | 227 | ||
224 | return_ACPI_STATUS(status); | 228 | return_ACPI_STATUS(status); |
225 | } | 229 | } |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index e5d53b7ddc7e..5577762daee1 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -558,33 +558,48 @@ void apei_resources_release(struct apei_resources *resources) | |||
558 | } | 558 | } |
559 | EXPORT_SYMBOL_GPL(apei_resources_release); | 559 | EXPORT_SYMBOL_GPL(apei_resources_release); |
560 | 560 | ||
561 | static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) | 561 | static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, |
562 | u32 *access_bit_width) | ||
562 | { | 563 | { |
563 | u32 width, space_id; | 564 | u32 bit_width, bit_offset, access_size_code, space_id; |
564 | 565 | ||
565 | width = reg->bit_width; | 566 | bit_width = reg->bit_width; |
567 | bit_offset = reg->bit_offset; | ||
568 | access_size_code = reg->access_width; | ||
566 | space_id = reg->space_id; | 569 | space_id = reg->space_id; |
567 | /* Handle possible alignment issues */ | 570 | /* Handle possible alignment issues */ |
568 | memcpy(paddr, ®->address, sizeof(*paddr)); | 571 | memcpy(paddr, ®->address, sizeof(*paddr)); |
569 | if (!*paddr) { | 572 | if (!*paddr) { |
570 | pr_warning(FW_BUG APEI_PFX | 573 | pr_warning(FW_BUG APEI_PFX |
571 | "Invalid physical address in GAR [0x%llx/%u/%u]\n", | 574 | "Invalid physical address in GAR [0x%llx/%u/%u/%u/%u]\n", |
572 | *paddr, width, space_id); | 575 | *paddr, bit_width, bit_offset, access_size_code, |
576 | space_id); | ||
573 | return -EINVAL; | 577 | return -EINVAL; |
574 | } | 578 | } |
575 | 579 | ||
576 | if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { | 580 | if (access_size_code < 1 || access_size_code > 4) { |
577 | pr_warning(FW_BUG APEI_PFX | 581 | pr_warning(FW_BUG APEI_PFX |
578 | "Invalid bit width in GAR [0x%llx/%u/%u]\n", | 582 | "Invalid access size code in GAR [0x%llx/%u/%u/%u/%u]\n", |
579 | *paddr, width, space_id); | 583 | *paddr, bit_width, bit_offset, access_size_code, |
584 | space_id); | ||
585 | return -EINVAL; | ||
586 | } | ||
587 | *access_bit_width = 1UL << (access_size_code + 2); | ||
588 | |||
589 | if ((bit_width + bit_offset) > *access_bit_width) { | ||
590 | pr_warning(FW_BUG APEI_PFX | ||
591 | "Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n", | ||
592 | *paddr, bit_width, bit_offset, access_size_code, | ||
593 | space_id); | ||
580 | return -EINVAL; | 594 | return -EINVAL; |
581 | } | 595 | } |
582 | 596 | ||
583 | if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && | 597 | if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && |
584 | space_id != ACPI_ADR_SPACE_SYSTEM_IO) { | 598 | space_id != ACPI_ADR_SPACE_SYSTEM_IO) { |
585 | pr_warning(FW_BUG APEI_PFX | 599 | pr_warning(FW_BUG APEI_PFX |
586 | "Invalid address space type in GAR [0x%llx/%u/%u]\n", | 600 | "Invalid address space type in GAR [0x%llx/%u/%u/%u/%u]\n", |
587 | *paddr, width, space_id); | 601 | *paddr, bit_width, bit_offset, access_size_code, |
602 | space_id); | ||
588 | return -EINVAL; | 603 | return -EINVAL; |
589 | } | 604 | } |
590 | 605 | ||
@@ -595,23 +610,25 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) | |||
595 | int apei_read(u64 *val, struct acpi_generic_address *reg) | 610 | int apei_read(u64 *val, struct acpi_generic_address *reg) |
596 | { | 611 | { |
597 | int rc; | 612 | int rc; |
613 | u32 access_bit_width; | ||
598 | u64 address; | 614 | u64 address; |
599 | acpi_status status; | 615 | acpi_status status; |
600 | 616 | ||
601 | rc = apei_check_gar(reg, &address); | 617 | rc = apei_check_gar(reg, &address, &access_bit_width); |
602 | if (rc) | 618 | if (rc) |
603 | return rc; | 619 | return rc; |
604 | 620 | ||
605 | *val = 0; | 621 | *val = 0; |
606 | switch(reg->space_id) { | 622 | switch(reg->space_id) { |
607 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 623 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
608 | status = acpi_os_read_memory64((acpi_physical_address) | 624 | status = acpi_os_read_memory((acpi_physical_address) address, |
609 | address, val, reg->bit_width); | 625 | val, access_bit_width); |
610 | if (ACPI_FAILURE(status)) | 626 | if (ACPI_FAILURE(status)) |
611 | return -EIO; | 627 | return -EIO; |
612 | break; | 628 | break; |
613 | case ACPI_ADR_SPACE_SYSTEM_IO: | 629 | case ACPI_ADR_SPACE_SYSTEM_IO: |
614 | status = acpi_os_read_port(address, (u32 *)val, reg->bit_width); | 630 | status = acpi_os_read_port(address, (u32 *)val, |
631 | access_bit_width); | ||
615 | if (ACPI_FAILURE(status)) | 632 | if (ACPI_FAILURE(status)) |
616 | return -EIO; | 633 | return -EIO; |
617 | break; | 634 | break; |
@@ -627,22 +644,23 @@ EXPORT_SYMBOL_GPL(apei_read); | |||
627 | int apei_write(u64 val, struct acpi_generic_address *reg) | 644 | int apei_write(u64 val, struct acpi_generic_address *reg) |
628 | { | 645 | { |
629 | int rc; | 646 | int rc; |
647 | u32 access_bit_width; | ||
630 | u64 address; | 648 | u64 address; |
631 | acpi_status status; | 649 | acpi_status status; |
632 | 650 | ||
633 | rc = apei_check_gar(reg, &address); | 651 | rc = apei_check_gar(reg, &address, &access_bit_width); |
634 | if (rc) | 652 | if (rc) |
635 | return rc; | 653 | return rc; |
636 | 654 | ||
637 | switch (reg->space_id) { | 655 | switch (reg->space_id) { |
638 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 656 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
639 | status = acpi_os_write_memory64((acpi_physical_address) | 657 | status = acpi_os_write_memory((acpi_physical_address) address, |
640 | address, val, reg->bit_width); | 658 | val, access_bit_width); |
641 | if (ACPI_FAILURE(status)) | 659 | if (ACPI_FAILURE(status)) |
642 | return -EIO; | 660 | return -EIO; |
643 | break; | 661 | break; |
644 | case ACPI_ADR_SPACE_SYSTEM_IO: | 662 | case ACPI_ADR_SPACE_SYSTEM_IO: |
645 | status = acpi_os_write_port(address, val, reg->bit_width); | 663 | status = acpi_os_write_port(address, val, access_bit_width); |
646 | if (ACPI_FAILURE(status)) | 664 | if (ACPI_FAILURE(status)) |
647 | return -EIO; | 665 | return -EIO; |
648 | break; | 666 | break; |
@@ -661,23 +679,24 @@ static int collect_res_callback(struct apei_exec_context *ctx, | |||
661 | struct apei_resources *resources = data; | 679 | struct apei_resources *resources = data; |
662 | struct acpi_generic_address *reg = &entry->register_region; | 680 | struct acpi_generic_address *reg = &entry->register_region; |
663 | u8 ins = entry->instruction; | 681 | u8 ins = entry->instruction; |
682 | u32 access_bit_width; | ||
664 | u64 paddr; | 683 | u64 paddr; |
665 | int rc; | 684 | int rc; |
666 | 685 | ||
667 | if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) | 686 | if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) |
668 | return 0; | 687 | return 0; |
669 | 688 | ||
670 | rc = apei_check_gar(reg, &paddr); | 689 | rc = apei_check_gar(reg, &paddr, &access_bit_width); |
671 | if (rc) | 690 | if (rc) |
672 | return rc; | 691 | return rc; |
673 | 692 | ||
674 | switch (reg->space_id) { | 693 | switch (reg->space_id) { |
675 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 694 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
676 | return apei_res_add(&resources->iomem, paddr, | 695 | return apei_res_add(&resources->iomem, paddr, |
677 | reg->bit_width / 8); | 696 | access_bit_width / 8); |
678 | case ACPI_ADR_SPACE_SYSTEM_IO: | 697 | case ACPI_ADR_SPACE_SYSTEM_IO: |
679 | return apei_res_add(&resources->ioport, paddr, | 698 | return apei_res_add(&resources->ioport, paddr, |
680 | reg->bit_width / 8); | 699 | access_bit_width / 8); |
681 | default: | 700 | default: |
682 | return -EINVAL; | 701 | return -EINVAL; |
683 | } | 702 | } |
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index 5d4189464d63..e6defd86b424 100644 --- a/drivers/acpi/apei/cper.c +++ b/drivers/acpi/apei/cper.c | |||
@@ -362,6 +362,7 @@ void apei_estatus_print(const char *pfx, | |||
362 | gedata_len = gdata->error_data_length; | 362 | gedata_len = gdata->error_data_length; |
363 | apei_estatus_print_section(pfx, gdata, sec_no); | 363 | apei_estatus_print_section(pfx, gdata, sec_no); |
364 | data_len -= gedata_len + sizeof(*gdata); | 364 | data_len -= gedata_len + sizeof(*gdata); |
365 | gdata = (void *)(gdata + 1) + gedata_len; | ||
365 | sec_no++; | 366 | sec_no++; |
366 | } | 367 | } |
367 | } | 368 | } |
@@ -396,6 +397,7 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus) | |||
396 | if (gedata_len > data_len - sizeof(*gdata)) | 397 | if (gedata_len > data_len - sizeof(*gdata)) |
397 | return -EINVAL; | 398 | return -EINVAL; |
398 | data_len -= gedata_len + sizeof(*gdata); | 399 | data_len -= gedata_len + sizeof(*gdata); |
400 | gdata = (void *)(gdata + 1) + gedata_len; | ||
399 | } | 401 | } |
400 | if (data_len) | 402 | if (data_len) |
401 | return -EINVAL; | 403 | return -EINVAL; |
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 4ca087dd5f4f..8e1793649ec0 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -74,6 +74,8 @@ struct vendor_error_type_extension { | |||
74 | u8 reserved[3]; | 74 | u8 reserved[3]; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static u32 notrigger; | ||
78 | |||
77 | static u32 vendor_flags; | 79 | static u32 vendor_flags; |
78 | static struct debugfs_blob_wrapper vendor_blob; | 80 | static struct debugfs_blob_wrapper vendor_blob; |
79 | static char vendor_dev[64]; | 81 | static char vendor_dev[64]; |
@@ -238,7 +240,7 @@ static void *einj_get_parameter_address(void) | |||
238 | return v5param; | 240 | return v5param; |
239 | } | 241 | } |
240 | } | 242 | } |
241 | if (paddrv4) { | 243 | if (param_extension && paddrv4) { |
242 | struct einj_parameter *v4param; | 244 | struct einj_parameter *v4param; |
243 | 245 | ||
244 | v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param)); | 246 | v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param)); |
@@ -496,9 +498,11 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) | |||
496 | if (rc) | 498 | if (rc) |
497 | return rc; | 499 | return rc; |
498 | trigger_paddr = apei_exec_ctx_get_output(&ctx); | 500 | trigger_paddr = apei_exec_ctx_get_output(&ctx); |
499 | rc = __einj_error_trigger(trigger_paddr, type, param1, param2); | 501 | if (notrigger == 0) { |
500 | if (rc) | 502 | rc = __einj_error_trigger(trigger_paddr, type, param1, param2); |
501 | return rc; | 503 | if (rc) |
504 | return rc; | ||
505 | } | ||
502 | rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION); | 506 | rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION); |
503 | 507 | ||
504 | return rc; | 508 | return rc; |
@@ -700,6 +704,11 @@ static int __init einj_init(void) | |||
700 | einj_debug_dir, &error_param2); | 704 | einj_debug_dir, &error_param2); |
701 | if (!fentry) | 705 | if (!fentry) |
702 | goto err_unmap; | 706 | goto err_unmap; |
707 | |||
708 | fentry = debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR, | ||
709 | einj_debug_dir, ¬rigger); | ||
710 | if (!fentry) | ||
711 | goto err_unmap; | ||
703 | } | 712 | } |
704 | 713 | ||
705 | if (vendor_dev[0]) { | 714 | if (vendor_dev[0]) { |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index eb9fab5b96e4..e4d9d24eb73d 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -917,7 +917,7 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) | |||
917 | { | 917 | { |
918 | if ((erst_tab->header_length != | 918 | if ((erst_tab->header_length != |
919 | (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) | 919 | (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) |
920 | && (erst_tab->header_length != sizeof(struct acpi_table_einj))) | 920 | && (erst_tab->header_length != sizeof(struct acpi_table_erst))) |
921 | return -EINVAL; | 921 | return -EINVAL; |
922 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) | 922 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) |
923 | return -EINVAL; | 923 | return -EINVAL; |
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 | |||
17 | static struct acpi_table_bgrt *bgrt_tab; | ||
18 | static struct kobject *bgrt_kobj; | ||
19 | |||
20 | struct bmp_header { | ||
21 | u16 id; | ||
22 | u32 size; | ||
23 | } __attribute ((packed)); | ||
24 | |||
25 | static struct bmp_header bmp_header; | ||
26 | |||
27 | static 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 | } | ||
32 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); | ||
33 | |||
34 | static 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 | } | ||
39 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | ||
40 | |||
41 | static 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 | } | ||
46 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); | ||
47 | |||
48 | static 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 | } | ||
53 | static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL); | ||
54 | |||
55 | static 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 | } | ||
60 | static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL); | ||
61 | |||
62 | static 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 | |||
80 | static struct bin_attribute image_attr = { | ||
81 | .attr = { | ||
82 | .name = "image", | ||
83 | .mode = S_IRUGO, | ||
84 | }, | ||
85 | .read = show_image, | ||
86 | }; | ||
87 | |||
88 | static 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 | |||
97 | static struct attribute_group bgrt_attribute_group = { | ||
98 | .attrs = bgrt_attributes, | ||
99 | }; | ||
100 | |||
101 | static 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 | |||
153 | out_group: | ||
154 | sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group); | ||
155 | out_kobject: | ||
156 | kobject_put(bgrt_kobj); | ||
157 | out_iounmap: | ||
158 | iounmap(image_attr.private); | ||
159 | out_err: | ||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | static 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 | |||
170 | module_init(bgrt_init); | ||
171 | module_exit(bgrt_exit); | ||
172 | |||
173 | MODULE_AUTHOR("Matthew Garrett"); | ||
174 | MODULE_DESCRIPTION("BGRT boot graphic support"); | ||
175 | MODULE_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 | ||
1012 | struct kobject *acpi_kobj; | 1012 | struct kobject *acpi_kobj; |
1013 | EXPORT_SYMBOL_GPL(acpi_kobj); | ||
1013 | 1014 | ||
1014 | static int __init acpi_init(void) | 1015 | static int __init acpi_init(void) |
1015 | { | 1016 | { |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e37615f310d7..7edaccce6640 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -822,10 +822,10 @@ static int acpi_ec_add(struct acpi_device *device) | |||
822 | first_ec = ec; | 822 | first_ec = ec; |
823 | device->driver_data = ec; | 823 | device->driver_data = ec; |
824 | 824 | ||
825 | WARN(!request_region(ec->data_addr, 1, "EC data"), | 825 | ret = !!request_region(ec->data_addr, 1, "EC data"); |
826 | "Could not request EC data io port 0x%lx", ec->data_addr); | 826 | WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr); |
827 | WARN(!request_region(ec->command_addr, 1, "EC cmd"), | 827 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); |
828 | "Could not request EC cmd io port 0x%lx", ec->command_addr); | 828 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); |
829 | 829 | ||
830 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 830 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
831 | ec->gpe, ec->command_addr, ec->data_addr); | 831 | 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 412a1e04a922..ba14fb93c929 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -77,6 +77,9 @@ EXPORT_SYMBOL(acpi_in_debugger); | |||
77 | extern char line_buf[80]; | 77 | extern char line_buf[80]; |
78 | #endif /*ENABLE_DEBUGGER */ | 78 | #endif /*ENABLE_DEBUGGER */ |
79 | 79 | ||
80 | static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl, | ||
81 | u32 pm1b_ctrl); | ||
82 | |||
80 | static acpi_osd_handler acpi_irq_handler; | 83 | static acpi_osd_handler acpi_irq_handler; |
81 | static void *acpi_irq_context; | 84 | static void *acpi_irq_context; |
82 | static struct workqueue_struct *kacpid_wq; | 85 | static struct workqueue_struct *kacpid_wq; |
@@ -347,7 +350,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) | |||
347 | unsigned long pfn; | 350 | unsigned long pfn; |
348 | 351 | ||
349 | pfn = pg_off >> PAGE_SHIFT; | 352 | pfn = pg_off >> PAGE_SHIFT; |
350 | if (page_is_ram(pfn)) | 353 | if (should_use_kmap(pfn)) |
351 | kunmap(pfn_to_page(pfn)); | 354 | kunmap(pfn_to_page(pfn)); |
352 | else | 355 | else |
353 | iounmap(vaddr); | 356 | iounmap(vaddr); |
@@ -554,6 +557,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table, | |||
554 | return AE_OK; | 557 | return AE_OK; |
555 | } | 558 | } |
556 | 559 | ||
560 | acpi_status | ||
561 | acpi_os_physical_table_override(struct acpi_table_header *existing_table, | ||
562 | acpi_physical_address * new_address, | ||
563 | u32 *new_table_length) | ||
564 | { | ||
565 | return AE_SUPPORT; | ||
566 | } | ||
567 | |||
568 | |||
557 | static irqreturn_t acpi_irq(int irq, void *dev_id) | 569 | static irqreturn_t acpi_irq(int irq, void *dev_id) |
558 | { | 570 | { |
559 | u32 handled; | 571 | u32 handled; |
@@ -595,7 +607,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
595 | 607 | ||
596 | acpi_irq_handler = handler; | 608 | acpi_irq_handler = handler; |
597 | acpi_irq_context = context; | 609 | acpi_irq_context = context; |
598 | if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { | 610 | if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi", |
611 | acpi_irq)) { | ||
599 | printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); | 612 | printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); |
600 | acpi_irq_handler = NULL; | 613 | acpi_irq_handler = NULL; |
601 | return AE_NOT_ACQUIRED; | 614 | return AE_NOT_ACQUIRED; |
@@ -699,49 +712,6 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width) | |||
699 | 712 | ||
700 | EXPORT_SYMBOL(acpi_os_write_port); | 713 | EXPORT_SYMBOL(acpi_os_write_port); |
701 | 714 | ||
702 | acpi_status | ||
703 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | ||
704 | { | ||
705 | void __iomem *virt_addr; | ||
706 | unsigned int size = width / 8; | ||
707 | bool unmap = false; | ||
708 | u32 dummy; | ||
709 | |||
710 | rcu_read_lock(); | ||
711 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | ||
712 | if (!virt_addr) { | ||
713 | rcu_read_unlock(); | ||
714 | virt_addr = acpi_os_ioremap(phys_addr, size); | ||
715 | if (!virt_addr) | ||
716 | return AE_BAD_ADDRESS; | ||
717 | unmap = true; | ||
718 | } | ||
719 | |||
720 | if (!value) | ||
721 | value = &dummy; | ||
722 | |||
723 | switch (width) { | ||
724 | case 8: | ||
725 | *(u8 *) value = readb(virt_addr); | ||
726 | break; | ||
727 | case 16: | ||
728 | *(u16 *) value = readw(virt_addr); | ||
729 | break; | ||
730 | case 32: | ||
731 | *(u32 *) value = readl(virt_addr); | ||
732 | break; | ||
733 | default: | ||
734 | BUG(); | ||
735 | } | ||
736 | |||
737 | if (unmap) | ||
738 | iounmap(virt_addr); | ||
739 | else | ||
740 | rcu_read_unlock(); | ||
741 | |||
742 | return AE_OK; | ||
743 | } | ||
744 | |||
745 | #ifdef readq | 715 | #ifdef readq |
746 | static inline u64 read64(const volatile void __iomem *addr) | 716 | static inline u64 read64(const volatile void __iomem *addr) |
747 | { | 717 | { |
@@ -758,7 +728,7 @@ static inline u64 read64(const volatile void __iomem *addr) | |||
758 | #endif | 728 | #endif |
759 | 729 | ||
760 | acpi_status | 730 | acpi_status |
761 | acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) | 731 | acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) |
762 | { | 732 | { |
763 | void __iomem *virt_addr; | 733 | void __iomem *virt_addr; |
764 | unsigned int size = width / 8; | 734 | unsigned int size = width / 8; |
@@ -803,45 +773,6 @@ acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) | |||
803 | return AE_OK; | 773 | return AE_OK; |
804 | } | 774 | } |
805 | 775 | ||
806 | acpi_status | ||
807 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | ||
808 | { | ||
809 | void __iomem *virt_addr; | ||
810 | unsigned int size = width / 8; | ||
811 | bool unmap = false; | ||
812 | |||
813 | rcu_read_lock(); | ||
814 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | ||
815 | if (!virt_addr) { | ||
816 | rcu_read_unlock(); | ||
817 | virt_addr = acpi_os_ioremap(phys_addr, size); | ||
818 | if (!virt_addr) | ||
819 | return AE_BAD_ADDRESS; | ||
820 | unmap = true; | ||
821 | } | ||
822 | |||
823 | switch (width) { | ||
824 | case 8: | ||
825 | writeb(value, virt_addr); | ||
826 | break; | ||
827 | case 16: | ||
828 | writew(value, virt_addr); | ||
829 | break; | ||
830 | case 32: | ||
831 | writel(value, virt_addr); | ||
832 | break; | ||
833 | default: | ||
834 | BUG(); | ||
835 | } | ||
836 | |||
837 | if (unmap) | ||
838 | iounmap(virt_addr); | ||
839 | else | ||
840 | rcu_read_unlock(); | ||
841 | |||
842 | return AE_OK; | ||
843 | } | ||
844 | |||
845 | #ifdef writeq | 776 | #ifdef writeq |
846 | static inline void write64(u64 val, volatile void __iomem *addr) | 777 | static inline void write64(u64 val, volatile void __iomem *addr) |
847 | { | 778 | { |
@@ -856,7 +787,7 @@ static inline void write64(u64 val, volatile void __iomem *addr) | |||
856 | #endif | 787 | #endif |
857 | 788 | ||
858 | acpi_status | 789 | acpi_status |
859 | acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width) | 790 | acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width) |
860 | { | 791 | { |
861 | void __iomem *virt_addr; | 792 | void __iomem *virt_addr; |
862 | unsigned int size = width / 8; | 793 | unsigned int size = width / 8; |
@@ -1641,3 +1572,24 @@ acpi_status acpi_os_terminate(void) | |||
1641 | 1572 | ||
1642 | return AE_OK; | 1573 | return AE_OK; |
1643 | } | 1574 | } |
1575 | |||
1576 | acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control, | ||
1577 | u32 pm1b_control) | ||
1578 | { | ||
1579 | int rc = 0; | ||
1580 | if (__acpi_os_prepare_sleep) | ||
1581 | rc = __acpi_os_prepare_sleep(sleep_state, | ||
1582 | pm1a_control, pm1b_control); | ||
1583 | if (rc < 0) | ||
1584 | return AE_ERROR; | ||
1585 | else if (rc > 0) | ||
1586 | return AE_CTRL_SKIP; | ||
1587 | |||
1588 | return AE_OK; | ||
1589 | } | ||
1590 | |||
1591 | void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, | ||
1592 | u32 pm1a_ctrl, u32 pm1b_ctrl)) | ||
1593 | { | ||
1594 | __acpi_os_prepare_sleep = func; | ||
1595 | } | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 9ac2a9fa90ff..7049a7d27c4f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -40,9 +40,11 @@ | |||
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/types.h> | 41 | #include <linux/types.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/pm_runtime.h> | ||
43 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
44 | #include <acpi/acpi_drivers.h> | 45 | #include <acpi/acpi_drivers.h> |
45 | #include "sleep.h" | 46 | #include "sleep.h" |
47 | #include "internal.h" | ||
46 | 48 | ||
47 | #define PREFIX "ACPI: " | 49 | #define PREFIX "ACPI: " |
48 | 50 | ||
@@ -77,6 +79,20 @@ static struct acpi_driver acpi_power_driver = { | |||
77 | }, | 79 | }, |
78 | }; | 80 | }; |
79 | 81 | ||
82 | /* | ||
83 | * A power managed device | ||
84 | * A device may rely on multiple power resources. | ||
85 | * */ | ||
86 | struct acpi_power_managed_device { | ||
87 | struct device *dev; /* The physical device */ | ||
88 | acpi_handle *handle; | ||
89 | }; | ||
90 | |||
91 | struct acpi_power_resource_device { | ||
92 | struct acpi_power_managed_device *device; | ||
93 | struct acpi_power_resource_device *next; | ||
94 | }; | ||
95 | |||
80 | struct acpi_power_resource { | 96 | struct acpi_power_resource { |
81 | struct acpi_device * device; | 97 | struct acpi_device * device; |
82 | acpi_bus_id name; | 98 | acpi_bus_id name; |
@@ -84,6 +100,9 @@ struct acpi_power_resource { | |||
84 | u32 order; | 100 | u32 order; |
85 | unsigned int ref_count; | 101 | unsigned int ref_count; |
86 | struct mutex resource_lock; | 102 | struct mutex resource_lock; |
103 | |||
104 | /* List of devices relying on this power resource */ | ||
105 | struct acpi_power_resource_device *devices; | ||
87 | }; | 106 | }; |
88 | 107 | ||
89 | static struct list_head acpi_power_resource_list; | 108 | static struct list_head acpi_power_resource_list; |
@@ -183,8 +202,26 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) | |||
183 | return 0; | 202 | return 0; |
184 | } | 203 | } |
185 | 204 | ||
205 | /* Resume the device when all power resources in _PR0 are on */ | ||
206 | static void acpi_power_on_device(struct acpi_power_managed_device *device) | ||
207 | { | ||
208 | struct acpi_device *acpi_dev; | ||
209 | acpi_handle handle = device->handle; | ||
210 | int state; | ||
211 | |||
212 | if (acpi_bus_get_device(handle, &acpi_dev)) | ||
213 | return; | ||
214 | |||
215 | if(acpi_power_get_inferred_state(acpi_dev, &state)) | ||
216 | return; | ||
217 | |||
218 | if (state == ACPI_STATE_D0 && pm_runtime_suspended(device->dev)) | ||
219 | pm_request_resume(device->dev); | ||
220 | } | ||
221 | |||
186 | static int __acpi_power_on(struct acpi_power_resource *resource) | 222 | static int __acpi_power_on(struct acpi_power_resource *resource) |
187 | { | 223 | { |
224 | struct acpi_power_resource_device *device_list = resource->devices; | ||
188 | acpi_status status = AE_OK; | 225 | acpi_status status = AE_OK; |
189 | 226 | ||
190 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); | 227 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); |
@@ -197,6 +234,12 @@ static int __acpi_power_on(struct acpi_power_resource *resource) | |||
197 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", | 234 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", |
198 | resource->name)); | 235 | resource->name)); |
199 | 236 | ||
237 | while (device_list) { | ||
238 | acpi_power_on_device(device_list->device); | ||
239 | |||
240 | device_list = device_list->next; | ||
241 | } | ||
242 | |||
200 | return 0; | 243 | return 0; |
201 | } | 244 | } |
202 | 245 | ||
@@ -299,6 +342,125 @@ static int acpi_power_on_list(struct acpi_handle_list *list) | |||
299 | return result; | 342 | return result; |
300 | } | 343 | } |
301 | 344 | ||
345 | static void __acpi_power_resource_unregister_device(struct device *dev, | ||
346 | acpi_handle res_handle) | ||
347 | { | ||
348 | struct acpi_power_resource *resource = NULL; | ||
349 | struct acpi_power_resource_device *prev, *curr; | ||
350 | |||
351 | if (acpi_power_get_context(res_handle, &resource)) | ||
352 | return; | ||
353 | |||
354 | mutex_lock(&resource->resource_lock); | ||
355 | prev = NULL; | ||
356 | curr = resource->devices; | ||
357 | while (curr) { | ||
358 | if (curr->device->dev == dev) { | ||
359 | if (!prev) | ||
360 | resource->devices = curr->next; | ||
361 | else | ||
362 | prev->next = curr->next; | ||
363 | |||
364 | kfree(curr); | ||
365 | break; | ||
366 | } | ||
367 | |||
368 | prev = curr; | ||
369 | curr = curr->next; | ||
370 | } | ||
371 | mutex_unlock(&resource->resource_lock); | ||
372 | } | ||
373 | |||
374 | /* Unlink dev from all power resources in _PR0 */ | ||
375 | void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle) | ||
376 | { | ||
377 | struct acpi_device *acpi_dev; | ||
378 | struct acpi_handle_list *list; | ||
379 | int i; | ||
380 | |||
381 | if (!dev || !handle) | ||
382 | return; | ||
383 | |||
384 | if (acpi_bus_get_device(handle, &acpi_dev)) | ||
385 | return; | ||
386 | |||
387 | list = &acpi_dev->power.states[ACPI_STATE_D0].resources; | ||
388 | |||
389 | for (i = 0; i < list->count; i++) | ||
390 | __acpi_power_resource_unregister_device(dev, | ||
391 | list->handles[i]); | ||
392 | } | ||
393 | |||
394 | static int __acpi_power_resource_register_device( | ||
395 | struct acpi_power_managed_device *powered_device, acpi_handle handle) | ||
396 | { | ||
397 | struct acpi_power_resource *resource = NULL; | ||
398 | struct acpi_power_resource_device *power_resource_device; | ||
399 | int result; | ||
400 | |||
401 | result = acpi_power_get_context(handle, &resource); | ||
402 | if (result) | ||
403 | return result; | ||
404 | |||
405 | power_resource_device = kzalloc( | ||
406 | sizeof(*power_resource_device), GFP_KERNEL); | ||
407 | if (!power_resource_device) | ||
408 | return -ENOMEM; | ||
409 | |||
410 | power_resource_device->device = powered_device; | ||
411 | |||
412 | mutex_lock(&resource->resource_lock); | ||
413 | power_resource_device->next = resource->devices; | ||
414 | resource->devices = power_resource_device; | ||
415 | mutex_unlock(&resource->resource_lock); | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | /* Link dev to all power resources in _PR0 */ | ||
421 | int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) | ||
422 | { | ||
423 | struct acpi_device *acpi_dev; | ||
424 | struct acpi_handle_list *list; | ||
425 | struct acpi_power_managed_device *powered_device; | ||
426 | int i, ret; | ||
427 | |||
428 | if (!dev || !handle) | ||
429 | return -ENODEV; | ||
430 | |||
431 | ret = acpi_bus_get_device(handle, &acpi_dev); | ||
432 | if (ret) | ||
433 | goto no_power_resource; | ||
434 | |||
435 | if (!acpi_dev->power.flags.power_resources) | ||
436 | goto no_power_resource; | ||
437 | |||
438 | powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL); | ||
439 | if (!powered_device) | ||
440 | return -ENOMEM; | ||
441 | |||
442 | powered_device->dev = dev; | ||
443 | powered_device->handle = handle; | ||
444 | |||
445 | list = &acpi_dev->power.states[ACPI_STATE_D0].resources; | ||
446 | |||
447 | for (i = 0; i < list->count; i++) { | ||
448 | ret = __acpi_power_resource_register_device(powered_device, | ||
449 | list->handles[i]); | ||
450 | |||
451 | if (ret) { | ||
452 | acpi_power_resource_unregister_device(dev, handle); | ||
453 | break; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | return ret; | ||
458 | |||
459 | no_power_resource: | ||
460 | printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); | ||
461 | return -ENODEV; | ||
462 | } | ||
463 | |||
302 | /** | 464 | /** |
303 | * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in | 465 | * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in |
304 | * ACPI 3.0) _PSW (Power State Wake) | 466 | * ACPI 3.0) _PSW (Power State Wake) |
@@ -500,14 +662,14 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
500 | { | 662 | { |
501 | int result; | 663 | int result; |
502 | 664 | ||
503 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | 665 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) |
504 | return -EINVAL; | 666 | return -EINVAL; |
505 | 667 | ||
506 | if (device->power.state == state) | 668 | if (device->power.state == state) |
507 | return 0; | 669 | return 0; |
508 | 670 | ||
509 | if ((device->power.state < ACPI_STATE_D0) | 671 | if ((device->power.state < ACPI_STATE_D0) |
510 | || (device->power.state > ACPI_STATE_D3)) | 672 | || (device->power.state > ACPI_STATE_D3_COLD)) |
511 | return -ENODEV; | 673 | return -ENODEV; |
512 | 674 | ||
513 | /* TBD: Resources must be ordered. */ | 675 | /* TBD: Resources must be ordered. */ |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index d4d9cb7e016a..0734086537b8 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 | 67 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 |
68 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 | 68 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 |
69 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 | 69 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 |
70 | #define ACPI_PROCESSOR_DEVICE_HID "ACPI0007" | ||
70 | 71 | ||
71 | #define ACPI_PROCESSOR_LIMIT_USER 0 | 72 | #define ACPI_PROCESSOR_LIMIT_USER 0 |
72 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 | 73 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 |
@@ -87,7 +88,7 @@ static int acpi_processor_start(struct acpi_processor *pr); | |||
87 | 88 | ||
88 | static const struct acpi_device_id processor_device_ids[] = { | 89 | static const struct acpi_device_id processor_device_ids[] = { |
89 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | 90 | {ACPI_PROCESSOR_OBJECT_HID, 0}, |
90 | {"ACPI0007", 0}, | 91 | {ACPI_PROCESSOR_DEVICE_HID, 0}, |
91 | {"", 0}, | 92 | {"", 0}, |
92 | }; | 93 | }; |
93 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | 94 | MODULE_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 | ||
595 | err_remove_sysfs: | 596 | err_remove_sysfs: |
596 | sysfs_remove_link(&device->dev.kobj, "sysdev"); | 597 | sysfs_remove_link(&device->dev.kobj, "sysdev"); |
598 | err_clear_processor: | ||
599 | /* | ||
600 | * processor_device_array is not cleared to allow checks for buggy BIOS | ||
601 | */ | ||
602 | per_cpu(processors, pr->id) = NULL; | ||
597 | err_free_cpumask: | 603 | err_free_cpumask: |
598 | free_cpumask_var(pr->throttling.shared_cpu_map); | 604 | free_cpumask_var(pr->throttling.shared_cpu_map); |
599 | 605 | err_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 | ||
751 | static 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 | |||
744 | static acpi_status | 781 | static acpi_status |
745 | processor_walk_namespace_cb(acpi_handle handle, | 782 | processor_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 | ||
778 | static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) | 812 | static 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 | */ | ||
779 | static 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"); | |||
57 | static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); | 57 | static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); |
58 | static unsigned int acpi_thermal_cpufreq_is_init = 0; | 58 | static 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 | */ | ||
70 | static 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 | |||
60 | static int cpu_has_cpufreq(unsigned int cpu) | 81 | static 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 | ||
108 | static int cpufreq_set_cur_state(unsigned int cpu, int state) | 129 | static 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..767e2dcb9616 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -880,18 +880,22 @@ 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 | } |
887 | 886 | ||
887 | /* The exist of _PR3 indicates D3Cold support */ | ||
888 | if (i == ACPI_STATE_D3) { | ||
889 | status = acpi_get_handle(device->handle, object_name, &handle); | ||
890 | if (ACPI_SUCCESS(status)) | ||
891 | device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; | ||
892 | } | ||
893 | |||
888 | /* Evaluate "_PSx" to see if we can do explicit sets */ | 894 | /* Evaluate "_PSx" to see if we can do explicit sets */ |
889 | object_name[2] = 'S'; | 895 | object_name[2] = 'S'; |
890 | status = acpi_get_handle(device->handle, object_name, &handle); | 896 | status = acpi_get_handle(device->handle, object_name, &handle); |
891 | if (ACPI_SUCCESS(status)) { | 897 | if (ACPI_SUCCESS(status)) |
892 | ps->flags.explicit_set = 1; | 898 | ps->flags.explicit_set = 1; |
893 | ps->flags.valid = 1; | ||
894 | } | ||
895 | 899 | ||
896 | /* State is valid if we have some power control */ | 900 | /* State is valid if we have some power control */ |
897 | if (ps->resources.count || ps->flags.explicit_set) | 901 | if (ps->resources.count || ps->flags.explicit_set) |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index ca191ff97844..1d661b5c3287 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/suspend.h> | 17 | #include <linux/suspend.h> |
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/acpi.h> | 19 | #include <linux/acpi.h> |
20 | #include <linux/module.h> | ||
21 | #include <linux/pm_runtime.h> | ||
20 | 22 | ||
21 | #include <asm/io.h> | 23 | #include <asm/io.h> |
22 | 24 | ||
@@ -26,6 +28,24 @@ | |||
26 | #include "internal.h" | 28 | #include "internal.h" |
27 | #include "sleep.h" | 29 | #include "sleep.h" |
28 | 30 | ||
31 | static unsigned int gts, bfs; | ||
32 | module_param(gts, uint, 0644); | ||
33 | module_param(bfs, uint, 0644); | ||
34 | MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); | ||
35 | MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); | ||
36 | |||
37 | static u8 wake_sleep_flags(void) | ||
38 | { | ||
39 | u8 flags = ACPI_NO_OPTIONAL_METHODS; | ||
40 | |||
41 | if (gts) | ||
42 | flags |= ACPI_EXECUTE_GTS; | ||
43 | if (bfs) | ||
44 | flags |= ACPI_EXECUTE_BFS; | ||
45 | |||
46 | return flags; | ||
47 | } | ||
48 | |||
29 | static u8 sleep_states[ACPI_S_STATE_COUNT]; | 49 | static u8 sleep_states[ACPI_S_STATE_COUNT]; |
30 | 50 | ||
31 | static void acpi_sleep_tts_switch(u32 acpi_state) | 51 | static void acpi_sleep_tts_switch(u32 acpi_state) |
@@ -243,6 +263,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
243 | { | 263 | { |
244 | acpi_status status = AE_OK; | 264 | acpi_status status = AE_OK; |
245 | u32 acpi_state = acpi_target_sleep_state; | 265 | u32 acpi_state = acpi_target_sleep_state; |
266 | u8 flags = wake_sleep_flags(); | ||
246 | int error; | 267 | int error; |
247 | 268 | ||
248 | ACPI_FLUSH_CPU_CACHE(); | 269 | ACPI_FLUSH_CPU_CACHE(); |
@@ -250,7 +271,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
250 | switch (acpi_state) { | 271 | switch (acpi_state) { |
251 | case ACPI_STATE_S1: | 272 | case ACPI_STATE_S1: |
252 | barrier(); | 273 | barrier(); |
253 | status = acpi_enter_sleep_state(acpi_state); | 274 | status = acpi_enter_sleep_state(acpi_state, flags); |
254 | break; | 275 | break; |
255 | 276 | ||
256 | case ACPI_STATE_S3: | 277 | case ACPI_STATE_S3: |
@@ -265,7 +286,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
265 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); | 286 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); |
266 | 287 | ||
267 | /* Reprogram control registers and execute _BFS */ | 288 | /* Reprogram control registers and execute _BFS */ |
268 | acpi_leave_sleep_state_prep(acpi_state); | 289 | acpi_leave_sleep_state_prep(acpi_state, flags); |
269 | 290 | ||
270 | /* ACPI 3.0 specs (P62) says that it's the responsibility | 291 | /* ACPI 3.0 specs (P62) says that it's the responsibility |
271 | * of the OSPM to clear the status bit [ implying that the | 292 | * of the OSPM to clear the status bit [ implying that the |
@@ -529,27 +550,30 @@ static int acpi_hibernation_begin(void) | |||
529 | 550 | ||
530 | static int acpi_hibernation_enter(void) | 551 | static int acpi_hibernation_enter(void) |
531 | { | 552 | { |
553 | u8 flags = wake_sleep_flags(); | ||
532 | acpi_status status = AE_OK; | 554 | acpi_status status = AE_OK; |
533 | 555 | ||
534 | ACPI_FLUSH_CPU_CACHE(); | 556 | ACPI_FLUSH_CPU_CACHE(); |
535 | 557 | ||
536 | /* This shouldn't return. If it returns, we have a problem */ | 558 | /* This shouldn't return. If it returns, we have a problem */ |
537 | status = acpi_enter_sleep_state(ACPI_STATE_S4); | 559 | status = acpi_enter_sleep_state(ACPI_STATE_S4, flags); |
538 | /* Reprogram control registers and execute _BFS */ | 560 | /* Reprogram control registers and execute _BFS */ |
539 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | 561 | acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags); |
540 | 562 | ||
541 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 563 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
542 | } | 564 | } |
543 | 565 | ||
544 | static void acpi_hibernation_leave(void) | 566 | static void acpi_hibernation_leave(void) |
545 | { | 567 | { |
568 | u8 flags = wake_sleep_flags(); | ||
569 | |||
546 | /* | 570 | /* |
547 | * If ACPI is not enabled by the BIOS and the boot kernel, we need to | 571 | * If ACPI is not enabled by the BIOS and the boot kernel, we need to |
548 | * enable it here. | 572 | * enable it here. |
549 | */ | 573 | */ |
550 | acpi_enable(); | 574 | acpi_enable(); |
551 | /* Reprogram control registers and execute _BFS */ | 575 | /* Reprogram control registers and execute _BFS */ |
552 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | 576 | acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags); |
553 | /* Check the hardware signature */ | 577 | /* Check the hardware signature */ |
554 | if (facs && s4_hardware_signature != facs->hardware_signature) { | 578 | if (facs && s4_hardware_signature != facs->hardware_signature) { |
555 | printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " | 579 | printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " |
@@ -730,6 +754,40 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) | |||
730 | 754 | ||
731 | #ifdef CONFIG_PM_SLEEP | 755 | #ifdef CONFIG_PM_SLEEP |
732 | /** | 756 | /** |
757 | * acpi_pm_device_run_wake - Enable/disable wake-up for given device. | ||
758 | * @phys_dev: Device to enable/disable the platform to wake-up the system for. | ||
759 | * @enable: Whether enable or disable the wake-up functionality. | ||
760 | * | ||
761 | * Find the ACPI device object corresponding to @pci_dev and try to | ||
762 | * enable/disable the GPE associated with it. | ||
763 | */ | ||
764 | int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) | ||
765 | { | ||
766 | struct acpi_device *dev; | ||
767 | acpi_handle handle; | ||
768 | |||
769 | if (!device_run_wake(phys_dev)) | ||
770 | return -EINVAL; | ||
771 | |||
772 | handle = DEVICE_ACPI_HANDLE(phys_dev); | ||
773 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { | ||
774 | dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", | ||
775 | __func__); | ||
776 | return -ENODEV; | ||
777 | } | ||
778 | |||
779 | if (enable) { | ||
780 | acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | ||
781 | acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||
782 | } else { | ||
783 | acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||
784 | acpi_disable_wakeup_device_power(dev); | ||
785 | } | ||
786 | |||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | /** | ||
733 | * acpi_pm_device_sleep_wake - enable or disable the system wake-up | 791 | * acpi_pm_device_sleep_wake - enable or disable the system wake-up |
734 | * capability of given device | 792 | * capability of given device |
735 | * @dev: device to handle | 793 | * @dev: device to handle |
@@ -770,10 +828,12 @@ static void acpi_power_off_prepare(void) | |||
770 | 828 | ||
771 | static void acpi_power_off(void) | 829 | static void acpi_power_off(void) |
772 | { | 830 | { |
831 | u8 flags = wake_sleep_flags(); | ||
832 | |||
773 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ | 833 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ |
774 | printk(KERN_DEBUG "%s called\n", __func__); | 834 | printk(KERN_DEBUG "%s called\n", __func__); |
775 | local_irq_disable(); | 835 | local_irq_disable(); |
776 | acpi_enter_sleep_state(ACPI_STATE_S5); | 836 | acpi_enter_sleep_state(ACPI_STATE_S5, flags); |
777 | } | 837 | } |
778 | 838 | ||
779 | /* | 839 | /* |
@@ -788,13 +848,13 @@ static void __init acpi_gts_bfs_check(void) | |||
788 | { | 848 | { |
789 | acpi_handle dummy; | 849 | acpi_handle dummy; |
790 | 850 | ||
791 | if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__GTS, &dummy))) | 851 | if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__GTS, &dummy))) |
792 | { | 852 | { |
793 | printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n"); | 853 | printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n"); |
794 | printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, " | 854 | printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, " |
795 | "please notify linux-acpi@vger.kernel.org\n"); | 855 | "please notify linux-acpi@vger.kernel.org\n"); |
796 | } | 856 | } |
797 | if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__BFS, &dummy))) | 857 | if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__BFS, &dummy))) |
798 | { | 858 | { |
799 | printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n"); | 859 | printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n"); |
800 | printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, " | 860 | printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, " |
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 | ||
554 | static int | 554 | static int |
555 | acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) | 555 | acpi_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 | |||
1343 | acpi_video_bus_get_devices(struct acpi_video_bus *video, | 1343 | acpi_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 6588f43017bd..87411cebc577 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -53,6 +53,52 @@ static void cpuidle_kick_cpus(void) {} | |||
53 | 53 | ||
54 | static int __cpuidle_register_device(struct cpuidle_device *dev); | 54 | static int __cpuidle_register_device(struct cpuidle_device *dev); |
55 | 55 | ||
56 | static 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 | |||
63 | static 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 | |||
69 | typedef int (*cpuidle_enter_t)(struct cpuidle_device *dev, | ||
70 | struct cpuidle_driver *drv, int index); | ||
71 | |||
72 | static 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 | */ | ||
79 | int 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_rcuidle(POWER_CSTATE, next_state, dev->cpu); | 140 | trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu); |
98 | trace_cpu_idle_rcuidle(next_state, dev->cpu); | 141 | trace_cpu_idle_rcuidle(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_rcuidle(dev->cpu); | 145 | trace_power_end_rcuidle(dev->cpu); |
103 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); | 146 | trace_cpu_idle_rcuidle(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 | ||
165 | EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); | 210 | EXPORT_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 | */ | ||
218 | int 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 |
168 | static int poll_idle(struct cpuidle_device *dev, | 244 | static 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 |
202 | static void poll_idle_init(struct cpuidle_driver *drv) {} | 279 | static void poll_idle_init(struct cpuidle_driver *drv) {} |
@@ -212,13 +289,14 @@ static void poll_idle_init(struct cpuidle_driver *drv) {} | |||
212 | int cpuidle_enable_device(struct cpuidle_device *dev) | 289 | int 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 | */ |
48 | int cpuidle_register_driver(struct cpuidle_driver *drv) | 48 | int 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) \ |
223 | static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL) | 224 | static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL) |
224 | 225 | ||
226 | #define define_one_state_rw(_name, show, store) \ | ||
227 | static 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) \ |
226 | static ssize_t show_state_##_name(struct cpuidle_state *state, \ | 230 | static 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) \ | ||
237 | static 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) \ |
233 | static ssize_t show_state_##_name(struct cpuidle_state *state, \ | 255 | static 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) | |||
251 | define_show_state_ull_function(time) | 273 | define_show_state_ull_function(time) |
252 | define_show_state_str_function(name) | 274 | define_show_state_str_function(name) |
253 | define_show_state_str_function(desc) | 275 | define_show_state_str_function(desc) |
276 | define_show_state_function(disable) | ||
277 | define_store_state_function(disable) | ||
254 | 278 | ||
255 | define_one_state_ro(name, show_state_name); | 279 | define_one_state_ro(name, show_state_name); |
256 | define_one_state_ro(desc, show_state_desc); | 280 | define_one_state_ro(desc, show_state_desc); |
@@ -258,6 +282,7 @@ define_one_state_ro(latency, show_state_exit_latency); | |||
258 | define_one_state_ro(power, show_state_power_usage); | 282 | define_one_state_ro(power, show_state_power_usage); |
259 | define_one_state_ro(usage, show_state_usage); | 283 | define_one_state_ro(usage, show_state_usage); |
260 | define_one_state_ro(time, show_state_time); | 284 | define_one_state_ro(time, show_state_time); |
285 | define_one_state_rw(disable, show_state_disable, store_state_disable); | ||
261 | 286 | ||
262 | static struct attribute *cpuidle_state_default_attrs[] = { | 287 | static 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 | ||
316 | static 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 | |||
290 | static const struct sysfs_ops cpuidle_state_sysfs_ops = { | 329 | static 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 | ||
294 | static void cpuidle_state_sysfs_release(struct kobject *kobj) | 334 | static void cpuidle_state_sysfs_release(struct kobject *kobj) |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 060fd22a1103..0f150f271c2a 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -277,40 +277,6 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
277 | return 0; | 277 | return 0; |
278 | } | 278 | } |
279 | 279 | ||
280 | /** | ||
281 | * acpi_dev_run_wake - Enable/disable wake-up for given device. | ||
282 | * @phys_dev: Device to enable/disable the platform to wake-up the system for. | ||
283 | * @enable: Whether enable or disable the wake-up functionality. | ||
284 | * | ||
285 | * Find the ACPI device object corresponding to @pci_dev and try to | ||
286 | * enable/disable the GPE associated with it. | ||
287 | */ | ||
288 | static int acpi_dev_run_wake(struct device *phys_dev, bool enable) | ||
289 | { | ||
290 | struct acpi_device *dev; | ||
291 | acpi_handle handle; | ||
292 | |||
293 | if (!device_run_wake(phys_dev)) | ||
294 | return -EINVAL; | ||
295 | |||
296 | handle = DEVICE_ACPI_HANDLE(phys_dev); | ||
297 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { | ||
298 | dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", | ||
299 | __func__); | ||
300 | return -ENODEV; | ||
301 | } | ||
302 | |||
303 | if (enable) { | ||
304 | acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | ||
305 | acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||
306 | } else { | ||
307 | acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||
308 | acpi_disable_wakeup_device_power(dev); | ||
309 | } | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | 280 | static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) |
315 | { | 281 | { |
316 | while (bus->parent) { | 282 | while (bus->parent) { |
@@ -318,14 +284,14 @@ static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | |||
318 | 284 | ||
319 | if (bridge->pme_interrupt) | 285 | if (bridge->pme_interrupt) |
320 | return; | 286 | return; |
321 | if (!acpi_dev_run_wake(&bridge->dev, enable)) | 287 | if (!acpi_pm_device_run_wake(&bridge->dev, enable)) |
322 | return; | 288 | return; |
323 | bus = bus->parent; | 289 | bus = bus->parent; |
324 | } | 290 | } |
325 | 291 | ||
326 | /* We have reached the root bus. */ | 292 | /* We have reached the root bus. */ |
327 | if (bus->bridge) | 293 | if (bus->bridge) |
328 | acpi_dev_run_wake(bus->bridge, enable); | 294 | acpi_pm_device_run_wake(bus->bridge, enable); |
329 | } | 295 | } |
330 | 296 | ||
331 | static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | 297 | static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) |
@@ -333,7 +299,7 @@ static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | |||
333 | if (dev->pme_interrupt) | 299 | if (dev->pme_interrupt) |
334 | return 0; | 300 | return 0; |
335 | 301 | ||
336 | if (!acpi_dev_run_wake(&dev->dev, enable)) | 302 | if (!acpi_pm_device_run_wake(&dev->dev, enable)) |
337 | return 0; | 303 | return 0; |
338 | 304 | ||
339 | acpi_pci_propagate_run_wake(dev->bus, enable); | 305 | acpi_pci_propagate_run_wake(dev->bus, enable); |
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 | |||
22 | config 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 | ||
5 | obj-$(CONFIG_THERMAL) += thermal_sys.o | 5 | obj-$(CONFIG_THERMAL) += thermal_sys.o |
6 | obj-$(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 */ | ||
31 | struct 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 | |||
40 | static 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 | |||
53 | static struct thermal_zone_device_ops ops = { | ||
54 | .get_temp = thermal_get_temp, | ||
55 | }; | ||
56 | |||
57 | #ifdef CONFIG_PM | ||
58 | static 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 | |||
75 | static 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 | |||
99 | static SIMPLE_DEV_PM_OPS(spear_thermal_pm_ops, spear_thermal_suspend, | ||
100 | spear_thermal_resume); | ||
101 | |||
102 | static 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 | |||
165 | disable_clk: | ||
166 | clk_disable(stdev->clk); | ||
167 | put_clk: | ||
168 | clk_put(stdev->clk); | ||
169 | |||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static 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 | |||
192 | static 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 | |||
202 | module_platform_driver(spear_thermal_driver); | ||
203 | |||
204 | MODULE_AUTHOR("Vincenzo Frascino <vincenzo.frascino@st.com>"); | ||
205 | MODULE_DESCRIPTION("SPEAr thermal driver"); | ||
206 | MODULE_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"); | |||
39 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); | 41 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); |
40 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
41 | 43 | ||
42 | #define PREFIX "Thermal: " | ||
43 | |||
44 | struct thermal_cooling_device_instance { | 44 | struct 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); | |||
60 | static LIST_HEAD(thermal_cdev_list); | 60 | static LIST_HEAD(thermal_cdev_list); |
61 | static DEFINE_MUTEX(thermal_list_lock); | 61 | static DEFINE_MUTEX(thermal_list_lock); |
62 | 62 | ||
63 | static unsigned int thermal_event_seqnum; | ||
64 | |||
65 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) | 63 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) |
66 | { | 64 | { |
67 | int err; | 65 | int err; |
68 | 66 | ||
69 | again: | 67 | again: |
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, | |||
283 | static DEVICE_ATTR(type, 0444, type_show, NULL); | 281 | static DEVICE_ATTR(type, 0444, type_show, NULL); |
284 | static DEVICE_ATTR(temp, 0444, temp_show, NULL); | 282 | static DEVICE_ATTR(temp, 0444, temp_show, NULL); |
285 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); | 283 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); |
286 | static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \ | 284 | static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); |
287 | passive_store); | ||
288 | 285 | ||
289 | static struct device_attribute trip_point_attrs[] = { | 286 | static 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) \ | ||
317 | do { \ | ||
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) \ | ||
327 | do { \ | ||
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: | 819 | remove_symbol_link: |
839 | sysfs_remove_link(&tz->device.kobj, dev->name); | 820 | sysfs_remove_link(&tz->device.kobj, dev->name); |
840 | release_idr: | 821 | release_idr: |
841 | release_idr(&tz->idr, &tz->lock, dev->id); | 822 | release_idr(&tz->idr, &tz->lock, dev->id); |
842 | free_mem: | 823 | free_mem: |
843 | kfree(dev); | 824 | kfree(dev); |
844 | return result; | 825 | return result; |
845 | } | 826 | } |
846 | |||
847 | EXPORT_SYMBOL(thermal_zone_bind_cooling_device); | 827 | EXPORT_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: | 856 | unbind: |
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 | |||
884 | EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); | 863 | EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); |
885 | 864 | ||
886 | static void thermal_release(struct device *dev) | 865 | static 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 | */ |
911 | struct thermal_cooling_device *thermal_cooling_device_register( | 891 | struct thermal_cooling_device * |
912 | char *type, void *devdata, const struct thermal_cooling_device_ops *ops) | 892 | thermal_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: | 958 | unregister: |
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 | |||
983 | EXPORT_SYMBOL(thermal_cooling_device_register); | 963 | EXPORT_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 | |||
1028 | EXPORT_SYMBOL(thermal_cooling_device_unregister); | 1007 | EXPORT_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: | 1080 | leave: |
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: | 1220 | unregister: |
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 | |||
1244 | EXPORT_SYMBOL(thermal_zone_device_register); | 1225 | EXPORT_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 | |||
1293 | EXPORT_SYMBOL(thermal_zone_device_unregister); | 1276 | EXPORT_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/drivers/acpi/acpica/acconfig.h b/include/acpi/acconfig.h index 1f30af613e87..03f14856bd09 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/include/acpi/acconfig.h | |||
@@ -85,6 +85,23 @@ | |||
85 | */ | 85 | */ |
86 | #define ACPI_CHECKSUM_ABORT FALSE | 86 | #define ACPI_CHECKSUM_ABORT FALSE |
87 | 87 | ||
88 | /* | ||
89 | * Generate a version of ACPICA that only supports "reduced hardware" | ||
90 | * platforms (as defined in ACPI 5.0). Set to TRUE to generate a specialized | ||
91 | * version of ACPICA that ONLY supports the ACPI 5.0 "reduced hardware" | ||
92 | * model. In other words, no ACPI hardware is supported. | ||
93 | * | ||
94 | * If TRUE, this means no support for the following: | ||
95 | * PM Event and Control registers | ||
96 | * SCI interrupt (and handler) | ||
97 | * Fixed Events | ||
98 | * General Purpose Events (GPEs) | ||
99 | * Global Lock | ||
100 | * ACPI PM timer | ||
101 | * FACS table (Waking vectors and Global Lock) | ||
102 | */ | ||
103 | #define ACPI_REDUCED_HARDWARE FALSE | ||
104 | |||
88 | /****************************************************************************** | 105 | /****************************************************************************** |
89 | * | 106 | * |
90 | * Subsystem Constants | 107 | * Subsystem Constants |
@@ -93,7 +110,7 @@ | |||
93 | 110 | ||
94 | /* Version of ACPI supported */ | 111 | /* Version of ACPI supported */ |
95 | 112 | ||
96 | #define ACPI_CA_SUPPORT_LEVEL 3 | 113 | #define ACPI_CA_SUPPORT_LEVEL 5 |
97 | 114 | ||
98 | /* Maximum count for a semaphore object */ | 115 | /* Maximum count for a semaphore object */ |
99 | 116 | ||
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 5b6c391efc8e..92d6e1d701ff 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h | |||
@@ -57,6 +57,7 @@ | |||
57 | #define ACPI_SUCCESS(a) (!(a)) | 57 | #define ACPI_SUCCESS(a) (!(a)) |
58 | #define ACPI_FAILURE(a) (a) | 58 | #define ACPI_FAILURE(a) (a) |
59 | 59 | ||
60 | #define ACPI_SKIP(a) (a == AE_CTRL_SKIP) | ||
60 | #define AE_OK (acpi_status) 0x0000 | 61 | #define AE_OK (acpi_status) 0x0000 |
61 | 62 | ||
62 | /* | 63 | /* |
@@ -89,8 +90,9 @@ | |||
89 | #define AE_SAME_HANDLER (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL) | 90 | #define AE_SAME_HANDLER (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL) |
90 | #define AE_NO_HANDLER (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) | 91 | #define AE_NO_HANDLER (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) |
91 | #define AE_OWNER_ID_LIMIT (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL) | 92 | #define AE_OWNER_ID_LIMIT (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL) |
93 | #define AE_NOT_CONFIGURED (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL) | ||
92 | 94 | ||
93 | #define AE_CODE_ENV_MAX 0x001B | 95 | #define AE_CODE_ENV_MAX 0x001C |
94 | 96 | ||
95 | /* | 97 | /* |
96 | * Programmer exceptions | 98 | * Programmer exceptions |
@@ -213,7 +215,8 @@ char const *acpi_gbl_exception_names_env[] = { | |||
213 | "AE_ABORT_METHOD", | 215 | "AE_ABORT_METHOD", |
214 | "AE_SAME_HANDLER", | 216 | "AE_SAME_HANDLER", |
215 | "AE_NO_HANDLER", | 217 | "AE_NO_HANDLER", |
216 | "AE_OWNER_ID_LIMIT" | 218 | "AE_OWNER_ID_LIMIT", |
219 | "AE_NOT_CONFIGURED" | ||
217 | }; | 220 | }; |
218 | 221 | ||
219 | char const *acpi_gbl_exception_names_pgm[] = { | 222 | char const *acpi_gbl_exception_names_pgm[] = { |
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 5b5af0d30a97..38f508816e4a 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | /* Method names - these methods can appear anywhere in the namespace */ | 47 | /* Method names - these methods can appear anywhere in the namespace */ |
48 | 48 | ||
49 | #define METHOD_NAME__SB_ "_SB_" | ||
49 | #define METHOD_NAME__HID "_HID" | 50 | #define METHOD_NAME__HID "_HID" |
50 | #define METHOD_NAME__CID "_CID" | 51 | #define METHOD_NAME__CID "_CID" |
51 | #define METHOD_NAME__UID "_UID" | 52 | #define METHOD_NAME__UID "_UID" |
@@ -64,11 +65,11 @@ | |||
64 | 65 | ||
65 | /* Method names - these methods must appear at the namespace root */ | 66 | /* Method names - these methods must appear at the namespace root */ |
66 | 67 | ||
67 | #define METHOD_NAME__BFS "\\_BFS" | 68 | #define METHOD_PATHNAME__BFS "\\_BFS" |
68 | #define METHOD_NAME__GTS "\\_GTS" | 69 | #define METHOD_PATHNAME__GTS "\\_GTS" |
69 | #define METHOD_NAME__PTS "\\_PTS" | 70 | #define METHOD_PATHNAME__PTS "\\_PTS" |
70 | #define METHOD_NAME__SST "\\_SI._SST" | 71 | #define METHOD_PATHNAME__SST "\\_SI._SST" |
71 | #define METHOD_NAME__WAK "\\_WAK" | 72 | #define METHOD_PATHNAME__WAK "\\_WAK" |
72 | 73 | ||
73 | /* Definitions of the predefined namespace names */ | 74 | /* Definitions of the predefined namespace names */ |
74 | 75 | ||
@@ -79,6 +80,5 @@ | |||
79 | #define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */ | 80 | #define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */ |
80 | 81 | ||
81 | #define ACPI_NS_ROOT_PATH "\\" | 82 | #define ACPI_NS_ROOT_PATH "\\" |
82 | #define ACPI_NS_SYSTEM_BUS "_SB_" | ||
83 | 83 | ||
84 | #endif /* __ACNAMES_H__ */ | 84 | #endif /* __ACNAMES_H__ */ |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 6cd5b6403a7b..f1c8ca60e824 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -323,6 +323,8 @@ int acpi_bus_set_power(acpi_handle handle, int state); | |||
323 | int acpi_bus_update_power(acpi_handle handle, int *state_p); | 323 | int acpi_bus_update_power(acpi_handle handle, int *state_p); |
324 | bool acpi_bus_power_manageable(acpi_handle handle); | 324 | bool acpi_bus_power_manageable(acpi_handle handle); |
325 | bool acpi_bus_can_wakeup(acpi_handle handle); | 325 | bool acpi_bus_can_wakeup(acpi_handle handle); |
326 | int acpi_power_resource_register_device(struct device *dev, acpi_handle handle); | ||
327 | void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle); | ||
326 | #ifdef CONFIG_ACPI_PROC_EVENT | 328 | #ifdef CONFIG_ACPI_PROC_EVENT |
327 | int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); | 329 | int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); |
328 | int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); | 330 | int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); |
@@ -392,8 +394,13 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p) | |||
392 | #endif | 394 | #endif |
393 | 395 | ||
394 | #ifdef CONFIG_PM_SLEEP | 396 | #ifdef CONFIG_PM_SLEEP |
397 | int acpi_pm_device_run_wake(struct device *, bool); | ||
395 | int acpi_pm_device_sleep_wake(struct device *, bool); | 398 | int acpi_pm_device_sleep_wake(struct device *, bool); |
396 | #else | 399 | #else |
400 | static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) | ||
401 | { | ||
402 | return -ENODEV; | ||
403 | } | ||
397 | static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | 404 | static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) |
398 | { | 405 | { |
399 | return -ENODEV; | 406 | return -ENODEV; |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 7c9aebe8a7aa..21a5548c6686 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -95,6 +95,11 @@ acpi_status | |||
95 | acpi_os_table_override(struct acpi_table_header *existing_table, | 95 | acpi_os_table_override(struct acpi_table_header *existing_table, |
96 | struct acpi_table_header **new_table); | 96 | struct acpi_table_header **new_table); |
97 | 97 | ||
98 | acpi_status | ||
99 | acpi_os_physical_table_override(struct acpi_table_header *existing_table, | ||
100 | acpi_physical_address * new_address, | ||
101 | u32 *new_table_length); | ||
102 | |||
98 | /* | 103 | /* |
99 | * Spinlock primitives | 104 | * Spinlock primitives |
100 | */ | 105 | */ |
@@ -217,14 +222,10 @@ acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width); | |||
217 | * Platform and hardware-independent physical memory interfaces | 222 | * Platform and hardware-independent physical memory interfaces |
218 | */ | 223 | */ |
219 | acpi_status | 224 | acpi_status |
220 | acpi_os_read_memory(acpi_physical_address address, u32 * value, u32 width); | 225 | acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width); |
221 | acpi_status | ||
222 | acpi_os_read_memory64(acpi_physical_address address, u64 *value, u32 width); | ||
223 | 226 | ||
224 | acpi_status | 227 | acpi_status |
225 | acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width); | 228 | acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width); |
226 | acpi_status | ||
227 | acpi_os_write_memory64(acpi_physical_address address, u64 value, u32 width); | ||
228 | 229 | ||
229 | /* | 230 | /* |
230 | * Platform and hardware-independent PCI configuration space access | 231 | * Platform and hardware-independent PCI configuration space access |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index a28da35ba45e..982110134672 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -47,8 +47,9 @@ | |||
47 | 47 | ||
48 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 48 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
49 | 49 | ||
50 | #define ACPI_CA_VERSION 0x20120111 | 50 | #define ACPI_CA_VERSION 0x20120320 |
51 | 51 | ||
52 | #include "acconfig.h" | ||
52 | #include "actypes.h" | 53 | #include "actypes.h" |
53 | #include "actbl.h" | 54 | #include "actbl.h" |
54 | 55 | ||
@@ -71,6 +72,33 @@ extern u8 acpi_gbl_copy_dsdt_locally; | |||
71 | extern u8 acpi_gbl_truncate_io_addresses; | 72 | extern u8 acpi_gbl_truncate_io_addresses; |
72 | extern u8 acpi_gbl_disable_auto_repair; | 73 | extern u8 acpi_gbl_disable_auto_repair; |
73 | 74 | ||
75 | /* | ||
76 | * Hardware-reduced prototypes. All interfaces that use these macros will | ||
77 | * be configured out of the ACPICA build if the ACPI_REDUCED_HARDWARE flag | ||
78 | * is set to TRUE. | ||
79 | */ | ||
80 | #if (!ACPI_REDUCED_HARDWARE) | ||
81 | #define ACPI_HW_DEPENDENT_RETURN_STATUS(prototype) \ | ||
82 | prototype; | ||
83 | |||
84 | #define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \ | ||
85 | prototype; | ||
86 | |||
87 | #define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \ | ||
88 | prototype; | ||
89 | |||
90 | #else | ||
91 | #define ACPI_HW_DEPENDENT_RETURN_STATUS(prototype) \ | ||
92 | static ACPI_INLINE prototype {return(AE_NOT_CONFIGURED);} | ||
93 | |||
94 | #define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \ | ||
95 | static ACPI_INLINE prototype {return(AE_OK);} | ||
96 | |||
97 | #define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \ | ||
98 | static ACPI_INLINE prototype {} | ||
99 | |||
100 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
101 | |||
74 | extern u32 acpi_current_gpe_count; | 102 | extern u32 acpi_current_gpe_count; |
75 | extern struct acpi_table_fadt acpi_gbl_FADT; | 103 | extern struct acpi_table_fadt acpi_gbl_FADT; |
76 | extern u8 acpi_gbl_system_awake_and_running; | 104 | extern u8 acpi_gbl_system_awake_and_running; |
@@ -96,9 +124,8 @@ acpi_status acpi_terminate(void); | |||
96 | acpi_status acpi_subsystem_status(void); | 124 | acpi_status acpi_subsystem_status(void); |
97 | #endif | 125 | #endif |
98 | 126 | ||
99 | acpi_status acpi_enable(void); | 127 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void)) |
100 | 128 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void)) | |
101 | acpi_status acpi_disable(void); | ||
102 | 129 | ||
103 | #ifdef ACPI_FUTURE_USAGE | 130 | #ifdef ACPI_FUTURE_USAGE |
104 | acpi_status acpi_get_system_info(struct acpi_buffer *ret_buffer); | 131 | acpi_status acpi_get_system_info(struct acpi_buffer *ret_buffer); |
@@ -235,17 +262,34 @@ acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle); | |||
235 | acpi_status | 262 | acpi_status |
236 | acpi_install_initialization_handler(acpi_init_handler handler, u32 function); | 263 | acpi_install_initialization_handler(acpi_init_handler handler, u32 function); |
237 | 264 | ||
238 | acpi_status | 265 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
239 | acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, | 266 | acpi_install_global_event_handler |
240 | void *context); | 267 | (ACPI_GBL_EVENT_HANDLER handler, void *context)) |
241 | 268 | ||
242 | acpi_status | 269 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
243 | acpi_install_fixed_event_handler(u32 acpi_event, | 270 | acpi_install_fixed_event_handler(u32 |
244 | acpi_event_handler handler, void *context); | 271 | acpi_event, |
245 | 272 | acpi_event_handler | |
246 | acpi_status | 273 | handler, |
247 | acpi_remove_fixed_event_handler(u32 acpi_event, acpi_event_handler handler); | 274 | void |
248 | 275 | *context)) | |
276 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
277 | acpi_remove_fixed_event_handler(u32 acpi_event, | ||
278 | acpi_event_handler | ||
279 | handler)) | ||
280 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
281 | acpi_install_gpe_handler(acpi_handle | ||
282 | gpe_device, | ||
283 | u32 gpe_number, | ||
284 | u32 type, | ||
285 | acpi_gpe_handler | ||
286 | address, | ||
287 | void *context)) | ||
288 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
289 | acpi_remove_gpe_handler(acpi_handle gpe_device, | ||
290 | u32 gpe_number, | ||
291 | acpi_gpe_handler | ||
292 | address)) | ||
249 | acpi_status | 293 | acpi_status |
250 | acpi_install_notify_handler(acpi_handle device, | 294 | acpi_install_notify_handler(acpi_handle device, |
251 | u32 handler_type, | 295 | u32 handler_type, |
@@ -266,15 +310,6 @@ acpi_remove_address_space_handler(acpi_handle device, | |||
266 | acpi_adr_space_type space_id, | 310 | acpi_adr_space_type space_id, |
267 | acpi_adr_space_handler handler); | 311 | acpi_adr_space_handler handler); |
268 | 312 | ||
269 | acpi_status | ||
270 | acpi_install_gpe_handler(acpi_handle gpe_device, | ||
271 | u32 gpe_number, | ||
272 | u32 type, acpi_gpe_handler address, void *context); | ||
273 | |||
274 | acpi_status | ||
275 | acpi_remove_gpe_handler(acpi_handle gpe_device, | ||
276 | u32 gpe_number, acpi_gpe_handler address); | ||
277 | |||
278 | #ifdef ACPI_FUTURE_USAGE | 313 | #ifdef ACPI_FUTURE_USAGE |
279 | acpi_status acpi_install_exception_handler(acpi_exception_handler handler); | 314 | acpi_status acpi_install_exception_handler(acpi_exception_handler handler); |
280 | #endif | 315 | #endif |
@@ -284,9 +319,11 @@ acpi_status acpi_install_interface_handler(acpi_interface_handler handler); | |||
284 | /* | 319 | /* |
285 | * Global Lock interfaces | 320 | * Global Lock interfaces |
286 | */ | 321 | */ |
287 | acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle); | 322 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
288 | 323 | acpi_acquire_global_lock(u16 timeout, | |
289 | acpi_status acpi_release_global_lock(u32 handle); | 324 | u32 *handle)) |
325 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
326 | acpi_release_global_lock(u32 handle)) | ||
290 | 327 | ||
291 | /* | 328 | /* |
292 | * Interfaces to AML mutex objects | 329 | * Interfaces to AML mutex objects |
@@ -299,47 +336,75 @@ acpi_status acpi_release_mutex(acpi_handle handle, acpi_string pathname); | |||
299 | /* | 336 | /* |
300 | * Fixed Event interfaces | 337 | * Fixed Event interfaces |
301 | */ | 338 | */ |
302 | acpi_status acpi_enable_event(u32 event, u32 flags); | 339 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
303 | 340 | acpi_enable_event(u32 event, u32 flags)) | |
304 | acpi_status acpi_disable_event(u32 event, u32 flags); | ||
305 | 341 | ||
306 | acpi_status acpi_clear_event(u32 event); | 342 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
343 | acpi_disable_event(u32 event, u32 flags)) | ||
307 | 344 | ||
308 | acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status); | 345 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_clear_event(u32 event)) |
309 | 346 | ||
347 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
348 | acpi_get_event_status(u32 event, | ||
349 | acpi_event_status | ||
350 | *event_status)) | ||
310 | /* | 351 | /* |
311 | * General Purpose Event (GPE) Interfaces | 352 | * General Purpose Event (GPE) Interfaces |
312 | */ | 353 | */ |
313 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number); | 354 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_update_all_gpes(void)) |
314 | 355 | ||
315 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number); | 356 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
316 | 357 | acpi_enable_gpe(acpi_handle gpe_device, | |
317 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number); | 358 | u32 gpe_number)) |
318 | 359 | ||
319 | acpi_status | 360 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
320 | acpi_setup_gpe_for_wake(acpi_handle parent_device, | 361 | acpi_disable_gpe(acpi_handle gpe_device, |
321 | acpi_handle gpe_device, u32 gpe_number); | 362 | u32 gpe_number)) |
322 | 363 | ||
323 | acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action); | 364 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
324 | 365 | acpi_clear_gpe(acpi_handle gpe_device, | |
325 | acpi_status | 366 | u32 gpe_number)) |
326 | acpi_get_gpe_status(acpi_handle gpe_device, | 367 | |
327 | u32 gpe_number, acpi_event_status *event_status); | 368 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
328 | 369 | acpi_set_gpe(acpi_handle gpe_device, | |
329 | acpi_status acpi_disable_all_gpes(void); | 370 | u32 gpe_number, u8 action)) |
330 | 371 | ||
331 | acpi_status acpi_enable_all_runtime_gpes(void); | 372 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
332 | 373 | acpi_finish_gpe(acpi_handle gpe_device, | |
333 | acpi_status acpi_get_gpe_device(u32 gpe_index, acpi_handle *gpe_device); | 374 | u32 gpe_number)) |
334 | 375 | ||
335 | acpi_status | 376 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
336 | acpi_install_gpe_block(acpi_handle gpe_device, | 377 | acpi_setup_gpe_for_wake(acpi_handle |
337 | struct acpi_generic_address *gpe_block_address, | 378 | parent_device, |
338 | u32 register_count, u32 interrupt_number); | 379 | acpi_handle gpe_device, |
339 | 380 | u32 gpe_number)) | |
340 | acpi_status acpi_remove_gpe_block(acpi_handle gpe_device); | 381 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
341 | 382 | acpi_set_gpe_wake_mask(acpi_handle gpe_device, | |
342 | acpi_status acpi_update_all_gpes(void); | 383 | u32 gpe_number, |
384 | u8 action)) | ||
385 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
386 | acpi_get_gpe_status(acpi_handle gpe_device, | ||
387 | u32 gpe_number, | ||
388 | acpi_event_status | ||
389 | *event_status)) | ||
390 | |||
391 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void)) | ||
392 | |||
393 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void)) | ||
394 | |||
395 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
396 | acpi_get_gpe_device(u32 gpe_index, | ||
397 | acpi_handle * gpe_device)) | ||
398 | |||
399 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
400 | acpi_install_gpe_block(acpi_handle gpe_device, | ||
401 | struct | ||
402 | acpi_generic_address | ||
403 | *gpe_block_address, | ||
404 | u32 register_count, | ||
405 | u32 interrupt_number)) | ||
406 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
407 | acpi_remove_gpe_block(acpi_handle gpe_device)) | ||
343 | 408 | ||
344 | /* | 409 | /* |
345 | * Resource interfaces | 410 | * Resource interfaces |
@@ -391,34 +456,60 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
391 | */ | 456 | */ |
392 | acpi_status acpi_reset(void); | 457 | acpi_status acpi_reset(void); |
393 | 458 | ||
394 | acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value); | 459 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
460 | acpi_read_bit_register(u32 register_id, | ||
461 | u32 *return_value)) | ||
395 | 462 | ||
396 | acpi_status acpi_write_bit_register(u32 register_id, u32 value); | 463 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
464 | acpi_write_bit_register(u32 register_id, | ||
465 | u32 value)) | ||
397 | 466 | ||
398 | acpi_status acpi_set_firmware_waking_vector(u32 physical_address); | 467 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
468 | acpi_set_firmware_waking_vector(u32 | ||
469 | physical_address)) | ||
399 | 470 | ||
400 | #if ACPI_MACHINE_WIDTH == 64 | 471 | #if ACPI_MACHINE_WIDTH == 64 |
401 | acpi_status acpi_set_firmware_waking_vector64(u64 physical_address); | 472 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
473 | acpi_set_firmware_waking_vector64(u64 | ||
474 | physical_address)) | ||
402 | #endif | 475 | #endif |
403 | 476 | ||
404 | acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg); | 477 | acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg); |
405 | 478 | ||
406 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg); | 479 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg); |
407 | 480 | ||
481 | /* | ||
482 | * Sleep/Wake interfaces | ||
483 | */ | ||
408 | acpi_status | 484 | acpi_status |
409 | acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); | 485 | acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); |
410 | 486 | ||
411 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state); | 487 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state); |
412 | 488 | ||
413 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state); | 489 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags); |
414 | 490 | ||
415 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void); | 491 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)) |
416 | 492 | ||
417 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); | 493 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags); |
418 | 494 | ||
419 | acpi_status acpi_leave_sleep_state(u8 sleep_state); | 495 | acpi_status acpi_leave_sleep_state(u8 sleep_state); |
420 | 496 | ||
421 | /* | 497 | /* |
498 | * ACPI Timer interfaces | ||
499 | */ | ||
500 | #ifdef ACPI_FUTURE_USAGE | ||
501 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
502 | acpi_get_timer_resolution(u32 *resolution)) | ||
503 | |||
504 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks)) | ||
505 | |||
506 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
507 | acpi_get_timer_duration(u32 start_ticks, | ||
508 | u32 end_ticks, | ||
509 | u32 *time_elapsed)) | ||
510 | #endif /* ACPI_FUTURE_USAGE */ | ||
511 | |||
512 | /* | ||
422 | * Error/Warning output | 513 | * Error/Warning output |
423 | */ | 514 | */ |
424 | void ACPI_INTERNAL_VAR_XFACE | 515 | void ACPI_INTERNAL_VAR_XFACE |
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 8e1b92f6f650..8dea54665dcf 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h | |||
@@ -309,6 +309,13 @@ enum acpi_prefered_pm_profiles { | |||
309 | PM_TABLET = 8 | 309 | PM_TABLET = 8 |
310 | }; | 310 | }; |
311 | 311 | ||
312 | /* Values for sleep_status and sleep_control registers (V5 FADT) */ | ||
313 | |||
314 | #define ACPI_X_WAKE_STATUS 0x80 | ||
315 | #define ACPI_X_SLEEP_TYPE_MASK 0x1C | ||
316 | #define ACPI_X_SLEEP_TYPE_POSITION 0x02 | ||
317 | #define ACPI_X_SLEEP_ENABLE 0x20 | ||
318 | |||
312 | /* Reset to default packing */ | 319 | /* Reset to default packing */ |
313 | 320 | ||
314 | #pragma pack() | 321 | #pragma pack() |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index d5dee7ce9474..eba66043cf1b 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -518,6 +518,13 @@ typedef u64 acpi_integer; | |||
518 | #define ACPI_SLEEP_TYPE_INVALID 0xFF | 518 | #define ACPI_SLEEP_TYPE_INVALID 0xFF |
519 | 519 | ||
520 | /* | 520 | /* |
521 | * Sleep/Wake flags | ||
522 | */ | ||
523 | #define ACPI_NO_OPTIONAL_METHODS 0x00 /* Do not execute any optional methods */ | ||
524 | #define ACPI_EXECUTE_GTS 0x01 /* For enter sleep interface */ | ||
525 | #define ACPI_EXECUTE_BFS 0x02 /* For leave sleep prep interface */ | ||
526 | |||
527 | /* | ||
521 | * Standard notify values | 528 | * Standard notify values |
522 | */ | 529 | */ |
523 | #define ACPI_NOTIFY_BUS_CHECK (u8) 0x00 | 530 | #define ACPI_NOTIFY_BUS_CHECK (u8) 0x00 |
@@ -532,8 +539,9 @@ typedef u64 acpi_integer; | |||
532 | #define ACPI_NOTIFY_DEVICE_PLD_CHECK (u8) 0x09 | 539 | #define ACPI_NOTIFY_DEVICE_PLD_CHECK (u8) 0x09 |
533 | #define ACPI_NOTIFY_RESERVED (u8) 0x0A | 540 | #define ACPI_NOTIFY_RESERVED (u8) 0x0A |
534 | #define ACPI_NOTIFY_LOCALITY_UPDATE (u8) 0x0B | 541 | #define ACPI_NOTIFY_LOCALITY_UPDATE (u8) 0x0B |
542 | #define ACPI_NOTIFY_SHUTDOWN_REQUEST (u8) 0x0C | ||
535 | 543 | ||
536 | #define ACPI_NOTIFY_MAX 0x0B | 544 | #define ACPI_NOTIFY_MAX 0x0C |
537 | 545 | ||
538 | /* | 546 | /* |
539 | * Types associated with ACPI names and objects. The first group of | 547 | * Types associated with ACPI names and objects. The first group of |
@@ -698,7 +706,8 @@ typedef u32 acpi_event_status; | |||
698 | #define ACPI_ALL_NOTIFY (ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY) | 706 | #define ACPI_ALL_NOTIFY (ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY) |
699 | #define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3 | 707 | #define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3 |
700 | 708 | ||
701 | #define ACPI_MAX_SYS_NOTIFY 0x7f | 709 | #define ACPI_MAX_SYS_NOTIFY 0x7F |
710 | #define ACPI_MAX_DEVICE_SPECIFIC_NOTIFY 0xBF | ||
702 | 711 | ||
703 | /* Address Space (Operation Region) Types */ | 712 | /* Address Space (Operation Region) Types */ |
704 | 713 | ||
@@ -786,6 +795,15 @@ typedef u8 acpi_adr_space_type; | |||
786 | #define ACPI_ENABLE_EVENT 1 | 795 | #define ACPI_ENABLE_EVENT 1 |
787 | #define ACPI_DISABLE_EVENT 0 | 796 | #define ACPI_DISABLE_EVENT 0 |
788 | 797 | ||
798 | /* Sleep function dispatch */ | ||
799 | |||
800 | typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state, u8 flags); | ||
801 | |||
802 | struct acpi_sleep_functions { | ||
803 | ACPI_SLEEP_FUNCTION legacy_function; | ||
804 | ACPI_SLEEP_FUNCTION extended_function; | ||
805 | }; | ||
806 | |||
789 | /* | 807 | /* |
790 | * External ACPI object definition | 808 | * External ACPI object definition |
791 | */ | 809 | */ |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index f53fea61f40a..f421dd84f29d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -372,4 +372,14 @@ static inline int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *), | |||
372 | 372 | ||
373 | #endif /* !CONFIG_ACPI */ | 373 | #endif /* !CONFIG_ACPI */ |
374 | 374 | ||
375 | #ifdef CONFIG_ACPI | ||
376 | void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, | ||
377 | u32 pm1a_ctrl, u32 pm1b_ctrl)); | ||
378 | |||
379 | acpi_status acpi_os_prepare_sleep(u8 sleep_state, | ||
380 | u32 pm1a_control, u32 pm1b_control); | ||
381 | #else | ||
382 | #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0) | ||
383 | #endif | ||
384 | |||
375 | #endif /*_LINUX_ACPI_H*/ | 385 | #endif /*_LINUX_ACPI_H*/ |
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 | ||
102 | DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); | 105 | DECLARE_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 | ||
120 | struct cpuidle_driver { | 123 | struct 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); | |||
140 | extern void cpuidle_resume_and_unlock(void); | 145 | extern void cpuidle_resume_and_unlock(void); |
141 | extern int cpuidle_enable_device(struct cpuidle_device *dev); | 146 | extern int cpuidle_enable_device(struct cpuidle_device *dev); |
142 | extern void cpuidle_disable_device(struct cpuidle_device *dev); | 147 | extern void cpuidle_disable_device(struct cpuidle_device *dev); |
148 | extern 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)); | ||
152 | extern int cpuidle_play_dead(void); | ||
143 | 153 | ||
144 | #else | 154 | #else |
145 | static inline void disable_cpuidle(void) { } | 155 | static inline void disable_cpuidle(void) { } |
@@ -157,6 +167,12 @@ static inline void cpuidle_resume_and_unlock(void) { } | |||
157 | static inline int cpuidle_enable_device(struct cpuidle_device *dev) | 167 | static inline int cpuidle_enable_device(struct cpuidle_device *dev) |
158 | {return -ENODEV; } | 168 | {return -ENODEV; } |
159 | static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } | 169 | static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } |
170 | static 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; } | ||
175 | static 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 */ | ||
21 | struct 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/include/linux/tboot.h b/include/linux/tboot.h index 1dba6ee55203..c75128bed5fa 100644 --- a/include/linux/tboot.h +++ b/include/linux/tboot.h | |||
@@ -143,7 +143,6 @@ static inline int tboot_enabled(void) | |||
143 | 143 | ||
144 | extern void tboot_probe(void); | 144 | extern void tboot_probe(void); |
145 | extern void tboot_shutdown(u32 shutdown_type); | 145 | extern void tboot_shutdown(u32 shutdown_type); |
146 | extern void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control); | ||
147 | extern struct acpi_table_header *tboot_get_dmar_table( | 146 | extern struct acpi_table_header *tboot_get_dmar_table( |
148 | struct acpi_table_header *dmar_tbl); | 147 | struct acpi_table_header *dmar_tbl); |
149 | extern int tboot_force_iommu(void); | 148 | extern int tboot_force_iommu(void); |
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. | |||
25 | on processors that additionally support C-state residency counters. | 27 | on processors that additionally support C-state residency counters. |
26 | 28 | ||
27 | .SS Options | 29 | .SS Options |
30 | The \fB-s\fP option prints only a 1-line summary for each sample interval. | ||
31 | .PP | ||
28 | The \fB-v\fP option increases verbosity. | 32 | The \fB-v\fP option increases verbosity. |
29 | .PP | 33 | .PP |
30 | The \fB-M MSR#\fP option dumps the specified MSR, | 34 | The \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. |
48 | Note 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 |
54 | for turbostat to fork). | 59 | for turbostat to fork). |
55 | 60 | ||
56 | The first row of statistics reflect the average for the entire system. | 61 | The first row of statistics is a summary for the entire system. |
62 | Note that the summary is a weighted average. | ||
57 | Subsequent rows show per-CPU statistics. | 63 | Subsequent rows show per-CPU statistics. |
58 | 64 | ||
59 | .nf | 65 | .nf |
60 | [root@x980]# ./turbostat | 66 | [root@x980]# ./turbostat |
61 | cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 | 67 | cor 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 | ||
83 | The "-s" option prints the column headers just once, | ||
84 | and 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 |
77 | The "-v" option adds verbosity to the output: | 94 | The "-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 | 122 | cor 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 |
119 | 6.950866 sec | 136 | 4.907015 sec |
120 | 137 | ||
121 | .fi | 138 | .fi |
122 | Above the cycle soaker drives cpu9 up 3.6 Ghz turbo limit | 139 | Above the cycle soaker drives cpu6 up 3.6 Ghz turbo limit |
123 | while the other processors are generally in various states of idle. | 140 | while the other processors are generally in various states of idle. |
124 | 141 | ||
125 | Note that cpu3 is an HT sibling sharing core9 | 142 | Note that cpu0 is an HT sibling sharing core0 |
126 | with cpu9, and thus it is unable to get to an idle state | 143 | with cpu6, and thus it is unable to get to an idle state |
127 | deeper than c1 while cpu9 is busy. | 144 | deeper than c1 while cpu6 is busy. |
128 | 145 | ||
129 | Note that turbostat reports average GHz of 3.61, while | 146 | Note that turbostat reports average GHz of 3.64, while |
130 | the arithmetic average of the GHz column above is 3.24. | 147 | the arithmetic average of the GHz column above is lower. |
131 | This is a weighted average, where the weight is %c0. ie. it is the total number of | 148 | This is a weighted average, where the weight is %c0. ie. it is the total number of |
132 | un-halted cycles elapsed per time divided by the number of CPUs. | 149 | un-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" |
168 | msr(4), vmstat(8) | 185 | msr(4), vmstat(8) |
169 | .PP | 186 | .PP |
170 | .SH AUTHORS | 187 | .SH AUTHOR |
171 | .nf | 188 | .nf |
172 | Written by Len Brown <len.brown@intel.com> | 189 | Written 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 @@ | |||
49 | char *proc_stat = "/proc/stat"; | 51 | char *proc_stat = "/proc/stat"; |
50 | unsigned int interval_sec = 5; /* set with -i interval_sec */ | 52 | unsigned int interval_sec = 5; /* set with -i interval_sec */ |
51 | unsigned int verbose; /* set with -v */ | 53 | unsigned int verbose; /* set with -v */ |
54 | unsigned int summary_only; /* set with -s */ | ||
52 | unsigned int skip_c0; | 55 | unsigned int skip_c0; |
53 | unsigned int skip_c1; | 56 | unsigned int skip_c1; |
54 | unsigned int do_nhm_cstates; | 57 | unsigned int do_nhm_cstates; |
@@ -68,9 +71,10 @@ unsigned int show_cpu; | |||
68 | int aperf_mperf_unstable; | 71 | int aperf_mperf_unstable; |
69 | int backwards_count; | 72 | int backwards_count; |
70 | char *progname; | 73 | char *progname; |
71 | int need_reinitialize; | ||
72 | 74 | ||
73 | int num_cpus; | 75 | int num_cpus; |
76 | cpu_set_t *cpu_mask; | ||
77 | size_t cpu_mask_size; | ||
74 | 78 | ||
75 | struct counters { | 79 | struct counters { |
76 | unsigned long long tsc; /* per thread */ | 80 | unsigned long long tsc; /* per thread */ |
@@ -99,44 +103,76 @@ struct timeval tv_even; | |||
99 | struct timeval tv_odd; | 103 | struct timeval tv_odd; |
100 | struct timeval tv_delta; | 104 | struct timeval tv_delta; |
101 | 105 | ||
102 | unsigned 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 | */ | ||
112 | void 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 | |||
123 | void cpu_mask_uninit() | ||
124 | { | ||
125 | CPU_FREE(cpu_mask); | ||
126 | cpu_mask = NULL; | ||
127 | cpu_mask_size = 0; | ||
128 | } | ||
129 | |||
130 | int 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 | |||
140 | int 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 | ||
128 | void print_header(void) | 160 | void 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 | */ | ||
190 | void print_cnt(struct counters *p) | 235 | void 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) | |||
267 | void print_counters(struct counters *counters) | 318 | void 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 | ||
443 | void get_counters(struct counters *cnt) | 502 | int 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 | ||
470 | void print_nehalem_info(void) | 549 | void 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 | ||
687 | int for_all_cpus(void (func)(int, int, int)) | 769 | int for_all_cpus(void (func)(int, int, int)) |
@@ -717,18 +799,18 @@ int for_all_cpus(void (func)(int, int, int)) | |||
717 | 799 | ||
718 | void re_initialize(void) | 800 | void 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 | ||
727 | void dummy(int pkg, int core, int cpu) { return; } | 809 | void 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 | */ |
731 | void verify_num_cpus(void) | 813 | int 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 | ||
745 | void turbostat_loop() | 828 | void 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; |