diff options
242 files changed, 4649 insertions, 2749 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 468e4d48f884..d5a0d33c571f 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
@@ -200,3 +200,27 @@ Description: address and size of the percpu note. | |||
200 | note of cpu#. | 200 | note of cpu#. |
201 | 201 | ||
202 | crash_notes_size: size of the note of cpu#. | 202 | crash_notes_size: size of the note of cpu#. |
203 | |||
204 | |||
205 | What: /sys/devices/system/cpu/intel_pstate/max_perf_pct | ||
206 | /sys/devices/system/cpu/intel_pstate/min_perf_pct | ||
207 | /sys/devices/system/cpu/intel_pstate/no_turbo | ||
208 | Date: February 2013 | ||
209 | Contact: linux-pm@vger.kernel.org | ||
210 | Description: Parameters for the Intel P-state driver | ||
211 | |||
212 | Logic for selecting the current P-state in Intel | ||
213 | Sandybridge+ processors. The three knobs control | ||
214 | limits for the P-state that will be requested by the | ||
215 | driver. | ||
216 | |||
217 | max_perf_pct: limits the maximum P state that will be requested by | ||
218 | the driver stated as a percentage of the available performance. | ||
219 | |||
220 | min_perf_pct: limits the minimum P state that will be requested by | ||
221 | the driver stated as a percentage of the available performance. | ||
222 | |||
223 | no_turbo: limits the driver to selecting P states below the turbo | ||
224 | frequency range. | ||
225 | |||
226 | More details can be found in Documentation/cpu-freq/intel-pstate.txt | ||
diff --git a/Documentation/acpi/namespace.txt b/Documentation/acpi/namespace.txt index 260f6a3661fa..1860cb3865c6 100644 --- a/Documentation/acpi/namespace.txt +++ b/Documentation/acpi/namespace.txt | |||
@@ -235,10 +235,6 @@ Wysocki <rafael.j.wysocki@intel.com>. | |||
235 | named object's type in the second column). In that case the object's | 235 | named object's type in the second column). In that case the object's |
236 | directory in sysfs will contain the 'path' attribute whose value is | 236 | directory in sysfs will contain the 'path' attribute whose value is |
237 | the full path to the node from the namespace root. | 237 | the full path to the node from the namespace root. |
238 | struct acpi_device objects are created for the ACPI namespace nodes | ||
239 | whose _STA control methods return PRESENT or FUNCTIONING. The power | ||
240 | resource nodes or nodes without _STA are assumed to be both PRESENT | ||
241 | and FUNCTIONING. | ||
242 | F: | 238 | F: |
243 | The struct acpi_device object is created for a fixed hardware | 239 | The struct acpi_device object is created for a fixed hardware |
244 | feature (as indicated by the fixed feature flag's name in the second | 240 | feature (as indicated by the fixed feature flag's name in the second |
@@ -340,7 +336,7 @@ Wysocki <rafael.j.wysocki@intel.com>. | |||
340 | | +-------------+-------+----------------+ | 336 | | +-------------+-------+----------------+ |
341 | | | | 337 | | | |
342 | | | +- - - - - - - +- - - - - - +- - - - - - - -+ | 338 | | | +- - - - - - - +- - - - - - +- - - - - - - -+ |
343 | | +-| * PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: | | 339 | | +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: | |
344 | | | +- - - - - - - +- - - - - - +- - - - - - - -+ | 340 | | | +- - - - - - - +- - - - - - +- - - - - - - -+ |
345 | | | | 341 | | | |
346 | | | +------------+------------+-----------------------+ | 342 | | | +------------+------------+-----------------------+ |
@@ -390,6 +386,3 @@ Wysocki <rafael.j.wysocki@intel.com>. | |||
390 | attribute (as described earlier in this document). | 386 | attribute (as described earlier in this document). |
391 | NOTE: N/A indicates the device object does not have the 'path' or the | 387 | NOTE: N/A indicates the device object does not have the 'path' or the |
392 | 'modalias' attribute. | 388 | 'modalias' attribute. |
393 | NOTE: The PNP0C0D device listed above is highlighted (marked by "*") | ||
394 | to indicate it will be created only when its _STA methods return | ||
395 | PRESENT or FUNCTIONING. | ||
diff --git a/Documentation/cpu-freq/boost.txt b/Documentation/cpu-freq/boost.txt index 9b4edfcf486f..dd62e1334f0a 100644 --- a/Documentation/cpu-freq/boost.txt +++ b/Documentation/cpu-freq/boost.txt | |||
@@ -17,8 +17,8 @@ Introduction | |||
17 | Some CPUs support a functionality to raise the operating frequency of | 17 | Some CPUs support a functionality to raise the operating frequency of |
18 | some cores in a multi-core package if certain conditions apply, mostly | 18 | some cores in a multi-core package if certain conditions apply, mostly |
19 | if the whole chip is not fully utilized and below it's intended thermal | 19 | if the whole chip is not fully utilized and below it's intended thermal |
20 | budget. This is done without operating system control by a combination | 20 | budget. The decision about boost disable/enable is made either at hardware |
21 | of hardware and firmware. | 21 | (e.g. x86) or software (e.g ARM). |
22 | On Intel CPUs this is called "Turbo Boost", AMD calls it "Turbo-Core", | 22 | On Intel CPUs this is called "Turbo Boost", AMD calls it "Turbo-Core", |
23 | in technical documentation "Core performance boost". In Linux we use | 23 | in technical documentation "Core performance boost". In Linux we use |
24 | the term "boost" for convenience. | 24 | the term "boost" for convenience. |
@@ -48,24 +48,24 @@ be desirable: | |||
48 | User controlled switch | 48 | User controlled switch |
49 | ---------------------- | 49 | ---------------------- |
50 | 50 | ||
51 | To allow the user to toggle the boosting functionality, the acpi-cpufreq | 51 | To allow the user to toggle the boosting functionality, the cpufreq core |
52 | driver exports a sysfs knob to disable it. There is a file: | 52 | driver exports a sysfs knob to enable or disable it. There is a file: |
53 | /sys/devices/system/cpu/cpufreq/boost | 53 | /sys/devices/system/cpu/cpufreq/boost |
54 | which can either read "0" (boosting disabled) or "1" (boosting enabled). | 54 | which can either read "0" (boosting disabled) or "1" (boosting enabled). |
55 | Reading the file is always supported, even if the processor does not | 55 | The file is exported only when cpufreq driver supports boosting. |
56 | support boosting. In this case the file will be read-only and always | 56 | Explicitly changing the permissions and writing to that file anyway will |
57 | reads as "0". Explicitly changing the permissions and writing to that | 57 | return EINVAL. |
58 | file anyway will return EINVAL. | ||
59 | 58 | ||
60 | On supported CPUs one can write either a "0" or a "1" into this file. | 59 | On supported CPUs one can write either a "0" or a "1" into this file. |
61 | This will either disable the boost functionality on all cores in the | 60 | This will either disable the boost functionality on all cores in the |
62 | whole system (0) or will allow the hardware to boost at will (1). | 61 | whole system (0) or will allow the software or hardware to boost at will |
62 | (1). | ||
63 | 63 | ||
64 | Writing a "1" does not explicitly boost the system, but just allows the | 64 | Writing a "1" does not explicitly boost the system, but just allows the |
65 | CPU (and the firmware) to boost at their discretion. Some implementations | 65 | CPU to boost at their discretion. Some implementations take external |
66 | take external factors like the chip's temperature into account, so | 66 | factors like the chip's temperature into account, so boosting once does |
67 | boosting once does not necessarily mean that it will occur every time | 67 | not necessarily mean that it will occur every time even using the exact |
68 | even using the exact same software setup. | 68 | same software setup. |
69 | 69 | ||
70 | 70 | ||
71 | AMD legacy cpb switch | 71 | AMD legacy cpb switch |
diff --git a/Documentation/cpu-freq/intel-pstate.txt b/Documentation/cpu-freq/intel-pstate.txt new file mode 100644 index 000000000000..e742d21dbd96 --- /dev/null +++ b/Documentation/cpu-freq/intel-pstate.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | Intel P-state driver | ||
2 | -------------------- | ||
3 | |||
4 | This driver implements a scaling driver with an internal governor for | ||
5 | Intel Core processors. The driver follows the same model as the | ||
6 | Transmeta scaling driver (longrun.c) and implements the setpolicy() | ||
7 | instead of target(). Scaling drivers that implement setpolicy() are | ||
8 | assumed to implement internal governors by the cpufreq core. All the | ||
9 | logic for selecting the current P state is contained within the | ||
10 | driver; no external governor is used by the cpufreq core. | ||
11 | |||
12 | Intel SandyBridge+ processors are supported. | ||
13 | |||
14 | New sysfs files for controlling P state selection have been added to | ||
15 | /sys/devices/system/cpu/intel_pstate/ | ||
16 | |||
17 | max_perf_pct: limits the maximum P state that will be requested by | ||
18 | the driver stated as a percentage of the available performance. | ||
19 | |||
20 | min_perf_pct: limits the minimum P state that will be requested by | ||
21 | the driver stated as a percentage of the available performance. | ||
22 | |||
23 | no_turbo: limits the driver to selecting P states below the turbo | ||
24 | frequency range. | ||
25 | |||
26 | For contemporary Intel processors, the frequency is controlled by the | ||
27 | processor itself and the P-states exposed to software are related to | ||
28 | performance levels. The idea that frequency can be set to a single | ||
29 | frequency is fiction for Intel Core processors. Even if the scaling | ||
30 | driver selects a single P state the actual frequency the processor | ||
31 | will run at is selected by the processor itself. | ||
32 | |||
33 | New debugfs files have also been added to /sys/kernel/debug/pstate_snb/ | ||
34 | |||
35 | deadband | ||
36 | d_gain_pct | ||
37 | i_gain_pct | ||
38 | p_gain_pct | ||
39 | sample_rate_ms | ||
40 | setpoint | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 44738564b2ee..be6ba33d4ff1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -343,6 +343,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
343 | no: ACPI OperationRegions are not marked as reserved, | 343 | no: ACPI OperationRegions are not marked as reserved, |
344 | no further checks are performed. | 344 | no further checks are performed. |
345 | 345 | ||
346 | acpi_no_memhotplug [ACPI] Disable memory hotplug. Useful for kdump | ||
347 | kernels. | ||
348 | |||
346 | add_efi_memmap [EFI; X86] Include EFI memory map in | 349 | add_efi_memmap [EFI; X86] Include EFI memory map in |
347 | kernel's map of available physical RAM. | 350 | kernel's map of available physical RAM. |
348 | 351 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 6270a0b2b99d..c9f0da19048b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -257,6 +257,7 @@ F: Documentation/ABI/testing/sysfs-bus-acpi | |||
257 | F: drivers/pci/*acpi* | 257 | F: drivers/pci/*acpi* |
258 | F: drivers/pci/*/*acpi* | 258 | F: drivers/pci/*/*acpi* |
259 | F: drivers/pci/*/*/*acpi* | 259 | F: drivers/pci/*/*/*acpi* |
260 | F: tools/power/acpi | ||
260 | 261 | ||
261 | ACPI COMPONENT ARCHITECTURE (ACPICA) | 262 | ACPI COMPONENT ARCHITECTURE (ACPICA) |
262 | M: Robert Moore <robert.moore@intel.com> | 263 | M: Robert Moore <robert.moore@intel.com> |
@@ -271,6 +272,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm | |||
271 | S: Supported | 272 | S: Supported |
272 | F: drivers/acpi/acpica/ | 273 | F: drivers/acpi/acpica/ |
273 | F: include/acpi/ | 274 | F: include/acpi/ |
275 | F: tools/power/acpi/ | ||
274 | 276 | ||
275 | ACPI FAN DRIVER | 277 | ACPI FAN DRIVER |
276 | M: Zhang Rui <rui.zhang@intel.com> | 278 | M: Zhang Rui <rui.zhang@intel.com> |
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 72ae5d3a87d2..f18be40e5b21 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c | |||
@@ -303,6 +303,11 @@ void __init exynos_cpuidle_init(void) | |||
303 | platform_device_register(&exynos_cpuidle); | 303 | platform_device_register(&exynos_cpuidle); |
304 | } | 304 | } |
305 | 305 | ||
306 | void __init exynos_cpufreq_init(void) | ||
307 | { | ||
308 | platform_device_register_simple("exynos-cpufreq", -1, NULL, 0); | ||
309 | } | ||
310 | |||
306 | void __init exynos_init_late(void) | 311 | void __init exynos_init_late(void) |
307 | { | 312 | { |
308 | if (of_machine_is_compatible("samsung,exynos5440")) | 313 | if (of_machine_is_compatible("samsung,exynos5440")) |
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 0c31b34f0de5..f76967b1c551 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h | |||
@@ -22,6 +22,7 @@ void exynos_init_io(void); | |||
22 | void exynos4_restart(enum reboot_mode mode, const char *cmd); | 22 | void exynos4_restart(enum reboot_mode mode, const char *cmd); |
23 | void exynos5_restart(enum reboot_mode mode, const char *cmd); | 23 | void exynos5_restart(enum reboot_mode mode, const char *cmd); |
24 | void exynos_cpuidle_init(void); | 24 | void exynos_cpuidle_init(void); |
25 | void exynos_cpufreq_init(void); | ||
25 | void exynos_init_late(void); | 26 | void exynos_init_late(void); |
26 | 27 | ||
27 | void exynos_firmware_init(void); | 28 | void exynos_firmware_init(void); |
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index da65b036af2b..f57cb91f02aa 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c | |||
@@ -172,8 +172,8 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev, | |||
172 | { | 172 | { |
173 | int new_index = index; | 173 | int new_index = index; |
174 | 174 | ||
175 | /* This mode only can be entered when other core's are offline */ | 175 | /* AFTR can only be entered when cores other than CPU0 are offline */ |
176 | if (num_online_cpus() > 1) | 176 | if (num_online_cpus() > 1 || dev->cpu != 0) |
177 | new_index = drv->safe_state_index; | 177 | new_index = drv->safe_state_index; |
178 | 178 | ||
179 | if (new_index == 0) | 179 | if (new_index == 0) |
@@ -235,10 +235,6 @@ static int exynos_cpuidle_probe(struct platform_device *pdev) | |||
235 | device = &per_cpu(exynos4_cpuidle_device, cpu_id); | 235 | device = &per_cpu(exynos4_cpuidle_device, cpu_id); |
236 | device->cpu = cpu_id; | 236 | device->cpu = cpu_id; |
237 | 237 | ||
238 | /* Support IDLE only */ | ||
239 | if (cpu_id != 0) | ||
240 | device->state_count = 1; | ||
241 | |||
242 | ret = cpuidle_register_device(device); | 238 | ret = cpuidle_register_device(device); |
243 | if (ret) { | 239 | if (ret) { |
244 | dev_err(&pdev->dev, "failed to register cpuidle device\n"); | 240 | dev_err(&pdev->dev, "failed to register cpuidle device\n"); |
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c index 4603e6bd424b..d3e54b7644d7 100644 --- a/arch/arm/mach-exynos/mach-exynos4-dt.c +++ b/arch/arm/mach-exynos/mach-exynos4-dt.c | |||
@@ -22,6 +22,7 @@ | |||
22 | static void __init exynos4_dt_machine_init(void) | 22 | static void __init exynos4_dt_machine_init(void) |
23 | { | 23 | { |
24 | exynos_cpuidle_init(); | 24 | exynos_cpuidle_init(); |
25 | exynos_cpufreq_init(); | ||
25 | 26 | ||
26 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 27 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
27 | } | 28 | } |
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 65a46465ac5e..37ea261f0f6c 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c | |||
@@ -44,6 +44,7 @@ static void __init exynos5_dt_machine_init(void) | |||
44 | } | 44 | } |
45 | 45 | ||
46 | exynos_cpuidle_init(); | 46 | exynos_cpuidle_init(); |
47 | exynos_cpufreq_init(); | ||
47 | 48 | ||
48 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 49 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
49 | } | 50 | } |
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c index 172ebd0ee0a2..9fa6a990cf03 100644 --- a/arch/arm/mach-sa1100/clock.c +++ b/arch/arm/mach-sa1100/clock.c | |||
@@ -33,6 +33,13 @@ struct clk clk_##_name = { \ | |||
33 | 33 | ||
34 | static DEFINE_SPINLOCK(clocks_lock); | 34 | static DEFINE_SPINLOCK(clocks_lock); |
35 | 35 | ||
36 | /* Dummy clk routine to build generic kernel parts that may be using them */ | ||
37 | unsigned long clk_get_rate(struct clk *clk) | ||
38 | { | ||
39 | return 0; | ||
40 | } | ||
41 | EXPORT_SYMBOL(clk_get_rate); | ||
42 | |||
36 | static void clk_gpio27_enable(struct clk *clk) | 43 | static void clk_gpio27_enable(struct clk *clk) |
37 | { | 44 | { |
38 | /* | 45 | /* |
diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c index 916ffe770bcf..84715fcbba08 100644 --- a/arch/ia64/hp/common/aml_nfw.c +++ b/arch/ia64/hp/common/aml_nfw.c | |||
@@ -23,8 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <acpi/acpi_bus.h> | 26 | #include <linux/acpi.h> |
27 | #include <acpi/acpi_drivers.h> | ||
28 | #include <asm/sal.h> | 27 | #include <asm/sal.h> |
29 | 28 | ||
30 | MODULE_AUTHOR("Bjorn Helgaas <bjorn.helgaas@hp.com>"); | 29 | MODULE_AUTHOR("Bjorn Helgaas <bjorn.helgaas@hp.com>"); |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index bfa19311e09c..07d209c9507f 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -60,7 +60,6 @@ | |||
60 | 60 | ||
61 | #define PREFIX "ACPI: " | 61 | #define PREFIX "ACPI: " |
62 | 62 | ||
63 | u32 acpi_rsdt_forced; | ||
64 | unsigned int acpi_cpei_override; | 63 | unsigned int acpi_cpei_override; |
65 | unsigned int acpi_cpei_phys_cpuid; | 64 | unsigned int acpi_cpei_phys_cpuid; |
66 | 65 | ||
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c index a166e38bd683..94134a5aecaa 100644 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ b/arch/powerpc/platforms/pseries/processor_idle.c | |||
@@ -28,7 +28,6 @@ struct cpuidle_driver pseries_idle_driver = { | |||
28 | #define MAX_IDLE_STATE_COUNT 2 | 28 | #define MAX_IDLE_STATE_COUNT 2 |
29 | 29 | ||
30 | static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; | 30 | static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; |
31 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; | ||
32 | static struct cpuidle_state *cpuidle_state_table; | 31 | static struct cpuidle_state *cpuidle_state_table; |
33 | 32 | ||
34 | static inline void idle_loop_prolog(unsigned long *in_purr) | 33 | static inline void idle_loop_prolog(unsigned long *in_purr) |
@@ -191,7 +190,7 @@ static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, | |||
191 | { | 190 | { |
192 | int hotcpu = (unsigned long)hcpu; | 191 | int hotcpu = (unsigned long)hcpu; |
193 | struct cpuidle_device *dev = | 192 | struct cpuidle_device *dev = |
194 | per_cpu_ptr(pseries_cpuidle_devices, hotcpu); | 193 | per_cpu_ptr(cpuidle_devices, hotcpu); |
195 | 194 | ||
196 | if (dev && cpuidle_get_driver()) { | 195 | if (dev && cpuidle_get_driver()) { |
197 | switch (action) { | 196 | switch (action) { |
@@ -248,50 +247,6 @@ static int pseries_cpuidle_driver_init(void) | |||
248 | return 0; | 247 | return 0; |
249 | } | 248 | } |
250 | 249 | ||
251 | /* pseries_idle_devices_uninit(void) | ||
252 | * unregister cpuidle devices and de-allocate memory | ||
253 | */ | ||
254 | static void pseries_idle_devices_uninit(void) | ||
255 | { | ||
256 | int i; | ||
257 | struct cpuidle_device *dev; | ||
258 | |||
259 | for_each_possible_cpu(i) { | ||
260 | dev = per_cpu_ptr(pseries_cpuidle_devices, i); | ||
261 | cpuidle_unregister_device(dev); | ||
262 | } | ||
263 | |||
264 | free_percpu(pseries_cpuidle_devices); | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | /* pseries_idle_devices_init() | ||
269 | * allocate, initialize and register cpuidle device | ||
270 | */ | ||
271 | static int pseries_idle_devices_init(void) | ||
272 | { | ||
273 | int i; | ||
274 | struct cpuidle_driver *drv = &pseries_idle_driver; | ||
275 | struct cpuidle_device *dev; | ||
276 | |||
277 | pseries_cpuidle_devices = alloc_percpu(struct cpuidle_device); | ||
278 | if (pseries_cpuidle_devices == NULL) | ||
279 | return -ENOMEM; | ||
280 | |||
281 | for_each_possible_cpu(i) { | ||
282 | dev = per_cpu_ptr(pseries_cpuidle_devices, i); | ||
283 | dev->state_count = drv->state_count; | ||
284 | dev->cpu = i; | ||
285 | if (cpuidle_register_device(dev)) { | ||
286 | printk(KERN_DEBUG \ | ||
287 | "cpuidle_register_device %d failed!\n", i); | ||
288 | return -EIO; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | /* | 250 | /* |
296 | * pseries_idle_probe() | 251 | * pseries_idle_probe() |
297 | * Choose state table for shared versus dedicated partition | 252 | * Choose state table for shared versus dedicated partition |
@@ -327,19 +282,12 @@ static int __init pseries_processor_idle_init(void) | |||
327 | return retval; | 282 | return retval; |
328 | 283 | ||
329 | pseries_cpuidle_driver_init(); | 284 | pseries_cpuidle_driver_init(); |
330 | retval = cpuidle_register_driver(&pseries_idle_driver); | 285 | retval = cpuidle_register(&pseries_idle_driver, NULL); |
331 | if (retval) { | 286 | if (retval) { |
332 | printk(KERN_DEBUG "Registration of pseries driver failed.\n"); | 287 | printk(KERN_DEBUG "Registration of pseries driver failed.\n"); |
333 | return retval; | 288 | return retval; |
334 | } | 289 | } |
335 | 290 | ||
336 | retval = pseries_idle_devices_init(); | ||
337 | if (retval) { | ||
338 | pseries_idle_devices_uninit(); | ||
339 | cpuidle_unregister_driver(&pseries_idle_driver); | ||
340 | return retval; | ||
341 | } | ||
342 | |||
343 | register_cpu_notifier(&setup_hotplug_notifier); | 291 | register_cpu_notifier(&setup_hotplug_notifier); |
344 | printk(KERN_DEBUG "pseries_idle_driver registered\n"); | 292 | printk(KERN_DEBUG "pseries_idle_driver registered\n"); |
345 | 293 | ||
@@ -350,8 +298,7 @@ static void __exit pseries_processor_idle_exit(void) | |||
350 | { | 298 | { |
351 | 299 | ||
352 | unregister_cpu_notifier(&setup_hotplug_notifier); | 300 | unregister_cpu_notifier(&setup_hotplug_notifier); |
353 | pseries_idle_devices_uninit(); | 301 | cpuidle_unregister(&pseries_idle_driver); |
354 | cpuidle_unregister_driver(&pseries_idle_driver); | ||
355 | 302 | ||
356 | return; | 303 | return; |
357 | } | 304 | } |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index d359d0fffa50..1dac94265b59 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -46,7 +46,6 @@ | |||
46 | 46 | ||
47 | #include "sleep.h" /* To include x86_acpi_suspend_lowlevel */ | 47 | #include "sleep.h" /* To include x86_acpi_suspend_lowlevel */ |
48 | static int __initdata acpi_force = 0; | 48 | static int __initdata acpi_force = 0; |
49 | u32 acpi_rsdt_forced; | ||
50 | int acpi_disabled; | 49 | int acpi_disabled; |
51 | EXPORT_SYMBOL(acpi_disabled); | 50 | EXPORT_SYMBOL(acpi_disabled); |
52 | 51 | ||
@@ -1562,7 +1561,7 @@ static int __init parse_acpi(char *arg) | |||
1562 | } | 1561 | } |
1563 | /* acpi=rsdt use RSDT instead of XSDT */ | 1562 | /* acpi=rsdt use RSDT instead of XSDT */ |
1564 | else if (strcmp(arg, "rsdt") == 0) { | 1563 | else if (strcmp(arg, "rsdt") == 0) { |
1565 | acpi_rsdt_forced = 1; | 1564 | acpi_gbl_do_not_use_xsdt = TRUE; |
1566 | } | 1565 | } |
1567 | /* "acpi=noirq" disables ACPI interrupt routing */ | 1566 | /* "acpi=noirq" disables ACPI interrupt routing */ |
1568 | else if (strcmp(arg, "noirq") == 0) { | 1567 | else if (strcmp(arg, "noirq") == 0) { |
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 5d5b9eb2b7a4..2c621a6b901a 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c | |||
@@ -20,9 +20,7 @@ | |||
20 | #include <asm/apic.h> | 20 | #include <asm/apic.h> |
21 | #include <asm/ipi.h> | 21 | #include <asm/ipi.h> |
22 | 22 | ||
23 | #ifdef CONFIG_ACPI | 23 | #include <linux/acpi.h> |
24 | #include <acpi/acpi_bus.h> | ||
25 | #endif | ||
26 | 24 | ||
27 | static struct apic apic_physflat; | 25 | static struct apic apic_physflat; |
28 | static struct apic apic_flat; | 26 | static struct apic apic_flat; |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index a43f068ebec1..6ad4658de705 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -37,9 +37,6 @@ | |||
37 | #include <linux/kthread.h> | 37 | #include <linux/kthread.h> |
38 | #include <linux/jiffies.h> /* time_after() */ | 38 | #include <linux/jiffies.h> /* time_after() */ |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #ifdef CONFIG_ACPI | ||
41 | #include <acpi/acpi_bus.h> | ||
42 | #endif | ||
43 | #include <linux/bootmem.h> | 40 | #include <linux/bootmem.h> |
44 | #include <linux/dmar.h> | 41 | #include <linux/dmar.h> |
45 | #include <linux/hpet.h> | 42 | #include <linux/hpet.h> |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 082e88129712..248642f4bab7 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/acpi.h> | ||
16 | #include <linux/sfi_acpi.h> | 15 | #include <linux/sfi_acpi.h> |
17 | #include <linux/bitmap.h> | 16 | #include <linux/bitmap.h> |
18 | #include <linux/dmi.h> | 17 | #include <linux/dmi.h> |
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index 5c90975cdf0f..43984bc1665a 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/rcupdate.h> | 14 | #include <linux/rcupdate.h> |
15 | #include <asm/e820.h> | 15 | #include <asm/e820.h> |
16 | #include <asm/pci_x86.h> | 16 | #include <asm/pci_x86.h> |
17 | #include <acpi/acpi.h> | ||
18 | 17 | ||
19 | /* Assume systems with more busses have correct MCFG */ | 18 | /* Assume systems with more busses have correct MCFG */ |
20 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | 19 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c index 649a12befba9..08e350e757dc 100644 --- a/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/arch/x86/platform/olpc/olpc-xo15-sci.c | |||
@@ -15,8 +15,7 @@ | |||
15 | #include <linux/power_supply.h> | 15 | #include <linux/power_supply.h> |
16 | #include <linux/olpc-ec.h> | 16 | #include <linux/olpc-ec.h> |
17 | 17 | ||
18 | #include <acpi/acpi_bus.h> | 18 | #include <linux/acpi.h> |
19 | #include <acpi/acpi_drivers.h> | ||
20 | #include <asm/olpc.h> | 19 | #include <asm/olpc.h> |
21 | 20 | ||
22 | #define DRV_NAME "olpc-xo15-sci" | 21 | #define DRV_NAME "olpc-xo15-sci" |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 3c2e4aa529c4..e7515aa43d6b 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -32,8 +32,7 @@ | |||
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/power_supply.h> | 34 | #include <linux/power_supply.h> |
35 | #include <acpi/acpi_bus.h> | 35 | #include <linux/acpi.h> |
36 | #include <acpi/acpi_drivers.h> | ||
37 | 36 | ||
38 | #define PREFIX "ACPI: " | 37 | #define PREFIX "ACPI: " |
39 | 38 | ||
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index 5d33c5415405..c4a5d87ede7e 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/acpi.h> | 11 | #include <linux/acpi.h> |
12 | #include <acpi/acpi_bus.h> | ||
13 | #include <linux/cper.h> | 12 | #include <linux/cper.h> |
14 | #include <linux/ratelimit.h> | 13 | #include <linux/ratelimit.h> |
15 | #include <linux/edac.h> | 14 | #include <linux/edac.h> |
@@ -21,11 +20,9 @@ | |||
21 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ | 20 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ |
22 | 21 | ||
23 | #define EXTLOG_DSM_REV 0x0 | 22 | #define EXTLOG_DSM_REV 0x0 |
24 | #define EXTLOG_FN_QUERY 0x0 | ||
25 | #define EXTLOG_FN_ADDR 0x1 | 23 | #define EXTLOG_FN_ADDR 0x1 |
26 | 24 | ||
27 | #define FLAG_OS_OPTIN BIT(0) | 25 | #define FLAG_OS_OPTIN BIT(0) |
28 | #define EXTLOG_QUERY_L1_EXIST BIT(1) | ||
29 | #define ELOG_ENTRY_VALID (1ULL<<63) | 26 | #define ELOG_ENTRY_VALID (1ULL<<63) |
30 | #define ELOG_ENTRY_LEN 0x1000 | 27 | #define ELOG_ENTRY_LEN 0x1000 |
31 | 28 | ||
@@ -46,7 +43,7 @@ struct extlog_l1_head { | |||
46 | 43 | ||
47 | static int old_edac_report_status; | 44 | static int old_edac_report_status; |
48 | 45 | ||
49 | static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; | 46 | static u8 extlog_dsm_uuid[] __initdata = "663E35AF-CC10-41A4-88EA-5470AF055295"; |
50 | 47 | ||
51 | /* L1 table related physical address */ | 48 | /* L1 table related physical address */ |
52 | static u64 elog_base; | 49 | static u64 elog_base; |
@@ -156,62 +153,27 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, | |||
156 | return NOTIFY_STOP; | 153 | return NOTIFY_STOP; |
157 | } | 154 | } |
158 | 155 | ||
159 | static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret) | 156 | static bool __init extlog_get_l1addr(void) |
160 | { | 157 | { |
161 | struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
162 | struct acpi_object_list input; | ||
163 | union acpi_object params[4], *obj; | ||
164 | u8 uuid[16]; | 158 | u8 uuid[16]; |
165 | int i; | 159 | acpi_handle handle; |
160 | union acpi_object *obj; | ||
166 | 161 | ||
167 | acpi_str_to_uuid(extlog_dsm_uuid, uuid); | 162 | acpi_str_to_uuid(extlog_dsm_uuid, uuid); |
168 | input.count = 4; | ||
169 | input.pointer = params; | ||
170 | params[0].type = ACPI_TYPE_BUFFER; | ||
171 | params[0].buffer.length = 16; | ||
172 | params[0].buffer.pointer = uuid; | ||
173 | params[1].type = ACPI_TYPE_INTEGER; | ||
174 | params[1].integer.value = rev; | ||
175 | params[2].type = ACPI_TYPE_INTEGER; | ||
176 | params[2].integer.value = func; | ||
177 | params[3].type = ACPI_TYPE_PACKAGE; | ||
178 | params[3].package.count = 0; | ||
179 | params[3].package.elements = NULL; | ||
180 | |||
181 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf))) | ||
182 | return -1; | ||
183 | |||
184 | *ret = 0; | ||
185 | obj = (union acpi_object *)buf.pointer; | ||
186 | if (obj->type == ACPI_TYPE_INTEGER) { | ||
187 | *ret = obj->integer.value; | ||
188 | } else if (obj->type == ACPI_TYPE_BUFFER) { | ||
189 | if (obj->buffer.length <= 8) { | ||
190 | for (i = 0; i < obj->buffer.length; i++) | ||
191 | *ret |= (obj->buffer.pointer[i] << (i * 8)); | ||
192 | } | ||
193 | } | ||
194 | kfree(buf.pointer); | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static bool extlog_get_l1addr(void) | ||
200 | { | ||
201 | acpi_handle handle; | ||
202 | u64 ret; | ||
203 | 163 | ||
204 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) | 164 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) |
205 | return false; | 165 | return false; |
206 | 166 | if (!acpi_check_dsm(handle, uuid, EXTLOG_DSM_REV, 1 << EXTLOG_FN_ADDR)) | |
207 | if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_QUERY, &ret) || | ||
208 | !(ret & EXTLOG_QUERY_L1_EXIST)) | ||
209 | return false; | 167 | return false; |
210 | 168 | obj = acpi_evaluate_dsm_typed(handle, uuid, EXTLOG_DSM_REV, | |
211 | if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret)) | 169 | EXTLOG_FN_ADDR, NULL, ACPI_TYPE_INTEGER); |
170 | if (!obj) { | ||
212 | return false; | 171 | return false; |
172 | } else { | ||
173 | l1_dirbase = obj->integer.value; | ||
174 | ACPI_FREE(obj); | ||
175 | } | ||
213 | 176 | ||
214 | l1_dirbase = ret; | ||
215 | /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ | 177 | /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ |
216 | if (l1_dirbase & ((1 << 12) - 1)) { | 178 | if (l1_dirbase & ((1 << 12) - 1)) { |
217 | pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", | 179 | pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 551dad712ffe..b67be85ff0fc 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -180,14 +180,14 @@ static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info) | |||
180 | 180 | ||
181 | static int acpi_bind_memblk(struct memory_block *mem, void *arg) | 181 | static int acpi_bind_memblk(struct memory_block *mem, void *arg) |
182 | { | 182 | { |
183 | return acpi_bind_one(&mem->dev, (acpi_handle)arg); | 183 | return acpi_bind_one(&mem->dev, arg); |
184 | } | 184 | } |
185 | 185 | ||
186 | static int acpi_bind_memory_blocks(struct acpi_memory_info *info, | 186 | static int acpi_bind_memory_blocks(struct acpi_memory_info *info, |
187 | acpi_handle handle) | 187 | struct acpi_device *adev) |
188 | { | 188 | { |
189 | return walk_memory_range(acpi_meminfo_start_pfn(info), | 189 | return walk_memory_range(acpi_meminfo_start_pfn(info), |
190 | acpi_meminfo_end_pfn(info), (void *)handle, | 190 | acpi_meminfo_end_pfn(info), adev, |
191 | acpi_bind_memblk); | 191 | acpi_bind_memblk); |
192 | } | 192 | } |
193 | 193 | ||
@@ -197,8 +197,7 @@ static int acpi_unbind_memblk(struct memory_block *mem, void *arg) | |||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | static void acpi_unbind_memory_blocks(struct acpi_memory_info *info, | 200 | static void acpi_unbind_memory_blocks(struct acpi_memory_info *info) |
201 | acpi_handle handle) | ||
202 | { | 201 | { |
203 | walk_memory_range(acpi_meminfo_start_pfn(info), | 202 | walk_memory_range(acpi_meminfo_start_pfn(info), |
204 | acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk); | 203 | acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk); |
@@ -242,9 +241,9 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
242 | if (result && result != -EEXIST) | 241 | if (result && result != -EEXIST) |
243 | continue; | 242 | continue; |
244 | 243 | ||
245 | result = acpi_bind_memory_blocks(info, handle); | 244 | result = acpi_bind_memory_blocks(info, mem_device->device); |
246 | if (result) { | 245 | if (result) { |
247 | acpi_unbind_memory_blocks(info, handle); | 246 | acpi_unbind_memory_blocks(info); |
248 | return -ENODEV; | 247 | return -ENODEV; |
249 | } | 248 | } |
250 | 249 | ||
@@ -285,7 +284,7 @@ static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device) | |||
285 | if (nid == NUMA_NO_NODE) | 284 | if (nid == NUMA_NO_NODE) |
286 | nid = memory_add_physaddr_to_nid(info->start_addr); | 285 | nid = memory_add_physaddr_to_nid(info->start_addr); |
287 | 286 | ||
288 | acpi_unbind_memory_blocks(info, handle); | 287 | acpi_unbind_memory_blocks(info); |
289 | remove_memory(nid, info->start_addr, info->length); | 288 | remove_memory(nid, info->start_addr, info->length); |
290 | list_del(&info->list); | 289 | list_del(&info->list); |
291 | kfree(info); | 290 | kfree(info); |
@@ -361,7 +360,19 @@ static void acpi_memory_device_remove(struct acpi_device *device) | |||
361 | acpi_memory_device_free(mem_device); | 360 | acpi_memory_device_free(mem_device); |
362 | } | 361 | } |
363 | 362 | ||
363 | static bool __initdata acpi_no_memhotplug; | ||
364 | |||
364 | void __init acpi_memory_hotplug_init(void) | 365 | void __init acpi_memory_hotplug_init(void) |
365 | { | 366 | { |
367 | if (acpi_no_memhotplug) | ||
368 | return; | ||
369 | |||
366 | acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); | 370 | acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); |
367 | } | 371 | } |
372 | |||
373 | static int __init disable_acpi_memory_hotplug(char *str) | ||
374 | { | ||
375 | acpi_no_memhotplug = true; | ||
376 | return 1; | ||
377 | } | ||
378 | __setup("acpi_no_memhotplug", disable_acpi_memory_hotplug); | ||
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 509452a62f96..df96a0fe4890 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -28,8 +28,7 @@ | |||
28 | #include <linux/cpu.h> | 28 | #include <linux/cpu.h> |
29 | #include <linux/clockchips.h> | 29 | #include <linux/clockchips.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <acpi/acpi_bus.h> | 31 | #include <linux/acpi.h> |
32 | #include <acpi/acpi_drivers.h> | ||
33 | #include <asm/mwait.h> | 32 | #include <asm/mwait.h> |
34 | 33 | ||
35 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" | 34 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" |
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 3c1d6b0c09a4..c9311be29a64 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -212,7 +212,7 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
212 | union acpi_object object = { 0 }; | 212 | union acpi_object object = { 0 }; |
213 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | 213 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; |
214 | struct acpi_processor *pr = acpi_driver_data(device); | 214 | struct acpi_processor *pr = acpi_driver_data(device); |
215 | int cpu_index, device_declaration = 0; | 215 | int apic_id, cpu_index, device_declaration = 0; |
216 | acpi_status status = AE_OK; | 216 | acpi_status status = AE_OK; |
217 | static int cpu0_initialized; | 217 | static int cpu0_initialized; |
218 | unsigned long long value; | 218 | unsigned long long value; |
@@ -258,18 +258,21 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
258 | device_declaration = 1; | 258 | device_declaration = 1; |
259 | pr->acpi_id = value; | 259 | pr->acpi_id = value; |
260 | } | 260 | } |
261 | pr->apic_id = acpi_get_apicid(pr->handle, device_declaration, | ||
262 | pr->acpi_id); | ||
263 | cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); | ||
264 | 261 | ||
265 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | 262 | apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); |
266 | if (!cpu0_initialized && (cpu_index == -1) && | 263 | if (apic_id < 0) { |
267 | (num_online_cpus() == 1)) { | 264 | acpi_handle_err(pr->handle, "failed to get CPU APIC ID.\n"); |
268 | cpu_index = 0; | 265 | return -ENODEV; |
269 | } | 266 | } |
267 | pr->apic_id = apic_id; | ||
270 | 268 | ||
271 | cpu0_initialized = 1; | 269 | cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); |
272 | 270 | if (!cpu0_initialized) { | |
271 | cpu0_initialized = 1; | ||
272 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | ||
273 | if ((cpu_index == -1) && (num_online_cpus() == 1)) | ||
274 | cpu_index = 0; | ||
275 | } | ||
273 | pr->id = cpu_index; | 276 | pr->id = cpu_index; |
274 | 277 | ||
275 | /* | 278 | /* |
@@ -282,6 +285,7 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
282 | if (ret) | 285 | if (ret) |
283 | return ret; | 286 | return ret; |
284 | } | 287 | } |
288 | |||
285 | /* | 289 | /* |
286 | * On some boxes several processors use the same processor bus id. | 290 | * On some boxes several processors use the same processor bus id. |
287 | * But they are located in different scope. For example: | 291 | * But they are located in different scope. For example: |
@@ -395,7 +399,7 @@ static int acpi_processor_add(struct acpi_device *device, | |||
395 | goto err; | 399 | goto err; |
396 | } | 400 | } |
397 | 401 | ||
398 | result = acpi_bind_one(dev, pr->handle); | 402 | result = acpi_bind_one(dev, device); |
399 | if (result) | 403 | if (result) |
400 | goto err; | 404 | goto err; |
401 | 405 | ||
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index a9fd0b872062..2bf3ca2b8a7a 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -113,7 +113,6 @@ void acpi_db_display_handlers(void); | |||
113 | ACPI_HW_DEPENDENT_RETURN_VOID(void | 113 | ACPI_HW_DEPENDENT_RETURN_VOID(void |
114 | acpi_db_generate_gpe(char *gpe_arg, | 114 | acpi_db_generate_gpe(char *gpe_arg, |
115 | char *block_arg)) | 115 | char *block_arg)) |
116 | |||
117 | ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_generate_sci(void)) | 116 | ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_generate_sci(void)) |
118 | 117 | ||
119 | /* | 118 | /* |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 41abe552c7a3..0fb0adf435d6 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -71,9 +71,8 @@ acpi_status acpi_ev_init_global_lock_handler(void); | |||
71 | 71 | ||
72 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status | 72 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status |
73 | acpi_ev_acquire_global_lock(u16 timeout)) | 73 | acpi_ev_acquire_global_lock(u16 timeout)) |
74 | |||
75 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_ev_release_global_lock(void)) | 74 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_ev_release_global_lock(void)) |
76 | acpi_status acpi_ev_remove_global_lock_handler(void); | 75 | 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 |
@@ -133,7 +132,7 @@ acpi_status acpi_ev_gpe_initialize(void); | |||
133 | ACPI_HW_DEPENDENT_RETURN_VOID(void | 132 | ACPI_HW_DEPENDENT_RETURN_VOID(void |
134 | acpi_ev_update_gpes(acpi_owner_id table_owner_id)) | 133 | acpi_ev_update_gpes(acpi_owner_id table_owner_id)) |
135 | 134 | ||
136 | acpi_status | 135 | acpi_status |
137 | acpi_ev_match_gpe_method(acpi_handle obj_handle, | 136 | acpi_ev_match_gpe_method(acpi_handle obj_handle, |
138 | u32 level, void *context, void **return_value); | 137 | u32 level, void *context, void **return_value); |
139 | 138 | ||
@@ -149,7 +148,9 @@ acpi_status | |||
149 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 148 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
150 | struct acpi_gpe_block_info *gpe_block, void *context); | 149 | struct acpi_gpe_block_info *gpe_block, void *context); |
151 | 150 | ||
152 | struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number); | 151 | acpi_status |
152 | acpi_ev_get_gpe_xrupt_block(u32 interrupt_number, | ||
153 | struct acpi_gpe_xrupt_info **gpe_xrupt_block); | ||
153 | 154 | ||
154 | acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt); | 155 | acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt); |
155 | 156 | ||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index e9f1fc7f99c7..24db8e153bf0 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -119,6 +119,24 @@ bool ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); | |||
119 | u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); | 119 | u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Optionally ignore an XSDT if present and use the RSDT instead. | ||
123 | * Although the ACPI specification requires that an XSDT be used instead | ||
124 | * of the RSDT, the XSDT has been found to be corrupt or ill-formed on | ||
125 | * some machines. Default behavior is to use the XSDT if present. | ||
126 | */ | ||
127 | u8 ACPI_INIT_GLOBAL(acpi_gbl_do_not_use_xsdt, FALSE); | ||
128 | |||
129 | /* | ||
130 | * Optionally use 32-bit FADT addresses if and when there is a conflict | ||
131 | * (address mismatch) between the 32-bit and 64-bit versions of the | ||
132 | * address. Although ACPICA adheres to the ACPI specification which | ||
133 | * requires the use of the corresponding 64-bit address if it is non-zero, | ||
134 | * some machines have been found to have a corrupted non-zero 64-bit | ||
135 | * address. Default is FALSE, do not favor the 32-bit addresses. | ||
136 | */ | ||
137 | u8 ACPI_INIT_GLOBAL(acpi_gbl_use32_bit_fadt_addresses, FALSE); | ||
138 | |||
139 | /* | ||
122 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility | 140 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility |
123 | * with other ACPI implementations. NOTE: During ACPICA initialization, | 141 | * with other ACPI implementations. NOTE: During ACPICA initialization, |
124 | * this value is set to TRUE if any Windows OSI strings have been | 142 | * this value is set to TRUE if any Windows OSI strings have been |
@@ -484,6 +502,18 @@ ACPI_EXTERN u32 acpi_gbl_size_of_acpi_objects; | |||
484 | 502 | ||
485 | /***************************************************************************** | 503 | /***************************************************************************** |
486 | * | 504 | * |
505 | * Application globals | ||
506 | * | ||
507 | ****************************************************************************/ | ||
508 | |||
509 | #ifdef ACPI_APPLICATION | ||
510 | |||
511 | ACPI_FILE ACPI_INIT_GLOBAL(acpi_gbl_debug_file, NULL); | ||
512 | |||
513 | #endif /* ACPI_APPLICATION */ | ||
514 | |||
515 | /***************************************************************************** | ||
516 | * | ||
487 | * Info/help support | 517 | * Info/help support |
488 | * | 518 | * |
489 | ****************************************************************************/ | 519 | ****************************************************************************/ |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 53ed1a8ba4f0..d95ca5449ace 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -1038,15 +1038,16 @@ struct acpi_external_list { | |||
1038 | struct acpi_external_list *next; | 1038 | struct acpi_external_list *next; |
1039 | u32 value; | 1039 | u32 value; |
1040 | u16 length; | 1040 | u16 length; |
1041 | u16 flags; | ||
1041 | u8 type; | 1042 | u8 type; |
1042 | u8 flags; | ||
1043 | u8 resolved; | ||
1044 | u8 emitted; | ||
1045 | }; | 1043 | }; |
1046 | 1044 | ||
1047 | /* Values for Flags field above */ | 1045 | /* Values for Flags field above */ |
1048 | 1046 | ||
1049 | #define ACPI_IPATH_ALLOCATED 0x01 | 1047 | #define ACPI_EXT_RESOLVED_REFERENCE 0x01 /* Object was resolved during cross ref */ |
1048 | #define ACPI_EXT_ORIGIN_FROM_FILE 0x02 /* External came from a file */ | ||
1049 | #define ACPI_EXT_INTERNAL_PATH_ALLOCATED 0x04 /* Deallocate internal path on completion */ | ||
1050 | #define ACPI_EXT_EXTERNAL_EMITTED 0x08 /* External() statement has been emitted */ | ||
1050 | 1051 | ||
1051 | struct acpi_external_file { | 1052 | struct acpi_external_file { |
1052 | char *path; | 1053 | char *path; |
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 2d4c07322576..e7a57c554e84 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c | |||
@@ -105,7 +105,7 @@ acpi_ds_create_external_region(acpi_status lookup_status, | |||
105 | * operation_region not found. Generate an External for it, and | 105 | * operation_region not found. Generate an External for it, and |
106 | * insert the name into the namespace. | 106 | * insert the name into the namespace. |
107 | */ | 107 | */ |
108 | acpi_dm_add_to_external_list(op, path, ACPI_TYPE_REGION, 0); | 108 | acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0); |
109 | status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION, | 109 | status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION, |
110 | ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, | 110 | ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, |
111 | walk_state, node); | 111 | walk_state, node); |
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index ade44e49deb4..d7f53fb2979a 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c | |||
@@ -727,27 +727,26 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
727 | index++; | 727 | index++; |
728 | } | 728 | } |
729 | 729 | ||
730 | index--; | 730 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
731 | "NumOperands %d, ArgCount %d, Index %d\n", | ||
732 | walk_state->num_operands, arg_count, index)); | ||
731 | 733 | ||
732 | /* It is the appropriate order to get objects from the Result stack */ | 734 | /* Create the interpreter arguments, in reverse order */ |
733 | 735 | ||
736 | index--; | ||
734 | for (i = 0; i < arg_count; i++) { | 737 | for (i = 0; i < arg_count; i++) { |
735 | arg = arguments[index]; | 738 | arg = arguments[index]; |
736 | 739 | walk_state->operand_index = (u8)index; | |
737 | /* Force the filling of the operand stack in inverse order */ | ||
738 | |||
739 | walk_state->operand_index = (u8) index; | ||
740 | 740 | ||
741 | status = acpi_ds_create_operand(walk_state, arg, index); | 741 | status = acpi_ds_create_operand(walk_state, arg, index); |
742 | if (ACPI_FAILURE(status)) { | 742 | if (ACPI_FAILURE(status)) { |
743 | goto cleanup; | 743 | goto cleanup; |
744 | } | 744 | } |
745 | 745 | ||
746 | index--; | ||
747 | |||
748 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 746 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
749 | "Arg #%u (%p) done, Arg1=%p\n", index, arg, | 747 | "Created Arg #%u (%p) %u args total\n", |
750 | first_arg)); | 748 | index, arg, arg_count)); |
749 | index--; | ||
751 | } | 750 | } |
752 | 751 | ||
753 | return_ACPI_STATUS(status); | 752 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 95e681a36f9c..2dbe109727c8 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c | |||
@@ -181,8 +181,8 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
181 | * Target of Scope() not found. Generate an External for it, and | 181 | * Target of Scope() not found. Generate an External for it, and |
182 | * insert the name into the namespace. | 182 | * insert the name into the namespace. |
183 | */ | 183 | */ |
184 | acpi_dm_add_to_external_list(op, path, ACPI_TYPE_DEVICE, | 184 | acpi_dm_add_op_to_external_list(op, path, |
185 | 0); | 185 | ACPI_TYPE_DEVICE, 0, 0); |
186 | status = | 186 | status = |
187 | acpi_ns_lookup(walk_state->scope_info, path, | 187 | acpi_ns_lookup(walk_state->scope_info, path, |
188 | object_type, ACPI_IMODE_LOAD_PASS1, | 188 | object_type, ACPI_IMODE_LOAD_PASS1, |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index a9e76bc4ad97..a31e549e64cc 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -87,9 +87,9 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, | |||
87 | return_ACPI_STATUS(status); | 87 | return_ACPI_STATUS(status); |
88 | } | 88 | } |
89 | 89 | ||
90 | gpe_xrupt_block = acpi_ev_get_gpe_xrupt_block(interrupt_number); | 90 | status = |
91 | if (!gpe_xrupt_block) { | 91 | acpi_ev_get_gpe_xrupt_block(interrupt_number, &gpe_xrupt_block); |
92 | status = AE_NO_MEMORY; | 92 | if (ACPI_FAILURE(status)) { |
93 | goto unlock_and_exit; | 93 | goto unlock_and_exit; |
94 | } | 94 | } |
95 | 95 | ||
@@ -112,7 +112,7 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, | |||
112 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 112 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
113 | 113 | ||
114 | unlock_and_exit: | 114 | unlock_and_exit: |
115 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 115 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
116 | return_ACPI_STATUS(status); | 116 | return_ACPI_STATUS(status); |
117 | } | 117 | } |
118 | 118 | ||
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index d3f5e1e2a2b1..4d764e847a08 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c | |||
@@ -197,8 +197,9 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
197 | * FUNCTION: acpi_ev_get_gpe_xrupt_block | 197 | * FUNCTION: acpi_ev_get_gpe_xrupt_block |
198 | * | 198 | * |
199 | * PARAMETERS: interrupt_number - Interrupt for a GPE block | 199 | * PARAMETERS: interrupt_number - Interrupt for a GPE block |
200 | * gpe_xrupt_block - Where the block is returned | ||
200 | * | 201 | * |
201 | * RETURN: A GPE interrupt block | 202 | * RETURN: Status |
202 | * | 203 | * |
203 | * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt | 204 | * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt |
204 | * block per unique interrupt level used for GPEs. Should be | 205 | * block per unique interrupt level used for GPEs. Should be |
@@ -207,7 +208,9 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
207 | * | 208 | * |
208 | ******************************************************************************/ | 209 | ******************************************************************************/ |
209 | 210 | ||
210 | struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number) | 211 | acpi_status |
212 | acpi_ev_get_gpe_xrupt_block(u32 interrupt_number, | ||
213 | struct acpi_gpe_xrupt_info ** gpe_xrupt_block) | ||
211 | { | 214 | { |
212 | struct acpi_gpe_xrupt_info *next_gpe_xrupt; | 215 | struct acpi_gpe_xrupt_info *next_gpe_xrupt; |
213 | struct acpi_gpe_xrupt_info *gpe_xrupt; | 216 | struct acpi_gpe_xrupt_info *gpe_xrupt; |
@@ -221,7 +224,8 @@ struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number) | |||
221 | next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head; | 224 | next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head; |
222 | while (next_gpe_xrupt) { | 225 | while (next_gpe_xrupt) { |
223 | if (next_gpe_xrupt->interrupt_number == interrupt_number) { | 226 | if (next_gpe_xrupt->interrupt_number == interrupt_number) { |
224 | return_PTR(next_gpe_xrupt); | 227 | *gpe_xrupt_block = next_gpe_xrupt; |
228 | return_ACPI_STATUS(AE_OK); | ||
225 | } | 229 | } |
226 | 230 | ||
227 | next_gpe_xrupt = next_gpe_xrupt->next; | 231 | next_gpe_xrupt = next_gpe_xrupt->next; |
@@ -231,7 +235,7 @@ struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number) | |||
231 | 235 | ||
232 | gpe_xrupt = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_xrupt_info)); | 236 | gpe_xrupt = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_xrupt_info)); |
233 | if (!gpe_xrupt) { | 237 | if (!gpe_xrupt) { |
234 | return_PTR(NULL); | 238 | return_ACPI_STATUS(AE_NO_MEMORY); |
235 | } | 239 | } |
236 | 240 | ||
237 | gpe_xrupt->interrupt_number = interrupt_number; | 241 | gpe_xrupt->interrupt_number = interrupt_number; |
@@ -250,6 +254,7 @@ struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number) | |||
250 | } else { | 254 | } else { |
251 | acpi_gbl_gpe_xrupt_list_head = gpe_xrupt; | 255 | acpi_gbl_gpe_xrupt_list_head = gpe_xrupt; |
252 | } | 256 | } |
257 | |||
253 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 258 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
254 | 259 | ||
255 | /* Install new interrupt handler if not SCI_INT */ | 260 | /* Install new interrupt handler if not SCI_INT */ |
@@ -259,14 +264,15 @@ struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number) | |||
259 | acpi_ev_gpe_xrupt_handler, | 264 | acpi_ev_gpe_xrupt_handler, |
260 | gpe_xrupt); | 265 | gpe_xrupt); |
261 | if (ACPI_FAILURE(status)) { | 266 | if (ACPI_FAILURE(status)) { |
262 | ACPI_ERROR((AE_INFO, | 267 | ACPI_EXCEPTION((AE_INFO, status, |
263 | "Could not install GPE interrupt handler at level 0x%X", | 268 | "Could not install GPE interrupt handler at level 0x%X", |
264 | interrupt_number)); | 269 | interrupt_number)); |
265 | return_PTR(NULL); | 270 | return_ACPI_STATUS(status); |
266 | } | 271 | } |
267 | } | 272 | } |
268 | 273 | ||
269 | return_PTR(gpe_xrupt); | 274 | *gpe_xrupt_block = gpe_xrupt; |
275 | return_ACPI_STATUS(AE_OK); | ||
270 | } | 276 | } |
271 | 277 | ||
272 | /******************************************************************************* | 278 | /******************************************************************************* |
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index acd34f599313..7ca6925a87ca 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c | |||
@@ -124,7 +124,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
124 | } | 124 | } |
125 | 125 | ||
126 | if (!source_desc) { | 126 | if (!source_desc) { |
127 | ACPI_ERROR((AE_INFO, "No object attached to node %p", node)); | 127 | ACPI_ERROR((AE_INFO, "No object attached to node [%4.4s] %p", |
128 | node->name.ascii, node)); | ||
128 | return_ACPI_STATUS(AE_AML_NO_OPERAND); | 129 | return_ACPI_STATUS(AE_AML_NO_OPERAND); |
129 | } | 130 | } |
130 | 131 | ||
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index e973e311f856..1f0c28ba50df 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -84,7 +84,7 @@ acpi_evaluate_object_typed(acpi_handle handle, | |||
84 | acpi_object_type return_type) | 84 | acpi_object_type return_type) |
85 | { | 85 | { |
86 | acpi_status status; | 86 | acpi_status status; |
87 | u8 must_free = FALSE; | 87 | u8 free_buffer_on_error = FALSE; |
88 | 88 | ||
89 | ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed); | 89 | ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed); |
90 | 90 | ||
@@ -95,14 +95,13 @@ acpi_evaluate_object_typed(acpi_handle handle, | |||
95 | } | 95 | } |
96 | 96 | ||
97 | if (return_buffer->length == ACPI_ALLOCATE_BUFFER) { | 97 | if (return_buffer->length == ACPI_ALLOCATE_BUFFER) { |
98 | must_free = TRUE; | 98 | free_buffer_on_error = TRUE; |
99 | } | 99 | } |
100 | 100 | ||
101 | /* Evaluate the object */ | 101 | /* Evaluate the object */ |
102 | 102 | ||
103 | status = | 103 | status = acpi_evaluate_object(handle, pathname, |
104 | acpi_evaluate_object(handle, pathname, external_params, | 104 | external_params, return_buffer); |
105 | return_buffer); | ||
106 | if (ACPI_FAILURE(status)) { | 105 | if (ACPI_FAILURE(status)) { |
107 | return_ACPI_STATUS(status); | 106 | return_ACPI_STATUS(status); |
108 | } | 107 | } |
@@ -135,11 +134,15 @@ acpi_evaluate_object_typed(acpi_handle handle, | |||
135 | pointer)->type), | 134 | pointer)->type), |
136 | acpi_ut_get_type_name(return_type))); | 135 | acpi_ut_get_type_name(return_type))); |
137 | 136 | ||
138 | if (must_free) { | 137 | if (free_buffer_on_error) { |
139 | 138 | /* | |
140 | /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ | 139 | * Free a buffer created via ACPI_ALLOCATE_BUFFER. |
141 | 140 | * Note: We use acpi_os_free here because acpi_os_allocate was used | |
142 | ACPI_FREE_BUFFER(*return_buffer); | 141 | * to allocate the buffer. This purposefully bypasses the |
142 | * (optionally enabled) allocation tracking mechanism since we | ||
143 | * only want to track internal allocations. | ||
144 | */ | ||
145 | acpi_os_free(return_buffer->pointer); | ||
143 | return_buffer->pointer = NULL; | 146 | return_buffer->pointer = NULL; |
144 | } | 147 | } |
145 | 148 | ||
diff --git a/drivers/acpi/acpica/psopinfo.c b/drivers/acpi/acpica/psopinfo.c index 9ba5301e5751..b0c9787dbe61 100644 --- a/drivers/acpi/acpica/psopinfo.c +++ b/drivers/acpi/acpica/psopinfo.c | |||
@@ -71,6 +71,10 @@ static const u8 acpi_gbl_argument_count[] = | |||
71 | 71 | ||
72 | const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode) | 72 | const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode) |
73 | { | 73 | { |
74 | #ifdef ACPI_DEBUG_OUTPUT | ||
75 | const char *opcode_name = "Unknown AML opcode"; | ||
76 | #endif | ||
77 | |||
74 | ACPI_FUNCTION_NAME(ps_get_opcode_info); | 78 | ACPI_FUNCTION_NAME(ps_get_opcode_info); |
75 | 79 | ||
76 | /* | 80 | /* |
@@ -92,11 +96,54 @@ const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode) | |||
92 | return (&acpi_gbl_aml_op_info | 96 | return (&acpi_gbl_aml_op_info |
93 | [acpi_gbl_long_op_index[(u8)opcode]]); | 97 | [acpi_gbl_long_op_index[(u8)opcode]]); |
94 | } | 98 | } |
99 | #if defined ACPI_ASL_COMPILER && defined ACPI_DEBUG_OUTPUT | ||
100 | #include "asldefine.h" | ||
101 | |||
102 | switch (opcode) { | ||
103 | case AML_RAW_DATA_BYTE: | ||
104 | opcode_name = "-Raw Data Byte-"; | ||
105 | break; | ||
106 | |||
107 | case AML_RAW_DATA_WORD: | ||
108 | opcode_name = "-Raw Data Word-"; | ||
109 | break; | ||
110 | |||
111 | case AML_RAW_DATA_DWORD: | ||
112 | opcode_name = "-Raw Data Dword-"; | ||
113 | break; | ||
114 | |||
115 | case AML_RAW_DATA_QWORD: | ||
116 | opcode_name = "-Raw Data Qword-"; | ||
117 | break; | ||
118 | |||
119 | case AML_RAW_DATA_BUFFER: | ||
120 | opcode_name = "-Raw Data Buffer-"; | ||
121 | break; | ||
122 | |||
123 | case AML_RAW_DATA_CHAIN: | ||
124 | opcode_name = "-Raw Data Buffer Chain-"; | ||
125 | break; | ||
126 | |||
127 | case AML_PACKAGE_LENGTH: | ||
128 | opcode_name = "-Package Length-"; | ||
129 | break; | ||
130 | |||
131 | case AML_UNASSIGNED_OPCODE: | ||
132 | opcode_name = "-Unassigned Opcode-"; | ||
133 | break; | ||
134 | |||
135 | case AML_DEFAULT_ARG_OP: | ||
136 | opcode_name = "-Default Arg-"; | ||
137 | break; | ||
138 | |||
139 | default: | ||
140 | break; | ||
141 | } | ||
142 | #endif | ||
95 | 143 | ||
96 | /* Unknown AML opcode */ | 144 | /* Unknown AML opcode */ |
97 | 145 | ||
98 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 146 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%4.4X]\n", opcode_name, opcode)); |
99 | "Unknown AML opcode [%4.4X]\n", opcode)); | ||
100 | 147 | ||
101 | return (&acpi_gbl_aml_op_info[_UNK]); | 148 | return (&acpi_gbl_aml_op_info[_UNK]); |
102 | } | 149 | } |
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 9d99f2189693..8f89263ac47e 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -56,10 +56,11 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | |||
56 | 56 | ||
57 | static void acpi_tb_convert_fadt(void); | 57 | static void acpi_tb_convert_fadt(void); |
58 | 58 | ||
59 | static void acpi_tb_validate_fadt(void); | ||
60 | |||
61 | static void acpi_tb_setup_fadt_registers(void); | 59 | static void acpi_tb_setup_fadt_registers(void); |
62 | 60 | ||
61 | static u64 | ||
62 | acpi_tb_select_address(char *register_name, u32 address32, u64 address64); | ||
63 | |||
63 | /* Table for conversion of FADT to common internal format and FADT validation */ | 64 | /* Table for conversion of FADT to common internal format and FADT validation */ |
64 | 65 | ||
65 | typedef struct acpi_fadt_info { | 66 | typedef struct acpi_fadt_info { |
@@ -175,6 +176,7 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = { | |||
175 | * space_id - ACPI Space ID for this register | 176 | * space_id - ACPI Space ID for this register |
176 | * byte_width - Width of this register | 177 | * byte_width - Width of this register |
177 | * address - Address of the register | 178 | * address - Address of the register |
179 | * register_name - ASCII name of the ACPI register | ||
178 | * | 180 | * |
179 | * RETURN: None | 181 | * RETURN: None |
180 | * | 182 | * |
@@ -220,6 +222,68 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | |||
220 | 222 | ||
221 | /******************************************************************************* | 223 | /******************************************************************************* |
222 | * | 224 | * |
225 | * FUNCTION: acpi_tb_select_address | ||
226 | * | ||
227 | * PARAMETERS: register_name - ASCII name of the ACPI register | ||
228 | * address32 - 32-bit address of the register | ||
229 | * address64 - 64-bit address of the register | ||
230 | * | ||
231 | * RETURN: The resolved 64-bit address | ||
232 | * | ||
233 | * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within | ||
234 | * the FADT. Used for the FACS and DSDT addresses. | ||
235 | * | ||
236 | * NOTES: | ||
237 | * | ||
238 | * Check for FACS and DSDT address mismatches. An address mismatch between | ||
239 | * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and | ||
240 | * DSDT/X_DSDT) could be a corrupted address field or it might indicate | ||
241 | * the presence of two FACS or two DSDT tables. | ||
242 | * | ||
243 | * November 2013: | ||
244 | * By default, as per the ACPICA specification, a valid 64-bit address is | ||
245 | * used regardless of the value of the 32-bit address. However, this | ||
246 | * behavior can be overridden via the acpi_gbl_use32_bit_fadt_addresses flag. | ||
247 | * | ||
248 | ******************************************************************************/ | ||
249 | |||
250 | static u64 | ||
251 | acpi_tb_select_address(char *register_name, u32 address32, u64 address64) | ||
252 | { | ||
253 | |||
254 | if (!address64) { | ||
255 | |||
256 | /* 64-bit address is zero, use 32-bit address */ | ||
257 | |||
258 | return ((u64)address32); | ||
259 | } | ||
260 | |||
261 | if (address32 && (address64 != (u64)address32)) { | ||
262 | |||
263 | /* Address mismatch between 32-bit and 64-bit versions */ | ||
264 | |||
265 | ACPI_BIOS_WARNING((AE_INFO, | ||
266 | "32/64X %s address mismatch in FADT: " | ||
267 | "0x%8.8X/0x%8.8X%8.8X, using %u-bit address", | ||
268 | register_name, address32, | ||
269 | ACPI_FORMAT_UINT64(address64), | ||
270 | acpi_gbl_use32_bit_fadt_addresses ? 32 : | ||
271 | 64)); | ||
272 | |||
273 | /* 32-bit address override */ | ||
274 | |||
275 | if (acpi_gbl_use32_bit_fadt_addresses) { | ||
276 | return ((u64)address32); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | /* Default is to use the 64-bit address */ | ||
281 | |||
282 | return (address64); | ||
283 | } | ||
284 | |||
285 | /******************************************************************************* | ||
286 | * | ||
223 | * FUNCTION: acpi_tb_parse_fadt | 287 | * FUNCTION: acpi_tb_parse_fadt |
224 | * | 288 | * |
225 | * PARAMETERS: table_index - Index for the FADT | 289 | * PARAMETERS: table_index - Index for the FADT |
@@ -331,10 +395,6 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
331 | 395 | ||
332 | acpi_tb_convert_fadt(); | 396 | acpi_tb_convert_fadt(); |
333 | 397 | ||
334 | /* Validate FADT values now, before we make any changes */ | ||
335 | |||
336 | acpi_tb_validate_fadt(); | ||
337 | |||
338 | /* Initialize the global ACPI register structures */ | 398 | /* Initialize the global ACPI register structures */ |
339 | 399 | ||
340 | acpi_tb_setup_fadt_registers(); | 400 | acpi_tb_setup_fadt_registers(); |
@@ -344,66 +404,55 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
344 | * | 404 | * |
345 | * FUNCTION: acpi_tb_convert_fadt | 405 | * FUNCTION: acpi_tb_convert_fadt |
346 | * | 406 | * |
347 | * PARAMETERS: None, uses acpi_gbl_FADT | 407 | * PARAMETERS: none - acpi_gbl_FADT is used. |
348 | * | 408 | * |
349 | * RETURN: None | 409 | * RETURN: None |
350 | * | 410 | * |
351 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. | 411 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. |
352 | * Expand 32-bit addresses to 64-bit as necessary. | 412 | * Expand 32-bit addresses to 64-bit as necessary. Also validate |
413 | * important fields within the FADT. | ||
353 | * | 414 | * |
354 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), | 415 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), and must |
355 | * and must contain a copy of the actual FADT. | 416 | * contain a copy of the actual BIOS-provided FADT. |
356 | * | 417 | * |
357 | * Notes on 64-bit register addresses: | 418 | * Notes on 64-bit register addresses: |
358 | * | 419 | * |
359 | * After this FADT conversion, later ACPICA code will only use the 64-bit "X" | 420 | * After this FADT conversion, later ACPICA code will only use the 64-bit "X" |
360 | * fields of the FADT for all ACPI register addresses. | 421 | * fields of the FADT for all ACPI register addresses. |
361 | * | 422 | * |
362 | * The 64-bit "X" fields are optional extensions to the original 32-bit FADT | 423 | * The 64-bit X fields are optional extensions to the original 32-bit FADT |
363 | * V1.0 fields. Even if they are present in the FADT, they are optional and | 424 | * V1.0 fields. Even if they are present in the FADT, they are optional and |
364 | * are unused if the BIOS sets them to zero. Therefore, we must copy/expand | 425 | * are unused if the BIOS sets them to zero. Therefore, we must copy/expand |
365 | * 32-bit V1.0 fields if the corresponding X field is zero. | 426 | * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is |
427 | * originally zero. | ||
366 | * | 428 | * |
367 | * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the | 429 | * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address |
368 | * corresponding "X" fields in the internal FADT. | 430 | * fields are expanded to the corresponding 64-bit X fields in the internal |
431 | * common FADT. | ||
369 | * | 432 | * |
370 | * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded | 433 | * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded |
371 | * to the corresponding 64-bit X fields. For compatibility with other ACPI | 434 | * to the corresponding 64-bit X fields, if the 64-bit field is originally |
372 | * implementations, we ignore the 64-bit field if the 32-bit field is valid, | 435 | * zero. Adhering to the ACPI specification, we completely ignore the 32-bit |
373 | * regardless of whether the host OS is 32-bit or 64-bit. | 436 | * field if the 64-bit field is valid, regardless of whether the host OS is |
437 | * 32-bit or 64-bit. | ||
438 | * | ||
439 | * Possible additional checks: | ||
440 | * (acpi_gbl_FADT.pm1_event_length >= 4) | ||
441 | * (acpi_gbl_FADT.pm1_control_length >= 2) | ||
442 | * (acpi_gbl_FADT.pm_timer_length >= 4) | ||
443 | * Gpe block lengths must be multiple of 2 | ||
374 | * | 444 | * |
375 | ******************************************************************************/ | 445 | ******************************************************************************/ |
376 | 446 | ||
377 | static void acpi_tb_convert_fadt(void) | 447 | static void acpi_tb_convert_fadt(void) |
378 | { | 448 | { |
449 | char *name; | ||
379 | struct acpi_generic_address *address64; | 450 | struct acpi_generic_address *address64; |
380 | u32 address32; | 451 | u32 address32; |
452 | u8 length; | ||
381 | u32 i; | 453 | u32 i; |
382 | 454 | ||
383 | /* | 455 | /* |
384 | * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. | ||
385 | * Later code will always use the X 64-bit field. Also, check for an | ||
386 | * address mismatch between the 32-bit and 64-bit address fields | ||
387 | * (FIRMWARE_CTRL/X_FIRMWARE_CTRL, DSDT/X_DSDT) which would indicate | ||
388 | * the presence of two FACS or two DSDT tables. | ||
389 | */ | ||
390 | if (!acpi_gbl_FADT.Xfacs) { | ||
391 | acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; | ||
392 | } else if (acpi_gbl_FADT.facs && | ||
393 | (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) { | ||
394 | ACPI_WARNING((AE_INFO, | ||
395 | "32/64 FACS address mismatch in FADT - two FACS tables!")); | ||
396 | } | ||
397 | |||
398 | if (!acpi_gbl_FADT.Xdsdt) { | ||
399 | acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; | ||
400 | } else if (acpi_gbl_FADT.dsdt && | ||
401 | (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) { | ||
402 | ACPI_WARNING((AE_INFO, | ||
403 | "32/64 DSDT address mismatch in FADT - two DSDT tables!")); | ||
404 | } | ||
405 | |||
406 | /* | ||
407 | * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which | 456 | * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which |
408 | * should be zero are indeed zero. This will workaround BIOSs that | 457 | * should be zero are indeed zero. This will workaround BIOSs that |
409 | * inadvertently place values in these fields. | 458 | * inadvertently place values in these fields. |
@@ -421,119 +470,24 @@ static void acpi_tb_convert_fadt(void) | |||
421 | acpi_gbl_FADT.boot_flags = 0; | 470 | acpi_gbl_FADT.boot_flags = 0; |
422 | } | 471 | } |
423 | 472 | ||
424 | /* Update the local FADT table header length */ | ||
425 | |||
426 | acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); | ||
427 | |||
428 | /* | 473 | /* |
429 | * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" | 474 | * Now we can update the local FADT length to the length of the |
430 | * generic address structures as necessary. Later code will always use | 475 | * current FADT version as defined by the ACPI specification. |
431 | * the 64-bit address structures. | 476 | * Thus, we will have a common FADT internally. |
432 | * | ||
433 | * March 2009: | ||
434 | * We now always use the 32-bit address if it is valid (non-null). This | ||
435 | * is not in accordance with the ACPI specification which states that | ||
436 | * the 64-bit address supersedes the 32-bit version, but we do this for | ||
437 | * compatibility with other ACPI implementations. Most notably, in the | ||
438 | * case where both the 32 and 64 versions are non-null, we use the 32-bit | ||
439 | * version. This is the only address that is guaranteed to have been | ||
440 | * tested by the BIOS manufacturer. | ||
441 | */ | 477 | */ |
442 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | 478 | acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); |
443 | address32 = *ACPI_ADD_PTR(u32, | ||
444 | &acpi_gbl_FADT, | ||
445 | fadt_info_table[i].address32); | ||
446 | |||
447 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, | ||
448 | &acpi_gbl_FADT, | ||
449 | fadt_info_table[i].address64); | ||
450 | |||
451 | /* | ||
452 | * If both 32- and 64-bit addresses are valid (non-zero), | ||
453 | * they must match. | ||
454 | */ | ||
455 | if (address64->address && address32 && | ||
456 | (address64->address != (u64)address32)) { | ||
457 | ACPI_BIOS_ERROR((AE_INFO, | ||
458 | "32/64X address mismatch in FADT/%s: " | ||
459 | "0x%8.8X/0x%8.8X%8.8X, using 32", | ||
460 | fadt_info_table[i].name, address32, | ||
461 | ACPI_FORMAT_UINT64(address64-> | ||
462 | address))); | ||
463 | } | ||
464 | |||
465 | /* Always use 32-bit address if it is valid (non-null) */ | ||
466 | |||
467 | if (address32) { | ||
468 | /* | ||
469 | * Copy the 32-bit address to the 64-bit GAS structure. The | ||
470 | * Space ID is always I/O for 32-bit legacy address fields | ||
471 | */ | ||
472 | acpi_tb_init_generic_address(address64, | ||
473 | ACPI_ADR_SPACE_SYSTEM_IO, | ||
474 | *ACPI_ADD_PTR(u8, | ||
475 | &acpi_gbl_FADT, | ||
476 | fadt_info_table | ||
477 | [i].length), | ||
478 | (u64) address32, | ||
479 | fadt_info_table[i].name); | ||
480 | } | ||
481 | } | ||
482 | } | ||
483 | |||
484 | /******************************************************************************* | ||
485 | * | ||
486 | * FUNCTION: acpi_tb_validate_fadt | ||
487 | * | ||
488 | * PARAMETERS: table - Pointer to the FADT to be validated | ||
489 | * | ||
490 | * RETURN: None | ||
491 | * | ||
492 | * DESCRIPTION: Validate various important fields within the FADT. If a problem | ||
493 | * is found, issue a message, but no status is returned. | ||
494 | * Used by both the table manager and the disassembler. | ||
495 | * | ||
496 | * Possible additional checks: | ||
497 | * (acpi_gbl_FADT.pm1_event_length >= 4) | ||
498 | * (acpi_gbl_FADT.pm1_control_length >= 2) | ||
499 | * (acpi_gbl_FADT.pm_timer_length >= 4) | ||
500 | * Gpe block lengths must be multiple of 2 | ||
501 | * | ||
502 | ******************************************************************************/ | ||
503 | |||
504 | static void acpi_tb_validate_fadt(void) | ||
505 | { | ||
506 | char *name; | ||
507 | struct acpi_generic_address *address64; | ||
508 | u8 length; | ||
509 | u32 i; | ||
510 | 479 | ||
511 | /* | 480 | /* |
512 | * Check for FACS and DSDT address mismatches. An address mismatch between | 481 | * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. |
513 | * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and | 482 | * Later ACPICA code will always use the X 64-bit field. |
514 | * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables. | ||
515 | */ | 483 | */ |
516 | if (acpi_gbl_FADT.facs && | 484 | acpi_gbl_FADT.Xfacs = acpi_tb_select_address("FACS", |
517 | (acpi_gbl_FADT.Xfacs != (u64)acpi_gbl_FADT.facs)) { | 485 | acpi_gbl_FADT.facs, |
518 | ACPI_BIOS_WARNING((AE_INFO, | 486 | acpi_gbl_FADT.Xfacs); |
519 | "32/64X FACS address mismatch in FADT - " | ||
520 | "0x%8.8X/0x%8.8X%8.8X, using 32", | ||
521 | acpi_gbl_FADT.facs, | ||
522 | ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs))); | ||
523 | |||
524 | acpi_gbl_FADT.Xfacs = (u64)acpi_gbl_FADT.facs; | ||
525 | } | ||
526 | |||
527 | if (acpi_gbl_FADT.dsdt && | ||
528 | (acpi_gbl_FADT.Xdsdt != (u64)acpi_gbl_FADT.dsdt)) { | ||
529 | ACPI_BIOS_WARNING((AE_INFO, | ||
530 | "32/64X DSDT address mismatch in FADT - " | ||
531 | "0x%8.8X/0x%8.8X%8.8X, using 32", | ||
532 | acpi_gbl_FADT.dsdt, | ||
533 | ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt))); | ||
534 | 487 | ||
535 | acpi_gbl_FADT.Xdsdt = (u64)acpi_gbl_FADT.dsdt; | 488 | acpi_gbl_FADT.Xdsdt = acpi_tb_select_address("DSDT", |
536 | } | 489 | acpi_gbl_FADT.dsdt, |
490 | acpi_gbl_FADT.Xdsdt); | ||
537 | 491 | ||
538 | /* If Hardware Reduced flag is set, we are all done */ | 492 | /* If Hardware Reduced flag is set, we are all done */ |
539 | 493 | ||
@@ -545,18 +499,95 @@ static void acpi_tb_validate_fadt(void) | |||
545 | 499 | ||
546 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | 500 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { |
547 | /* | 501 | /* |
548 | * Generate pointer to the 64-bit address, get the register | 502 | * Get the 32-bit and 64-bit addresses, as well as the register |
549 | * length (width) and the register name | 503 | * length and register name. |
550 | */ | 504 | */ |
505 | address32 = *ACPI_ADD_PTR(u32, | ||
506 | &acpi_gbl_FADT, | ||
507 | fadt_info_table[i].address32); | ||
508 | |||
551 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, | 509 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, |
552 | &acpi_gbl_FADT, | 510 | &acpi_gbl_FADT, |
553 | fadt_info_table[i].address64); | 511 | fadt_info_table[i].address64); |
554 | length = | 512 | |
555 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, | 513 | length = *ACPI_ADD_PTR(u8, |
556 | fadt_info_table[i].length); | 514 | &acpi_gbl_FADT, |
515 | fadt_info_table[i].length); | ||
516 | |||
557 | name = fadt_info_table[i].name; | 517 | name = fadt_info_table[i].name; |
558 | 518 | ||
559 | /* | 519 | /* |
520 | * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" | ||
521 | * generic address structures as necessary. Later code will always use | ||
522 | * the 64-bit address structures. | ||
523 | * | ||
524 | * November 2013: | ||
525 | * Now always use the 64-bit address if it is valid (non-zero), in | ||
526 | * accordance with the ACPI specification which states that a 64-bit | ||
527 | * address supersedes the 32-bit version. This behavior can be | ||
528 | * overridden by the acpi_gbl_use32_bit_fadt_addresses flag. | ||
529 | * | ||
530 | * During 64-bit address construction and verification, | ||
531 | * these cases are handled: | ||
532 | * | ||
533 | * Address32 zero, Address64 [don't care] - Use Address64 | ||
534 | * | ||
535 | * Address32 non-zero, Address64 zero - Copy/use Address32 | ||
536 | * Address32 non-zero == Address64 non-zero - Use Address64 | ||
537 | * Address32 non-zero != Address64 non-zero - Warning, use Address64 | ||
538 | * | ||
539 | * Override: if acpi_gbl_use32_bit_fadt_addresses is TRUE, and: | ||
540 | * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32 | ||
541 | * | ||
542 | * Note: space_id is always I/O for 32-bit legacy address fields | ||
543 | */ | ||
544 | if (address32) { | ||
545 | if (!address64->address) { | ||
546 | |||
547 | /* 64-bit address is zero, use 32-bit address */ | ||
548 | |||
549 | acpi_tb_init_generic_address(address64, | ||
550 | ACPI_ADR_SPACE_SYSTEM_IO, | ||
551 | *ACPI_ADD_PTR(u8, | ||
552 | &acpi_gbl_FADT, | ||
553 | fadt_info_table | ||
554 | [i]. | ||
555 | length), | ||
556 | (u64)address32, | ||
557 | name); | ||
558 | } else if (address64->address != (u64)address32) { | ||
559 | |||
560 | /* Address mismatch */ | ||
561 | |||
562 | ACPI_BIOS_WARNING((AE_INFO, | ||
563 | "32/64X address mismatch in FADT/%s: " | ||
564 | "0x%8.8X/0x%8.8X%8.8X, using %u-bit address", | ||
565 | name, address32, | ||
566 | ACPI_FORMAT_UINT64 | ||
567 | (address64->address), | ||
568 | acpi_gbl_use32_bit_fadt_addresses | ||
569 | ? 32 : 64)); | ||
570 | |||
571 | if (acpi_gbl_use32_bit_fadt_addresses) { | ||
572 | |||
573 | /* 32-bit address override */ | ||
574 | |||
575 | acpi_tb_init_generic_address(address64, | ||
576 | ACPI_ADR_SPACE_SYSTEM_IO, | ||
577 | *ACPI_ADD_PTR | ||
578 | (u8, | ||
579 | &acpi_gbl_FADT, | ||
580 | fadt_info_table | ||
581 | [i]. | ||
582 | length), | ||
583 | (u64) | ||
584 | address32, | ||
585 | name); | ||
586 | } | ||
587 | } | ||
588 | } | ||
589 | |||
590 | /* | ||
560 | * For each extended field, check for length mismatch between the | 591 | * For each extended field, check for length mismatch between the |
561 | * legacy length field and the corresponding 64-bit X length field. | 592 | * legacy length field and the corresponding 64-bit X length field. |
562 | * Note: If the legacy length field is > 0xFF bits, ignore this | 593 | * Note: If the legacy length field is > 0xFF bits, ignore this |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 3d6bb83aa7e7..6412d3c301cb 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -49,69 +49,11 @@ | |||
49 | ACPI_MODULE_NAME("tbutils") | 49 | ACPI_MODULE_NAME("tbutils") |
50 | 50 | ||
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static acpi_status acpi_tb_validate_xsdt(acpi_physical_address address); | ||
53 | |||
52 | static acpi_physical_address | 54 | static acpi_physical_address |
53 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); | 55 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); |
54 | 56 | ||
55 | /******************************************************************************* | ||
56 | * | ||
57 | * FUNCTION: acpi_tb_check_xsdt | ||
58 | * | ||
59 | * PARAMETERS: address - Pointer to the XSDT | ||
60 | * | ||
61 | * RETURN: status | ||
62 | * AE_OK - XSDT is okay | ||
63 | * AE_NO_MEMORY - can't map XSDT | ||
64 | * AE_INVALID_TABLE_LENGTH - invalid table length | ||
65 | * AE_NULL_ENTRY - XSDT has NULL entry | ||
66 | * | ||
67 | * DESCRIPTION: validate XSDT | ||
68 | ******************************************************************************/ | ||
69 | |||
70 | static acpi_status | ||
71 | acpi_tb_check_xsdt(acpi_physical_address address) | ||
72 | { | ||
73 | struct acpi_table_header *table; | ||
74 | u32 length; | ||
75 | u64 xsdt_entry_address; | ||
76 | u8 *table_entry; | ||
77 | u32 table_count; | ||
78 | int i; | ||
79 | |||
80 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | ||
81 | if (!table) | ||
82 | return AE_NO_MEMORY; | ||
83 | |||
84 | length = table->length; | ||
85 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
86 | if (length < sizeof(struct acpi_table_header)) | ||
87 | return AE_INVALID_TABLE_LENGTH; | ||
88 | |||
89 | table = acpi_os_map_memory(address, length); | ||
90 | if (!table) | ||
91 | return AE_NO_MEMORY; | ||
92 | |||
93 | /* Calculate the number of tables described in XSDT */ | ||
94 | table_count = | ||
95 | (u32) ((table->length - | ||
96 | sizeof(struct acpi_table_header)) / sizeof(u64)); | ||
97 | table_entry = | ||
98 | ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); | ||
99 | for (i = 0; i < table_count; i++) { | ||
100 | ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry); | ||
101 | if (!xsdt_entry_address) { | ||
102 | /* XSDT has NULL entry */ | ||
103 | break; | ||
104 | } | ||
105 | table_entry += sizeof(u64); | ||
106 | } | ||
107 | acpi_os_unmap_memory(table, length); | ||
108 | |||
109 | if (i < table_count) | ||
110 | return AE_NULL_ENTRY; | ||
111 | else | ||
112 | return AE_OK; | ||
113 | } | ||
114 | |||
115 | #if (!ACPI_REDUCED_HARDWARE) | 57 | #if (!ACPI_REDUCED_HARDWARE) |
116 | /******************************************************************************* | 58 | /******************************************************************************* |
117 | * | 59 | * |
@@ -383,7 +325,7 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
383 | * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): | 325 | * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): |
384 | * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT | 326 | * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT |
385 | */ | 327 | */ |
386 | if (table_entry_size == sizeof(u32)) { | 328 | if (table_entry_size == ACPI_RSDT_ENTRY_SIZE) { |
387 | /* | 329 | /* |
388 | * 32-bit platform, RSDT: Return 32-bit table entry | 330 | * 32-bit platform, RSDT: Return 32-bit table entry |
389 | * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return | 331 | * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return |
@@ -415,6 +357,87 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
415 | 357 | ||
416 | /******************************************************************************* | 358 | /******************************************************************************* |
417 | * | 359 | * |
360 | * FUNCTION: acpi_tb_validate_xsdt | ||
361 | * | ||
362 | * PARAMETERS: address - Physical address of the XSDT (from RSDP) | ||
363 | * | ||
364 | * RETURN: Status. AE_OK if the table appears to be valid. | ||
365 | * | ||
366 | * DESCRIPTION: Validate an XSDT to ensure that it is of minimum size and does | ||
367 | * not contain any NULL entries. A problem that is seen in the | ||
368 | * field is that the XSDT exists, but is actually useless because | ||
369 | * of one or more (or all) NULL entries. | ||
370 | * | ||
371 | ******************************************************************************/ | ||
372 | |||
373 | static acpi_status acpi_tb_validate_xsdt(acpi_physical_address xsdt_address) | ||
374 | { | ||
375 | struct acpi_table_header *table; | ||
376 | u8 *next_entry; | ||
377 | acpi_physical_address address; | ||
378 | u32 length; | ||
379 | u32 entry_count; | ||
380 | acpi_status status; | ||
381 | u32 i; | ||
382 | |||
383 | /* Get the XSDT length */ | ||
384 | |||
385 | table = | ||
386 | acpi_os_map_memory(xsdt_address, sizeof(struct acpi_table_header)); | ||
387 | if (!table) { | ||
388 | return (AE_NO_MEMORY); | ||
389 | } | ||
390 | |||
391 | length = table->length; | ||
392 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
393 | |||
394 | /* | ||
395 | * Minimum XSDT length is the size of the standard ACPI header | ||
396 | * plus one physical address entry | ||
397 | */ | ||
398 | if (length < (sizeof(struct acpi_table_header) + ACPI_XSDT_ENTRY_SIZE)) { | ||
399 | return (AE_INVALID_TABLE_LENGTH); | ||
400 | } | ||
401 | |||
402 | /* Map the entire XSDT */ | ||
403 | |||
404 | table = acpi_os_map_memory(xsdt_address, length); | ||
405 | if (!table) { | ||
406 | return (AE_NO_MEMORY); | ||
407 | } | ||
408 | |||
409 | /* Get the number of entries and pointer to first entry */ | ||
410 | |||
411 | status = AE_OK; | ||
412 | next_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header)); | ||
413 | entry_count = (u32)((table->length - sizeof(struct acpi_table_header)) / | ||
414 | ACPI_XSDT_ENTRY_SIZE); | ||
415 | |||
416 | /* Validate each entry (physical address) within the XSDT */ | ||
417 | |||
418 | for (i = 0; i < entry_count; i++) { | ||
419 | address = | ||
420 | acpi_tb_get_root_table_entry(next_entry, | ||
421 | ACPI_XSDT_ENTRY_SIZE); | ||
422 | if (!address) { | ||
423 | |||
424 | /* Detected a NULL entry, XSDT is invalid */ | ||
425 | |||
426 | status = AE_NULL_ENTRY; | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | next_entry += ACPI_XSDT_ENTRY_SIZE; | ||
431 | } | ||
432 | |||
433 | /* Unmap table */ | ||
434 | |||
435 | acpi_os_unmap_memory(table, length); | ||
436 | return (status); | ||
437 | } | ||
438 | |||
439 | /******************************************************************************* | ||
440 | * | ||
418 | * FUNCTION: acpi_tb_parse_root_table | 441 | * FUNCTION: acpi_tb_parse_root_table |
419 | * | 442 | * |
420 | * PARAMETERS: rsdp - Pointer to the RSDP | 443 | * PARAMETERS: rsdp - Pointer to the RSDP |
@@ -438,16 +461,14 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
438 | u32 table_count; | 461 | u32 table_count; |
439 | struct acpi_table_header *table; | 462 | struct acpi_table_header *table; |
440 | acpi_physical_address address; | 463 | acpi_physical_address address; |
441 | acpi_physical_address uninitialized_var(rsdt_address); | ||
442 | u32 length; | 464 | u32 length; |
443 | u8 *table_entry; | 465 | u8 *table_entry; |
444 | acpi_status status; | 466 | acpi_status status; |
445 | 467 | ||
446 | ACPI_FUNCTION_TRACE(tb_parse_root_table); | 468 | ACPI_FUNCTION_TRACE(tb_parse_root_table); |
447 | 469 | ||
448 | /* | 470 | /* Map the entire RSDP and extract the address of the RSDT or XSDT */ |
449 | * Map the entire RSDP and extract the address of the RSDT or XSDT | 471 | |
450 | */ | ||
451 | rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp)); | 472 | rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp)); |
452 | if (!rsdp) { | 473 | if (!rsdp) { |
453 | return_ACPI_STATUS(AE_NO_MEMORY); | 474 | return_ACPI_STATUS(AE_NO_MEMORY); |
@@ -457,24 +478,22 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
457 | ACPI_CAST_PTR(struct acpi_table_header, | 478 | ACPI_CAST_PTR(struct acpi_table_header, |
458 | rsdp)); | 479 | rsdp)); |
459 | 480 | ||
460 | /* Differentiate between RSDT and XSDT root tables */ | 481 | /* Use XSDT if present and not overridden. Otherwise, use RSDT */ |
461 | 482 | ||
462 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address | 483 | if ((rsdp->revision > 1) && |
463 | && !acpi_rsdt_forced) { | 484 | rsdp->xsdt_physical_address && !acpi_gbl_do_not_use_xsdt) { |
464 | /* | 485 | /* |
465 | * Root table is an XSDT (64-bit physical addresses). We must use the | 486 | * RSDP contains an XSDT (64-bit physical addresses). We must use |
466 | * XSDT if the revision is > 1 and the XSDT pointer is present, as per | 487 | * the XSDT if the revision is > 1 and the XSDT pointer is present, |
467 | * the ACPI specification. | 488 | * as per the ACPI specification. |
468 | */ | 489 | */ |
469 | address = (acpi_physical_address) rsdp->xsdt_physical_address; | 490 | address = (acpi_physical_address) rsdp->xsdt_physical_address; |
470 | table_entry_size = sizeof(u64); | 491 | table_entry_size = ACPI_XSDT_ENTRY_SIZE; |
471 | rsdt_address = (acpi_physical_address) | ||
472 | rsdp->rsdt_physical_address; | ||
473 | } else { | 492 | } else { |
474 | /* Root table is an RSDT (32-bit physical addresses) */ | 493 | /* Root table is an RSDT (32-bit physical addresses) */ |
475 | 494 | ||
476 | address = (acpi_physical_address) rsdp->rsdt_physical_address; | 495 | address = (acpi_physical_address) rsdp->rsdt_physical_address; |
477 | table_entry_size = sizeof(u32); | 496 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; |
478 | } | 497 | } |
479 | 498 | ||
480 | /* | 499 | /* |
@@ -483,15 +502,25 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
483 | */ | 502 | */ |
484 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); | 503 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); |
485 | 504 | ||
486 | if (table_entry_size == sizeof(u64)) { | 505 | /* |
487 | if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) { | 506 | * If it is present and used, validate the XSDT for access/size |
488 | /* XSDT has NULL entry, RSDT is used */ | 507 | * and ensure that all table entries are at least non-NULL |
489 | address = rsdt_address; | 508 | */ |
490 | table_entry_size = sizeof(u32); | 509 | if (table_entry_size == ACPI_XSDT_ENTRY_SIZE) { |
491 | ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry, " | 510 | status = acpi_tb_validate_xsdt(address); |
492 | "using RSDT")); | 511 | if (ACPI_FAILURE(status)) { |
512 | ACPI_BIOS_WARNING((AE_INFO, | ||
513 | "XSDT is invalid (%s), using RSDT", | ||
514 | acpi_format_exception(status))); | ||
515 | |||
516 | /* Fall back to the RSDT */ | ||
517 | |||
518 | address = | ||
519 | (acpi_physical_address) rsdp->rsdt_physical_address; | ||
520 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; | ||
493 | } | 521 | } |
494 | } | 522 | } |
523 | |||
495 | /* Map the RSDT/XSDT table header to get the full table length */ | 524 | /* Map the RSDT/XSDT table header to get the full table length */ |
496 | 525 | ||
497 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | 526 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); |
@@ -501,12 +530,14 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
501 | 530 | ||
502 | acpi_tb_print_table_header(address, table); | 531 | acpi_tb_print_table_header(address, table); |
503 | 532 | ||
504 | /* Get the length of the full table, verify length and map entire table */ | 533 | /* |
505 | 534 | * Validate length of the table, and map entire table. | |
535 | * Minimum length table must contain at least one entry. | ||
536 | */ | ||
506 | length = table->length; | 537 | length = table->length; |
507 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | 538 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); |
508 | 539 | ||
509 | if (length < sizeof(struct acpi_table_header)) { | 540 | if (length < (sizeof(struct acpi_table_header) + table_entry_size)) { |
510 | ACPI_BIOS_ERROR((AE_INFO, | 541 | ACPI_BIOS_ERROR((AE_INFO, |
511 | "Invalid table length 0x%X in RSDT/XSDT", | 542 | "Invalid table length 0x%X in RSDT/XSDT", |
512 | length)); | 543 | length)); |
@@ -526,22 +557,21 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
526 | return_ACPI_STATUS(status); | 557 | return_ACPI_STATUS(status); |
527 | } | 558 | } |
528 | 559 | ||
529 | /* Calculate the number of tables described in the root table */ | 560 | /* Get the number of entries and pointer to first entry */ |
530 | 561 | ||
531 | table_count = (u32)((table->length - sizeof(struct acpi_table_header)) / | 562 | table_count = (u32)((table->length - sizeof(struct acpi_table_header)) / |
532 | table_entry_size); | 563 | table_entry_size); |
564 | table_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header)); | ||
565 | |||
533 | /* | 566 | /* |
534 | * First two entries in the table array are reserved for the DSDT | 567 | * First two entries in the table array are reserved for the DSDT |
535 | * and FACS, which are not actually present in the RSDT/XSDT - they | 568 | * and FACS, which are not actually present in the RSDT/XSDT - they |
536 | * come from the FADT | 569 | * come from the FADT |
537 | */ | 570 | */ |
538 | table_entry = | ||
539 | ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); | ||
540 | acpi_gbl_root_table_list.current_table_count = 2; | 571 | acpi_gbl_root_table_list.current_table_count = 2; |
541 | 572 | ||
542 | /* | 573 | /* Initialize the root table array from the RSDT/XSDT */ |
543 | * Initialize the root table array from the RSDT/XSDT | 574 | |
544 | */ | ||
545 | for (i = 0; i < table_count; i++) { | 575 | for (i = 0; i < table_count; i++) { |
546 | if (acpi_gbl_root_table_list.current_table_count >= | 576 | if (acpi_gbl_root_table_list.current_table_count >= |
547 | acpi_gbl_root_table_list.max_table_count) { | 577 | acpi_gbl_root_table_list.max_table_count) { |
@@ -584,7 +614,7 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
584 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. | 614 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. |
585 | address, NULL, i); | 615 | address, NULL, i); |
586 | 616 | ||
587 | /* Special case for FADT - get the DSDT and FACS */ | 617 | /* Special case for FADT - validate it then get the DSDT and FACS */ |
588 | 618 | ||
589 | if (ACPI_COMPARE_NAME | 619 | if (ACPI_COMPARE_NAME |
590 | (&acpi_gbl_root_table_list.tables[i].signature, | 620 | (&acpi_gbl_root_table_list.tables[i].signature, |
diff --git a/drivers/acpi/acpica/utaddress.c b/drivers/acpi/acpica/utaddress.c index e0a2e2779c2e..2c2b6ae5dfc4 100644 --- a/drivers/acpi/acpica/utaddress.c +++ b/drivers/acpi/acpica/utaddress.c | |||
@@ -224,10 +224,11 @@ acpi_ut_check_address_range(acpi_adr_space_type space_id, | |||
224 | 224 | ||
225 | while (range_info) { | 225 | while (range_info) { |
226 | /* | 226 | /* |
227 | * Check if the requested Address/Length overlaps this address_range. | 227 | * Check if the requested address/length overlaps this |
228 | * Four cases to consider: | 228 | * address range. There are four cases to consider: |
229 | * | 229 | * |
230 | * 1) Input address/length is contained completely in the address range | 230 | * 1) Input address/length is contained completely in the |
231 | * address range | ||
231 | * 2) Input address/length overlaps range at the range start | 232 | * 2) Input address/length overlaps range at the range start |
232 | * 3) Input address/length overlaps range at the range end | 233 | * 3) Input address/length overlaps range at the range end |
233 | * 4) Input address/length completely encompasses the range | 234 | * 4) Input address/length completely encompasses the range |
@@ -244,11 +245,17 @@ acpi_ut_check_address_range(acpi_adr_space_type space_id, | |||
244 | region_node); | 245 | region_node); |
245 | 246 | ||
246 | ACPI_WARNING((AE_INFO, | 247 | ACPI_WARNING((AE_INFO, |
247 | "0x%p-0x%p %s conflicts with Region %s %d", | 248 | "%s range 0x%p-0x%p conflicts with OpRegion 0x%p-0x%p (%s)", |
249 | acpi_ut_get_region_name(space_id), | ||
248 | ACPI_CAST_PTR(void, address), | 250 | ACPI_CAST_PTR(void, address), |
249 | ACPI_CAST_PTR(void, end_address), | 251 | ACPI_CAST_PTR(void, end_address), |
250 | acpi_ut_get_region_name(space_id), | 252 | ACPI_CAST_PTR(void, |
251 | pathname, overlap_count)); | 253 | range_info-> |
254 | start_address), | ||
255 | ACPI_CAST_PTR(void, | ||
256 | range_info-> | ||
257 | end_address), | ||
258 | pathname)); | ||
252 | ACPI_FREE(pathname); | 259 | ACPI_FREE(pathname); |
253 | } | 260 | } |
254 | } | 261 | } |
diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index 814267f52715..1851762fc5b5 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c | |||
@@ -302,9 +302,13 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, | |||
302 | return (AE_BUFFER_OVERFLOW); | 302 | return (AE_BUFFER_OVERFLOW); |
303 | 303 | ||
304 | case ACPI_ALLOCATE_BUFFER: | 304 | case ACPI_ALLOCATE_BUFFER: |
305 | 305 | /* | |
306 | /* Allocate a new buffer */ | 306 | * Allocate a new buffer. We directectly call acpi_os_allocate here to |
307 | 307 | * purposefully bypass the (optionally enabled) internal allocation | |
308 | * tracking mechanism since we only want to track internal | ||
309 | * allocations. Note: The caller should use acpi_os_free to free this | ||
310 | * buffer created via ACPI_ALLOCATE_BUFFER. | ||
311 | */ | ||
308 | buffer->pointer = acpi_os_allocate(required_length); | 312 | buffer->pointer = acpi_os_allocate(required_length); |
309 | break; | 313 | break; |
310 | 314 | ||
diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c index 366bfec4b770..cacd2fd9e665 100644 --- a/drivers/acpi/acpica/utcache.c +++ b/drivers/acpi/acpica/utcache.c | |||
@@ -248,12 +248,12 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) | |||
248 | ACPI_FUNCTION_NAME(os_acquire_object); | 248 | ACPI_FUNCTION_NAME(os_acquire_object); |
249 | 249 | ||
250 | if (!cache) { | 250 | if (!cache) { |
251 | return (NULL); | 251 | return_PTR(NULL); |
252 | } | 252 | } |
253 | 253 | ||
254 | status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); | 254 | status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); |
255 | if (ACPI_FAILURE(status)) { | 255 | if (ACPI_FAILURE(status)) { |
256 | return (NULL); | 256 | return_PTR(NULL); |
257 | } | 257 | } |
258 | 258 | ||
259 | ACPI_MEM_TRACKING(cache->requests++); | 259 | ACPI_MEM_TRACKING(cache->requests++); |
@@ -276,7 +276,7 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) | |||
276 | 276 | ||
277 | status = acpi_ut_release_mutex(ACPI_MTX_CACHES); | 277 | status = acpi_ut_release_mutex(ACPI_MTX_CACHES); |
278 | if (ACPI_FAILURE(status)) { | 278 | if (ACPI_FAILURE(status)) { |
279 | return (NULL); | 279 | return_PTR(NULL); |
280 | } | 280 | } |
281 | 281 | ||
282 | /* Clear (zero) the previously used Object */ | 282 | /* Clear (zero) the previously used Object */ |
@@ -299,15 +299,15 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) | |||
299 | 299 | ||
300 | status = acpi_ut_release_mutex(ACPI_MTX_CACHES); | 300 | status = acpi_ut_release_mutex(ACPI_MTX_CACHES); |
301 | if (ACPI_FAILURE(status)) { | 301 | if (ACPI_FAILURE(status)) { |
302 | return (NULL); | 302 | return_PTR(NULL); |
303 | } | 303 | } |
304 | 304 | ||
305 | object = ACPI_ALLOCATE_ZEROED(cache->object_size); | 305 | object = ACPI_ALLOCATE_ZEROED(cache->object_size); |
306 | if (!object) { | 306 | if (!object) { |
307 | return (NULL); | 307 | return_PTR(NULL); |
308 | } | 308 | } |
309 | } | 309 | } |
310 | 310 | ||
311 | return (object); | 311 | return_PTR(object); |
312 | } | 312 | } |
313 | #endif /* ACPI_USE_LOCAL_CACHE */ | 313 | #endif /* ACPI_USE_LOCAL_CACHE */ |
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 03ae8affe48f..d971c8631263 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
@@ -194,9 +194,9 @@ acpi_debug_print(u32 requested_debug_level, | |||
194 | */ | 194 | */ |
195 | acpi_os_printf("%9s-%04ld ", module_name, line_number); | 195 | acpi_os_printf("%9s-%04ld ", module_name, line_number); |
196 | 196 | ||
197 | #ifdef ACPI_EXEC_APP | 197 | #ifdef ACPI_APPLICATION |
198 | /* | 198 | /* |
199 | * For acpi_exec only, emit the thread ID and nesting level. | 199 | * For acpi_exec/iASL only, emit the thread ID and nesting level. |
200 | * Note: nesting level is really only useful during a single-thread | 200 | * Note: nesting level is really only useful during a single-thread |
201 | * execution. Otherwise, multiple threads will keep resetting the | 201 | * execution. Otherwise, multiple threads will keep resetting the |
202 | * level. | 202 | * level. |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 81f9a9584451..030cb0dc673c 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -388,11 +388,7 @@ acpi_status acpi_ut_init_globals(void) | |||
388 | /* Public globals */ | 388 | /* Public globals */ |
389 | 389 | ||
390 | ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) | 390 | ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) |
391 | |||
392 | ACPI_EXPORT_SYMBOL(acpi_dbg_level) | 391 | ACPI_EXPORT_SYMBOL(acpi_dbg_level) |
393 | |||
394 | ACPI_EXPORT_SYMBOL(acpi_dbg_layer) | 392 | ACPI_EXPORT_SYMBOL(acpi_dbg_layer) |
395 | |||
396 | ACPI_EXPORT_SYMBOL(acpi_gpe_count) | 393 | ACPI_EXPORT_SYMBOL(acpi_gpe_count) |
397 | |||
398 | ACPI_EXPORT_SYMBOL(acpi_current_gpe_count) | 394 | ACPI_EXPORT_SYMBOL(acpi_current_gpe_count) |
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 75efea0539c1..246ef68681f4 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c | |||
@@ -122,8 +122,16 @@ acpi_status __init acpi_initialize_subsystem(void) | |||
122 | 122 | ||
123 | /* If configured, initialize the AML debugger */ | 123 | /* If configured, initialize the AML debugger */ |
124 | 124 | ||
125 | ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); | 125 | #ifdef ACPI_DEBUGGER |
126 | return_ACPI_STATUS(status); | 126 | status = acpi_db_initialize(); |
127 | if (ACPI_FAILURE(status)) { | ||
128 | ACPI_EXCEPTION((AE_INFO, status, | ||
129 | "During Debugger initialization")); | ||
130 | return_ACPI_STATUS(status); | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | return_ACPI_STATUS(AE_OK); | ||
127 | } | 135 | } |
128 | 136 | ||
129 | ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_subsystem) | 137 | ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_subsystem) |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index e55584a072c6..8678dfe5366b 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
37 | #include <linux/acpi_io.h> | ||
38 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
39 | #include <linux/io.h> | 38 | #include <linux/io.h> |
40 | #include <linux/kref.h> | 39 | #include <linux/kref.h> |
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index 21ba34a73883..e5bcd919d4e6 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/cper.h> | 9 | #include <linux/cper.h> |
10 | #include <linux/acpi.h> | 10 | #include <linux/acpi.h> |
11 | #include <linux/acpi_io.h> | ||
12 | 11 | ||
13 | struct apei_exec_context; | 12 | struct apei_exec_context; |
14 | 13 | ||
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 7dcc8a824aae..1be6f5564485 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/nmi.h> | 33 | #include <linux/nmi.h> |
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/mm.h> | 35 | #include <linux/mm.h> |
36 | #include <acpi/acpi.h> | ||
37 | #include <asm/unaligned.h> | 36 | #include <asm/unaligned.h> |
38 | 37 | ||
39 | #include "apei-internal.h" | 38 | #include "apei-internal.h" |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 46766ef7ef5d..dab7cb7349df 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
36 | #include <linux/acpi_io.h> | ||
37 | #include <linux/io.h> | 36 | #include <linux/io.h> |
38 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
39 | #include <linux/timer.h> | 38 | #include <linux/timer.h> |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 5876a49dfd38..470e7542bf31 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -36,8 +36,7 @@ | |||
36 | #include <linux/suspend.h> | 36 | #include <linux/suspend.h> |
37 | #include <asm/unaligned.h> | 37 | #include <asm/unaligned.h> |
38 | 38 | ||
39 | #include <acpi/acpi_bus.h> | 39 | #include <linux/acpi.h> |
40 | #include <acpi/acpi_drivers.h> | ||
41 | #include <linux/power_supply.h> | 40 | #include <linux/power_supply.h> |
42 | 41 | ||
43 | #define PREFIX "ACPI: " | 42 | #define PREFIX "ACPI: " |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 078c4f7fe2dd..10e4964d051a 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/acpi.h> | 32 | #include <linux/acpi.h> |
33 | #include <acpi/acpi_bus.h> | ||
34 | #include <linux/dmi.h> | 33 | #include <linux/dmi.h> |
35 | 34 | ||
36 | #include "internal.h" | 35 | #include "internal.h" |
@@ -323,6 +322,56 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
323 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), | 322 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), |
324 | }, | 323 | }, |
325 | }, | 324 | }, |
325 | { | ||
326 | .callback = dmi_disable_osi_win8, | ||
327 | .ident = "HP ProBook 2013 models", | ||
328 | .matches = { | ||
329 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
330 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook "), | ||
331 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
332 | }, | ||
333 | }, | ||
334 | { | ||
335 | .callback = dmi_disable_osi_win8, | ||
336 | .ident = "HP EliteBook 2013 models", | ||
337 | .matches = { | ||
338 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
339 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "), | ||
340 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
341 | }, | ||
342 | }, | ||
343 | { | ||
344 | .callback = dmi_disable_osi_win8, | ||
345 | .ident = "HP ZBook 14", | ||
346 | .matches = { | ||
347 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
348 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 14"), | ||
349 | }, | ||
350 | }, | ||
351 | { | ||
352 | .callback = dmi_disable_osi_win8, | ||
353 | .ident = "HP ZBook 15", | ||
354 | .matches = { | ||
355 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
356 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 15"), | ||
357 | }, | ||
358 | }, | ||
359 | { | ||
360 | .callback = dmi_disable_osi_win8, | ||
361 | .ident = "HP ZBook 17", | ||
362 | .matches = { | ||
363 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
364 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 17"), | ||
365 | }, | ||
366 | }, | ||
367 | { | ||
368 | .callback = dmi_disable_osi_win8, | ||
369 | .ident = "HP EliteBook 8780w", | ||
370 | .matches = { | ||
371 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
372 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"), | ||
373 | }, | ||
374 | }, | ||
326 | 375 | ||
327 | /* | 376 | /* |
328 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 377 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 0710004055c8..384da5ab5955 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include <asm/mpspec.h> | 37 | #include <asm/mpspec.h> |
38 | #endif | 38 | #endif |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <acpi/acpi_bus.h> | ||
41 | #include <acpi/acpi_drivers.h> | ||
42 | #include <acpi/apei.h> | 40 | #include <acpi/apei.h> |
43 | #include <linux/dmi.h> | 41 | #include <linux/dmi.h> |
44 | #include <linux/suspend.h> | 42 | #include <linux/suspend.h> |
@@ -52,9 +50,6 @@ struct acpi_device *acpi_root; | |||
52 | struct proc_dir_entry *acpi_root_dir; | 50 | struct proc_dir_entry *acpi_root_dir; |
53 | EXPORT_SYMBOL(acpi_root_dir); | 51 | EXPORT_SYMBOL(acpi_root_dir); |
54 | 52 | ||
55 | #define STRUCT_TO_INT(s) (*((int*)&s)) | ||
56 | |||
57 | |||
58 | #ifdef CONFIG_X86 | 53 | #ifdef CONFIG_X86 |
59 | static int set_copy_dsdt(const struct dmi_system_id *id) | 54 | static int set_copy_dsdt(const struct dmi_system_id *id) |
60 | { | 55 | { |
@@ -115,18 +110,16 @@ int acpi_bus_get_status(struct acpi_device *device) | |||
115 | if (ACPI_FAILURE(status)) | 110 | if (ACPI_FAILURE(status)) |
116 | return -ENODEV; | 111 | return -ENODEV; |
117 | 112 | ||
118 | STRUCT_TO_INT(device->status) = (int) sta; | 113 | acpi_set_device_status(device, sta); |
119 | 114 | ||
120 | if (device->status.functional && !device->status.present) { | 115 | if (device->status.functional && !device->status.present) { |
121 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: " | 116 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: " |
122 | "functional but not present;\n", | 117 | "functional but not present;\n", |
123 | device->pnp.bus_id, | 118 | device->pnp.bus_id, (u32)sta)); |
124 | (u32) STRUCT_TO_INT(device->status))); | ||
125 | } | 119 | } |
126 | 120 | ||
127 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", | 121 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", |
128 | device->pnp.bus_id, | 122 | device->pnp.bus_id, (u32)sta)); |
129 | (u32) STRUCT_TO_INT(device->status))); | ||
130 | return 0; | 123 | return 0; |
131 | } | 124 | } |
132 | EXPORT_SYMBOL(acpi_bus_get_status); | 125 | EXPORT_SYMBOL(acpi_bus_get_status); |
@@ -339,58 +332,6 @@ static void acpi_bus_osc_support(void) | |||
339 | Notification Handling | 332 | Notification Handling |
340 | -------------------------------------------------------------------------- */ | 333 | -------------------------------------------------------------------------- */ |
341 | 334 | ||
342 | static void acpi_bus_check_device(acpi_handle handle) | ||
343 | { | ||
344 | struct acpi_device *device; | ||
345 | acpi_status status; | ||
346 | struct acpi_device_status old_status; | ||
347 | |||
348 | if (acpi_bus_get_device(handle, &device)) | ||
349 | return; | ||
350 | if (!device) | ||
351 | return; | ||
352 | |||
353 | old_status = device->status; | ||
354 | |||
355 | /* | ||
356 | * Make sure this device's parent is present before we go about | ||
357 | * messing with the device. | ||
358 | */ | ||
359 | if (device->parent && !device->parent->status.present) { | ||
360 | device->status = device->parent->status; | ||
361 | return; | ||
362 | } | ||
363 | |||
364 | status = acpi_bus_get_status(device); | ||
365 | if (ACPI_FAILURE(status)) | ||
366 | return; | ||
367 | |||
368 | if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) | ||
369 | return; | ||
370 | |||
371 | /* | ||
372 | * Device Insertion/Removal | ||
373 | */ | ||
374 | if ((device->status.present) && !(old_status.present)) { | ||
375 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n")); | ||
376 | /* TBD: Handle device insertion */ | ||
377 | } else if (!(device->status.present) && (old_status.present)) { | ||
378 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); | ||
379 | /* TBD: Handle device removal */ | ||
380 | } | ||
381 | } | ||
382 | |||
383 | static void acpi_bus_check_scope(acpi_handle handle) | ||
384 | { | ||
385 | /* Status Change? */ | ||
386 | acpi_bus_check_device(handle); | ||
387 | |||
388 | /* | ||
389 | * TBD: Enumerate child devices within this device's scope and | ||
390 | * run acpi_bus_check_device()'s on them. | ||
391 | */ | ||
392 | } | ||
393 | |||
394 | /** | 335 | /** |
395 | * acpi_bus_notify | 336 | * acpi_bus_notify |
396 | * --------------- | 337 | * --------------- |
@@ -407,19 +348,11 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
407 | switch (type) { | 348 | switch (type) { |
408 | 349 | ||
409 | case ACPI_NOTIFY_BUS_CHECK: | 350 | case ACPI_NOTIFY_BUS_CHECK: |
410 | acpi_bus_check_scope(handle); | 351 | /* TBD */ |
411 | /* | ||
412 | * TBD: We'll need to outsource certain events to non-ACPI | ||
413 | * drivers via the device manager (device.c). | ||
414 | */ | ||
415 | break; | 352 | break; |
416 | 353 | ||
417 | case ACPI_NOTIFY_DEVICE_CHECK: | 354 | case ACPI_NOTIFY_DEVICE_CHECK: |
418 | acpi_bus_check_device(handle); | 355 | /* TBD */ |
419 | /* | ||
420 | * TBD: We'll need to outsource certain events to non-ACPI | ||
421 | * drivers via the device manager (device.c). | ||
422 | */ | ||
423 | break; | 356 | break; |
424 | 357 | ||
425 | case ACPI_NOTIFY_DEVICE_WAKE: | 358 | case ACPI_NOTIFY_DEVICE_WAKE: |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index c971929d75c2..11c11f6b8fa1 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -31,8 +31,7 @@ | |||
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/input.h> | 32 | #include <linux/input.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <acpi/acpi_bus.h> | 34 | #include <linux/acpi.h> |
35 | #include <acpi/acpi_drivers.h> | ||
36 | #include <acpi/button.h> | 35 | #include <acpi/button.h> |
37 | 36 | ||
38 | #define PREFIX "ACPI: " | 37 | #define PREFIX "ACPI: " |
@@ -101,7 +100,6 @@ struct acpi_button { | |||
101 | struct input_dev *input; | 100 | struct input_dev *input; |
102 | char phys[32]; /* for input device */ | 101 | char phys[32]; /* for input device */ |
103 | unsigned long pushed; | 102 | unsigned long pushed; |
104 | bool wakeup_enabled; | ||
105 | }; | 103 | }; |
106 | 104 | ||
107 | static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); | 105 | static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); |
@@ -407,16 +405,6 @@ static int acpi_button_add(struct acpi_device *device) | |||
407 | lid_device = device; | 405 | lid_device = device; |
408 | } | 406 | } |
409 | 407 | ||
410 | if (device->wakeup.flags.valid) { | ||
411 | /* Button's GPE is run-wake GPE */ | ||
412 | acpi_enable_gpe(device->wakeup.gpe_device, | ||
413 | device->wakeup.gpe_number); | ||
414 | if (!device_may_wakeup(&device->dev)) { | ||
415 | device_set_wakeup_enable(&device->dev, true); | ||
416 | button->wakeup_enabled = true; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); | 408 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); |
421 | return 0; | 409 | return 0; |
422 | 410 | ||
@@ -433,13 +421,6 @@ static int acpi_button_remove(struct acpi_device *device) | |||
433 | { | 421 | { |
434 | struct acpi_button *button = acpi_driver_data(device); | 422 | struct acpi_button *button = acpi_driver_data(device); |
435 | 423 | ||
436 | if (device->wakeup.flags.valid) { | ||
437 | acpi_disable_gpe(device->wakeup.gpe_device, | ||
438 | device->wakeup.gpe_number); | ||
439 | if (button->wakeup_enabled) | ||
440 | device_set_wakeup_enable(&device->dev, false); | ||
441 | } | ||
442 | |||
443 | acpi_button_remove_fs(device); | 424 | acpi_button_remove_fs(device); |
444 | input_unregister_device(button->input); | 425 | input_unregister_device(button->input); |
445 | kfree(button); | 426 | kfree(button); |
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index e23151667655..0b6ae6eb5c4a 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -27,8 +27,7 @@ | |||
27 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 27 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
28 | */ | 28 | */ |
29 | #include <linux/acpi.h> | 29 | #include <linux/acpi.h> |
30 | 30 | #include <linux/container.h> | |
31 | #include "internal.h" | ||
32 | 31 | ||
33 | #include "internal.h" | 32 | #include "internal.h" |
34 | 33 | ||
@@ -44,19 +43,65 @@ static const struct acpi_device_id container_device_ids[] = { | |||
44 | {"", 0}, | 43 | {"", 0}, |
45 | }; | 44 | }; |
46 | 45 | ||
47 | static int container_device_attach(struct acpi_device *device, | 46 | static int acpi_container_offline(struct container_dev *cdev) |
47 | { | ||
48 | struct acpi_device *adev = ACPI_COMPANION(&cdev->dev); | ||
49 | struct acpi_device *child; | ||
50 | |||
51 | /* Check all of the dependent devices' physical companions. */ | ||
52 | list_for_each_entry(child, &adev->children, node) | ||
53 | if (!acpi_scan_is_offline(child, false)) | ||
54 | return -EBUSY; | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static void acpi_container_release(struct device *dev) | ||
60 | { | ||
61 | kfree(to_container_dev(dev)); | ||
62 | } | ||
63 | |||
64 | static int container_device_attach(struct acpi_device *adev, | ||
48 | const struct acpi_device_id *not_used) | 65 | const struct acpi_device_id *not_used) |
49 | { | 66 | { |
50 | /* This is necessary for container hotplug to work. */ | 67 | struct container_dev *cdev; |
68 | struct device *dev; | ||
69 | int ret; | ||
70 | |||
71 | cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); | ||
72 | if (!cdev) | ||
73 | return -ENOMEM; | ||
74 | |||
75 | cdev->offline = acpi_container_offline; | ||
76 | dev = &cdev->dev; | ||
77 | dev->bus = &container_subsys; | ||
78 | dev_set_name(dev, "%s", dev_name(&adev->dev)); | ||
79 | ACPI_COMPANION_SET(dev, adev); | ||
80 | dev->release = acpi_container_release; | ||
81 | ret = device_register(dev); | ||
82 | if (ret) | ||
83 | return ret; | ||
84 | |||
85 | adev->driver_data = dev; | ||
51 | return 1; | 86 | return 1; |
52 | } | 87 | } |
53 | 88 | ||
89 | static void container_device_detach(struct acpi_device *adev) | ||
90 | { | ||
91 | struct device *dev = acpi_driver_data(adev); | ||
92 | |||
93 | adev->driver_data = NULL; | ||
94 | if (dev) | ||
95 | device_unregister(dev); | ||
96 | } | ||
97 | |||
54 | static struct acpi_scan_handler container_handler = { | 98 | static struct acpi_scan_handler container_handler = { |
55 | .ids = container_device_ids, | 99 | .ids = container_device_ids, |
56 | .attach = container_device_attach, | 100 | .attach = container_device_attach, |
101 | .detach = container_device_detach, | ||
57 | .hotplug = { | 102 | .hotplug = { |
58 | .enabled = true, | 103 | .enabled = true, |
59 | .mode = AHM_CONTAINER, | 104 | .demand_offline = true, |
60 | }, | 105 | }, |
61 | }; | 106 | }; |
62 | 107 | ||
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c index 12b62f2cdb3f..c68e72414a67 100644 --- a/drivers/acpi/custom_method.c +++ b/drivers/acpi/custom_method.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/uaccess.h> | 8 | #include <linux/uaccess.h> |
9 | #include <linux/debugfs.h> | 9 | #include <linux/debugfs.h> |
10 | #include <acpi/acpi_drivers.h> | 10 | #include <linux/acpi.h> |
11 | 11 | ||
12 | #include "internal.h" | 12 | #include "internal.h" |
13 | 13 | ||
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index b55d6a20dc0e..6b1919f6bd82 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <linux/export.h> | 5 | #include <linux/export.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/debugfs.h> | 7 | #include <linux/debugfs.h> |
8 | #include <acpi/acpi_drivers.h> | 8 | #include <linux/acpi.h> |
9 | 9 | ||
10 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 10 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
11 | ACPI_MODULE_NAME("debugfs"); | 11 | ACPI_MODULE_NAME("debugfs"); |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index b3480cf7db1a..d49f1e464703 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -256,6 +256,8 @@ int acpi_bus_init_power(struct acpi_device *device) | |||
256 | return -EINVAL; | 256 | return -EINVAL; |
257 | 257 | ||
258 | device->power.state = ACPI_STATE_UNKNOWN; | 258 | device->power.state = ACPI_STATE_UNKNOWN; |
259 | if (!acpi_device_is_present(device)) | ||
260 | return 0; | ||
259 | 261 | ||
260 | result = acpi_device_get_power(device, &state); | 262 | result = acpi_device_get_power(device, &state); |
261 | if (result) | 263 | if (result) |
@@ -302,15 +304,18 @@ int acpi_device_fix_up_power(struct acpi_device *device) | |||
302 | return ret; | 304 | return ret; |
303 | } | 305 | } |
304 | 306 | ||
305 | int acpi_bus_update_power(acpi_handle handle, int *state_p) | 307 | int acpi_device_update_power(struct acpi_device *device, int *state_p) |
306 | { | 308 | { |
307 | struct acpi_device *device; | ||
308 | int state; | 309 | int state; |
309 | int result; | 310 | int result; |
310 | 311 | ||
311 | result = acpi_bus_get_device(handle, &device); | 312 | if (device->power.state == ACPI_STATE_UNKNOWN) { |
312 | if (result) | 313 | result = acpi_bus_init_power(device); |
314 | if (!result && state_p) | ||
315 | *state_p = device->power.state; | ||
316 | |||
313 | return result; | 317 | return result; |
318 | } | ||
314 | 319 | ||
315 | result = acpi_device_get_power(device, &state); | 320 | result = acpi_device_get_power(device, &state); |
316 | if (result) | 321 | if (result) |
@@ -338,6 +343,15 @@ int acpi_bus_update_power(acpi_handle handle, int *state_p) | |||
338 | 343 | ||
339 | return 0; | 344 | return 0; |
340 | } | 345 | } |
346 | |||
347 | int acpi_bus_update_power(acpi_handle handle, int *state_p) | ||
348 | { | ||
349 | struct acpi_device *device; | ||
350 | int result; | ||
351 | |||
352 | result = acpi_bus_get_device(handle, &device); | ||
353 | return result ? result : acpi_device_update_power(device, state_p); | ||
354 | } | ||
341 | EXPORT_SYMBOL_GPL(acpi_bus_update_power); | 355 | EXPORT_SYMBOL_GPL(acpi_bus_update_power); |
342 | 356 | ||
343 | bool acpi_bus_power_manageable(acpi_handle handle) | 357 | bool acpi_bus_power_manageable(acpi_handle handle) |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index dcd73ccb514c..c431c88faaff 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -32,8 +32,8 @@ | |||
32 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
33 | #include <linux/stddef.h> | 33 | #include <linux/stddef.h> |
34 | #include <linux/acpi.h> | 34 | #include <linux/acpi.h> |
35 | #include <acpi/acpi_bus.h> | 35 | |
36 | #include <acpi/acpi_drivers.h> | 36 | #include "internal.h" |
37 | 37 | ||
38 | #define PREFIX "ACPI: " | 38 | #define PREFIX "ACPI: " |
39 | 39 | ||
@@ -323,14 +323,11 @@ static int dock_present(struct dock_station *ds) | |||
323 | */ | 323 | */ |
324 | static void dock_create_acpi_device(acpi_handle handle) | 324 | static void dock_create_acpi_device(acpi_handle handle) |
325 | { | 325 | { |
326 | struct acpi_device *device; | 326 | struct acpi_device *device = NULL; |
327 | int ret; | 327 | int ret; |
328 | 328 | ||
329 | if (acpi_bus_get_device(handle, &device)) { | 329 | acpi_bus_get_device(handle, &device); |
330 | /* | 330 | if (!acpi_device_enumerated(device)) { |
331 | * no device created for this object, | ||
332 | * so we should create one. | ||
333 | */ | ||
334 | ret = acpi_bus_scan(handle); | 331 | ret = acpi_bus_scan(handle); |
335 | if (ret) | 332 | if (ret) |
336 | pr_debug("error adding bus, %x\n", -ret); | 333 | pr_debug("error adding bus, %x\n", -ret); |
@@ -898,9 +895,6 @@ find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
898 | 895 | ||
899 | void __init acpi_dock_init(void) | 896 | void __init acpi_dock_init(void) |
900 | { | 897 | { |
901 | if (acpi_disabled) | ||
902 | return; | ||
903 | |||
904 | /* look for dock stations and bays */ | 898 | /* look for dock stations and bays */ |
905 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 899 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
906 | ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL); | 900 | ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ba5b56db9d27..959d41acc108 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -39,10 +39,9 @@ | |||
39 | #include <linux/list.h> | 39 | #include <linux/list.h> |
40 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <asm/io.h> | 42 | #include <linux/acpi.h> |
43 | #include <acpi/acpi_bus.h> | ||
44 | #include <acpi/acpi_drivers.h> | ||
45 | #include <linux/dmi.h> | 43 | #include <linux/dmi.h> |
44 | #include <asm/io.h> | ||
46 | 45 | ||
47 | #include "internal.h" | 46 | #include "internal.h" |
48 | 47 | ||
@@ -91,10 +90,6 @@ static unsigned int ec_storm_threshold __read_mostly = 8; | |||
91 | module_param(ec_storm_threshold, uint, 0644); | 90 | module_param(ec_storm_threshold, uint, 0644); |
92 | MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); | 91 | MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); |
93 | 92 | ||
94 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | ||
95 | /* External interfaces use first EC only, so remember */ | ||
96 | typedef int (*acpi_ec_query_func) (void *data); | ||
97 | |||
98 | struct acpi_ec_query_handler { | 93 | struct acpi_ec_query_handler { |
99 | struct list_head node; | 94 | struct list_head node; |
100 | acpi_ec_query_func func; | 95 | acpi_ec_query_func func; |
@@ -387,27 +382,6 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | |||
387 | return acpi_ec_transaction(ec, &t); | 382 | return acpi_ec_transaction(ec, &t); |
388 | } | 383 | } |
389 | 384 | ||
390 | /* | ||
391 | * Externally callable EC access functions. For now, assume 1 EC only | ||
392 | */ | ||
393 | int ec_burst_enable(void) | ||
394 | { | ||
395 | if (!first_ec) | ||
396 | return -ENODEV; | ||
397 | return acpi_ec_burst_enable(first_ec); | ||
398 | } | ||
399 | |||
400 | EXPORT_SYMBOL(ec_burst_enable); | ||
401 | |||
402 | int ec_burst_disable(void) | ||
403 | { | ||
404 | if (!first_ec) | ||
405 | return -ENODEV; | ||
406 | return acpi_ec_burst_disable(first_ec); | ||
407 | } | ||
408 | |||
409 | EXPORT_SYMBOL(ec_burst_disable); | ||
410 | |||
411 | int ec_read(u8 addr, u8 *val) | 385 | int ec_read(u8 addr, u8 *val) |
412 | { | 386 | { |
413 | int err; | 387 | int err; |
@@ -779,9 +753,9 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
779 | pr_err("Fail in evaluating the _REG object" | 753 | pr_err("Fail in evaluating the _REG object" |
780 | " of EC device. Broken bios is suspected.\n"); | 754 | " of EC device. Broken bios is suspected.\n"); |
781 | } else { | 755 | } else { |
756 | acpi_disable_gpe(NULL, ec->gpe); | ||
782 | acpi_remove_gpe_handler(NULL, ec->gpe, | 757 | acpi_remove_gpe_handler(NULL, ec->gpe, |
783 | &acpi_ec_gpe_handler); | 758 | &acpi_ec_gpe_handler); |
784 | acpi_disable_gpe(NULL, ec->gpe); | ||
785 | return -ENODEV; | 759 | return -ENODEV; |
786 | } | 760 | } |
787 | } | 761 | } |
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index 4e7b798900f2..b4c216bab22b 100644 --- a/drivers/acpi/ec_sys.c +++ b/drivers/acpi/ec_sys.c | |||
@@ -105,7 +105,7 @@ static const struct file_operations acpi_ec_io_ops = { | |||
105 | .llseek = default_llseek, | 105 | .llseek = default_llseek, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) | 108 | static int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) |
109 | { | 109 | { |
110 | struct dentry *dev_dir; | 110 | struct dentry *dev_dir; |
111 | char name[64]; | 111 | char name[64]; |
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index cae3b387b867..ef2d730734dc 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/poll.h> | 13 | #include <linux/poll.h> |
14 | #include <linux/gfp.h> | 14 | #include <linux/gfp.h> |
15 | #include <acpi/acpi_drivers.h> | 15 | #include <linux/acpi.h> |
16 | #include <net/netlink.h> | 16 | #include <net/netlink.h> |
17 | #include <net/genetlink.h> | 17 | #include <net/genetlink.h> |
18 | 18 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index ba3da88cee45..1fb62900f32a 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -29,8 +29,7 @@ | |||
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
31 | #include <linux/thermal.h> | 31 | #include <linux/thermal.h> |
32 | #include <acpi/acpi_bus.h> | 32 | #include <linux/acpi.h> |
33 | #include <acpi/acpi_drivers.h> | ||
34 | 33 | ||
35 | #define PREFIX "ACPI: " | 34 | #define PREFIX "ACPI: " |
36 | 35 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index a22a295edb69..0c789224d40d 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -37,7 +37,7 @@ int register_acpi_bus_type(struct acpi_bus_type *type) | |||
37 | { | 37 | { |
38 | if (acpi_disabled) | 38 | if (acpi_disabled) |
39 | return -ENODEV; | 39 | return -ENODEV; |
40 | if (type && type->match && type->find_device) { | 40 | if (type && type->match && type->find_companion) { |
41 | down_write(&bus_type_sem); | 41 | down_write(&bus_type_sem); |
42 | list_add_tail(&type->list, &bus_type_list); | 42 | list_add_tail(&type->list, &bus_type_list); |
43 | up_write(&bus_type_sem); | 43 | up_write(&bus_type_sem); |
@@ -82,109 +82,74 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) | |||
82 | #define FIND_CHILD_MIN_SCORE 1 | 82 | #define FIND_CHILD_MIN_SCORE 1 |
83 | #define FIND_CHILD_MAX_SCORE 2 | 83 | #define FIND_CHILD_MAX_SCORE 2 |
84 | 84 | ||
85 | static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used, | 85 | static int find_child_checks(struct acpi_device *adev, bool check_children) |
86 | void *not_used, void **ret_p) | ||
87 | { | ||
88 | struct acpi_device *adev = NULL; | ||
89 | |||
90 | acpi_bus_get_device(handle, &adev); | ||
91 | if (adev) { | ||
92 | *ret_p = handle; | ||
93 | return AE_CTRL_TERMINATE; | ||
94 | } | ||
95 | return AE_OK; | ||
96 | } | ||
97 | |||
98 | static int do_find_child_checks(acpi_handle handle, bool is_bridge) | ||
99 | { | 86 | { |
100 | bool sta_present = true; | 87 | bool sta_present = true; |
101 | unsigned long long sta; | 88 | unsigned long long sta; |
102 | acpi_status status; | 89 | acpi_status status; |
103 | 90 | ||
104 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | 91 | status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta); |
105 | if (status == AE_NOT_FOUND) | 92 | if (status == AE_NOT_FOUND) |
106 | sta_present = false; | 93 | sta_present = false; |
107 | else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) | 94 | else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) |
108 | return -ENODEV; | 95 | return -ENODEV; |
109 | 96 | ||
110 | if (is_bridge) { | 97 | if (check_children && list_empty(&adev->children)) |
111 | void *test = NULL; | 98 | return -ENODEV; |
112 | 99 | ||
113 | /* Check if this object has at least one child device. */ | ||
114 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, | ||
115 | acpi_dev_present, NULL, NULL, &test); | ||
116 | if (!test) | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE; | 100 | return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE; |
120 | } | 101 | } |
121 | 102 | ||
122 | struct find_child_context { | 103 | struct acpi_device *acpi_find_child_device(struct acpi_device *parent, |
123 | u64 addr; | 104 | u64 address, bool check_children) |
124 | bool is_bridge; | ||
125 | acpi_handle ret; | ||
126 | int ret_score; | ||
127 | }; | ||
128 | |||
129 | static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, | ||
130 | void *data, void **not_used) | ||
131 | { | ||
132 | struct find_child_context *context = data; | ||
133 | unsigned long long addr; | ||
134 | acpi_status status; | ||
135 | int score; | ||
136 | |||
137 | status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); | ||
138 | if (ACPI_FAILURE(status) || addr != context->addr) | ||
139 | return AE_OK; | ||
140 | |||
141 | if (!context->ret) { | ||
142 | /* This is the first matching object. Save its handle. */ | ||
143 | context->ret = handle; | ||
144 | return AE_OK; | ||
145 | } | ||
146 | /* | ||
147 | * There is more than one matching object with the same _ADR value. | ||
148 | * That really is unexpected, so we are kind of beyond the scope of the | ||
149 | * spec here. We have to choose which one to return, though. | ||
150 | * | ||
151 | * First, check if the previously found object is good enough and return | ||
152 | * its handle if so. Second, check the same for the object that we've | ||
153 | * just found. | ||
154 | */ | ||
155 | if (!context->ret_score) { | ||
156 | score = do_find_child_checks(context->ret, context->is_bridge); | ||
157 | if (score == FIND_CHILD_MAX_SCORE) | ||
158 | return AE_CTRL_TERMINATE; | ||
159 | else | ||
160 | context->ret_score = score; | ||
161 | } | ||
162 | score = do_find_child_checks(handle, context->is_bridge); | ||
163 | if (score == FIND_CHILD_MAX_SCORE) { | ||
164 | context->ret = handle; | ||
165 | return AE_CTRL_TERMINATE; | ||
166 | } else if (score > context->ret_score) { | ||
167 | context->ret = handle; | ||
168 | context->ret_score = score; | ||
169 | } | ||
170 | return AE_OK; | ||
171 | } | ||
172 | |||
173 | acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge) | ||
174 | { | 105 | { |
175 | if (parent) { | 106 | struct acpi_device *adev, *ret = NULL; |
176 | struct find_child_context context = { | 107 | int ret_score = 0; |
177 | .addr = addr, | 108 | |
178 | .is_bridge = is_bridge, | 109 | if (!parent) |
179 | }; | 110 | return NULL; |
180 | 111 | ||
181 | acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, do_find_child, | 112 | list_for_each_entry(adev, &parent->children, node) { |
182 | NULL, &context, NULL); | 113 | unsigned long long addr; |
183 | return context.ret; | 114 | acpi_status status; |
115 | int score; | ||
116 | |||
117 | status = acpi_evaluate_integer(adev->handle, METHOD_NAME__ADR, | ||
118 | NULL, &addr); | ||
119 | if (ACPI_FAILURE(status) || addr != address) | ||
120 | continue; | ||
121 | |||
122 | if (!ret) { | ||
123 | /* This is the first matching object. Save it. */ | ||
124 | ret = adev; | ||
125 | continue; | ||
126 | } | ||
127 | /* | ||
128 | * There is more than one matching device object with the same | ||
129 | * _ADR value. That really is unexpected, so we are kind of | ||
130 | * beyond the scope of the spec here. We have to choose which | ||
131 | * one to return, though. | ||
132 | * | ||
133 | * First, check if the previously found object is good enough | ||
134 | * and return it if so. Second, do the same for the object that | ||
135 | * we've just found. | ||
136 | */ | ||
137 | if (!ret_score) { | ||
138 | ret_score = find_child_checks(ret, check_children); | ||
139 | if (ret_score == FIND_CHILD_MAX_SCORE) | ||
140 | return ret; | ||
141 | } | ||
142 | score = find_child_checks(adev, check_children); | ||
143 | if (score == FIND_CHILD_MAX_SCORE) { | ||
144 | return adev; | ||
145 | } else if (score > ret_score) { | ||
146 | ret = adev; | ||
147 | ret_score = score; | ||
148 | } | ||
184 | } | 149 | } |
185 | return NULL; | 150 | return ret; |
186 | } | 151 | } |
187 | EXPORT_SYMBOL_GPL(acpi_find_child); | 152 | EXPORT_SYMBOL_GPL(acpi_find_child_device); |
188 | 153 | ||
189 | static void acpi_physnode_link_name(char *buf, unsigned int node_id) | 154 | static void acpi_physnode_link_name(char *buf, unsigned int node_id) |
190 | { | 155 | { |
@@ -195,9 +160,8 @@ static void acpi_physnode_link_name(char *buf, unsigned int node_id) | |||
195 | strcpy(buf, PHYSICAL_NODE_STRING); | 160 | strcpy(buf, PHYSICAL_NODE_STRING); |
196 | } | 161 | } |
197 | 162 | ||
198 | int acpi_bind_one(struct device *dev, acpi_handle handle) | 163 | int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) |
199 | { | 164 | { |
200 | struct acpi_device *acpi_dev = NULL; | ||
201 | struct acpi_device_physical_node *physical_node, *pn; | 165 | struct acpi_device_physical_node *physical_node, *pn; |
202 | char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; | 166 | char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; |
203 | struct list_head *physnode_list; | 167 | struct list_head *physnode_list; |
@@ -205,14 +169,12 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
205 | int retval = -EINVAL; | 169 | int retval = -EINVAL; |
206 | 170 | ||
207 | if (ACPI_COMPANION(dev)) { | 171 | if (ACPI_COMPANION(dev)) { |
208 | if (handle) { | 172 | if (acpi_dev) { |
209 | dev_warn(dev, "ACPI companion already set\n"); | 173 | dev_warn(dev, "ACPI companion already set\n"); |
210 | return -EINVAL; | 174 | return -EINVAL; |
211 | } else { | 175 | } else { |
212 | acpi_dev = ACPI_COMPANION(dev); | 176 | acpi_dev = ACPI_COMPANION(dev); |
213 | } | 177 | } |
214 | } else { | ||
215 | acpi_bus_get_device(handle, &acpi_dev); | ||
216 | } | 178 | } |
217 | if (!acpi_dev) | 179 | if (!acpi_dev) |
218 | return -EINVAL; | 180 | return -EINVAL; |
@@ -322,29 +284,22 @@ int acpi_unbind_one(struct device *dev) | |||
322 | } | 284 | } |
323 | EXPORT_SYMBOL_GPL(acpi_unbind_one); | 285 | EXPORT_SYMBOL_GPL(acpi_unbind_one); |
324 | 286 | ||
325 | void acpi_preset_companion(struct device *dev, acpi_handle parent, u64 addr) | ||
326 | { | ||
327 | struct acpi_device *adev; | ||
328 | |||
329 | if (!acpi_bus_get_device(acpi_get_child(parent, addr), &adev)) | ||
330 | ACPI_COMPANION_SET(dev, adev); | ||
331 | } | ||
332 | EXPORT_SYMBOL_GPL(acpi_preset_companion); | ||
333 | |||
334 | static int acpi_platform_notify(struct device *dev) | 287 | static int acpi_platform_notify(struct device *dev) |
335 | { | 288 | { |
336 | struct acpi_bus_type *type = acpi_get_bus_type(dev); | 289 | struct acpi_bus_type *type = acpi_get_bus_type(dev); |
337 | acpi_handle handle; | ||
338 | int ret; | 290 | int ret; |
339 | 291 | ||
340 | ret = acpi_bind_one(dev, NULL); | 292 | ret = acpi_bind_one(dev, NULL); |
341 | if (ret && type) { | 293 | if (ret && type) { |
342 | ret = type->find_device(dev, &handle); | 294 | struct acpi_device *adev; |
343 | if (ret) { | 295 | |
296 | adev = type->find_companion(dev); | ||
297 | if (!adev) { | ||
344 | DBG("Unable to get handle for %s\n", dev_name(dev)); | 298 | DBG("Unable to get handle for %s\n", dev_name(dev)); |
299 | ret = -ENODEV; | ||
345 | goto out; | 300 | goto out; |
346 | } | 301 | } |
347 | ret = acpi_bind_one(dev, handle); | 302 | ret = acpi_bind_one(dev, adev); |
348 | if (ret) | 303 | if (ret) |
349 | goto out; | 304 | goto out; |
350 | } | 305 | } |
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index 13b1d39d7cdf..aafe3ca829c2 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
28 | #include <acpi/acpi_bus.h> | ||
29 | #include <acpi/acpi_drivers.h> | ||
30 | #include <acpi/hed.h> | 28 | #include <acpi/hed.h> |
31 | 29 | ||
32 | static struct acpi_device_id acpi_hed_ids[] = { | 30 | static struct acpi_device_id acpi_hed_ids[] = { |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index a29739c0ba79..dedbb2d802f1 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -28,7 +28,6 @@ int init_acpi_device_notify(void); | |||
28 | int acpi_scan_init(void); | 28 | int acpi_scan_init(void); |
29 | void acpi_pci_root_init(void); | 29 | void acpi_pci_root_init(void); |
30 | void acpi_pci_link_init(void); | 30 | void acpi_pci_link_init(void); |
31 | void acpi_pci_root_hp_init(void); | ||
32 | void acpi_processor_init(void); | 31 | void acpi_processor_init(void); |
33 | void acpi_platform_init(void); | 32 | void acpi_platform_init(void); |
34 | int acpi_sysfs_init(void); | 33 | int acpi_sysfs_init(void); |
@@ -73,6 +72,9 @@ void acpi_lpss_init(void); | |||
73 | static inline void acpi_lpss_init(void) {} | 72 | static inline void acpi_lpss_init(void) {} |
74 | #endif | 73 | #endif |
75 | 74 | ||
75 | bool acpi_queue_hotplug_work(struct work_struct *work); | ||
76 | bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent); | ||
77 | |||
76 | /* -------------------------------------------------------------------------- | 78 | /* -------------------------------------------------------------------------- |
77 | Device Node Initialization / Removal | 79 | Device Node Initialization / Removal |
78 | -------------------------------------------------------------------------- */ | 80 | -------------------------------------------------------------------------- */ |
@@ -85,9 +87,9 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, | |||
85 | int type, unsigned long long sta); | 87 | int type, unsigned long long sta); |
86 | void acpi_device_add_finalize(struct acpi_device *device); | 88 | void acpi_device_add_finalize(struct acpi_device *device); |
87 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); | 89 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); |
88 | int acpi_bind_one(struct device *dev, acpi_handle handle); | 90 | int acpi_bind_one(struct device *dev, struct acpi_device *adev); |
89 | int acpi_unbind_one(struct device *dev); | 91 | int acpi_unbind_one(struct device *dev); |
90 | void acpi_bus_device_eject(void *data, u32 ost_src); | 92 | bool acpi_device_is_present(struct acpi_device *adev); |
91 | 93 | ||
92 | /* -------------------------------------------------------------------------- | 94 | /* -------------------------------------------------------------------------- |
93 | Power Resource | 95 | Power Resource |
@@ -105,6 +107,8 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state); | |||
105 | int acpi_power_on_resources(struct acpi_device *device, int state); | 107 | int acpi_power_on_resources(struct acpi_device *device, int state); |
106 | int acpi_power_transition(struct acpi_device *device, int state); | 108 | int acpi_power_transition(struct acpi_device *device, int state); |
107 | 109 | ||
110 | int acpi_device_update_power(struct acpi_device *device, int *state_p); | ||
111 | |||
108 | int acpi_wakeup_device_init(void); | 112 | int acpi_wakeup_device_init(void); |
109 | void acpi_early_processor_set_pdc(void); | 113 | void acpi_early_processor_set_pdc(void); |
110 | 114 | ||
@@ -127,12 +131,21 @@ struct acpi_ec { | |||
127 | 131 | ||
128 | extern struct acpi_ec *first_ec; | 132 | extern struct acpi_ec *first_ec; |
129 | 133 | ||
134 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | ||
135 | /* External interfaces use first EC only, so remember */ | ||
136 | typedef int (*acpi_ec_query_func) (void *data); | ||
137 | |||
130 | int acpi_ec_init(void); | 138 | int acpi_ec_init(void); |
131 | int acpi_ec_ecdt_probe(void); | 139 | int acpi_ec_ecdt_probe(void); |
132 | int acpi_boot_ec_enable(void); | 140 | int acpi_boot_ec_enable(void); |
133 | void acpi_ec_block_transactions(void); | 141 | void acpi_ec_block_transactions(void); |
134 | void acpi_ec_unblock_transactions(void); | 142 | void acpi_ec_unblock_transactions(void); |
135 | void acpi_ec_unblock_transactions_early(void); | 143 | void acpi_ec_unblock_transactions_early(void); |
144 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | ||
145 | acpi_handle handle, acpi_ec_query_func func, | ||
146 | void *data); | ||
147 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); | ||
148 | |||
136 | 149 | ||
137 | /*-------------------------------------------------------------------------- | 150 | /*-------------------------------------------------------------------------- |
138 | Suspend/Resume | 151 | Suspend/Resume |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index a2343a1d9e0b..9e6816ef280a 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/acpi.h> | 30 | #include <linux/acpi.h> |
31 | #include <linux/numa.h> | 31 | #include <linux/numa.h> |
32 | #include <acpi/acpi_bus.h> | ||
33 | 32 | ||
34 | #define PREFIX "ACPI: " | 33 | #define PREFIX "ACPI: " |
35 | 34 | ||
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c index 386a9fe497b4..de4fe03873c5 100644 --- a/drivers/acpi/nvs.c +++ b/drivers/acpi/nvs.c | |||
@@ -12,7 +12,8 @@ | |||
12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/acpi_io.h> | 15 | |
16 | #include "internal.h" | ||
16 | 17 | ||
17 | /* ACPI NVS regions, APEI may use it */ | 18 | /* ACPI NVS regions, APEI may use it */ |
18 | 19 | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 54a20ff4b864..fc1aa7909690 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
40 | #include <linux/nmi.h> | 40 | #include <linux/nmi.h> |
41 | #include <linux/acpi.h> | 41 | #include <linux/acpi.h> |
42 | #include <linux/acpi_io.h> | ||
43 | #include <linux/efi.h> | 42 | #include <linux/efi.h> |
44 | #include <linux/ioport.h> | 43 | #include <linux/ioport.h> |
45 | #include <linux/list.h> | 44 | #include <linux/list.h> |
@@ -49,9 +48,6 @@ | |||
49 | #include <asm/io.h> | 48 | #include <asm/io.h> |
50 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
51 | 50 | ||
52 | #include <acpi/acpi.h> | ||
53 | #include <acpi/acpi_bus.h> | ||
54 | #include <acpi/processor.h> | ||
55 | #include "internal.h" | 51 | #include "internal.h" |
56 | 52 | ||
57 | #define _COMPONENT ACPI_OS_SERVICES | 53 | #define _COMPONENT ACPI_OS_SERVICES |
@@ -544,7 +540,7 @@ static u64 acpi_tables_addr; | |||
544 | static int all_tables_size; | 540 | static int all_tables_size; |
545 | 541 | ||
546 | /* Copied from acpica/tbutils.c:acpi_tb_checksum() */ | 542 | /* Copied from acpica/tbutils.c:acpi_tb_checksum() */ |
547 | u8 __init acpi_table_checksum(u8 *buffer, u32 length) | 543 | static u8 __init acpi_table_checksum(u8 *buffer, u32 length) |
548 | { | 544 | { |
549 | u8 sum = 0; | 545 | u8 sum = 0; |
550 | u8 *end = buffer + length; | 546 | u8 *end = buffer + length; |
@@ -1215,6 +1211,10 @@ acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src) | |||
1215 | return AE_OK; | 1211 | return AE_OK; |
1216 | } | 1212 | } |
1217 | 1213 | ||
1214 | bool acpi_queue_hotplug_work(struct work_struct *work) | ||
1215 | { | ||
1216 | return queue_work(kacpi_hotplug_wq, work); | ||
1217 | } | ||
1218 | 1218 | ||
1219 | acpi_status | 1219 | acpi_status |
1220 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) | 1220 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) |
@@ -1282,7 +1282,7 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) | |||
1282 | jiffies = MAX_SCHEDULE_TIMEOUT; | 1282 | jiffies = MAX_SCHEDULE_TIMEOUT; |
1283 | else | 1283 | else |
1284 | jiffies = msecs_to_jiffies(timeout); | 1284 | jiffies = msecs_to_jiffies(timeout); |
1285 | 1285 | ||
1286 | ret = down_timeout(sem, jiffies); | 1286 | ret = down_timeout(sem, jiffies); |
1287 | if (ret) | 1287 | if (ret) |
1288 | status = AE_TIME; | 1288 | status = AE_TIME; |
@@ -1794,7 +1794,7 @@ acpi_status __init acpi_os_initialize1(void) | |||
1794 | { | 1794 | { |
1795 | kacpid_wq = alloc_workqueue("kacpid", 0, 1); | 1795 | kacpid_wq = alloc_workqueue("kacpid", 0, 1); |
1796 | kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); | 1796 | kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); |
1797 | kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1); | 1797 | kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0); |
1798 | BUG_ON(!kacpid_wq); | 1798 | BUG_ON(!kacpid_wq); |
1799 | BUG_ON(!kacpi_notify_wq); | 1799 | BUG_ON(!kacpi_notify_wq); |
1800 | BUG_ON(!kacpi_hotplug_wq); | 1800 | BUG_ON(!kacpi_hotplug_wq); |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 41c5e1b799ef..52d45ea2bc4f 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <acpi/acpi_bus.h> | ||
41 | #include <acpi/acpi_drivers.h> | ||
42 | 40 | ||
43 | #define PREFIX "ACPI: " | 41 | #define PREFIX "ACPI: " |
44 | 42 | ||
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 2652a614deeb..9418c7a1f786 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -39,9 +39,9 @@ | |||
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/acpi.h> | ||
42 | 43 | ||
43 | #include <acpi/acpi_bus.h> | 44 | #include "internal.h" |
44 | #include <acpi/acpi_drivers.h> | ||
45 | 45 | ||
46 | #define PREFIX "ACPI: " | 46 | #define PREFIX "ACPI: " |
47 | 47 | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 5b01bd6d5ea0..c1c4102e6478 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -35,9 +35,7 @@ | |||
35 | #include <linux/pci-aspm.h> | 35 | #include <linux/pci-aspm.h> |
36 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <acpi/acpi_bus.h> | 38 | #include <acpi/apei.h> /* for acpi_hest_init() */ |
39 | #include <acpi/acpi_drivers.h> | ||
40 | #include <acpi/apei.h> | ||
41 | 39 | ||
42 | #include "internal.h" | 40 | #include "internal.h" |
43 | 41 | ||
@@ -51,6 +49,12 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
51 | const struct acpi_device_id *not_used); | 49 | const struct acpi_device_id *not_used); |
52 | static void acpi_pci_root_remove(struct acpi_device *device); | 50 | static void acpi_pci_root_remove(struct acpi_device *device); |
53 | 51 | ||
52 | static int acpi_pci_root_scan_dependent(struct acpi_device *adev) | ||
53 | { | ||
54 | acpiphp_check_host_bridge(adev->handle); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
54 | #define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \ | 58 | #define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \ |
55 | | OSC_PCI_ASPM_SUPPORT \ | 59 | | OSC_PCI_ASPM_SUPPORT \ |
56 | | OSC_PCI_CLOCK_PM_SUPPORT \ | 60 | | OSC_PCI_CLOCK_PM_SUPPORT \ |
@@ -66,7 +70,8 @@ static struct acpi_scan_handler pci_root_handler = { | |||
66 | .attach = acpi_pci_root_add, | 70 | .attach = acpi_pci_root_add, |
67 | .detach = acpi_pci_root_remove, | 71 | .detach = acpi_pci_root_remove, |
68 | .hotplug = { | 72 | .hotplug = { |
69 | .ignore = true, | 73 | .enabled = true, |
74 | .scan_dependent = acpi_pci_root_scan_dependent, | ||
70 | }, | 75 | }, |
71 | }; | 76 | }; |
72 | 77 | ||
@@ -630,116 +635,9 @@ static void acpi_pci_root_remove(struct acpi_device *device) | |||
630 | void __init acpi_pci_root_init(void) | 635 | void __init acpi_pci_root_init(void) |
631 | { | 636 | { |
632 | acpi_hest_init(); | 637 | acpi_hest_init(); |
633 | 638 | if (acpi_pci_disabled) | |
634 | if (!acpi_pci_disabled) { | ||
635 | pci_acpi_crs_quirks(); | ||
636 | acpi_scan_add_handler(&pci_root_handler); | ||
637 | } | ||
638 | } | ||
639 | /* Support root bridge hotplug */ | ||
640 | |||
641 | static void handle_root_bridge_insertion(acpi_handle handle) | ||
642 | { | ||
643 | struct acpi_device *device; | ||
644 | |||
645 | if (!acpi_bus_get_device(handle, &device)) { | ||
646 | dev_printk(KERN_DEBUG, &device->dev, | ||
647 | "acpi device already exists; ignoring notify\n"); | ||
648 | return; | 639 | return; |
649 | } | ||
650 | |||
651 | if (acpi_bus_scan(handle)) | ||
652 | acpi_handle_err(handle, "cannot add bridge to acpi list\n"); | ||
653 | } | ||
654 | |||
655 | static void hotplug_event_root(void *data, u32 type) | ||
656 | { | ||
657 | acpi_handle handle = data; | ||
658 | struct acpi_pci_root *root; | ||
659 | |||
660 | acpi_scan_lock_acquire(); | ||
661 | |||
662 | root = acpi_pci_find_root(handle); | ||
663 | |||
664 | switch (type) { | ||
665 | case ACPI_NOTIFY_BUS_CHECK: | ||
666 | /* bus enumerate */ | ||
667 | acpi_handle_printk(KERN_DEBUG, handle, | ||
668 | "Bus check notify on %s\n", __func__); | ||
669 | if (root) | ||
670 | acpiphp_check_host_bridge(handle); | ||
671 | else | ||
672 | handle_root_bridge_insertion(handle); | ||
673 | |||
674 | break; | ||
675 | |||
676 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
677 | /* device check */ | ||
678 | acpi_handle_printk(KERN_DEBUG, handle, | ||
679 | "Device check notify on %s\n", __func__); | ||
680 | if (!root) | ||
681 | handle_root_bridge_insertion(handle); | ||
682 | break; | ||
683 | |||
684 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
685 | /* request device eject */ | ||
686 | acpi_handle_printk(KERN_DEBUG, handle, | ||
687 | "Device eject notify on %s\n", __func__); | ||
688 | if (!root) | ||
689 | break; | ||
690 | |||
691 | get_device(&root->device->dev); | ||
692 | |||
693 | acpi_scan_lock_release(); | ||
694 | |||
695 | acpi_bus_device_eject(root->device, ACPI_NOTIFY_EJECT_REQUEST); | ||
696 | return; | ||
697 | default: | ||
698 | acpi_handle_warn(handle, | ||
699 | "notify_handler: unknown event type 0x%x\n", | ||
700 | type); | ||
701 | break; | ||
702 | } | ||
703 | |||
704 | acpi_scan_lock_release(); | ||
705 | } | ||
706 | |||
707 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, | ||
708 | void *context) | ||
709 | { | ||
710 | acpi_hotplug_execute(hotplug_event_root, handle, type); | ||
711 | } | ||
712 | |||
713 | static acpi_status __init | ||
714 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
715 | { | ||
716 | acpi_status status; | ||
717 | int *count = (int *)context; | ||
718 | |||
719 | if (!acpi_is_root_bridge(handle)) | ||
720 | return AE_OK; | ||
721 | |||
722 | (*count)++; | ||
723 | |||
724 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
725 | handle_hotplug_event_root, NULL); | ||
726 | if (ACPI_FAILURE(status)) | ||
727 | acpi_handle_printk(KERN_DEBUG, handle, | ||
728 | "notify handler is not installed, exit status: %u\n", | ||
729 | (unsigned int)status); | ||
730 | else | ||
731 | acpi_handle_printk(KERN_DEBUG, handle, | ||
732 | "notify handler is installed\n"); | ||
733 | |||
734 | return AE_OK; | ||
735 | } | ||
736 | |||
737 | void __init acpi_pci_root_hp_init(void) | ||
738 | { | ||
739 | int num = 0; | ||
740 | |||
741 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
742 | ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL); | ||
743 | 640 | ||
744 | printk(KERN_DEBUG "Found %d acpi root devices\n", num); | 641 | pci_acpi_crs_quirks(); |
642 | acpi_scan_add_handler_with_hotplug(&pci_root_handler, "pci_root"); | ||
745 | } | 643 | } |
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index d678a180ca2a..139d9e479370 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
37 | #include <linux/dmi.h> | 37 | #include <linux/dmi.h> |
38 | #include <linux/pci-acpi.h> | ||
38 | 39 | ||
39 | static bool debug; | 40 | static bool debug; |
40 | static int check_sta_before_sun; | 41 | static int check_sta_before_sun; |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index c2ad391d8041..ad7da686e6e6 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -42,8 +42,7 @@ | |||
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/pm_runtime.h> | 43 | #include <linux/pm_runtime.h> |
44 | #include <linux/sysfs.h> | 44 | #include <linux/sysfs.h> |
45 | #include <acpi/acpi_bus.h> | 45 | #include <linux/acpi.h> |
46 | #include <acpi/acpi_drivers.h> | ||
47 | #include "sleep.h" | 46 | #include "sleep.h" |
48 | #include "internal.h" | 47 | #include "internal.h" |
49 | 48 | ||
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 6a5b152ad4d0..50fe34ffe932 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -3,12 +3,11 @@ | |||
3 | #include <linux/export.h> | 3 | #include <linux/export.h> |
4 | #include <linux/suspend.h> | 4 | #include <linux/suspend.h> |
5 | #include <linux/bcd.h> | 5 | #include <linux/bcd.h> |
6 | #include <linux/acpi.h> | ||
6 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
7 | 8 | ||
8 | #include <acpi/acpi_bus.h> | ||
9 | #include <acpi/acpi_drivers.h> | ||
10 | |||
11 | #include "sleep.h" | 9 | #include "sleep.h" |
10 | #include "internal.h" | ||
12 | 11 | ||
13 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 12 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
14 | 13 | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index b3171f30b319..34e7b3c6a08d 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -10,8 +10,7 @@ | |||
10 | #include <linux/export.h> | 10 | #include <linux/export.h> |
11 | #include <linux/dmi.h> | 11 | #include <linux/dmi.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | 13 | #include <linux/acpi.h> | |
14 | #include <acpi/acpi_drivers.h> | ||
15 | #include <acpi/processor.h> | 14 | #include <acpi/processor.h> |
16 | 15 | ||
17 | #include "internal.h" | 16 | #include "internal.h" |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 146ab7e2b81d..c1c35623550f 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -224,9 +224,9 @@ static int __acpi_processor_start(struct acpi_device *device) | |||
224 | 224 | ||
225 | static int acpi_processor_start(struct device *dev) | 225 | static int acpi_processor_start(struct device *dev) |
226 | { | 226 | { |
227 | struct acpi_device *device; | 227 | struct acpi_device *device = ACPI_COMPANION(dev); |
228 | 228 | ||
229 | if (acpi_bus_get_device(ACPI_HANDLE(dev), &device)) | 229 | if (!device) |
230 | return -ENODEV; | 230 | return -ENODEV; |
231 | 231 | ||
232 | return __acpi_processor_start(device); | 232 | return __acpi_processor_start(device); |
@@ -234,10 +234,10 @@ static int acpi_processor_start(struct device *dev) | |||
234 | 234 | ||
235 | static int acpi_processor_stop(struct device *dev) | 235 | static int acpi_processor_stop(struct device *dev) |
236 | { | 236 | { |
237 | struct acpi_device *device; | 237 | struct acpi_device *device = ACPI_COMPANION(dev); |
238 | struct acpi_processor *pr; | 238 | struct acpi_processor *pr; |
239 | 239 | ||
240 | if (acpi_bus_get_device(ACPI_HANDLE(dev), &device)) | 240 | if (!device) |
241 | return 0; | 241 | return 0; |
242 | 242 | ||
243 | acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, | 243 | acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f90c56c8379e..3dca36d4ad26 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/clockchips.h> | 35 | #include <linux/clockchips.h> |
36 | #include <linux/cpuidle.h> | 36 | #include <linux/cpuidle.h> |
37 | #include <linux/syscore_ops.h> | 37 | #include <linux/syscore_ops.h> |
38 | #include <acpi/processor.h> | ||
38 | 39 | ||
39 | /* | 40 | /* |
40 | * Include the apic definitions for x86 to have the APIC timer related defines | 41 | * Include the apic definitions for x86 to have the APIC timer related defines |
@@ -46,9 +47,6 @@ | |||
46 | #include <asm/apic.h> | 47 | #include <asm/apic.h> |
47 | #endif | 48 | #endif |
48 | 49 | ||
49 | #include <acpi/acpi_bus.h> | ||
50 | #include <acpi/processor.h> | ||
51 | |||
52 | #define PREFIX "ACPI: " | 50 | #define PREFIX "ACPI: " |
53 | 51 | ||
54 | #define ACPI_PROCESSOR_CLASS "processor" | 52 | #define ACPI_PROCESSOR_CLASS "processor" |
@@ -213,7 +211,7 @@ static int acpi_processor_suspend(void) | |||
213 | 211 | ||
214 | static void acpi_processor_resume(void) | 212 | static void acpi_processor_resume(void) |
215 | { | 213 | { |
216 | u32 resumed_bm_rld; | 214 | u32 resumed_bm_rld = 0; |
217 | 215 | ||
218 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); | 216 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); |
219 | if (resumed_bm_rld == saved_bm_rld) | 217 | if (resumed_bm_rld == saved_bm_rld) |
@@ -598,7 +596,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
598 | case ACPI_STATE_C2: | 596 | case ACPI_STATE_C2: |
599 | if (!cx->address) | 597 | if (!cx->address) |
600 | break; | 598 | break; |
601 | cx->valid = 1; | 599 | cx->valid = 1; |
602 | break; | 600 | break; |
603 | 601 | ||
604 | case ACPI_STATE_C3: | 602 | case ACPI_STATE_C3: |
@@ -780,6 +778,13 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
780 | if (unlikely(!pr)) | 778 | if (unlikely(!pr)) |
781 | return -EINVAL; | 779 | return -EINVAL; |
782 | 780 | ||
781 | #ifdef CONFIG_HOTPLUG_CPU | ||
782 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && | ||
783 | !pr->flags.has_cst && | ||
784 | !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) | ||
785 | return acpi_idle_enter_c1(dev, drv, CPUIDLE_DRIVER_STATE_START); | ||
786 | #endif | ||
787 | |||
783 | /* | 788 | /* |
784 | * Must be done before busmaster disable as we might need to | 789 | * Must be done before busmaster disable as we might need to |
785 | * access HPET ! | 790 | * access HPET ! |
@@ -821,6 +826,13 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
821 | if (unlikely(!pr)) | 826 | if (unlikely(!pr)) |
822 | return -EINVAL; | 827 | return -EINVAL; |
823 | 828 | ||
829 | #ifdef CONFIG_HOTPLUG_CPU | ||
830 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && | ||
831 | !pr->flags.has_cst && | ||
832 | !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) | ||
833 | return acpi_idle_enter_c1(dev, drv, CPUIDLE_DRIVER_STATE_START); | ||
834 | #endif | ||
835 | |||
824 | if (!cx->bm_sts_skip && acpi_idle_bm_check()) { | 836 | if (!cx->bm_sts_skip && acpi_idle_bm_check()) { |
825 | if (drv->safe_state_index >= 0) { | 837 | if (drv->safe_state_index >= 0) { |
826 | return drv->states[drv->safe_state_index].enter(dev, | 838 | return drv->states[drv->safe_state_index].enter(dev, |
@@ -917,12 +929,6 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, | |||
917 | if (!cx->valid) | 929 | if (!cx->valid) |
918 | continue; | 930 | continue; |
919 | 931 | ||
920 | #ifdef CONFIG_HOTPLUG_CPU | ||
921 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && | ||
922 | !pr->flags.has_cst && | ||
923 | !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) | ||
924 | continue; | ||
925 | #endif | ||
926 | per_cpu(acpi_cstate[count], dev->cpu) = cx; | 932 | per_cpu(acpi_cstate[count], dev->cpu) = cx; |
927 | 933 | ||
928 | count++; | 934 | count++; |
@@ -930,8 +936,6 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, | |||
930 | break; | 936 | break; |
931 | } | 937 | } |
932 | 938 | ||
933 | dev->state_count = count; | ||
934 | |||
935 | if (!count) | 939 | if (!count) |
936 | return -EINVAL; | 940 | return -EINVAL; |
937 | 941 | ||
@@ -972,13 +976,6 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) | |||
972 | if (!cx->valid) | 976 | if (!cx->valid) |
973 | continue; | 977 | continue; |
974 | 978 | ||
975 | #ifdef CONFIG_HOTPLUG_CPU | ||
976 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && | ||
977 | !pr->flags.has_cst && | ||
978 | !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) | ||
979 | continue; | ||
980 | #endif | ||
981 | |||
982 | state = &drv->states[count]; | 979 | state = &drv->states[count]; |
983 | snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); | 980 | snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); |
984 | strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); | 981 | strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 60a7c28fc167..ff90054f04fd 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -31,15 +31,12 @@ | |||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/cpufreq.h> | 32 | #include <linux/cpufreq.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | 34 | #include <linux/acpi.h> | |
35 | #include <acpi/processor.h> | ||
35 | #ifdef CONFIG_X86 | 36 | #ifdef CONFIG_X86 |
36 | #include <asm/cpufeature.h> | 37 | #include <asm/cpufeature.h> |
37 | #endif | 38 | #endif |
38 | 39 | ||
39 | #include <acpi/acpi_bus.h> | ||
40 | #include <acpi/acpi_drivers.h> | ||
41 | #include <acpi/processor.h> | ||
42 | |||
43 | #define PREFIX "ACPI: " | 40 | #define PREFIX "ACPI: " |
44 | 41 | ||
45 | #define ACPI_PROCESSOR_CLASS "processor" | 42 | #define ACPI_PROCESSOR_CLASS "processor" |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index d1d2e7fb5b30..e003663b2f8e 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -30,12 +30,9 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/cpufreq.h> | 32 | #include <linux/cpufreq.h> |
33 | 33 | #include <linux/acpi.h> | |
34 | #include <asm/uaccess.h> | ||
35 | |||
36 | #include <acpi/acpi_bus.h> | ||
37 | #include <acpi/processor.h> | 34 | #include <acpi/processor.h> |
38 | #include <acpi/acpi_drivers.h> | 35 | #include <asm/uaccess.h> |
39 | 36 | ||
40 | #define PREFIX "ACPI: " | 37 | #define PREFIX "ACPI: " |
41 | 38 | ||
@@ -186,14 +183,14 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) | |||
186 | 183 | ||
187 | #endif | 184 | #endif |
188 | 185 | ||
189 | /* thermal coolign device callbacks */ | 186 | /* thermal cooling device callbacks */ |
190 | static int acpi_processor_max_state(struct acpi_processor *pr) | 187 | static int acpi_processor_max_state(struct acpi_processor *pr) |
191 | { | 188 | { |
192 | int max_state = 0; | 189 | int max_state = 0; |
193 | 190 | ||
194 | /* | 191 | /* |
195 | * There exists four states according to | 192 | * There exists four states according to |
196 | * cpufreq_thermal_reduction_ptg. 0, 1, 2, 3 | 193 | * cpufreq_thermal_reduction_pctg. 0, 1, 2, 3 |
197 | */ | 194 | */ |
198 | max_state += cpufreq_get_max_state(pr->id); | 195 | max_state += cpufreq_get_max_state(pr->id); |
199 | if (pr->flags.throttling) | 196 | if (pr->flags.throttling) |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index e7dd2c1fee79..28baa05b8018 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -32,14 +32,11 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/cpufreq.h> | 34 | #include <linux/cpufreq.h> |
35 | 35 | #include <linux/acpi.h> | |
36 | #include <acpi/processor.h> | ||
36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | 39 | ||
39 | #include <acpi/acpi_bus.h> | ||
40 | #include <acpi/acpi_drivers.h> | ||
41 | #include <acpi/processor.h> | ||
42 | |||
43 | #define PREFIX "ACPI: " | 40 | #define PREFIX "ACPI: " |
44 | 41 | ||
45 | #define ACPI_PROCESSOR_CLASS "processor" | 42 | #define ACPI_PROCESSOR_CLASS "processor" |
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index b78bc605837e..26e5b5060523 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c | |||
@@ -8,8 +8,7 @@ | |||
8 | * the Free Software Foundation version 2. | 8 | * the Free Software Foundation version 2. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <acpi/acpi_bus.h> | 11 | #include <linux/acpi.h> |
12 | #include <acpi/acpi_drivers.h> | ||
13 | #include <linux/wait.h> | 12 | #include <linux/wait.h> |
14 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
15 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fd39459926b1..e00365ccb897 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -12,13 +12,12 @@ | |||
12 | #include <linux/dmi.h> | 12 | #include <linux/dmi.h> |
13 | #include <linux/nls.h> | 13 | #include <linux/nls.h> |
14 | 14 | ||
15 | #include <acpi/acpi_drivers.h> | 15 | #include <asm/pgtable.h> |
16 | 16 | ||
17 | #include "internal.h" | 17 | #include "internal.h" |
18 | 18 | ||
19 | #define _COMPONENT ACPI_BUS_COMPONENT | 19 | #define _COMPONENT ACPI_BUS_COMPONENT |
20 | ACPI_MODULE_NAME("scan"); | 20 | ACPI_MODULE_NAME("scan"); |
21 | #define STRUCT_TO_INT(s) (*((int*)&s)) | ||
22 | extern struct acpi_device *acpi_root; | 21 | extern struct acpi_device *acpi_root; |
23 | 22 | ||
24 | #define ACPI_BUS_CLASS "system_bus" | 23 | #define ACPI_BUS_CLASS "system_bus" |
@@ -27,6 +26,8 @@ extern struct acpi_device *acpi_root; | |||
27 | 26 | ||
28 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) | 27 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
29 | 28 | ||
29 | #define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page) | ||
30 | |||
30 | /* | 31 | /* |
31 | * If set, devices will be hot-removed even if they cannot be put offline | 32 | * If set, devices will be hot-removed even if they cannot be put offline |
32 | * gracefully (from the kernel's standpoint). | 33 | * gracefully (from the kernel's standpoint). |
@@ -85,6 +86,9 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, | |||
85 | * Creates hid/cid(s) string needed for modalias and uevent | 86 | * Creates hid/cid(s) string needed for modalias and uevent |
86 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: | 87 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: |
87 | * char *modalias: "acpi:IBM0001:ACPI0001" | 88 | * char *modalias: "acpi:IBM0001:ACPI0001" |
89 | * Return: 0: no _HID and no _CID | ||
90 | * -EINVAL: output error | ||
91 | * -ENOMEM: output is truncated | ||
88 | */ | 92 | */ |
89 | static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | 93 | static int create_modalias(struct acpi_device *acpi_dev, char *modalias, |
90 | int size) | 94 | int size) |
@@ -101,8 +105,10 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
101 | 105 | ||
102 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { | 106 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { |
103 | count = snprintf(&modalias[len], size, "%s:", id->id); | 107 | count = snprintf(&modalias[len], size, "%s:", id->id); |
104 | if (count < 0 || count >= size) | 108 | if (count < 0) |
105 | return -EINVAL; | 109 | return EINVAL; |
110 | if (count >= size) | ||
111 | return -ENOMEM; | ||
106 | len += count; | 112 | len += count; |
107 | size -= count; | 113 | size -= count; |
108 | } | 114 | } |
@@ -111,20 +117,96 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
111 | return len; | 117 | return len; |
112 | } | 118 | } |
113 | 119 | ||
120 | /* | ||
121 | * Creates uevent modalias field for ACPI enumerated devices. | ||
122 | * Because the other buses does not support ACPI HIDs & CIDs. | ||
123 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | ||
124 | * "acpi:IBM0001:ACPI0001" | ||
125 | */ | ||
126 | int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) | ||
127 | { | ||
128 | struct acpi_device *acpi_dev; | ||
129 | int len; | ||
130 | |||
131 | acpi_dev = ACPI_COMPANION(dev); | ||
132 | if (!acpi_dev) | ||
133 | return -ENODEV; | ||
134 | |||
135 | /* Fall back to bus specific way of modalias exporting */ | ||
136 | if (list_empty(&acpi_dev->pnp.ids)) | ||
137 | return -ENODEV; | ||
138 | |||
139 | if (add_uevent_var(env, "MODALIAS=")) | ||
140 | return -ENOMEM; | ||
141 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], | ||
142 | sizeof(env->buf) - env->buflen); | ||
143 | if (len <= 0) | ||
144 | return len; | ||
145 | env->buflen += len; | ||
146 | return 0; | ||
147 | } | ||
148 | EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); | ||
149 | |||
150 | /* | ||
151 | * Creates modalias sysfs attribute for ACPI enumerated devices. | ||
152 | * Because the other buses does not support ACPI HIDs & CIDs. | ||
153 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | ||
154 | * "acpi:IBM0001:ACPI0001" | ||
155 | */ | ||
156 | int acpi_device_modalias(struct device *dev, char *buf, int size) | ||
157 | { | ||
158 | struct acpi_device *acpi_dev; | ||
159 | int len; | ||
160 | |||
161 | acpi_dev = ACPI_COMPANION(dev); | ||
162 | if (!acpi_dev) | ||
163 | return -ENODEV; | ||
164 | |||
165 | /* Fall back to bus specific way of modalias exporting */ | ||
166 | if (list_empty(&acpi_dev->pnp.ids)) | ||
167 | return -ENODEV; | ||
168 | |||
169 | len = create_modalias(acpi_dev, buf, size -1); | ||
170 | if (len <= 0) | ||
171 | return len; | ||
172 | buf[len++] = '\n'; | ||
173 | return len; | ||
174 | } | ||
175 | EXPORT_SYMBOL_GPL(acpi_device_modalias); | ||
176 | |||
114 | static ssize_t | 177 | static ssize_t |
115 | acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { | 178 | acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { |
116 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 179 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
117 | int len; | 180 | int len; |
118 | 181 | ||
119 | /* Device has no HID and no CID or string is >1024 */ | ||
120 | len = create_modalias(acpi_dev, buf, 1024); | 182 | len = create_modalias(acpi_dev, buf, 1024); |
121 | if (len <= 0) | 183 | if (len <= 0) |
122 | return 0; | 184 | return len; |
123 | buf[len++] = '\n'; | 185 | buf[len++] = '\n'; |
124 | return len; | 186 | return len; |
125 | } | 187 | } |
126 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); | 188 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); |
127 | 189 | ||
190 | bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent) | ||
191 | { | ||
192 | struct acpi_device_physical_node *pn; | ||
193 | bool offline = true; | ||
194 | |||
195 | mutex_lock(&adev->physical_node_lock); | ||
196 | |||
197 | list_for_each_entry(pn, &adev->physical_node_list, node) | ||
198 | if (device_supports_offline(pn->dev) && !pn->dev->offline) { | ||
199 | if (uevent) | ||
200 | kobject_uevent(&pn->dev->kobj, KOBJ_CHANGE); | ||
201 | |||
202 | offline = false; | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | mutex_unlock(&adev->physical_node_lock); | ||
207 | return offline; | ||
208 | } | ||
209 | |||
128 | static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data, | 210 | static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data, |
129 | void **ret_p) | 211 | void **ret_p) |
130 | { | 212 | { |
@@ -195,19 +277,11 @@ static acpi_status acpi_bus_online(acpi_handle handle, u32 lvl, void *data, | |||
195 | return AE_OK; | 277 | return AE_OK; |
196 | } | 278 | } |
197 | 279 | ||
198 | static int acpi_scan_hot_remove(struct acpi_device *device) | 280 | static int acpi_scan_try_to_offline(struct acpi_device *device) |
199 | { | 281 | { |
200 | acpi_handle handle = device->handle; | 282 | acpi_handle handle = device->handle; |
201 | struct device *errdev; | 283 | struct device *errdev = NULL; |
202 | acpi_status status; | 284 | acpi_status status; |
203 | unsigned long long sta; | ||
204 | |||
205 | /* If there is no handle, the device node has been unregistered. */ | ||
206 | if (!handle) { | ||
207 | dev_dbg(&device->dev, "ACPI handle missing\n"); | ||
208 | put_device(&device->dev); | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | 285 | ||
212 | /* | 286 | /* |
213 | * Carry out two passes here and ignore errors in the first pass, | 287 | * Carry out two passes here and ignore errors in the first pass, |
@@ -218,7 +292,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
218 | * | 292 | * |
219 | * If the first pass is successful, the second one isn't needed, though. | 293 | * If the first pass is successful, the second one isn't needed, though. |
220 | */ | 294 | */ |
221 | errdev = NULL; | ||
222 | status = acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 295 | status = acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
223 | NULL, acpi_bus_offline, (void *)false, | 296 | NULL, acpi_bus_offline, (void *)false, |
224 | (void **)&errdev); | 297 | (void **)&errdev); |
@@ -226,7 +299,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
226 | dev_warn(errdev, "Offline disabled.\n"); | 299 | dev_warn(errdev, "Offline disabled.\n"); |
227 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 300 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
228 | acpi_bus_online, NULL, NULL, NULL); | 301 | acpi_bus_online, NULL, NULL, NULL); |
229 | put_device(&device->dev); | ||
230 | return -EPERM; | 302 | return -EPERM; |
231 | } | 303 | } |
232 | acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev); | 304 | acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev); |
@@ -245,20 +317,32 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
245 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, | 317 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, |
246 | ACPI_UINT32_MAX, acpi_bus_online, | 318 | ACPI_UINT32_MAX, acpi_bus_online, |
247 | NULL, NULL, NULL); | 319 | NULL, NULL, NULL); |
248 | put_device(&device->dev); | ||
249 | return -EBUSY; | 320 | return -EBUSY; |
250 | } | 321 | } |
251 | } | 322 | } |
323 | return 0; | ||
324 | } | ||
325 | |||
326 | static int acpi_scan_hot_remove(struct acpi_device *device) | ||
327 | { | ||
328 | acpi_handle handle = device->handle; | ||
329 | unsigned long long sta; | ||
330 | acpi_status status; | ||
331 | |||
332 | if (device->handler->hotplug.demand_offline && !acpi_force_hot_remove) { | ||
333 | if (!acpi_scan_is_offline(device, true)) | ||
334 | return -EBUSY; | ||
335 | } else { | ||
336 | int error = acpi_scan_try_to_offline(device); | ||
337 | if (error) | ||
338 | return error; | ||
339 | } | ||
252 | 340 | ||
253 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 341 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
254 | "Hot-removing device %s...\n", dev_name(&device->dev))); | 342 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
255 | 343 | ||
256 | acpi_bus_trim(device); | 344 | acpi_bus_trim(device); |
257 | 345 | ||
258 | /* Device node has been unregistered. */ | ||
259 | put_device(&device->dev); | ||
260 | device = NULL; | ||
261 | |||
262 | acpi_evaluate_lck(handle, 0); | 346 | acpi_evaluate_lck(handle, 0); |
263 | /* | 347 | /* |
264 | * TBD: _EJD support. | 348 | * TBD: _EJD support. |
@@ -285,115 +369,127 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
285 | return 0; | 369 | return 0; |
286 | } | 370 | } |
287 | 371 | ||
288 | void acpi_bus_device_eject(void *data, u32 ost_src) | 372 | static int acpi_scan_device_not_present(struct acpi_device *adev) |
289 | { | 373 | { |
290 | struct acpi_device *device = data; | 374 | if (!acpi_device_enumerated(adev)) { |
291 | acpi_handle handle = device->handle; | 375 | dev_warn(&adev->dev, "Still not present\n"); |
292 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 376 | return -EALREADY; |
293 | int error; | 377 | } |
378 | acpi_bus_trim(adev); | ||
379 | return 0; | ||
380 | } | ||
294 | 381 | ||
295 | lock_device_hotplug(); | 382 | static int acpi_scan_device_check(struct acpi_device *adev) |
296 | mutex_lock(&acpi_scan_lock); | 383 | { |
384 | int error; | ||
297 | 385 | ||
298 | if (ost_src == ACPI_NOTIFY_EJECT_REQUEST) | 386 | acpi_bus_get_status(adev); |
299 | acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, | 387 | if (adev->status.present || adev->status.functional) { |
300 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 388 | /* |
389 | * This function is only called for device objects for which | ||
390 | * matching scan handlers exist. The only situation in which | ||
391 | * the scan handler is not attached to this device object yet | ||
392 | * is when the device has just appeared (either it wasn't | ||
393 | * present at all before or it was removed and then added | ||
394 | * again). | ||
395 | */ | ||
396 | if (adev->handler) { | ||
397 | dev_warn(&adev->dev, "Already enumerated\n"); | ||
398 | return -EALREADY; | ||
399 | } | ||
400 | error = acpi_bus_scan(adev->handle); | ||
401 | if (error) { | ||
402 | dev_warn(&adev->dev, "Namespace scan failure\n"); | ||
403 | return error; | ||
404 | } | ||
405 | if (!adev->handler) { | ||
406 | dev_warn(&adev->dev, "Enumeration failure\n"); | ||
407 | error = -ENODEV; | ||
408 | } | ||
409 | } else { | ||
410 | error = acpi_scan_device_not_present(adev); | ||
411 | } | ||
412 | return error; | ||
413 | } | ||
301 | 414 | ||
302 | if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER) | 415 | static int acpi_scan_bus_check(struct acpi_device *adev) |
303 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | 416 | { |
417 | struct acpi_scan_handler *handler = adev->handler; | ||
418 | struct acpi_device *child; | ||
419 | int error; | ||
304 | 420 | ||
305 | error = acpi_scan_hot_remove(device); | 421 | acpi_bus_get_status(adev); |
306 | if (error == -EPERM) { | 422 | if (!(adev->status.present || adev->status.functional)) { |
307 | goto err_support; | 423 | acpi_scan_device_not_present(adev); |
308 | } else if (error) { | 424 | return 0; |
309 | goto err_out; | ||
310 | } | 425 | } |
426 | if (handler && handler->hotplug.scan_dependent) | ||
427 | return handler->hotplug.scan_dependent(adev); | ||
311 | 428 | ||
312 | out: | 429 | error = acpi_bus_scan(adev->handle); |
313 | mutex_unlock(&acpi_scan_lock); | 430 | if (error) { |
314 | unlock_device_hotplug(); | 431 | dev_warn(&adev->dev, "Namespace scan failure\n"); |
315 | return; | 432 | return error; |
316 | 433 | } | |
317 | err_support: | 434 | list_for_each_entry(child, &adev->children, node) { |
318 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | 435 | error = acpi_scan_bus_check(child); |
319 | err_out: | 436 | if (error) |
320 | acpi_evaluate_hotplug_ost(handle, ost_src, ost_code, NULL); | 437 | return error; |
321 | goto out; | 438 | } |
439 | return 0; | ||
322 | } | 440 | } |
323 | 441 | ||
324 | static void acpi_scan_bus_device_check(void *data, u32 ost_source) | 442 | static void acpi_device_hotplug(void *data, u32 src) |
325 | { | 443 | { |
326 | acpi_handle handle = data; | ||
327 | struct acpi_device *device = NULL; | ||
328 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 444 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
445 | struct acpi_device *adev = data; | ||
329 | int error; | 446 | int error; |
330 | 447 | ||
331 | lock_device_hotplug(); | 448 | lock_device_hotplug(); |
332 | mutex_lock(&acpi_scan_lock); | 449 | mutex_lock(&acpi_scan_lock); |
333 | 450 | ||
334 | if (ost_source != ACPI_NOTIFY_BUS_CHECK) { | 451 | /* |
335 | acpi_bus_get_device(handle, &device); | 452 | * The device object's ACPI handle cannot become invalid as long as we |
336 | if (device) { | 453 | * are holding acpi_scan_lock, but it may have become invalid before |
337 | dev_warn(&device->dev, "Attempt to re-insert\n"); | 454 | * that lock was acquired. |
338 | goto out; | 455 | */ |
339 | } | 456 | if (adev->handle == INVALID_ACPI_HANDLE) |
340 | } | ||
341 | error = acpi_bus_scan(handle); | ||
342 | if (error) { | ||
343 | acpi_handle_warn(handle, "Namespace scan failure\n"); | ||
344 | goto out; | ||
345 | } | ||
346 | error = acpi_bus_get_device(handle, &device); | ||
347 | if (error) { | ||
348 | acpi_handle_warn(handle, "Missing device node object\n"); | ||
349 | goto out; | 457 | goto out; |
350 | } | ||
351 | ost_code = ACPI_OST_SC_SUCCESS; | ||
352 | if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER) | ||
353 | kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); | ||
354 | 458 | ||
355 | out: | 459 | switch (src) { |
356 | acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL); | ||
357 | mutex_unlock(&acpi_scan_lock); | ||
358 | unlock_device_hotplug(); | ||
359 | } | ||
360 | |||
361 | static void acpi_hotplug_unsupported(acpi_handle handle, u32 type) | ||
362 | { | ||
363 | u32 ost_status; | ||
364 | |||
365 | switch (type) { | ||
366 | case ACPI_NOTIFY_BUS_CHECK: | 460 | case ACPI_NOTIFY_BUS_CHECK: |
367 | acpi_handle_debug(handle, | 461 | error = acpi_scan_bus_check(adev); |
368 | "ACPI_NOTIFY_BUS_CHECK event: unsupported\n"); | ||
369 | ost_status = ACPI_OST_SC_INSERT_NOT_SUPPORTED; | ||
370 | break; | 462 | break; |
371 | case ACPI_NOTIFY_DEVICE_CHECK: | 463 | case ACPI_NOTIFY_DEVICE_CHECK: |
372 | acpi_handle_debug(handle, | 464 | error = acpi_scan_device_check(adev); |
373 | "ACPI_NOTIFY_DEVICE_CHECK event: unsupported\n"); | ||
374 | ost_status = ACPI_OST_SC_INSERT_NOT_SUPPORTED; | ||
375 | break; | 465 | break; |
376 | case ACPI_NOTIFY_EJECT_REQUEST: | 466 | case ACPI_NOTIFY_EJECT_REQUEST: |
377 | acpi_handle_debug(handle, | 467 | case ACPI_OST_EC_OSPM_EJECT: |
378 | "ACPI_NOTIFY_EJECT_REQUEST event: unsupported\n"); | 468 | error = acpi_scan_hot_remove(adev); |
379 | ost_status = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | ||
380 | break; | 469 | break; |
381 | default: | 470 | default: |
382 | /* non-hotplug event; possibly handled by other handler */ | 471 | error = -EINVAL; |
383 | return; | 472 | break; |
384 | } | 473 | } |
474 | if (!error) | ||
475 | ost_code = ACPI_OST_SC_SUCCESS; | ||
385 | 476 | ||
386 | acpi_evaluate_hotplug_ost(handle, type, ost_status, NULL); | 477 | out: |
478 | acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL); | ||
479 | put_device(&adev->dev); | ||
480 | mutex_unlock(&acpi_scan_lock); | ||
481 | unlock_device_hotplug(); | ||
387 | } | 482 | } |
388 | 483 | ||
389 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | 484 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) |
390 | { | 485 | { |
486 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | ||
391 | struct acpi_scan_handler *handler = data; | 487 | struct acpi_scan_handler *handler = data; |
392 | struct acpi_device *adev; | 488 | struct acpi_device *adev; |
393 | acpi_status status; | 489 | acpi_status status; |
394 | 490 | ||
395 | if (!handler->hotplug.enabled) | 491 | if (acpi_bus_get_device(handle, &adev)) |
396 | return acpi_hotplug_unsupported(handle, type); | 492 | goto err_out; |
397 | 493 | ||
398 | switch (type) { | 494 | switch (type) { |
399 | case ACPI_NOTIFY_BUS_CHECK: | 495 | case ACPI_NOTIFY_BUS_CHECK: |
@@ -404,27 +500,27 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
404 | break; | 500 | break; |
405 | case ACPI_NOTIFY_EJECT_REQUEST: | 501 | case ACPI_NOTIFY_EJECT_REQUEST: |
406 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); | 502 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); |
407 | if (acpi_bus_get_device(handle, &adev)) | 503 | if (!handler->hotplug.enabled) { |
504 | acpi_handle_err(handle, "Eject disabled\n"); | ||
505 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | ||
408 | goto err_out; | 506 | goto err_out; |
409 | 507 | } | |
410 | get_device(&adev->dev); | 508 | acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, |
411 | status = acpi_hotplug_execute(acpi_bus_device_eject, adev, type); | 509 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
412 | if (ACPI_SUCCESS(status)) | 510 | break; |
413 | return; | ||
414 | |||
415 | put_device(&adev->dev); | ||
416 | goto err_out; | ||
417 | default: | 511 | default: |
418 | /* non-hotplug event; possibly handled by other handler */ | 512 | /* non-hotplug event; possibly handled by other handler */ |
419 | return; | 513 | return; |
420 | } | 514 | } |
421 | status = acpi_hotplug_execute(acpi_scan_bus_device_check, handle, type); | 515 | get_device(&adev->dev); |
516 | status = acpi_hotplug_execute(acpi_device_hotplug, adev, type); | ||
422 | if (ACPI_SUCCESS(status)) | 517 | if (ACPI_SUCCESS(status)) |
423 | return; | 518 | return; |
424 | 519 | ||
520 | put_device(&adev->dev); | ||
521 | |||
425 | err_out: | 522 | err_out: |
426 | acpi_evaluate_hotplug_ost(handle, type, | 523 | acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); |
427 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); | ||
428 | } | 524 | } |
429 | 525 | ||
430 | static ssize_t real_power_state_show(struct device *dev, | 526 | static ssize_t real_power_state_show(struct device *dev, |
@@ -475,7 +571,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
475 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, | 571 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, |
476 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 572 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
477 | get_device(&acpi_device->dev); | 573 | get_device(&acpi_device->dev); |
478 | status = acpi_hotplug_execute(acpi_bus_device_eject, acpi_device, | 574 | status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device, |
479 | ACPI_OST_EC_OSPM_EJECT); | 575 | ACPI_OST_EC_OSPM_EJECT); |
480 | if (ACPI_SUCCESS(status)) | 576 | if (ACPI_SUCCESS(status)) |
481 | return count; | 577 | return count; |
@@ -567,6 +663,20 @@ acpi_device_sun_show(struct device *dev, struct device_attribute *attr, | |||
567 | } | 663 | } |
568 | static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); | 664 | static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); |
569 | 665 | ||
666 | static ssize_t status_show(struct device *dev, struct device_attribute *attr, | ||
667 | char *buf) { | ||
668 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
669 | acpi_status status; | ||
670 | unsigned long long sta; | ||
671 | |||
672 | status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta); | ||
673 | if (ACPI_FAILURE(status)) | ||
674 | return -ENODEV; | ||
675 | |||
676 | return sprintf(buf, "%llu\n", sta); | ||
677 | } | ||
678 | static DEVICE_ATTR_RO(status); | ||
679 | |||
570 | static int acpi_device_setup_files(struct acpi_device *dev) | 680 | static int acpi_device_setup_files(struct acpi_device *dev) |
571 | { | 681 | { |
572 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 682 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
@@ -622,6 +732,12 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
622 | dev->pnp.sun = (unsigned long)-1; | 732 | dev->pnp.sun = (unsigned long)-1; |
623 | } | 733 | } |
624 | 734 | ||
735 | if (acpi_has_method(dev->handle, "_STA")) { | ||
736 | result = device_create_file(&dev->dev, &dev_attr_status); | ||
737 | if (result) | ||
738 | goto end; | ||
739 | } | ||
740 | |||
625 | /* | 741 | /* |
626 | * If device has _EJ0, 'eject' file is created that is used to trigger | 742 | * If device has _EJ0, 'eject' file is created that is used to trigger |
627 | * hot-removal function from userland. | 743 | * hot-removal function from userland. |
@@ -677,6 +793,8 @@ static void acpi_device_remove_files(struct acpi_device *dev) | |||
677 | device_remove_file(&dev->dev, &dev_attr_adr); | 793 | device_remove_file(&dev->dev, &dev_attr_adr); |
678 | device_remove_file(&dev->dev, &dev_attr_modalias); | 794 | device_remove_file(&dev->dev, &dev_attr_modalias); |
679 | device_remove_file(&dev->dev, &dev_attr_hid); | 795 | device_remove_file(&dev->dev, &dev_attr_hid); |
796 | if (acpi_has_method(dev->handle, "_STA")) | ||
797 | device_remove_file(&dev->dev, &dev_attr_status); | ||
680 | if (dev->handle) | 798 | if (dev->handle) |
681 | device_remove_file(&dev->dev, &dev_attr_path); | 799 | device_remove_file(&dev->dev, &dev_attr_path); |
682 | } | 800 | } |
@@ -782,8 +900,8 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
782 | return -ENOMEM; | 900 | return -ENOMEM; |
783 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], | 901 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], |
784 | sizeof(env->buf) - env->buflen); | 902 | sizeof(env->buf) - env->buflen); |
785 | if (len >= (sizeof(env->buf) - env->buflen)) | 903 | if (len <= 0) |
786 | return -ENOMEM; | 904 | return len; |
787 | env->buflen += len; | 905 | env->buflen += len; |
788 | return 0; | 906 | return 0; |
789 | } | 907 | } |
@@ -907,9 +1025,91 @@ struct bus_type acpi_bus_type = { | |||
907 | .uevent = acpi_device_uevent, | 1025 | .uevent = acpi_device_uevent, |
908 | }; | 1026 | }; |
909 | 1027 | ||
910 | static void acpi_bus_data_handler(acpi_handle handle, void *context) | 1028 | static void acpi_device_del(struct acpi_device *device) |
1029 | { | ||
1030 | mutex_lock(&acpi_device_lock); | ||
1031 | if (device->parent) | ||
1032 | list_del(&device->node); | ||
1033 | |||
1034 | list_del(&device->wakeup_list); | ||
1035 | mutex_unlock(&acpi_device_lock); | ||
1036 | |||
1037 | acpi_power_add_remove_device(device, false); | ||
1038 | acpi_device_remove_files(device); | ||
1039 | if (device->remove) | ||
1040 | device->remove(device); | ||
1041 | |||
1042 | device_del(&device->dev); | ||
1043 | } | ||
1044 | |||
1045 | static LIST_HEAD(acpi_device_del_list); | ||
1046 | static DEFINE_MUTEX(acpi_device_del_lock); | ||
1047 | |||
1048 | static void acpi_device_del_work_fn(struct work_struct *work_not_used) | ||
1049 | { | ||
1050 | for (;;) { | ||
1051 | struct acpi_device *adev; | ||
1052 | |||
1053 | mutex_lock(&acpi_device_del_lock); | ||
1054 | |||
1055 | if (list_empty(&acpi_device_del_list)) { | ||
1056 | mutex_unlock(&acpi_device_del_lock); | ||
1057 | break; | ||
1058 | } | ||
1059 | adev = list_first_entry(&acpi_device_del_list, | ||
1060 | struct acpi_device, del_list); | ||
1061 | list_del(&adev->del_list); | ||
1062 | |||
1063 | mutex_unlock(&acpi_device_del_lock); | ||
1064 | |||
1065 | acpi_device_del(adev); | ||
1066 | /* | ||
1067 | * Drop references to all power resources that might have been | ||
1068 | * used by the device. | ||
1069 | */ | ||
1070 | acpi_power_transition(adev, ACPI_STATE_D3_COLD); | ||
1071 | put_device(&adev->dev); | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1075 | /** | ||
1076 | * acpi_scan_drop_device - Drop an ACPI device object. | ||
1077 | * @handle: Handle of an ACPI namespace node, not used. | ||
1078 | * @context: Address of the ACPI device object to drop. | ||
1079 | * | ||
1080 | * This is invoked by acpi_ns_delete_node() during the removal of the ACPI | ||
1081 | * namespace node the device object pointed to by @context is attached to. | ||
1082 | * | ||
1083 | * The unregistration is carried out asynchronously to avoid running | ||
1084 | * acpi_device_del() under the ACPICA's namespace mutex and the list is used to | ||
1085 | * ensure the correct ordering (the device objects must be unregistered in the | ||
1086 | * same order in which the corresponding namespace nodes are deleted). | ||
1087 | */ | ||
1088 | static void acpi_scan_drop_device(acpi_handle handle, void *context) | ||
911 | { | 1089 | { |
912 | /* Intentionally empty. */ | 1090 | static DECLARE_WORK(work, acpi_device_del_work_fn); |
1091 | struct acpi_device *adev = context; | ||
1092 | |||
1093 | mutex_lock(&acpi_device_del_lock); | ||
1094 | |||
1095 | /* | ||
1096 | * Use the ACPI hotplug workqueue which is ordered, so this work item | ||
1097 | * won't run after any hotplug work items submitted subsequently. That | ||
1098 | * prevents attempts to register device objects identical to those being | ||
1099 | * deleted from happening concurrently (such attempts result from | ||
1100 | * hotplug events handled via the ACPI hotplug workqueue). It also will | ||
1101 | * run after all of the work items submitted previosuly, which helps | ||
1102 | * those work items to ensure that they are not accessing stale device | ||
1103 | * objects. | ||
1104 | */ | ||
1105 | if (list_empty(&acpi_device_del_list)) | ||
1106 | acpi_queue_hotplug_work(&work); | ||
1107 | |||
1108 | list_add_tail(&adev->del_list, &acpi_device_del_list); | ||
1109 | /* Make acpi_ns_validate_handle() return NULL for this handle. */ | ||
1110 | adev->handle = INVALID_ACPI_HANDLE; | ||
1111 | |||
1112 | mutex_unlock(&acpi_device_del_lock); | ||
913 | } | 1113 | } |
914 | 1114 | ||
915 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | 1115 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) |
@@ -919,7 +1119,7 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | |||
919 | if (!device) | 1119 | if (!device) |
920 | return -EINVAL; | 1120 | return -EINVAL; |
921 | 1121 | ||
922 | status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device); | 1122 | status = acpi_get_data(handle, acpi_scan_drop_device, (void **)device); |
923 | if (ACPI_FAILURE(status) || !*device) { | 1123 | if (ACPI_FAILURE(status) || !*device) { |
924 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", | 1124 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", |
925 | handle)); | 1125 | handle)); |
@@ -939,7 +1139,7 @@ int acpi_device_add(struct acpi_device *device, | |||
939 | if (device->handle) { | 1139 | if (device->handle) { |
940 | acpi_status status; | 1140 | acpi_status status; |
941 | 1141 | ||
942 | status = acpi_attach_data(device->handle, acpi_bus_data_handler, | 1142 | status = acpi_attach_data(device->handle, acpi_scan_drop_device, |
943 | device); | 1143 | device); |
944 | if (ACPI_FAILURE(status)) { | 1144 | if (ACPI_FAILURE(status)) { |
945 | acpi_handle_err(device->handle, | 1145 | acpi_handle_err(device->handle, |
@@ -957,6 +1157,7 @@ int acpi_device_add(struct acpi_device *device, | |||
957 | INIT_LIST_HEAD(&device->node); | 1157 | INIT_LIST_HEAD(&device->node); |
958 | INIT_LIST_HEAD(&device->wakeup_list); | 1158 | INIT_LIST_HEAD(&device->wakeup_list); |
959 | INIT_LIST_HEAD(&device->physical_node_list); | 1159 | INIT_LIST_HEAD(&device->physical_node_list); |
1160 | INIT_LIST_HEAD(&device->del_list); | ||
960 | mutex_init(&device->physical_node_lock); | 1161 | mutex_init(&device->physical_node_lock); |
961 | 1162 | ||
962 | new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); | 1163 | new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); |
@@ -1020,37 +1221,10 @@ int acpi_device_add(struct acpi_device *device, | |||
1020 | mutex_unlock(&acpi_device_lock); | 1221 | mutex_unlock(&acpi_device_lock); |
1021 | 1222 | ||
1022 | err_detach: | 1223 | err_detach: |
1023 | acpi_detach_data(device->handle, acpi_bus_data_handler); | 1224 | acpi_detach_data(device->handle, acpi_scan_drop_device); |
1024 | return result; | 1225 | return result; |
1025 | } | 1226 | } |
1026 | 1227 | ||
1027 | static void acpi_device_unregister(struct acpi_device *device) | ||
1028 | { | ||
1029 | mutex_lock(&acpi_device_lock); | ||
1030 | if (device->parent) | ||
1031 | list_del(&device->node); | ||
1032 | |||
1033 | list_del(&device->wakeup_list); | ||
1034 | mutex_unlock(&acpi_device_lock); | ||
1035 | |||
1036 | acpi_detach_data(device->handle, acpi_bus_data_handler); | ||
1037 | |||
1038 | acpi_power_add_remove_device(device, false); | ||
1039 | acpi_device_remove_files(device); | ||
1040 | if (device->remove) | ||
1041 | device->remove(device); | ||
1042 | |||
1043 | device_del(&device->dev); | ||
1044 | /* | ||
1045 | * Transition the device to D3cold to drop the reference counts of all | ||
1046 | * power resources the device depends on and turn off the ones that have | ||
1047 | * no more references. | ||
1048 | */ | ||
1049 | acpi_device_set_power(device, ACPI_STATE_D3_COLD); | ||
1050 | device->handle = NULL; | ||
1051 | put_device(&device->dev); | ||
1052 | } | ||
1053 | |||
1054 | /* -------------------------------------------------------------------------- | 1228 | /* -------------------------------------------------------------------------- |
1055 | Driver Management | 1229 | Driver Management |
1056 | -------------------------------------------------------------------------- */ | 1230 | -------------------------------------------------------------------------- */ |
@@ -1624,11 +1798,13 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, | |||
1624 | device->device_type = type; | 1798 | device->device_type = type; |
1625 | device->handle = handle; | 1799 | device->handle = handle; |
1626 | device->parent = acpi_bus_get_parent(handle); | 1800 | device->parent = acpi_bus_get_parent(handle); |
1627 | STRUCT_TO_INT(device->status) = sta; | 1801 | acpi_set_device_status(device, sta); |
1628 | acpi_device_get_busid(device); | 1802 | acpi_device_get_busid(device); |
1629 | acpi_set_pnp_ids(handle, &device->pnp, type); | 1803 | acpi_set_pnp_ids(handle, &device->pnp, type); |
1630 | acpi_bus_get_flags(device); | 1804 | acpi_bus_get_flags(device); |
1631 | device->flags.match_driver = false; | 1805 | device->flags.match_driver = false; |
1806 | device->flags.initialized = true; | ||
1807 | device->flags.visited = false; | ||
1632 | device_initialize(&device->dev); | 1808 | device_initialize(&device->dev); |
1633 | dev_set_uevent_suppress(&device->dev, true); | 1809 | dev_set_uevent_suppress(&device->dev, true); |
1634 | } | 1810 | } |
@@ -1713,6 +1889,15 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type, | |||
1713 | return 0; | 1889 | return 0; |
1714 | } | 1890 | } |
1715 | 1891 | ||
1892 | bool acpi_device_is_present(struct acpi_device *adev) | ||
1893 | { | ||
1894 | if (adev->status.present || adev->status.functional) | ||
1895 | return true; | ||
1896 | |||
1897 | adev->flags.initialized = false; | ||
1898 | return false; | ||
1899 | } | ||
1900 | |||
1716 | static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler, | 1901 | static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler, |
1717 | char *idstr, | 1902 | char *idstr, |
1718 | const struct acpi_device_id **matchid) | 1903 | const struct acpi_device_id **matchid) |
@@ -1772,7 +1957,7 @@ static void acpi_scan_init_hotplug(acpi_handle handle, int type) | |||
1772 | */ | 1957 | */ |
1773 | list_for_each_entry(hwid, &pnp.ids, list) { | 1958 | list_for_each_entry(hwid, &pnp.ids, list) { |
1774 | handler = acpi_scan_match_handler(hwid->id, NULL); | 1959 | handler = acpi_scan_match_handler(hwid->id, NULL); |
1775 | if (handler && !handler->hotplug.ignore) { | 1960 | if (handler) { |
1776 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | 1961 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
1777 | acpi_hotplug_notify_cb, handler); | 1962 | acpi_hotplug_notify_cb, handler); |
1778 | break; | 1963 | break; |
@@ -1806,18 +1991,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | |||
1806 | 1991 | ||
1807 | acpi_scan_init_hotplug(handle, type); | 1992 | acpi_scan_init_hotplug(handle, type); |
1808 | 1993 | ||
1809 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && | ||
1810 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { | ||
1811 | struct acpi_device_wakeup wakeup; | ||
1812 | |||
1813 | if (acpi_has_method(handle, "_PRW")) { | ||
1814 | acpi_bus_extract_wakeup_device_power_package(handle, | ||
1815 | &wakeup); | ||
1816 | acpi_power_resources_list_free(&wakeup.resources); | ||
1817 | } | ||
1818 | return AE_CTRL_DEPTH; | ||
1819 | } | ||
1820 | |||
1821 | acpi_add_single_object(&device, handle, type, sta); | 1994 | acpi_add_single_object(&device, handle, type, sta); |
1822 | if (!device) | 1995 | if (!device) |
1823 | return AE_CTRL_DEPTH; | 1996 | return AE_CTRL_DEPTH; |
@@ -1852,36 +2025,40 @@ static int acpi_scan_attach_handler(struct acpi_device *device) | |||
1852 | return ret; | 2025 | return ret; |
1853 | } | 2026 | } |
1854 | 2027 | ||
1855 | static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, | 2028 | static void acpi_bus_attach(struct acpi_device *device) |
1856 | void *not_used, void **ret_not_used) | ||
1857 | { | 2029 | { |
1858 | struct acpi_device *device; | 2030 | struct acpi_device *child; |
1859 | unsigned long long sta_not_used; | ||
1860 | int ret; | 2031 | int ret; |
1861 | 2032 | ||
1862 | /* | 2033 | acpi_bus_get_status(device); |
1863 | * Ignore errors ignored by acpi_bus_check_add() to avoid terminating | 2034 | /* Skip devices that are not present. */ |
1864 | * namespace walks prematurely. | 2035 | if (!acpi_device_is_present(device)) { |
1865 | */ | 2036 | device->flags.visited = false; |
1866 | if (acpi_bus_type_and_status(handle, &ret, &sta_not_used)) | 2037 | return; |
1867 | return AE_OK; | 2038 | } |
1868 | |||
1869 | if (acpi_bus_get_device(handle, &device)) | ||
1870 | return AE_CTRL_DEPTH; | ||
1871 | |||
1872 | if (device->handler) | 2039 | if (device->handler) |
1873 | return AE_OK; | 2040 | goto ok; |
1874 | 2041 | ||
2042 | if (!device->flags.initialized) { | ||
2043 | acpi_bus_update_power(device, NULL); | ||
2044 | device->flags.initialized = true; | ||
2045 | } | ||
2046 | device->flags.visited = false; | ||
1875 | ret = acpi_scan_attach_handler(device); | 2047 | ret = acpi_scan_attach_handler(device); |
1876 | if (ret < 0) | 2048 | if (ret < 0) |
1877 | return AE_CTRL_DEPTH; | 2049 | return; |
1878 | 2050 | ||
1879 | device->flags.match_driver = true; | 2051 | device->flags.match_driver = true; |
1880 | if (ret > 0) | 2052 | if (!ret) { |
1881 | return AE_OK; | 2053 | ret = device_attach(&device->dev); |
2054 | if (ret < 0) | ||
2055 | return; | ||
2056 | } | ||
2057 | device->flags.visited = true; | ||
1882 | 2058 | ||
1883 | ret = device_attach(&device->dev); | 2059 | ok: |
1884 | return ret >= 0 ? AE_OK : AE_CTRL_DEPTH; | 2060 | list_for_each_entry(child, &device->children, node) |
2061 | acpi_bus_attach(child); | ||
1885 | } | 2062 | } |
1886 | 2063 | ||
1887 | /** | 2064 | /** |
@@ -1901,75 +2078,48 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, | |||
1901 | int acpi_bus_scan(acpi_handle handle) | 2078 | int acpi_bus_scan(acpi_handle handle) |
1902 | { | 2079 | { |
1903 | void *device = NULL; | 2080 | void *device = NULL; |
1904 | int error = 0; | ||
1905 | 2081 | ||
1906 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) | 2082 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) |
1907 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 2083 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
1908 | acpi_bus_check_add, NULL, NULL, &device); | 2084 | acpi_bus_check_add, NULL, NULL, &device); |
1909 | 2085 | ||
1910 | if (!device) | 2086 | if (device) { |
1911 | error = -ENODEV; | 2087 | acpi_bus_attach(device); |
1912 | else if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL))) | 2088 | return 0; |
1913 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | ||
1914 | acpi_bus_device_attach, NULL, NULL, NULL); | ||
1915 | |||
1916 | return error; | ||
1917 | } | ||
1918 | EXPORT_SYMBOL(acpi_bus_scan); | ||
1919 | |||
1920 | static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used, | ||
1921 | void *not_used, void **ret_not_used) | ||
1922 | { | ||
1923 | struct acpi_device *device = NULL; | ||
1924 | |||
1925 | if (!acpi_bus_get_device(handle, &device)) { | ||
1926 | struct acpi_scan_handler *dev_handler = device->handler; | ||
1927 | |||
1928 | if (dev_handler) { | ||
1929 | if (dev_handler->detach) | ||
1930 | dev_handler->detach(device); | ||
1931 | |||
1932 | device->handler = NULL; | ||
1933 | } else { | ||
1934 | device_release_driver(&device->dev); | ||
1935 | } | ||
1936 | } | 2089 | } |
1937 | return AE_OK; | 2090 | return -ENODEV; |
1938 | } | ||
1939 | |||
1940 | static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used, | ||
1941 | void *not_used, void **ret_not_used) | ||
1942 | { | ||
1943 | struct acpi_device *device = NULL; | ||
1944 | |||
1945 | if (!acpi_bus_get_device(handle, &device)) | ||
1946 | acpi_device_unregister(device); | ||
1947 | |||
1948 | return AE_OK; | ||
1949 | } | 2091 | } |
2092 | EXPORT_SYMBOL(acpi_bus_scan); | ||
1950 | 2093 | ||
1951 | /** | 2094 | /** |
1952 | * acpi_bus_trim - Remove ACPI device node and all of its descendants | 2095 | * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects. |
1953 | * @start: Root of the ACPI device nodes subtree to remove. | 2096 | * @adev: Root of the ACPI namespace scope to walk. |
1954 | * | 2097 | * |
1955 | * Must be called under acpi_scan_lock. | 2098 | * Must be called under acpi_scan_lock. |
1956 | */ | 2099 | */ |
1957 | void acpi_bus_trim(struct acpi_device *start) | 2100 | void acpi_bus_trim(struct acpi_device *adev) |
1958 | { | 2101 | { |
2102 | struct acpi_scan_handler *handler = adev->handler; | ||
2103 | struct acpi_device *child; | ||
2104 | |||
2105 | list_for_each_entry_reverse(child, &adev->children, node) | ||
2106 | acpi_bus_trim(child); | ||
2107 | |||
2108 | if (handler) { | ||
2109 | if (handler->detach) | ||
2110 | handler->detach(adev); | ||
2111 | |||
2112 | adev->handler = NULL; | ||
2113 | } else { | ||
2114 | device_release_driver(&adev->dev); | ||
2115 | } | ||
1959 | /* | 2116 | /* |
1960 | * Execute acpi_bus_device_detach() as a post-order callback to detach | 2117 | * Most likely, the device is going away, so put it into D3cold before |
1961 | * all ACPI drivers from the device nodes being removed. | 2118 | * that. |
1962 | */ | ||
1963 | acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, | ||
1964 | acpi_bus_device_detach, NULL, NULL); | ||
1965 | acpi_bus_device_detach(start->handle, 0, NULL, NULL); | ||
1966 | /* | ||
1967 | * Execute acpi_bus_remove() as a post-order callback to remove device | ||
1968 | * nodes in the given namespace scope. | ||
1969 | */ | 2119 | */ |
1970 | acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, | 2120 | acpi_device_set_power(adev, ACPI_STATE_D3_COLD); |
1971 | acpi_bus_remove, NULL, NULL); | 2121 | adev->flags.initialized = false; |
1972 | acpi_bus_remove(start->handle, 0, NULL, NULL); | 2122 | adev->flags.visited = false; |
1973 | } | 2123 | } |
1974 | EXPORT_SYMBOL_GPL(acpi_bus_trim); | 2124 | EXPORT_SYMBOL_GPL(acpi_bus_trim); |
1975 | 2125 | ||
@@ -2047,14 +2197,14 @@ int __init acpi_scan_init(void) | |||
2047 | 2197 | ||
2048 | result = acpi_bus_scan_fixed(); | 2198 | result = acpi_bus_scan_fixed(); |
2049 | if (result) { | 2199 | if (result) { |
2050 | acpi_device_unregister(acpi_root); | 2200 | acpi_detach_data(acpi_root->handle, acpi_scan_drop_device); |
2201 | acpi_device_del(acpi_root); | ||
2202 | put_device(&acpi_root->dev); | ||
2051 | goto out; | 2203 | goto out; |
2052 | } | 2204 | } |
2053 | 2205 | ||
2054 | acpi_update_all_gpes(); | 2206 | acpi_update_all_gpes(); |
2055 | 2207 | ||
2056 | acpi_pci_root_hp_init(); | ||
2057 | |||
2058 | out: | 2208 | out: |
2059 | mutex_unlock(&acpi_scan_lock); | 2209 | mutex_unlock(&acpi_scan_lock); |
2060 | return result; | 2210 | return result; |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721e949e606e..b718806657cd 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -18,12 +18,8 @@ | |||
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> | 20 | #include <linux/module.h> |
21 | |||
22 | #include <asm/io.h> | 21 | #include <asm/io.h> |
23 | 22 | ||
24 | #include <acpi/acpi_bus.h> | ||
25 | #include <acpi/acpi_drivers.h> | ||
26 | |||
27 | #include "internal.h" | 23 | #include "internal.h" |
28 | #include "sleep.h" | 24 | #include "sleep.h" |
29 | 25 | ||
@@ -670,11 +666,8 @@ static void acpi_hibernation_leave(void) | |||
670 | /* Reprogram control registers */ | 666 | /* Reprogram control registers */ |
671 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | 667 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
672 | /* Check the hardware signature */ | 668 | /* Check the hardware signature */ |
673 | if (facs && s4_hardware_signature != facs->hardware_signature) { | 669 | if (facs && s4_hardware_signature != facs->hardware_signature) |
674 | printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " | 670 | pr_crit("ACPI: Hardware changed while hibernated, success doubtful!\n"); |
675 | "cannot resume!\n"); | ||
676 | panic("ACPI S4 hardware signature mismatch"); | ||
677 | } | ||
678 | /* Restore the NVS memory area */ | 671 | /* Restore the NVS memory area */ |
679 | suspend_nvs_restore(); | 672 | suspend_nvs_restore(); |
680 | /* Allow EC transactions to happen. */ | 673 | /* Allow EC transactions to happen. */ |
@@ -806,9 +799,6 @@ int __init acpi_sleep_init(void) | |||
806 | char *pos = supported; | 799 | char *pos = supported; |
807 | int i; | 800 | int i; |
808 | 801 | ||
809 | if (acpi_disabled) | ||
810 | return 0; | ||
811 | |||
812 | acpi_sleep_dmi_check(); | 802 | acpi_sleep_dmi_check(); |
813 | 803 | ||
814 | sleep_states[ACPI_STATE_S0] = 1; | 804 | sleep_states[ACPI_STATE_S0] = 1; |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 6dbc3ca45223..443dc9366052 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/moduleparam.h> | 7 | #include <linux/moduleparam.h> |
8 | #include <acpi/acpi_drivers.h> | 8 | #include <linux/acpi.h> |
9 | 9 | ||
10 | #include "internal.h" | 10 | #include "internal.h" |
11 | 11 | ||
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index d67a1fe07f0e..5837f857ac2e 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -278,12 +278,13 @@ acpi_table_parse_madt(enum acpi_madt_type id, | |||
278 | 278 | ||
279 | /** | 279 | /** |
280 | * acpi_table_parse - find table with @id, run @handler on it | 280 | * acpi_table_parse - find table with @id, run @handler on it |
281 | * | ||
282 | * @id: table id to find | 281 | * @id: table id to find |
283 | * @handler: handler to run | 282 | * @handler: handler to run |
284 | * | 283 | * |
285 | * Scan the ACPI System Descriptor Table (STD) for a table matching @id, | 284 | * Scan the ACPI System Descriptor Table (STD) for a table matching @id, |
286 | * run @handler on it. Return 0 if table found, return on if not. | 285 | * run @handler on it. |
286 | * | ||
287 | * Return 0 if table found, -errno if not. | ||
287 | */ | 288 | */ |
288 | int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler) | 289 | int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler) |
289 | { | 290 | { |
@@ -293,7 +294,7 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler) | |||
293 | if (acpi_disabled) | 294 | if (acpi_disabled) |
294 | return -ENODEV; | 295 | return -ENODEV; |
295 | 296 | ||
296 | if (!handler) | 297 | if (!id || !handler) |
297 | return -EINVAL; | 298 | return -EINVAL; |
298 | 299 | ||
299 | if (strncmp(id, ACPI_SIG_MADT, 4) == 0) | 300 | if (strncmp(id, ACPI_SIG_MADT, 4) == 0) |
@@ -306,7 +307,7 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler) | |||
306 | early_acpi_os_unmap_memory(table, tbl_size); | 307 | early_acpi_os_unmap_memory(table, tbl_size); |
307 | return 0; | 308 | return 0; |
308 | } else | 309 | } else |
309 | return 1; | 310 | return -ENODEV; |
310 | } | 311 | } |
311 | 312 | ||
312 | /* | 313 | /* |
@@ -351,7 +352,7 @@ int __init acpi_table_init(void) | |||
351 | 352 | ||
352 | status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); | 353 | status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); |
353 | if (ACPI_FAILURE(status)) | 354 | if (ACPI_FAILURE(status)) |
354 | return 1; | 355 | return -EINVAL; |
355 | 356 | ||
356 | check_multiple_madt(); | 357 | check_multiple_madt(); |
357 | return 0; | 358 | return 0; |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 0d9f46b5ae6d..8349a555b92b 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -41,10 +41,9 @@ | |||
41 | #include <linux/kmod.h> | 41 | #include <linux/kmod.h> |
42 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
43 | #include <linux/device.h> | 43 | #include <linux/device.h> |
44 | #include <asm/uaccess.h> | ||
45 | #include <linux/thermal.h> | 44 | #include <linux/thermal.h> |
46 | #include <acpi/acpi_bus.h> | 45 | #include <linux/acpi.h> |
47 | #include <acpi/acpi_drivers.h> | 46 | #include <asm/uaccess.h> |
48 | 47 | ||
49 | #define PREFIX "ACPI: " | 48 | #define PREFIX "ACPI: " |
50 | 49 | ||
@@ -862,7 +861,7 @@ acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, | |||
862 | return acpi_thermal_cooling_device_cb(thermal, cdev, false); | 861 | return acpi_thermal_cooling_device_cb(thermal, cdev, false); |
863 | } | 862 | } |
864 | 863 | ||
865 | static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { | 864 | static struct thermal_zone_device_ops acpi_thermal_zone_ops = { |
866 | .bind = acpi_thermal_bind_cooling_device, | 865 | .bind = acpi_thermal_bind_cooling_device, |
867 | .unbind = acpi_thermal_unbind_cooling_device, | 866 | .unbind = acpi_thermal_unbind_cooling_device, |
868 | .get_temp = thermal_get_temp, | 867 | .get_temp = thermal_get_temp, |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 6d408bfbbb1d..0347a37eb438 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/hardirq.h> | 31 | #include <linux/hardirq.h> |
32 | #include <linux/acpi.h> | 32 | #include <linux/acpi.h> |
33 | #include <acpi/acpi_bus.h> | ||
34 | #include <acpi/acpi_drivers.h> | ||
35 | 33 | ||
36 | #include "internal.h" | 34 | #include "internal.h" |
37 | 35 | ||
@@ -574,3 +572,100 @@ acpi_status acpi_evaluate_lck(acpi_handle handle, int lock) | |||
574 | 572 | ||
575 | return status; | 573 | return status; |
576 | } | 574 | } |
575 | |||
576 | /** | ||
577 | * acpi_evaluate_dsm - evaluate device's _DSM method | ||
578 | * @handle: ACPI device handle | ||
579 | * @uuid: UUID of requested functions, should be 16 bytes | ||
580 | * @rev: revision number of requested function | ||
581 | * @func: requested function number | ||
582 | * @argv4: the function specific parameter | ||
583 | * | ||
584 | * Evaluate device's _DSM method with specified UUID, revision id and | ||
585 | * function number. Caller needs to free the returned object. | ||
586 | * | ||
587 | * Though ACPI defines the fourth parameter for _DSM should be a package, | ||
588 | * some old BIOSes do expect a buffer or an integer etc. | ||
589 | */ | ||
590 | union acpi_object * | ||
591 | acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, int rev, int func, | ||
592 | union acpi_object *argv4) | ||
593 | { | ||
594 | acpi_status ret; | ||
595 | struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
596 | union acpi_object params[4]; | ||
597 | struct acpi_object_list input = { | ||
598 | .count = 4, | ||
599 | .pointer = params, | ||
600 | }; | ||
601 | |||
602 | params[0].type = ACPI_TYPE_BUFFER; | ||
603 | params[0].buffer.length = 16; | ||
604 | params[0].buffer.pointer = (char *)uuid; | ||
605 | params[1].type = ACPI_TYPE_INTEGER; | ||
606 | params[1].integer.value = rev; | ||
607 | params[2].type = ACPI_TYPE_INTEGER; | ||
608 | params[2].integer.value = func; | ||
609 | if (argv4) { | ||
610 | params[3] = *argv4; | ||
611 | } else { | ||
612 | params[3].type = ACPI_TYPE_PACKAGE; | ||
613 | params[3].package.count = 0; | ||
614 | params[3].package.elements = NULL; | ||
615 | } | ||
616 | |||
617 | ret = acpi_evaluate_object(handle, "_DSM", &input, &buf); | ||
618 | if (ACPI_SUCCESS(ret)) | ||
619 | return (union acpi_object *)buf.pointer; | ||
620 | |||
621 | if (ret != AE_NOT_FOUND) | ||
622 | acpi_handle_warn(handle, | ||
623 | "failed to evaluate _DSM (0x%x)\n", ret); | ||
624 | |||
625 | return NULL; | ||
626 | } | ||
627 | EXPORT_SYMBOL(acpi_evaluate_dsm); | ||
628 | |||
629 | /** | ||
630 | * acpi_check_dsm - check if _DSM method supports requested functions. | ||
631 | * @handle: ACPI device handle | ||
632 | * @uuid: UUID of requested functions, should be 16 bytes at least | ||
633 | * @rev: revision number of requested functions | ||
634 | * @funcs: bitmap of requested functions | ||
635 | * @exclude: excluding special value, used to support i915 and nouveau | ||
636 | * | ||
637 | * Evaluate device's _DSM method to check whether it supports requested | ||
638 | * functions. Currently only support 64 functions at maximum, should be | ||
639 | * enough for now. | ||
640 | */ | ||
641 | bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs) | ||
642 | { | ||
643 | int i; | ||
644 | u64 mask = 0; | ||
645 | union acpi_object *obj; | ||
646 | |||
647 | if (funcs == 0) | ||
648 | return false; | ||
649 | |||
650 | obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL); | ||
651 | if (!obj) | ||
652 | return false; | ||
653 | |||
654 | /* For compatibility, old BIOSes may return an integer */ | ||
655 | if (obj->type == ACPI_TYPE_INTEGER) | ||
656 | mask = obj->integer.value; | ||
657 | else if (obj->type == ACPI_TYPE_BUFFER) | ||
658 | for (i = 0; i < obj->buffer.length && i < 8; i++) | ||
659 | mask |= (((u8)obj->buffer.pointer[i]) << (i * 8)); | ||
660 | ACPI_FREE(obj); | ||
661 | |||
662 | /* | ||
663 | * Bit 0 indicates whether there's support for any functions other than | ||
664 | * function 0 for the specified UUID and revision. | ||
665 | */ | ||
666 | if ((mask & 0x1) && (mask & funcs) == funcs) | ||
667 | return true; | ||
668 | |||
669 | return false; | ||
670 | } | ||
671 | EXPORT_SYMBOL(acpi_check_dsm); | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 995e91bcb97b..b727d105046d 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -37,12 +37,11 @@ | |||
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/pci_ids.h> | 38 | #include <linux/pci_ids.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <asm/uaccess.h> | ||
41 | #include <linux/dmi.h> | 40 | #include <linux/dmi.h> |
42 | #include <acpi/acpi_bus.h> | ||
43 | #include <acpi/acpi_drivers.h> | ||
44 | #include <linux/suspend.h> | 41 | #include <linux/suspend.h> |
42 | #include <linux/acpi.h> | ||
45 | #include <acpi/video.h> | 43 | #include <acpi/video.h> |
44 | #include <asm/uaccess.h> | ||
46 | 45 | ||
47 | #include "internal.h" | 46 | #include "internal.h" |
48 | 47 | ||
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 84875fd4c74f..f0447d3daf2c 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -50,7 +50,7 @@ static bool acpi_video_caps_checked; | |||
50 | 50 | ||
51 | static acpi_status | 51 | static acpi_status |
52 | acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | 52 | acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, |
53 | void **retyurn_value) | 53 | void **return_value) |
54 | { | 54 | { |
55 | long *cap = context; | 55 | long *cap = context; |
56 | 56 | ||
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 7bfbe40bc43b..1638401ab282 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
@@ -5,7 +5,6 @@ | |||
5 | 5 | ||
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/acpi.h> | 7 | #include <linux/acpi.h> |
8 | #include <acpi/acpi_drivers.h> | ||
9 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
10 | #include <linux/types.h> | 9 | #include <linux/types.h> |
11 | 10 | ||
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 4372cfa883c9..9e69a5308693 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -20,8 +20,6 @@ | |||
20 | #include <scsi/scsi_device.h> | 20 | #include <scsi/scsi_device.h> |
21 | #include "libata.h" | 21 | #include "libata.h" |
22 | 22 | ||
23 | #include <acpi/acpi_bus.h> | ||
24 | |||
25 | unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT; | 23 | unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT; |
26 | module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644); | 24 | module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644); |
27 | MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM, 0x8=FPDMA non-zero offset, 0x10=FPDMA DMA Setup FIS auto-activate)"); | 25 | MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM, 0x8=FPDMA non-zero offset, 0x10=FPDMA DMA Setup FIS auto-activate)"); |
@@ -180,12 +178,12 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = { | |||
180 | /* bind acpi handle to pata port */ | 178 | /* bind acpi handle to pata port */ |
181 | void ata_acpi_bind_port(struct ata_port *ap) | 179 | void ata_acpi_bind_port(struct ata_port *ap) |
182 | { | 180 | { |
183 | acpi_handle host_handle = ACPI_HANDLE(ap->host->dev); | 181 | struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev); |
184 | 182 | ||
185 | if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_handle) | 183 | if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion) |
186 | return; | 184 | return; |
187 | 185 | ||
188 | acpi_preset_companion(&ap->tdev, host_handle, ap->port_no); | 186 | acpi_preset_companion(&ap->tdev, host_companion, ap->port_no); |
189 | 187 | ||
190 | if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) | 188 | if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) |
191 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; | 189 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; |
@@ -198,17 +196,17 @@ void ata_acpi_bind_port(struct ata_port *ap) | |||
198 | void ata_acpi_bind_dev(struct ata_device *dev) | 196 | void ata_acpi_bind_dev(struct ata_device *dev) |
199 | { | 197 | { |
200 | struct ata_port *ap = dev->link->ap; | 198 | struct ata_port *ap = dev->link->ap; |
201 | acpi_handle port_handle = ACPI_HANDLE(&ap->tdev); | 199 | struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev); |
202 | acpi_handle host_handle = ACPI_HANDLE(ap->host->dev); | 200 | struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev); |
203 | acpi_handle parent_handle; | 201 | struct acpi_device *parent; |
204 | u64 adr; | 202 | u64 adr; |
205 | 203 | ||
206 | /* | 204 | /* |
207 | * For both sata/pata devices, host handle is required. | 205 | * For both sata/pata devices, host companion device is required. |
208 | * For pata device, port handle is also required. | 206 | * For pata device, port companion device is also required. |
209 | */ | 207 | */ |
210 | if (libata_noacpi || !host_handle || | 208 | if (libata_noacpi || !host_companion || |
211 | (!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_handle)) | 209 | (!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_companion)) |
212 | return; | 210 | return; |
213 | 211 | ||
214 | if (ap->flags & ATA_FLAG_ACPI_SATA) { | 212 | if (ap->flags & ATA_FLAG_ACPI_SATA) { |
@@ -216,13 +214,13 @@ void ata_acpi_bind_dev(struct ata_device *dev) | |||
216 | adr = SATA_ADR(ap->port_no, NO_PORT_MULT); | 214 | adr = SATA_ADR(ap->port_no, NO_PORT_MULT); |
217 | else | 215 | else |
218 | adr = SATA_ADR(ap->port_no, dev->link->pmp); | 216 | adr = SATA_ADR(ap->port_no, dev->link->pmp); |
219 | parent_handle = host_handle; | 217 | parent = host_companion; |
220 | } else { | 218 | } else { |
221 | adr = dev->devno; | 219 | adr = dev->devno; |
222 | parent_handle = port_handle; | 220 | parent = port_companion; |
223 | } | 221 | } |
224 | 222 | ||
225 | acpi_preset_companion(&dev->tdev, parent_handle, adr); | 223 | acpi_preset_companion(&dev->tdev, parent, adr); |
226 | 224 | ||
227 | register_hotplug_dock_device(ata_dev_acpi_handle(dev), | 225 | register_hotplug_dock_device(ata_dev_acpi_handle(dev), |
228 | &ata_acpi_dev_dock_ops, dev, NULL, NULL); | 226 | &ata_acpi_dev_dock_ops, dev, NULL, NULL); |
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 73212c9c6d5b..62c9ac80c6e9 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c | |||
@@ -12,11 +12,10 @@ | |||
12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/gfp.h> | 14 | #include <linux/gfp.h> |
15 | #include <scsi/scsi_host.h> | 15 | #include <linux/acpi.h> |
16 | #include <acpi/acpi_bus.h> | ||
17 | |||
18 | #include <linux/libata.h> | 16 | #include <linux/libata.h> |
19 | #include <linux/ata.h> | 17 | #include <linux/ata.h> |
18 | #include <scsi/scsi_host.h> | ||
20 | 19 | ||
21 | #define DRV_NAME "pata_acpi" | 20 | #define DRV_NAME "pata_acpi" |
22 | #define DRV_VERSION "0.2.3" | 21 | #define DRV_VERSION "0.2.3" |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 870ecfd503af..04b314e0fa51 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -4,7 +4,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ | |||
4 | driver.o class.o platform.o \ | 4 | driver.o class.o platform.o \ |
5 | cpu.o firmware.o init.o map.o devres.o \ | 5 | cpu.o firmware.o init.o map.o devres.o \ |
6 | attribute_container.o transport_class.o \ | 6 | attribute_container.o transport_class.o \ |
7 | topology.o | 7 | topology.o container.o |
8 | obj-$(CONFIG_DEVTMPFS) += devtmpfs.o | 8 | obj-$(CONFIG_DEVTMPFS) += devtmpfs.o |
9 | obj-$(CONFIG_DMA_CMA) += dma-contiguous.o | 9 | obj-$(CONFIG_DMA_CMA) += dma-contiguous.o |
10 | obj-y += power/ | 10 | obj-y += power/ |
diff --git a/drivers/base/base.h b/drivers/base/base.h index 2cbc6774f4cd..24f424249d9b 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -100,6 +100,7 @@ static inline int hypervisor_init(void) { return 0; } | |||
100 | #endif | 100 | #endif |
101 | extern int platform_bus_init(void); | 101 | extern int platform_bus_init(void); |
102 | extern void cpu_dev_init(void); | 102 | extern void cpu_dev_init(void); |
103 | extern void container_dev_init(void); | ||
103 | 104 | ||
104 | struct kobject *virtual_device_parent(struct device *dev); | 105 | struct kobject *virtual_device_parent(struct device *dev); |
105 | 106 | ||
diff --git a/drivers/base/container.c b/drivers/base/container.c new file mode 100644 index 000000000000..ecbfbe2e908f --- /dev/null +++ b/drivers/base/container.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * System bus type for containers. | ||
3 | * | ||
4 | * Copyright (C) 2013, Intel Corporation | ||
5 | * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/container.h> | ||
13 | |||
14 | #include "base.h" | ||
15 | |||
16 | #define CONTAINER_BUS_NAME "container" | ||
17 | |||
18 | static int trivial_online(struct device *dev) | ||
19 | { | ||
20 | return 0; | ||
21 | } | ||
22 | |||
23 | static int container_offline(struct device *dev) | ||
24 | { | ||
25 | struct container_dev *cdev = to_container_dev(dev); | ||
26 | |||
27 | return cdev->offline ? cdev->offline(cdev) : 0; | ||
28 | } | ||
29 | |||
30 | struct bus_type container_subsys = { | ||
31 | .name = CONTAINER_BUS_NAME, | ||
32 | .dev_name = CONTAINER_BUS_NAME, | ||
33 | .online = trivial_online, | ||
34 | .offline = container_offline, | ||
35 | }; | ||
36 | |||
37 | void __init container_dev_init(void) | ||
38 | { | ||
39 | int ret; | ||
40 | |||
41 | ret = subsys_system_register(&container_subsys, NULL); | ||
42 | if (ret) | ||
43 | pr_err("%s() failed: %d\n", __func__, ret); | ||
44 | } | ||
diff --git a/drivers/base/init.c b/drivers/base/init.c index c16f0b808a17..da033d3bab3c 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c | |||
@@ -33,4 +33,5 @@ void __init driver_init(void) | |||
33 | platform_bus_init(); | 33 | platform_bus_init(); |
34 | cpu_dev_init(); | 34 | cpu_dev_init(); |
35 | memory_dev_init(); | 35 | memory_dev_init(); |
36 | container_dev_init(); | ||
36 | } | 37 | } |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 3a94b799f166..bc78848dd59a 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -677,7 +677,17 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | |||
677 | char *buf) | 677 | char *buf) |
678 | { | 678 | { |
679 | struct platform_device *pdev = to_platform_device(dev); | 679 | struct platform_device *pdev = to_platform_device(dev); |
680 | int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | 680 | int len; |
681 | |||
682 | len = of_device_get_modalias(dev, buf, PAGE_SIZE -1); | ||
683 | if (len != -ENODEV) | ||
684 | return len; | ||
685 | |||
686 | len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); | ||
687 | if (len != -ENODEV) | ||
688 | return len; | ||
689 | |||
690 | len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | ||
681 | 691 | ||
682 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 692 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
683 | } | 693 | } |
@@ -699,6 +709,10 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
699 | if (rc != -ENODEV) | 709 | if (rc != -ENODEV) |
700 | return rc; | 710 | return rc; |
701 | 711 | ||
712 | rc = acpi_device_uevent_modalias(dev, env); | ||
713 | if (rc != -ENODEV) | ||
714 | return rc; | ||
715 | |||
702 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, | 716 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, |
703 | pdev->name); | 717 | pdev->name); |
704 | return 0; | 718 | return 0; |
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 9d8fde709390..e870bbe9ec4e 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c | |||
@@ -33,6 +33,21 @@ struct pm_clock_entry { | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * pm_clk_enable - Enable a clock, reporting any errors | ||
37 | * @dev: The device for the given clock | ||
38 | * @clk: The clock being enabled. | ||
39 | */ | ||
40 | static inline int __pm_clk_enable(struct device *dev, struct clk *clk) | ||
41 | { | ||
42 | int ret = clk_enable(clk); | ||
43 | if (ret) | ||
44 | dev_err(dev, "%s: failed to enable clk %p, error %d\n", | ||
45 | __func__, clk, ret); | ||
46 | |||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | /** | ||
36 | * pm_clk_acquire - Acquire a device clock. | 51 | * pm_clk_acquire - Acquire a device clock. |
37 | * @dev: Device whose clock is to be acquired. | 52 | * @dev: Device whose clock is to be acquired. |
38 | * @ce: PM clock entry corresponding to the clock. | 53 | * @ce: PM clock entry corresponding to the clock. |
@@ -43,6 +58,7 @@ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) | |||
43 | if (IS_ERR(ce->clk)) { | 58 | if (IS_ERR(ce->clk)) { |
44 | ce->status = PCE_STATUS_ERROR; | 59 | ce->status = PCE_STATUS_ERROR; |
45 | } else { | 60 | } else { |
61 | clk_prepare(ce->clk); | ||
46 | ce->status = PCE_STATUS_ACQUIRED; | 62 | ce->status = PCE_STATUS_ACQUIRED; |
47 | dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); | 63 | dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); |
48 | } | 64 | } |
@@ -99,10 +115,12 @@ static void __pm_clk_remove(struct pm_clock_entry *ce) | |||
99 | 115 | ||
100 | if (ce->status < PCE_STATUS_ERROR) { | 116 | if (ce->status < PCE_STATUS_ERROR) { |
101 | if (ce->status == PCE_STATUS_ENABLED) | 117 | if (ce->status == PCE_STATUS_ENABLED) |
102 | clk_disable_unprepare(ce->clk); | 118 | clk_disable(ce->clk); |
103 | 119 | ||
104 | if (ce->status >= PCE_STATUS_ACQUIRED) | 120 | if (ce->status >= PCE_STATUS_ACQUIRED) { |
121 | clk_unprepare(ce->clk); | ||
105 | clk_put(ce->clk); | 122 | clk_put(ce->clk); |
123 | } | ||
106 | } | 124 | } |
107 | 125 | ||
108 | kfree(ce->con_id); | 126 | kfree(ce->con_id); |
@@ -249,6 +267,7 @@ int pm_clk_resume(struct device *dev) | |||
249 | struct pm_subsys_data *psd = dev_to_psd(dev); | 267 | struct pm_subsys_data *psd = dev_to_psd(dev); |
250 | struct pm_clock_entry *ce; | 268 | struct pm_clock_entry *ce; |
251 | unsigned long flags; | 269 | unsigned long flags; |
270 | int ret; | ||
252 | 271 | ||
253 | dev_dbg(dev, "%s()\n", __func__); | 272 | dev_dbg(dev, "%s()\n", __func__); |
254 | 273 | ||
@@ -259,8 +278,9 @@ int pm_clk_resume(struct device *dev) | |||
259 | 278 | ||
260 | list_for_each_entry(ce, &psd->clock_list, node) { | 279 | list_for_each_entry(ce, &psd->clock_list, node) { |
261 | if (ce->status < PCE_STATUS_ERROR) { | 280 | if (ce->status < PCE_STATUS_ERROR) { |
262 | clk_enable(ce->clk); | 281 | ret = __pm_clk_enable(dev, ce->clk); |
263 | ce->status = PCE_STATUS_ENABLED; | 282 | if (!ret) |
283 | ce->status = PCE_STATUS_ENABLED; | ||
264 | } | 284 | } |
265 | } | 285 | } |
266 | 286 | ||
@@ -376,7 +396,7 @@ int pm_clk_resume(struct device *dev) | |||
376 | spin_lock_irqsave(&psd->lock, flags); | 396 | spin_lock_irqsave(&psd->lock, flags); |
377 | 397 | ||
378 | list_for_each_entry(ce, &psd->clock_list, node) | 398 | list_for_each_entry(ce, &psd->clock_list, node) |
379 | clk_enable(ce->clk); | 399 | __pm_clk_enable(dev, ce->clk); |
380 | 400 | ||
381 | spin_unlock_irqrestore(&psd->lock, flags); | 401 | spin_unlock_irqrestore(&psd->lock, flags); |
382 | 402 | ||
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index 5ee030a864f9..a2e55bfdf572 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/pm_runtime.h> | 10 | #include <linux/pm_runtime.h> |
11 | #include <linux/export.h> | 11 | #include <linux/export.h> |
12 | 12 | ||
13 | #ifdef CONFIG_PM_RUNTIME | 13 | #ifdef CONFIG_PM |
14 | /** | 14 | /** |
15 | * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. | 15 | * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. |
16 | * @dev: Device to suspend. | 16 | * @dev: Device to suspend. |
@@ -48,7 +48,7 @@ int pm_generic_runtime_resume(struct device *dev) | |||
48 | return ret; | 48 | return ret; |
49 | } | 49 | } |
50 | EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); | 50 | EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); |
51 | #endif /* CONFIG_PM_RUNTIME */ | 51 | #endif /* CONFIG_PM */ |
52 | 52 | ||
53 | #ifdef CONFIG_PM_SLEEP | 53 | #ifdef CONFIG_PM_SLEEP |
54 | /** | 54 | /** |
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index 46118f845948..dd9dfa15e9d1 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c | |||
@@ -531,6 +531,7 @@ static int apm_suspend_notifier(struct notifier_block *nb, | |||
531 | { | 531 | { |
532 | struct apm_user *as; | 532 | struct apm_user *as; |
533 | int err; | 533 | int err; |
534 | unsigned long apm_event; | ||
534 | 535 | ||
535 | /* short-cut emergency suspends */ | 536 | /* short-cut emergency suspends */ |
536 | if (atomic_read(&userspace_notification_inhibit)) | 537 | if (atomic_read(&userspace_notification_inhibit)) |
@@ -538,6 +539,9 @@ static int apm_suspend_notifier(struct notifier_block *nb, | |||
538 | 539 | ||
539 | switch (event) { | 540 | switch (event) { |
540 | case PM_SUSPEND_PREPARE: | 541 | case PM_SUSPEND_PREPARE: |
542 | case PM_HIBERNATION_PREPARE: | ||
543 | apm_event = (event == PM_SUSPEND_PREPARE) ? | ||
544 | APM_USER_SUSPEND : APM_USER_HIBERNATION; | ||
541 | /* | 545 | /* |
542 | * Queue an event to all "writer" users that we want | 546 | * Queue an event to all "writer" users that we want |
543 | * to suspend and need their ack. | 547 | * to suspend and need their ack. |
@@ -550,7 +554,7 @@ static int apm_suspend_notifier(struct notifier_block *nb, | |||
550 | as->writer && as->suser) { | 554 | as->writer && as->suser) { |
551 | as->suspend_state = SUSPEND_PENDING; | 555 | as->suspend_state = SUSPEND_PENDING; |
552 | atomic_inc(&suspend_acks_pending); | 556 | atomic_inc(&suspend_acks_pending); |
553 | queue_add_event(&as->queue, APM_USER_SUSPEND); | 557 | queue_add_event(&as->queue, apm_event); |
554 | } | 558 | } |
555 | } | 559 | } |
556 | 560 | ||
@@ -601,11 +605,14 @@ static int apm_suspend_notifier(struct notifier_block *nb, | |||
601 | return notifier_from_errno(err); | 605 | return notifier_from_errno(err); |
602 | 606 | ||
603 | case PM_POST_SUSPEND: | 607 | case PM_POST_SUSPEND: |
608 | case PM_POST_HIBERNATION: | ||
609 | apm_event = (event == PM_POST_SUSPEND) ? | ||
610 | APM_NORMAL_RESUME : APM_HIBERNATION_RESUME; | ||
604 | /* | 611 | /* |
605 | * Anyone on the APM queues will think we're still suspended. | 612 | * Anyone on the APM queues will think we're still suspended. |
606 | * Send a message so everyone knows we're now awake again. | 613 | * Send a message so everyone knows we're now awake again. |
607 | */ | 614 | */ |
608 | queue_event(APM_NORMAL_RESUME); | 615 | queue_event(apm_event); |
609 | 616 | ||
610 | /* | 617 | /* |
611 | * Finally, wake up anyone who is sleeping on the suspend. | 618 | * Finally, wake up anyone who is sleeping on the suspend. |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 5d9c31dfc905..d5d4cd82b9f7 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -34,15 +34,12 @@ | |||
34 | #include <linux/uaccess.h> | 34 | #include <linux/uaccess.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/io.h> | 36 | #include <linux/io.h> |
37 | 37 | #include <linux/acpi.h> | |
38 | #include <linux/hpet.h> | ||
38 | #include <asm/current.h> | 39 | #include <asm/current.h> |
39 | #include <asm/irq.h> | 40 | #include <asm/irq.h> |
40 | #include <asm/div64.h> | 41 | #include <asm/div64.h> |
41 | 42 | ||
42 | #include <linux/acpi.h> | ||
43 | #include <acpi/acpi_bus.h> | ||
44 | #include <linux/hpet.h> | ||
45 | |||
46 | /* | 43 | /* |
47 | * The High Precision Event Timer driver. | 44 | * The High Precision Event Timer driver. |
48 | * This driver is closely modelled after the rtc.c driver. | 45 | * This driver is closely modelled after the rtc.c driver. |
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c index 64420b3396a2..b9a57fa4b710 100644 --- a/drivers/char/tpm/tpm_acpi.c +++ b/drivers/char/tpm/tpm_acpi.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/security.h> | 23 | #include <linux/security.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <acpi/acpi.h> | 26 | #include <linux/acpi.h> |
27 | 27 | ||
28 | #include "tpm.h" | 28 | #include "tpm.h" |
29 | #include "tpm_eventlog.h" | 29 | #include "tpm_eventlog.h" |
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index 2db4419831be..b3ea223585bd 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c | |||
@@ -1,16 +1,6 @@ | |||
1 | #include <linux/acpi.h> | 1 | #include <linux/acpi.h> |
2 | #include <acpi/acpi_drivers.h> | ||
3 | #include "tpm.h" | 2 | #include "tpm.h" |
4 | 3 | ||
5 | static const u8 tpm_ppi_uuid[] = { | ||
6 | 0xA6, 0xFA, 0xDD, 0x3D, | ||
7 | 0x1B, 0x36, | ||
8 | 0xB4, 0x4E, | ||
9 | 0xA4, 0x24, | ||
10 | 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53 | ||
11 | }; | ||
12 | static char *tpm_device_name = "TPM"; | ||
13 | |||
14 | #define TPM_PPI_REVISION_ID 1 | 4 | #define TPM_PPI_REVISION_ID 1 |
15 | #define TPM_PPI_FN_VERSION 1 | 5 | #define TPM_PPI_FN_VERSION 1 |
16 | #define TPM_PPI_FN_SUBREQ 2 | 6 | #define TPM_PPI_FN_SUBREQ 2 |
@@ -24,250 +14,178 @@ static char *tpm_device_name = "TPM"; | |||
24 | #define PPI_VS_REQ_END 255 | 14 | #define PPI_VS_REQ_END 255 |
25 | #define PPI_VERSION_LEN 3 | 15 | #define PPI_VERSION_LEN 3 |
26 | 16 | ||
17 | static const u8 tpm_ppi_uuid[] = { | ||
18 | 0xA6, 0xFA, 0xDD, 0x3D, | ||
19 | 0x1B, 0x36, | ||
20 | 0xB4, 0x4E, | ||
21 | 0xA4, 0x24, | ||
22 | 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53 | ||
23 | }; | ||
24 | |||
25 | static char tpm_ppi_version[PPI_VERSION_LEN + 1]; | ||
26 | static acpi_handle tpm_ppi_handle; | ||
27 | |||
27 | static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context, | 28 | static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context, |
28 | void **return_value) | 29 | void **return_value) |
29 | { | 30 | { |
30 | acpi_status status = AE_OK; | 31 | union acpi_object *obj; |
31 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
32 | 32 | ||
33 | if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer))) { | 33 | if (!acpi_check_dsm(handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID, |
34 | if (strstr(buffer.pointer, context) != NULL) { | 34 | 1 << TPM_PPI_FN_VERSION)) |
35 | *return_value = handle; | 35 | return AE_OK; |
36 | status = AE_CTRL_TERMINATE; | 36 | |
37 | } | 37 | /* Cache version string */ |
38 | kfree(buffer.pointer); | 38 | obj = acpi_evaluate_dsm_typed(handle, tpm_ppi_uuid, |
39 | TPM_PPI_REVISION_ID, TPM_PPI_FN_VERSION, | ||
40 | NULL, ACPI_TYPE_STRING); | ||
41 | if (obj) { | ||
42 | strlcpy(tpm_ppi_version, obj->string.pointer, | ||
43 | PPI_VERSION_LEN + 1); | ||
44 | ACPI_FREE(obj); | ||
39 | } | 45 | } |
40 | 46 | ||
41 | return status; | 47 | *return_value = handle; |
48 | |||
49 | return AE_CTRL_TERMINATE; | ||
42 | } | 50 | } |
43 | 51 | ||
44 | static inline void ppi_assign_params(union acpi_object params[4], | 52 | static inline union acpi_object * |
45 | u64 function_num) | 53 | tpm_eval_dsm(int func, acpi_object_type type, union acpi_object *argv4) |
46 | { | 54 | { |
47 | params[0].type = ACPI_TYPE_BUFFER; | 55 | BUG_ON(!tpm_ppi_handle); |
48 | params[0].buffer.length = sizeof(tpm_ppi_uuid); | 56 | return acpi_evaluate_dsm_typed(tpm_ppi_handle, tpm_ppi_uuid, |
49 | params[0].buffer.pointer = (char *)tpm_ppi_uuid; | 57 | TPM_PPI_REVISION_ID, func, argv4, type); |
50 | params[1].type = ACPI_TYPE_INTEGER; | ||
51 | params[1].integer.value = TPM_PPI_REVISION_ID; | ||
52 | params[2].type = ACPI_TYPE_INTEGER; | ||
53 | params[2].integer.value = function_num; | ||
54 | params[3].type = ACPI_TYPE_PACKAGE; | ||
55 | params[3].package.count = 0; | ||
56 | params[3].package.elements = NULL; | ||
57 | } | 58 | } |
58 | 59 | ||
59 | static ssize_t tpm_show_ppi_version(struct device *dev, | 60 | static ssize_t tpm_show_ppi_version(struct device *dev, |
60 | struct device_attribute *attr, char *buf) | 61 | struct device_attribute *attr, char *buf) |
61 | { | 62 | { |
62 | acpi_handle handle; | 63 | return scnprintf(buf, PAGE_SIZE, "%s\n", tpm_ppi_version); |
63 | acpi_status status; | ||
64 | struct acpi_object_list input; | ||
65 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
66 | union acpi_object params[4]; | ||
67 | union acpi_object *obj; | ||
68 | |||
69 | input.count = 4; | ||
70 | ppi_assign_params(params, TPM_PPI_FN_VERSION); | ||
71 | input.pointer = params; | ||
72 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
73 | ACPI_UINT32_MAX, ppi_callback, NULL, | ||
74 | tpm_device_name, &handle); | ||
75 | if (ACPI_FAILURE(status)) | ||
76 | return -ENXIO; | ||
77 | |||
78 | status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, | ||
79 | ACPI_TYPE_STRING); | ||
80 | if (ACPI_FAILURE(status)) | ||
81 | return -ENOMEM; | ||
82 | obj = (union acpi_object *)output.pointer; | ||
83 | status = scnprintf(buf, PAGE_SIZE, "%s\n", obj->string.pointer); | ||
84 | kfree(output.pointer); | ||
85 | return status; | ||
86 | } | 64 | } |
87 | 65 | ||
88 | static ssize_t tpm_show_ppi_request(struct device *dev, | 66 | static ssize_t tpm_show_ppi_request(struct device *dev, |
89 | struct device_attribute *attr, char *buf) | 67 | struct device_attribute *attr, char *buf) |
90 | { | 68 | { |
91 | acpi_handle handle; | 69 | ssize_t size = -EINVAL; |
92 | acpi_status status; | 70 | union acpi_object *obj; |
93 | struct acpi_object_list input; | 71 | |
94 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 72 | obj = tpm_eval_dsm(TPM_PPI_FN_GETREQ, ACPI_TYPE_PACKAGE, NULL); |
95 | union acpi_object params[4]; | 73 | if (!obj) |
96 | union acpi_object *ret_obj; | ||
97 | |||
98 | input.count = 4; | ||
99 | ppi_assign_params(params, TPM_PPI_FN_GETREQ); | ||
100 | input.pointer = params; | ||
101 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
102 | ACPI_UINT32_MAX, ppi_callback, NULL, | ||
103 | tpm_device_name, &handle); | ||
104 | if (ACPI_FAILURE(status)) | ||
105 | return -ENXIO; | 74 | return -ENXIO; |
106 | 75 | ||
107 | status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, | ||
108 | ACPI_TYPE_PACKAGE); | ||
109 | if (ACPI_FAILURE(status)) | ||
110 | return -ENOMEM; | ||
111 | /* | 76 | /* |
112 | * output.pointer should be of package type, including two integers. | 77 | * output.pointer should be of package type, including two integers. |
113 | * The first is function return code, 0 means success and 1 means | 78 | * The first is function return code, 0 means success and 1 means |
114 | * error. The second is pending TPM operation requested by the OS, 0 | 79 | * error. The second is pending TPM operation requested by the OS, 0 |
115 | * means none and >0 means operation value. | 80 | * means none and >0 means operation value. |
116 | */ | 81 | */ |
117 | ret_obj = ((union acpi_object *)output.pointer)->package.elements; | 82 | if (obj->package.count == 2 && |
118 | if (ret_obj->type == ACPI_TYPE_INTEGER) { | 83 | obj->package.elements[0].type == ACPI_TYPE_INTEGER && |
119 | if (ret_obj->integer.value) { | 84 | obj->package.elements[1].type == ACPI_TYPE_INTEGER) { |
120 | status = -EFAULT; | 85 | if (obj->package.elements[0].integer.value) |
121 | goto cleanup; | 86 | size = -EFAULT; |
122 | } | ||
123 | ret_obj++; | ||
124 | if (ret_obj->type == ACPI_TYPE_INTEGER) | ||
125 | status = scnprintf(buf, PAGE_SIZE, "%llu\n", | ||
126 | ret_obj->integer.value); | ||
127 | else | 87 | else |
128 | status = -EINVAL; | 88 | size = scnprintf(buf, PAGE_SIZE, "%llu\n", |
129 | } else { | 89 | obj->package.elements[1].integer.value); |
130 | status = -EINVAL; | ||
131 | } | 90 | } |
132 | cleanup: | 91 | |
133 | kfree(output.pointer); | 92 | ACPI_FREE(obj); |
134 | return status; | 93 | |
94 | return size; | ||
135 | } | 95 | } |
136 | 96 | ||
137 | static ssize_t tpm_store_ppi_request(struct device *dev, | 97 | static ssize_t tpm_store_ppi_request(struct device *dev, |
138 | struct device_attribute *attr, | 98 | struct device_attribute *attr, |
139 | const char *buf, size_t count) | 99 | const char *buf, size_t count) |
140 | { | 100 | { |
141 | char version[PPI_VERSION_LEN + 1]; | ||
142 | acpi_handle handle; | ||
143 | acpi_status status; | ||
144 | struct acpi_object_list input; | ||
145 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
146 | union acpi_object params[4]; | ||
147 | union acpi_object obj; | ||
148 | u32 req; | 101 | u32 req; |
149 | u64 ret; | 102 | u64 ret; |
103 | int func = TPM_PPI_FN_SUBREQ; | ||
104 | union acpi_object *obj, tmp; | ||
105 | union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp); | ||
150 | 106 | ||
151 | input.count = 4; | ||
152 | ppi_assign_params(params, TPM_PPI_FN_VERSION); | ||
153 | input.pointer = params; | ||
154 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
155 | ACPI_UINT32_MAX, ppi_callback, NULL, | ||
156 | tpm_device_name, &handle); | ||
157 | if (ACPI_FAILURE(status)) | ||
158 | return -ENXIO; | ||
159 | |||
160 | status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, | ||
161 | ACPI_TYPE_STRING); | ||
162 | if (ACPI_FAILURE(status)) | ||
163 | return -ENOMEM; | ||
164 | strlcpy(version, | ||
165 | ((union acpi_object *)output.pointer)->string.pointer, | ||
166 | PPI_VERSION_LEN + 1); | ||
167 | kfree(output.pointer); | ||
168 | output.length = ACPI_ALLOCATE_BUFFER; | ||
169 | output.pointer = NULL; | ||
170 | /* | 107 | /* |
171 | * the function to submit TPM operation request to pre-os environment | 108 | * the function to submit TPM operation request to pre-os environment |
172 | * is updated with function index from SUBREQ to SUBREQ2 since PPI | 109 | * is updated with function index from SUBREQ to SUBREQ2 since PPI |
173 | * version 1.1 | 110 | * version 1.1 |
174 | */ | 111 | */ |
175 | if (strcmp(version, "1.1") < 0) | 112 | if (acpi_check_dsm(tpm_ppi_handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID, |
176 | params[2].integer.value = TPM_PPI_FN_SUBREQ; | 113 | 1 << TPM_PPI_FN_SUBREQ2)) |
177 | else | 114 | func = TPM_PPI_FN_SUBREQ2; |
178 | params[2].integer.value = TPM_PPI_FN_SUBREQ2; | 115 | |
179 | /* | 116 | /* |
180 | * PPI spec defines params[3].type as ACPI_TYPE_PACKAGE. Some BIOS | 117 | * PPI spec defines params[3].type as ACPI_TYPE_PACKAGE. Some BIOS |
181 | * accept buffer/string/integer type, but some BIOS accept buffer/ | 118 | * accept buffer/string/integer type, but some BIOS accept buffer/ |
182 | * string/package type. For PPI version 1.0 and 1.1, use buffer type | 119 | * string/package type. For PPI version 1.0 and 1.1, use buffer type |
183 | * for compatibility, and use package type since 1.2 according to spec. | 120 | * for compatibility, and use package type since 1.2 according to spec. |
184 | */ | 121 | */ |
185 | if (strcmp(version, "1.2") < 0) { | 122 | if (strcmp(tpm_ppi_version, "1.2") < 0) { |
186 | params[3].type = ACPI_TYPE_BUFFER; | 123 | if (sscanf(buf, "%d", &req) != 1) |
187 | params[3].buffer.length = sizeof(req); | 124 | return -EINVAL; |
188 | sscanf(buf, "%d", &req); | 125 | argv4.type = ACPI_TYPE_BUFFER; |
189 | params[3].buffer.pointer = (char *)&req; | 126 | argv4.buffer.length = sizeof(req); |
127 | argv4.buffer.pointer = (u8 *)&req; | ||
128 | } else { | ||
129 | tmp.type = ACPI_TYPE_INTEGER; | ||
130 | if (sscanf(buf, "%llu", &tmp.integer.value) != 1) | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | obj = tpm_eval_dsm(func, ACPI_TYPE_INTEGER, &argv4); | ||
135 | if (!obj) { | ||
136 | return -ENXIO; | ||
190 | } else { | 137 | } else { |
191 | params[3].package.count = 1; | 138 | ret = obj->integer.value; |
192 | obj.type = ACPI_TYPE_INTEGER; | 139 | ACPI_FREE(obj); |
193 | sscanf(buf, "%llu", &obj.integer.value); | ||
194 | params[3].package.elements = &obj; | ||
195 | } | 140 | } |
196 | 141 | ||
197 | status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, | ||
198 | ACPI_TYPE_INTEGER); | ||
199 | if (ACPI_FAILURE(status)) | ||
200 | return -ENOMEM; | ||
201 | ret = ((union acpi_object *)output.pointer)->integer.value; | ||
202 | if (ret == 0) | 142 | if (ret == 0) |
203 | status = (acpi_status)count; | 143 | return (acpi_status)count; |
204 | else if (ret == 1) | 144 | |
205 | status = -EPERM; | 145 | return (ret == 1) ? -EPERM : -EFAULT; |
206 | else | ||
207 | status = -EFAULT; | ||
208 | kfree(output.pointer); | ||
209 | return status; | ||
210 | } | 146 | } |
211 | 147 | ||
212 | static ssize_t tpm_show_ppi_transition_action(struct device *dev, | 148 | static ssize_t tpm_show_ppi_transition_action(struct device *dev, |
213 | struct device_attribute *attr, | 149 | struct device_attribute *attr, |
214 | char *buf) | 150 | char *buf) |
215 | { | 151 | { |
216 | char version[PPI_VERSION_LEN + 1]; | ||
217 | acpi_handle handle; | ||
218 | acpi_status status; | ||
219 | struct acpi_object_list input; | ||
220 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
221 | union acpi_object params[4]; | ||
222 | u32 ret; | 152 | u32 ret; |
223 | char *info[] = { | 153 | acpi_status status; |
154 | union acpi_object *obj = NULL; | ||
155 | union acpi_object tmp = { | ||
156 | .buffer.type = ACPI_TYPE_BUFFER, | ||
157 | .buffer.length = 0, | ||
158 | .buffer.pointer = NULL | ||
159 | }; | ||
160 | |||
161 | static char *info[] = { | ||
224 | "None", | 162 | "None", |
225 | "Shutdown", | 163 | "Shutdown", |
226 | "Reboot", | 164 | "Reboot", |
227 | "OS Vendor-specific", | 165 | "OS Vendor-specific", |
228 | "Error", | 166 | "Error", |
229 | }; | 167 | }; |
230 | input.count = 4; | ||
231 | ppi_assign_params(params, TPM_PPI_FN_VERSION); | ||
232 | input.pointer = params; | ||
233 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
234 | ACPI_UINT32_MAX, ppi_callback, NULL, | ||
235 | tpm_device_name, &handle); | ||
236 | if (ACPI_FAILURE(status)) | ||
237 | return -ENXIO; | ||
238 | 168 | ||
239 | status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, | ||
240 | ACPI_TYPE_STRING); | ||
241 | if (ACPI_FAILURE(status)) | ||
242 | return -ENOMEM; | ||
243 | strlcpy(version, | ||
244 | ((union acpi_object *)output.pointer)->string.pointer, | ||
245 | PPI_VERSION_LEN + 1); | ||
246 | /* | 169 | /* |
247 | * PPI spec defines params[3].type as empty package, but some platforms | 170 | * PPI spec defines params[3].type as empty package, but some platforms |
248 | * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for | 171 | * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for |
249 | * compatibility, define params[3].type as buffer, if PPI version < 1.2 | 172 | * compatibility, define params[3].type as buffer, if PPI version < 1.2 |
250 | */ | 173 | */ |
251 | if (strcmp(version, "1.2") < 0) { | 174 | if (strcmp(tpm_ppi_version, "1.2") < 0) |
252 | params[3].type = ACPI_TYPE_BUFFER; | 175 | obj = &tmp; |
253 | params[3].buffer.length = 0; | 176 | obj = tpm_eval_dsm(TPM_PPI_FN_GETACT, ACPI_TYPE_INTEGER, obj); |
254 | params[3].buffer.pointer = NULL; | 177 | if (!obj) { |
178 | return -ENXIO; | ||
179 | } else { | ||
180 | ret = obj->integer.value; | ||
181 | ACPI_FREE(obj); | ||
255 | } | 182 | } |
256 | params[2].integer.value = TPM_PPI_FN_GETACT; | 183 | |
257 | kfree(output.pointer); | ||
258 | output.length = ACPI_ALLOCATE_BUFFER; | ||
259 | output.pointer = NULL; | ||
260 | status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, | ||
261 | ACPI_TYPE_INTEGER); | ||
262 | if (ACPI_FAILURE(status)) | ||
263 | return -ENOMEM; | ||
264 | ret = ((union acpi_object *)output.pointer)->integer.value; | ||
265 | if (ret < ARRAY_SIZE(info) - 1) | 184 | if (ret < ARRAY_SIZE(info) - 1) |
266 | status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, info[ret]); | 185 | status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, info[ret]); |
267 | else | 186 | else |
268 | status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, | 187 | status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, |
269 | info[ARRAY_SIZE(info)-1]); | 188 | info[ARRAY_SIZE(info)-1]); |
270 | kfree(output.pointer); | ||
271 | return status; | 189 | return status; |
272 | } | 190 | } |
273 | 191 | ||
@@ -275,27 +193,14 @@ static ssize_t tpm_show_ppi_response(struct device *dev, | |||
275 | struct device_attribute *attr, | 193 | struct device_attribute *attr, |
276 | char *buf) | 194 | char *buf) |
277 | { | 195 | { |
278 | acpi_handle handle; | 196 | acpi_status status = -EINVAL; |
279 | acpi_status status; | 197 | union acpi_object *obj, *ret_obj; |
280 | struct acpi_object_list input; | 198 | u64 req, res; |
281 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 199 | |
282 | union acpi_object params[4]; | 200 | obj = tpm_eval_dsm(TPM_PPI_FN_GETRSP, ACPI_TYPE_PACKAGE, NULL); |
283 | union acpi_object *ret_obj; | 201 | if (!obj) |
284 | u64 req; | ||
285 | |||
286 | input.count = 4; | ||
287 | ppi_assign_params(params, TPM_PPI_FN_GETRSP); | ||
288 | input.pointer = params; | ||
289 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
290 | ACPI_UINT32_MAX, ppi_callback, NULL, | ||
291 | tpm_device_name, &handle); | ||
292 | if (ACPI_FAILURE(status)) | ||
293 | return -ENXIO; | 202 | return -ENXIO; |
294 | 203 | ||
295 | status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, | ||
296 | ACPI_TYPE_PACKAGE); | ||
297 | if (ACPI_FAILURE(status)) | ||
298 | return -ENOMEM; | ||
299 | /* | 204 | /* |
300 | * parameter output.pointer should be of package type, including | 205 | * parameter output.pointer should be of package type, including |
301 | * 3 integers. The first means function return code, the second means | 206 | * 3 integers. The first means function return code, the second means |
@@ -303,115 +208,82 @@ static ssize_t tpm_show_ppi_response(struct device *dev, | |||
303 | * the most recent TPM operation request. Only if the first is 0, and | 208 | * the most recent TPM operation request. Only if the first is 0, and |
304 | * the second integer is not 0, the response makes sense. | 209 | * the second integer is not 0, the response makes sense. |
305 | */ | 210 | */ |
306 | ret_obj = ((union acpi_object *)output.pointer)->package.elements; | 211 | ret_obj = obj->package.elements; |
307 | if (ret_obj->type != ACPI_TYPE_INTEGER) { | 212 | if (obj->package.count < 3 || |
308 | status = -EINVAL; | 213 | ret_obj[0].type != ACPI_TYPE_INTEGER || |
214 | ret_obj[1].type != ACPI_TYPE_INTEGER || | ||
215 | ret_obj[2].type != ACPI_TYPE_INTEGER) | ||
309 | goto cleanup; | 216 | goto cleanup; |
310 | } | 217 | |
311 | if (ret_obj->integer.value) { | 218 | if (ret_obj[0].integer.value) { |
312 | status = -EFAULT; | 219 | status = -EFAULT; |
313 | goto cleanup; | 220 | goto cleanup; |
314 | } | 221 | } |
315 | ret_obj++; | 222 | |
316 | if (ret_obj->type != ACPI_TYPE_INTEGER) { | 223 | req = ret_obj[1].integer.value; |
317 | status = -EINVAL; | 224 | res = ret_obj[2].integer.value; |
318 | goto cleanup; | 225 | if (req) { |
319 | } | 226 | if (res == 0) |
320 | if (ret_obj->integer.value) { | ||
321 | req = ret_obj->integer.value; | ||
322 | ret_obj++; | ||
323 | if (ret_obj->type != ACPI_TYPE_INTEGER) { | ||
324 | status = -EINVAL; | ||
325 | goto cleanup; | ||
326 | } | ||
327 | if (ret_obj->integer.value == 0) | ||
328 | status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, | 227 | status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, |
329 | "0: Success"); | 228 | "0: Success"); |
330 | else if (ret_obj->integer.value == 0xFFFFFFF0) | 229 | else if (res == 0xFFFFFFF0) |
331 | status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, | 230 | status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, |
332 | "0xFFFFFFF0: User Abort"); | 231 | "0xFFFFFFF0: User Abort"); |
333 | else if (ret_obj->integer.value == 0xFFFFFFF1) | 232 | else if (res == 0xFFFFFFF1) |
334 | status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, | 233 | status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, |
335 | "0xFFFFFFF1: BIOS Failure"); | 234 | "0xFFFFFFF1: BIOS Failure"); |
336 | else if (ret_obj->integer.value >= 1 && | 235 | else if (res >= 1 && res <= 0x00000FFF) |
337 | ret_obj->integer.value <= 0x00000FFF) | ||
338 | status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n", | 236 | status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n", |
339 | req, ret_obj->integer.value, | 237 | req, res, "Corresponding TPM error"); |
340 | "Corresponding TPM error"); | ||
341 | else | 238 | else |
342 | status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n", | 239 | status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n", |
343 | req, ret_obj->integer.value, | 240 | req, res, "Error"); |
344 | "Error"); | ||
345 | } else { | 241 | } else { |
346 | status = scnprintf(buf, PAGE_SIZE, "%llu: %s\n", | 242 | status = scnprintf(buf, PAGE_SIZE, "%llu: %s\n", |
347 | ret_obj->integer.value, "No Recent Request"); | 243 | req, "No Recent Request"); |
348 | } | 244 | } |
245 | |||
349 | cleanup: | 246 | cleanup: |
350 | kfree(output.pointer); | 247 | ACPI_FREE(obj); |
351 | return status; | 248 | return status; |
352 | } | 249 | } |
353 | 250 | ||
354 | static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) | 251 | static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) |
355 | { | 252 | { |
356 | char *str = buf; | ||
357 | char version[PPI_VERSION_LEN + 1]; | ||
358 | acpi_handle handle; | ||
359 | acpi_status status; | ||
360 | struct acpi_object_list input; | ||
361 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
362 | union acpi_object params[4]; | ||
363 | union acpi_object obj; | ||
364 | int i; | 253 | int i; |
365 | u32 ret; | 254 | u32 ret; |
366 | char *info[] = { | 255 | char *str = buf; |
256 | union acpi_object *obj, tmp; | ||
257 | union acpi_object argv = ACPI_INIT_DSM_ARGV4(1, &tmp); | ||
258 | |||
259 | static char *info[] = { | ||
367 | "Not implemented", | 260 | "Not implemented", |
368 | "BIOS only", | 261 | "BIOS only", |
369 | "Blocked for OS by BIOS", | 262 | "Blocked for OS by BIOS", |
370 | "User required", | 263 | "User required", |
371 | "User not required", | 264 | "User not required", |
372 | }; | 265 | }; |
373 | input.count = 4; | ||
374 | ppi_assign_params(params, TPM_PPI_FN_VERSION); | ||
375 | input.pointer = params; | ||
376 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
377 | ACPI_UINT32_MAX, ppi_callback, NULL, | ||
378 | tpm_device_name, &handle); | ||
379 | if (ACPI_FAILURE(status)) | ||
380 | return -ENXIO; | ||
381 | 266 | ||
382 | status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, | 267 | if (!acpi_check_dsm(tpm_ppi_handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID, |
383 | ACPI_TYPE_STRING); | 268 | 1 << TPM_PPI_FN_GETOPR)) |
384 | if (ACPI_FAILURE(status)) | ||
385 | return -ENOMEM; | ||
386 | |||
387 | strlcpy(version, | ||
388 | ((union acpi_object *)output.pointer)->string.pointer, | ||
389 | PPI_VERSION_LEN + 1); | ||
390 | kfree(output.pointer); | ||
391 | output.length = ACPI_ALLOCATE_BUFFER; | ||
392 | output.pointer = NULL; | ||
393 | if (strcmp(version, "1.2") < 0) | ||
394 | return -EPERM; | 269 | return -EPERM; |
395 | 270 | ||
396 | params[2].integer.value = TPM_PPI_FN_GETOPR; | 271 | tmp.integer.type = ACPI_TYPE_INTEGER; |
397 | params[3].package.count = 1; | ||
398 | obj.type = ACPI_TYPE_INTEGER; | ||
399 | params[3].package.elements = &obj; | ||
400 | for (i = start; i <= end; i++) { | 272 | for (i = start; i <= end; i++) { |
401 | obj.integer.value = i; | 273 | tmp.integer.value = i; |
402 | status = acpi_evaluate_object_typed(handle, "_DSM", | 274 | obj = tpm_eval_dsm(TPM_PPI_FN_GETOPR, ACPI_TYPE_INTEGER, &argv); |
403 | &input, &output, ACPI_TYPE_INTEGER); | 275 | if (!obj) { |
404 | if (ACPI_FAILURE(status)) | ||
405 | return -ENOMEM; | 276 | return -ENOMEM; |
277 | } else { | ||
278 | ret = obj->integer.value; | ||
279 | ACPI_FREE(obj); | ||
280 | } | ||
406 | 281 | ||
407 | ret = ((union acpi_object *)output.pointer)->integer.value; | ||
408 | if (ret > 0 && ret < ARRAY_SIZE(info)) | 282 | if (ret > 0 && ret < ARRAY_SIZE(info)) |
409 | str += scnprintf(str, PAGE_SIZE, "%d %d: %s\n", | 283 | str += scnprintf(str, PAGE_SIZE, "%d %d: %s\n", |
410 | i, ret, info[ret]); | 284 | i, ret, info[ret]); |
411 | kfree(output.pointer); | ||
412 | output.length = ACPI_ALLOCATE_BUFFER; | ||
413 | output.pointer = NULL; | ||
414 | } | 285 | } |
286 | |||
415 | return str - buf; | 287 | return str - buf; |
416 | } | 288 | } |
417 | 289 | ||
@@ -453,6 +325,12 @@ static struct attribute_group ppi_attr_grp = { | |||
453 | 325 | ||
454 | int tpm_add_ppi(struct kobject *parent) | 326 | int tpm_add_ppi(struct kobject *parent) |
455 | { | 327 | { |
328 | /* Cache TPM ACPI handle and version string */ | ||
329 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, | ||
330 | ppi_callback, NULL, NULL, &tpm_ppi_handle); | ||
331 | if (tpm_ppi_handle == NULL) | ||
332 | return -ENODEV; | ||
333 | |||
456 | return sysfs_create_group(parent, &ppi_attr_grp); | 334 | return sysfs_create_group(parent, &ppi_attr_grp); |
457 | } | 335 | } |
458 | 336 | ||
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 38093e272377..d100926aca0a 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
@@ -20,6 +20,10 @@ if CPU_FREQ | |||
20 | config CPU_FREQ_GOV_COMMON | 20 | config CPU_FREQ_GOV_COMMON |
21 | bool | 21 | bool |
22 | 22 | ||
23 | config CPU_FREQ_BOOST_SW | ||
24 | bool | ||
25 | depends on THERMAL | ||
26 | |||
23 | config CPU_FREQ_STAT | 27 | config CPU_FREQ_STAT |
24 | tristate "CPU frequency translation statistics" | 28 | tristate "CPU frequency translation statistics" |
25 | default y | 29 | default y |
@@ -181,7 +185,8 @@ config CPU_FREQ_GOV_CONSERVATIVE | |||
181 | 185 | ||
182 | config GENERIC_CPUFREQ_CPU0 | 186 | config GENERIC_CPUFREQ_CPU0 |
183 | tristate "Generic CPU0 cpufreq driver" | 187 | tristate "Generic CPU0 cpufreq driver" |
184 | depends on HAVE_CLK && REGULATOR && PM_OPP && OF | 188 | depends on HAVE_CLK && REGULATOR && OF |
189 | select PM_OPP | ||
185 | help | 190 | help |
186 | This adds a generic cpufreq driver for CPU0 frequency management. | 191 | This adds a generic cpufreq driver for CPU0 frequency management. |
187 | It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) | 192 | It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) |
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index ce52ed949249..31297499a60a 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
@@ -4,7 +4,8 @@ | |||
4 | 4 | ||
5 | config ARM_BIG_LITTLE_CPUFREQ | 5 | config ARM_BIG_LITTLE_CPUFREQ |
6 | tristate "Generic ARM big LITTLE CPUfreq driver" | 6 | tristate "Generic ARM big LITTLE CPUfreq driver" |
7 | depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK | 7 | depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK |
8 | select PM_OPP | ||
8 | help | 9 | help |
9 | This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. | 10 | This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. |
10 | 11 | ||
@@ -54,7 +55,8 @@ config ARM_EXYNOS5250_CPUFREQ | |||
54 | config ARM_EXYNOS5440_CPUFREQ | 55 | config ARM_EXYNOS5440_CPUFREQ |
55 | bool "SAMSUNG EXYNOS5440" | 56 | bool "SAMSUNG EXYNOS5440" |
56 | depends on SOC_EXYNOS5440 | 57 | depends on SOC_EXYNOS5440 |
57 | depends on HAVE_CLK && PM_OPP && OF | 58 | depends on HAVE_CLK && OF |
59 | select PM_OPP | ||
58 | default y | 60 | default y |
59 | help | 61 | help |
60 | This adds the CPUFreq driver for Samsung EXYNOS5440 | 62 | This adds the CPUFreq driver for Samsung EXYNOS5440 |
@@ -64,6 +66,21 @@ config ARM_EXYNOS5440_CPUFREQ | |||
64 | 66 | ||
65 | If in doubt, say N. | 67 | If in doubt, say N. |
66 | 68 | ||
69 | config ARM_EXYNOS_CPU_FREQ_BOOST_SW | ||
70 | bool "EXYNOS Frequency Overclocking - Software" | ||
71 | depends on ARM_EXYNOS_CPUFREQ | ||
72 | select CPU_FREQ_BOOST_SW | ||
73 | select EXYNOS_THERMAL | ||
74 | help | ||
75 | This driver supports software managed overclocking (BOOST). | ||
76 | It allows usage of special frequencies for Samsung Exynos | ||
77 | processors if thermal conditions are appropriate. | ||
78 | |||
79 | It reguires, for safe operation, thermal framework with properly | ||
80 | defined trip points. | ||
81 | |||
82 | If in doubt, say N. | ||
83 | |||
67 | config ARM_HIGHBANK_CPUFREQ | 84 | config ARM_HIGHBANK_CPUFREQ |
68 | tristate "Calxeda Highbank-based" | 85 | tristate "Calxeda Highbank-based" |
69 | depends on ARCH_HIGHBANK | 86 | depends on ARCH_HIGHBANK |
@@ -79,11 +96,11 @@ config ARM_HIGHBANK_CPUFREQ | |||
79 | If in doubt, say N. | 96 | If in doubt, say N. |
80 | 97 | ||
81 | config ARM_IMX6Q_CPUFREQ | 98 | config ARM_IMX6Q_CPUFREQ |
82 | tristate "Freescale i.MX6Q cpufreq support" | 99 | tristate "Freescale i.MX6 cpufreq support" |
83 | depends on SOC_IMX6Q | 100 | depends on ARCH_MXC |
84 | depends on REGULATOR_ANATOP | 101 | depends on REGULATOR_ANATOP |
85 | help | 102 | help |
86 | This adds cpufreq driver support for Freescale i.MX6Q SOC. | 103 | This adds cpufreq driver support for Freescale i.MX6 series SoCs. |
87 | 104 | ||
88 | If in doubt, say N. | 105 | If in doubt, say N. |
89 | 106 | ||
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index caf41ebea184..79e5608e71b5 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -80,7 +80,6 @@ static struct acpi_processor_performance __percpu *acpi_perf_data; | |||
80 | static struct cpufreq_driver acpi_cpufreq_driver; | 80 | static struct cpufreq_driver acpi_cpufreq_driver; |
81 | 81 | ||
82 | static unsigned int acpi_pstate_strict; | 82 | static unsigned int acpi_pstate_strict; |
83 | static bool boost_enabled, boost_supported; | ||
84 | static struct msr __percpu *msrs; | 83 | static struct msr __percpu *msrs; |
85 | 84 | ||
86 | static bool boost_state(unsigned int cpu) | 85 | static bool boost_state(unsigned int cpu) |
@@ -133,49 +132,16 @@ static void boost_set_msrs(bool enable, const struct cpumask *cpumask) | |||
133 | wrmsr_on_cpus(cpumask, msr_addr, msrs); | 132 | wrmsr_on_cpus(cpumask, msr_addr, msrs); |
134 | } | 133 | } |
135 | 134 | ||
136 | static ssize_t _store_boost(const char *buf, size_t count) | 135 | static int _store_boost(int val) |
137 | { | 136 | { |
138 | int ret; | ||
139 | unsigned long val = 0; | ||
140 | |||
141 | if (!boost_supported) | ||
142 | return -EINVAL; | ||
143 | |||
144 | ret = kstrtoul(buf, 10, &val); | ||
145 | if (ret || (val > 1)) | ||
146 | return -EINVAL; | ||
147 | |||
148 | if ((val && boost_enabled) || (!val && !boost_enabled)) | ||
149 | return count; | ||
150 | |||
151 | get_online_cpus(); | 137 | get_online_cpus(); |
152 | |||
153 | boost_set_msrs(val, cpu_online_mask); | 138 | boost_set_msrs(val, cpu_online_mask); |
154 | |||
155 | put_online_cpus(); | 139 | put_online_cpus(); |
156 | |||
157 | boost_enabled = val; | ||
158 | pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis"); | 140 | pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis"); |
159 | 141 | ||
160 | return count; | 142 | return 0; |
161 | } | ||
162 | |||
163 | static ssize_t store_global_boost(struct kobject *kobj, struct attribute *attr, | ||
164 | const char *buf, size_t count) | ||
165 | { | ||
166 | return _store_boost(buf, count); | ||
167 | } | ||
168 | |||
169 | static ssize_t show_global_boost(struct kobject *kobj, | ||
170 | struct attribute *attr, char *buf) | ||
171 | { | ||
172 | return sprintf(buf, "%u\n", boost_enabled); | ||
173 | } | 143 | } |
174 | 144 | ||
175 | static struct global_attr global_boost = __ATTR(boost, 0644, | ||
176 | show_global_boost, | ||
177 | store_global_boost); | ||
178 | |||
179 | static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) | 145 | static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) |
180 | { | 146 | { |
181 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | 147 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); |
@@ -186,15 +152,32 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) | |||
186 | cpufreq_freq_attr_ro(freqdomain_cpus); | 152 | cpufreq_freq_attr_ro(freqdomain_cpus); |
187 | 153 | ||
188 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB | 154 | #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB |
155 | static ssize_t store_boost(const char *buf, size_t count) | ||
156 | { | ||
157 | int ret; | ||
158 | unsigned long val = 0; | ||
159 | |||
160 | if (!acpi_cpufreq_driver.boost_supported) | ||
161 | return -EINVAL; | ||
162 | |||
163 | ret = kstrtoul(buf, 10, &val); | ||
164 | if (ret || (val > 1)) | ||
165 | return -EINVAL; | ||
166 | |||
167 | _store_boost((int) val); | ||
168 | |||
169 | return count; | ||
170 | } | ||
171 | |||
189 | static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, | 172 | static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, |
190 | size_t count) | 173 | size_t count) |
191 | { | 174 | { |
192 | return _store_boost(buf, count); | 175 | return store_boost(buf, count); |
193 | } | 176 | } |
194 | 177 | ||
195 | static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) | 178 | static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) |
196 | { | 179 | { |
197 | return sprintf(buf, "%u\n", boost_enabled); | 180 | return sprintf(buf, "%u\n", acpi_cpufreq_driver.boost_enabled); |
198 | } | 181 | } |
199 | 182 | ||
200 | cpufreq_freq_attr_rw(cpb); | 183 | cpufreq_freq_attr_rw(cpb); |
@@ -554,7 +537,7 @@ static int boost_notify(struct notifier_block *nb, unsigned long action, | |||
554 | switch (action) { | 537 | switch (action) { |
555 | case CPU_UP_PREPARE: | 538 | case CPU_UP_PREPARE: |
556 | case CPU_UP_PREPARE_FROZEN: | 539 | case CPU_UP_PREPARE_FROZEN: |
557 | boost_set_msrs(boost_enabled, cpumask); | 540 | boost_set_msrs(acpi_cpufreq_driver.boost_enabled, cpumask); |
558 | break; | 541 | break; |
559 | 542 | ||
560 | case CPU_DOWN_PREPARE: | 543 | case CPU_DOWN_PREPARE: |
@@ -911,6 +894,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = { | |||
911 | .resume = acpi_cpufreq_resume, | 894 | .resume = acpi_cpufreq_resume, |
912 | .name = "acpi-cpufreq", | 895 | .name = "acpi-cpufreq", |
913 | .attr = acpi_cpufreq_attr, | 896 | .attr = acpi_cpufreq_attr, |
897 | .set_boost = _store_boost, | ||
914 | }; | 898 | }; |
915 | 899 | ||
916 | static void __init acpi_cpufreq_boost_init(void) | 900 | static void __init acpi_cpufreq_boost_init(void) |
@@ -921,33 +905,22 @@ static void __init acpi_cpufreq_boost_init(void) | |||
921 | if (!msrs) | 905 | if (!msrs) |
922 | return; | 906 | return; |
923 | 907 | ||
924 | boost_supported = true; | 908 | acpi_cpufreq_driver.boost_supported = true; |
925 | boost_enabled = boost_state(0); | 909 | acpi_cpufreq_driver.boost_enabled = boost_state(0); |
926 | |||
927 | get_online_cpus(); | 910 | get_online_cpus(); |
928 | 911 | ||
929 | /* Force all MSRs to the same value */ | 912 | /* Force all MSRs to the same value */ |
930 | boost_set_msrs(boost_enabled, cpu_online_mask); | 913 | boost_set_msrs(acpi_cpufreq_driver.boost_enabled, |
914 | cpu_online_mask); | ||
931 | 915 | ||
932 | register_cpu_notifier(&boost_nb); | 916 | register_cpu_notifier(&boost_nb); |
933 | 917 | ||
934 | put_online_cpus(); | 918 | put_online_cpus(); |
935 | } else | 919 | } |
936 | global_boost.attr.mode = 0444; | ||
937 | |||
938 | /* We create the boost file in any case, though for systems without | ||
939 | * hardware support it will be read-only and hardwired to return 0. | ||
940 | */ | ||
941 | if (cpufreq_sysfs_create_file(&(global_boost.attr))) | ||
942 | pr_warn(PFX "could not register global boost sysfs file\n"); | ||
943 | else | ||
944 | pr_debug("registered global boost sysfs file\n"); | ||
945 | } | 920 | } |
946 | 921 | ||
947 | static void __exit acpi_cpufreq_boost_exit(void) | 922 | static void __exit acpi_cpufreq_boost_exit(void) |
948 | { | 923 | { |
949 | cpufreq_sysfs_remove_file(&(global_boost.attr)); | ||
950 | |||
951 | if (msrs) { | 924 | if (msrs) { |
952 | unregister_cpu_notifier(&boost_nb); | 925 | unregister_cpu_notifier(&boost_nb); |
953 | 926 | ||
@@ -993,12 +966,11 @@ static int __init acpi_cpufreq_init(void) | |||
993 | *iter = &cpb; | 966 | *iter = &cpb; |
994 | } | 967 | } |
995 | #endif | 968 | #endif |
969 | acpi_cpufreq_boost_init(); | ||
996 | 970 | ||
997 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); | 971 | ret = cpufreq_register_driver(&acpi_cpufreq_driver); |
998 | if (ret) | 972 | if (ret) |
999 | free_acpi_perf_data(); | 973 | free_acpi_perf_data(); |
1000 | else | ||
1001 | acpi_cpufreq_boost_init(); | ||
1002 | 974 | ||
1003 | return ret; | 975 | return ret; |
1004 | } | 976 | } |
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 5519933813ea..72f87e9317e3 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c | |||
@@ -488,7 +488,8 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) | |||
488 | static struct cpufreq_driver bL_cpufreq_driver = { | 488 | static struct cpufreq_driver bL_cpufreq_driver = { |
489 | .name = "arm-big-little", | 489 | .name = "arm-big-little", |
490 | .flags = CPUFREQ_STICKY | | 490 | .flags = CPUFREQ_STICKY | |
491 | CPUFREQ_HAVE_GOVERNOR_PER_POLICY, | 491 | CPUFREQ_HAVE_GOVERNOR_PER_POLICY | |
492 | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
492 | .verify = cpufreq_generic_frequency_table_verify, | 493 | .verify = cpufreq_generic_frequency_table_verify, |
493 | .target_index = bL_cpufreq_set_target, | 494 | .target_index = bL_cpufreq_set_target, |
494 | .get = bL_cpufreq_get_rate, | 495 | .get = bL_cpufreq_get_rate, |
diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c index 7c03dd84f66a..a1c79f549edb 100644 --- a/drivers/cpufreq/at32ap-cpufreq.c +++ b/drivers/cpufreq/at32ap-cpufreq.c | |||
@@ -21,17 +21,8 @@ | |||
21 | #include <linux/export.h> | 21 | #include <linux/export.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | 23 | ||
24 | static struct clk *cpuclk; | ||
25 | static struct cpufreq_frequency_table *freq_table; | 24 | static struct cpufreq_frequency_table *freq_table; |
26 | 25 | ||
27 | static unsigned int at32_get_speed(unsigned int cpu) | ||
28 | { | ||
29 | /* No SMP support */ | ||
30 | if (cpu) | ||
31 | return 0; | ||
32 | return (unsigned int)((clk_get_rate(cpuclk) + 500) / 1000); | ||
33 | } | ||
34 | |||
35 | static unsigned int ref_freq; | 26 | static unsigned int ref_freq; |
36 | static unsigned long loops_per_jiffy_ref; | 27 | static unsigned long loops_per_jiffy_ref; |
37 | 28 | ||
@@ -39,7 +30,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
39 | { | 30 | { |
40 | unsigned int old_freq, new_freq; | 31 | unsigned int old_freq, new_freq; |
41 | 32 | ||
42 | old_freq = at32_get_speed(0); | 33 | old_freq = policy->cur; |
43 | new_freq = freq_table[index].frequency; | 34 | new_freq = freq_table[index].frequency; |
44 | 35 | ||
45 | if (!ref_freq) { | 36 | if (!ref_freq) { |
@@ -50,7 +41,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
50 | if (old_freq < new_freq) | 41 | if (old_freq < new_freq) |
51 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( | 42 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( |
52 | loops_per_jiffy_ref, ref_freq, new_freq); | 43 | loops_per_jiffy_ref, ref_freq, new_freq); |
53 | clk_set_rate(cpuclk, new_freq * 1000); | 44 | clk_set_rate(policy->clk, new_freq * 1000); |
54 | if (new_freq < old_freq) | 45 | if (new_freq < old_freq) |
55 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( | 46 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( |
56 | loops_per_jiffy_ref, ref_freq, new_freq); | 47 | loops_per_jiffy_ref, ref_freq, new_freq); |
@@ -61,6 +52,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
61 | static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) | 52 | static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) |
62 | { | 53 | { |
63 | unsigned int frequency, rate, min_freq; | 54 | unsigned int frequency, rate, min_freq; |
55 | static struct clk *cpuclk; | ||
64 | int retval, steps, i; | 56 | int retval, steps, i; |
65 | 57 | ||
66 | if (policy->cpu != 0) | 58 | if (policy->cpu != 0) |
@@ -103,6 +95,7 @@ static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
103 | frequency /= 2; | 95 | frequency /= 2; |
104 | } | 96 | } |
105 | 97 | ||
98 | policy->clk = cpuclk; | ||
106 | freq_table[steps - 1].frequency = CPUFREQ_TABLE_END; | 99 | freq_table[steps - 1].frequency = CPUFREQ_TABLE_END; |
107 | 100 | ||
108 | retval = cpufreq_table_validate_and_show(policy, freq_table); | 101 | retval = cpufreq_table_validate_and_show(policy, freq_table); |
@@ -123,7 +116,7 @@ static struct cpufreq_driver at32_driver = { | |||
123 | .init = at32_cpufreq_driver_init, | 116 | .init = at32_cpufreq_driver_init, |
124 | .verify = cpufreq_generic_frequency_table_verify, | 117 | .verify = cpufreq_generic_frequency_table_verify, |
125 | .target_index = at32_set_target, | 118 | .target_index = at32_set_target, |
126 | .get = at32_get_speed, | 119 | .get = cpufreq_generic_get, |
127 | .flags = CPUFREQ_STICKY, | 120 | .flags = CPUFREQ_STICKY, |
128 | }; | 121 | }; |
129 | 122 | ||
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index d4585ce2346c..bb7b3082efb3 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c | |||
@@ -30,11 +30,6 @@ static struct clk *cpu_clk; | |||
30 | static struct regulator *cpu_reg; | 30 | static struct regulator *cpu_reg; |
31 | static struct cpufreq_frequency_table *freq_table; | 31 | static struct cpufreq_frequency_table *freq_table; |
32 | 32 | ||
33 | static unsigned int cpu0_get_speed(unsigned int cpu) | ||
34 | { | ||
35 | return clk_get_rate(cpu_clk) / 1000; | ||
36 | } | ||
37 | |||
38 | static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) | 33 | static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) |
39 | { | 34 | { |
40 | struct dev_pm_opp *opp; | 35 | struct dev_pm_opp *opp; |
@@ -44,7 +39,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
44 | int ret; | 39 | int ret; |
45 | 40 | ||
46 | freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); | 41 | freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); |
47 | if (freq_Hz < 0) | 42 | if (freq_Hz <= 0) |
48 | freq_Hz = freq_table[index].frequency * 1000; | 43 | freq_Hz = freq_table[index].frequency * 1000; |
49 | 44 | ||
50 | freq_exact = freq_Hz; | 45 | freq_exact = freq_Hz; |
@@ -100,6 +95,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
100 | 95 | ||
101 | static int cpu0_cpufreq_init(struct cpufreq_policy *policy) | 96 | static int cpu0_cpufreq_init(struct cpufreq_policy *policy) |
102 | { | 97 | { |
98 | policy->clk = cpu_clk; | ||
103 | return cpufreq_generic_init(policy, freq_table, transition_latency); | 99 | return cpufreq_generic_init(policy, freq_table, transition_latency); |
104 | } | 100 | } |
105 | 101 | ||
@@ -107,7 +103,7 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { | |||
107 | .flags = CPUFREQ_STICKY, | 103 | .flags = CPUFREQ_STICKY, |
108 | .verify = cpufreq_generic_frequency_table_verify, | 104 | .verify = cpufreq_generic_frequency_table_verify, |
109 | .target_index = cpu0_set_target, | 105 | .target_index = cpu0_set_target, |
110 | .get = cpu0_get_speed, | 106 | .get = cpufreq_generic_get, |
111 | .init = cpu0_cpufreq_init, | 107 | .init = cpu0_cpufreq_init, |
112 | .exit = cpufreq_generic_exit, | 108 | .exit = cpufreq_generic_exit, |
113 | .name = "generic_cpu0", | 109 | .name = "generic_cpu0", |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8d19f7c06010..08ca8c9f41cd 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -39,7 +39,7 @@ static struct cpufreq_driver *cpufreq_driver; | |||
39 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); | 39 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); |
40 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); | 40 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); |
41 | static DEFINE_RWLOCK(cpufreq_driver_lock); | 41 | static DEFINE_RWLOCK(cpufreq_driver_lock); |
42 | static DEFINE_MUTEX(cpufreq_governor_lock); | 42 | DEFINE_MUTEX(cpufreq_governor_lock); |
43 | static LIST_HEAD(cpufreq_policy_list); | 43 | static LIST_HEAD(cpufreq_policy_list); |
44 | 44 | ||
45 | #ifdef CONFIG_HOTPLUG_CPU | 45 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -176,6 +176,20 @@ int cpufreq_generic_init(struct cpufreq_policy *policy, | |||
176 | } | 176 | } |
177 | EXPORT_SYMBOL_GPL(cpufreq_generic_init); | 177 | EXPORT_SYMBOL_GPL(cpufreq_generic_init); |
178 | 178 | ||
179 | unsigned int cpufreq_generic_get(unsigned int cpu) | ||
180 | { | ||
181 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | ||
182 | |||
183 | if (!policy || IS_ERR(policy->clk)) { | ||
184 | pr_err("%s: No %s associated to cpu: %d\n", __func__, | ||
185 | policy ? "clk" : "policy", cpu); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | return clk_get_rate(policy->clk) / 1000; | ||
190 | } | ||
191 | EXPORT_SYMBOL_GPL(cpufreq_generic_get); | ||
192 | |||
179 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | 193 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) |
180 | { | 194 | { |
181 | struct cpufreq_policy *policy = NULL; | 195 | struct cpufreq_policy *policy = NULL; |
@@ -320,10 +334,51 @@ void cpufreq_notify_transition(struct cpufreq_policy *policy, | |||
320 | } | 334 | } |
321 | EXPORT_SYMBOL_GPL(cpufreq_notify_transition); | 335 | EXPORT_SYMBOL_GPL(cpufreq_notify_transition); |
322 | 336 | ||
337 | /* Do post notifications when there are chances that transition has failed */ | ||
338 | void cpufreq_notify_post_transition(struct cpufreq_policy *policy, | ||
339 | struct cpufreq_freqs *freqs, int transition_failed) | ||
340 | { | ||
341 | cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE); | ||
342 | if (!transition_failed) | ||
343 | return; | ||
344 | |||
345 | swap(freqs->old, freqs->new); | ||
346 | cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE); | ||
347 | cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE); | ||
348 | } | ||
349 | EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition); | ||
350 | |||
323 | 351 | ||
324 | /********************************************************************* | 352 | /********************************************************************* |
325 | * SYSFS INTERFACE * | 353 | * SYSFS INTERFACE * |
326 | *********************************************************************/ | 354 | *********************************************************************/ |
355 | ssize_t show_boost(struct kobject *kobj, | ||
356 | struct attribute *attr, char *buf) | ||
357 | { | ||
358 | return sprintf(buf, "%d\n", cpufreq_driver->boost_enabled); | ||
359 | } | ||
360 | |||
361 | static ssize_t store_boost(struct kobject *kobj, struct attribute *attr, | ||
362 | const char *buf, size_t count) | ||
363 | { | ||
364 | int ret, enable; | ||
365 | |||
366 | ret = sscanf(buf, "%d", &enable); | ||
367 | if (ret != 1 || enable < 0 || enable > 1) | ||
368 | return -EINVAL; | ||
369 | |||
370 | if (cpufreq_boost_trigger_state(enable)) { | ||
371 | pr_err("%s: Cannot %s BOOST!\n", __func__, | ||
372 | enable ? "enable" : "disable"); | ||
373 | return -EINVAL; | ||
374 | } | ||
375 | |||
376 | pr_debug("%s: cpufreq BOOST %s\n", __func__, | ||
377 | enable ? "enabled" : "disabled"); | ||
378 | |||
379 | return count; | ||
380 | } | ||
381 | define_one_global_rw(boost); | ||
327 | 382 | ||
328 | static struct cpufreq_governor *__find_governor(const char *str_governor) | 383 | static struct cpufreq_governor *__find_governor(const char *str_governor) |
329 | { | 384 | { |
@@ -929,6 +984,9 @@ static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy) | |||
929 | struct kobject *kobj; | 984 | struct kobject *kobj; |
930 | struct completion *cmp; | 985 | struct completion *cmp; |
931 | 986 | ||
987 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | ||
988 | CPUFREQ_REMOVE_POLICY, policy); | ||
989 | |||
932 | down_read(&policy->rwsem); | 990 | down_read(&policy->rwsem); |
933 | kobj = &policy->kobj; | 991 | kobj = &policy->kobj; |
934 | cmp = &policy->kobj_unregister; | 992 | cmp = &policy->kobj_unregister; |
@@ -1051,6 +1109,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1051 | goto err_set_policy_cpu; | 1109 | goto err_set_policy_cpu; |
1052 | } | 1110 | } |
1053 | 1111 | ||
1112 | write_lock_irqsave(&cpufreq_driver_lock, flags); | ||
1113 | for_each_cpu(j, policy->cpus) | ||
1114 | per_cpu(cpufreq_cpu_data, j) = policy; | ||
1115 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1116 | |||
1054 | if (cpufreq_driver->get) { | 1117 | if (cpufreq_driver->get) { |
1055 | policy->cur = cpufreq_driver->get(policy->cpu); | 1118 | policy->cur = cpufreq_driver->get(policy->cpu); |
1056 | if (!policy->cur) { | 1119 | if (!policy->cur) { |
@@ -1059,6 +1122,46 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1059 | } | 1122 | } |
1060 | } | 1123 | } |
1061 | 1124 | ||
1125 | /* | ||
1126 | * Sometimes boot loaders set CPU frequency to a value outside of | ||
1127 | * frequency table present with cpufreq core. In such cases CPU might be | ||
1128 | * unstable if it has to run on that frequency for long duration of time | ||
1129 | * and so its better to set it to a frequency which is specified in | ||
1130 | * freq-table. This also makes cpufreq stats inconsistent as | ||
1131 | * cpufreq-stats would fail to register because current frequency of CPU | ||
1132 | * isn't found in freq-table. | ||
1133 | * | ||
1134 | * Because we don't want this change to effect boot process badly, we go | ||
1135 | * for the next freq which is >= policy->cur ('cur' must be set by now, | ||
1136 | * otherwise we will end up setting freq to lowest of the table as 'cur' | ||
1137 | * is initialized to zero). | ||
1138 | * | ||
1139 | * We are passing target-freq as "policy->cur - 1" otherwise | ||
1140 | * __cpufreq_driver_target() would simply fail, as policy->cur will be | ||
1141 | * equal to target-freq. | ||
1142 | */ | ||
1143 | if ((cpufreq_driver->flags & CPUFREQ_NEED_INITIAL_FREQ_CHECK) | ||
1144 | && has_target()) { | ||
1145 | /* Are we running at unknown frequency ? */ | ||
1146 | ret = cpufreq_frequency_table_get_index(policy, policy->cur); | ||
1147 | if (ret == -EINVAL) { | ||
1148 | /* Warn user and fix it */ | ||
1149 | pr_warn("%s: CPU%d: Running at unlisted freq: %u KHz\n", | ||
1150 | __func__, policy->cpu, policy->cur); | ||
1151 | ret = __cpufreq_driver_target(policy, policy->cur - 1, | ||
1152 | CPUFREQ_RELATION_L); | ||
1153 | |||
1154 | /* | ||
1155 | * Reaching here after boot in a few seconds may not | ||
1156 | * mean that system will remain stable at "unknown" | ||
1157 | * frequency for longer duration. Hence, a BUG_ON(). | ||
1158 | */ | ||
1159 | BUG_ON(ret); | ||
1160 | pr_warn("%s: CPU%d: Unlisted initial frequency changed to: %u KHz\n", | ||
1161 | __func__, policy->cpu, policy->cur); | ||
1162 | } | ||
1163 | } | ||
1164 | |||
1062 | /* related cpus should atleast have policy->cpus */ | 1165 | /* related cpus should atleast have policy->cpus */ |
1063 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | 1166 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); |
1064 | 1167 | ||
@@ -1085,15 +1188,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1085 | } | 1188 | } |
1086 | #endif | 1189 | #endif |
1087 | 1190 | ||
1088 | write_lock_irqsave(&cpufreq_driver_lock, flags); | ||
1089 | for_each_cpu(j, policy->cpus) | ||
1090 | per_cpu(cpufreq_cpu_data, j) = policy; | ||
1091 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1092 | |||
1093 | if (!frozen) { | 1191 | if (!frozen) { |
1094 | ret = cpufreq_add_dev_interface(policy, dev); | 1192 | ret = cpufreq_add_dev_interface(policy, dev); |
1095 | if (ret) | 1193 | if (ret) |
1096 | goto err_out_unregister; | 1194 | goto err_out_unregister; |
1195 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | ||
1196 | CPUFREQ_CREATE_POLICY, policy); | ||
1097 | } | 1197 | } |
1098 | 1198 | ||
1099 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 1199 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
@@ -1115,12 +1215,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1115 | return 0; | 1215 | return 0; |
1116 | 1216 | ||
1117 | err_out_unregister: | 1217 | err_out_unregister: |
1218 | err_get_freq: | ||
1118 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 1219 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1119 | for_each_cpu(j, policy->cpus) | 1220 | for_each_cpu(j, policy->cpus) |
1120 | per_cpu(cpufreq_cpu_data, j) = NULL; | 1221 | per_cpu(cpufreq_cpu_data, j) = NULL; |
1121 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1222 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1122 | 1223 | ||
1123 | err_get_freq: | ||
1124 | if (cpufreq_driver->exit) | 1224 | if (cpufreq_driver->exit) |
1125 | cpufreq_driver->exit(policy); | 1225 | cpufreq_driver->exit(policy); |
1126 | err_set_policy_cpu: | 1226 | err_set_policy_cpu: |
@@ -1725,17 +1825,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1725 | pr_err("%s: Failed to change cpu frequency: %d\n", | 1825 | pr_err("%s: Failed to change cpu frequency: %d\n", |
1726 | __func__, retval); | 1826 | __func__, retval); |
1727 | 1827 | ||
1728 | if (notify) { | 1828 | if (notify) |
1729 | /* | 1829 | cpufreq_notify_post_transition(policy, &freqs, retval); |
1730 | * Notify with old freq in case we failed to change | ||
1731 | * frequency | ||
1732 | */ | ||
1733 | if (retval) | ||
1734 | freqs.new = freqs.old; | ||
1735 | |||
1736 | cpufreq_notify_transition(policy, &freqs, | ||
1737 | CPUFREQ_POSTCHANGE); | ||
1738 | } | ||
1739 | } | 1830 | } |
1740 | 1831 | ||
1741 | out: | 1832 | out: |
@@ -2120,6 +2211,73 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = { | |||
2120 | }; | 2211 | }; |
2121 | 2212 | ||
2122 | /********************************************************************* | 2213 | /********************************************************************* |
2214 | * BOOST * | ||
2215 | *********************************************************************/ | ||
2216 | static int cpufreq_boost_set_sw(int state) | ||
2217 | { | ||
2218 | struct cpufreq_frequency_table *freq_table; | ||
2219 | struct cpufreq_policy *policy; | ||
2220 | int ret = -EINVAL; | ||
2221 | |||
2222 | list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { | ||
2223 | freq_table = cpufreq_frequency_get_table(policy->cpu); | ||
2224 | if (freq_table) { | ||
2225 | ret = cpufreq_frequency_table_cpuinfo(policy, | ||
2226 | freq_table); | ||
2227 | if (ret) { | ||
2228 | pr_err("%s: Policy frequency update failed\n", | ||
2229 | __func__); | ||
2230 | break; | ||
2231 | } | ||
2232 | policy->user_policy.max = policy->max; | ||
2233 | __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); | ||
2234 | } | ||
2235 | } | ||
2236 | |||
2237 | return ret; | ||
2238 | } | ||
2239 | |||
2240 | int cpufreq_boost_trigger_state(int state) | ||
2241 | { | ||
2242 | unsigned long flags; | ||
2243 | int ret = 0; | ||
2244 | |||
2245 | if (cpufreq_driver->boost_enabled == state) | ||
2246 | return 0; | ||
2247 | |||
2248 | write_lock_irqsave(&cpufreq_driver_lock, flags); | ||
2249 | cpufreq_driver->boost_enabled = state; | ||
2250 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
2251 | |||
2252 | ret = cpufreq_driver->set_boost(state); | ||
2253 | if (ret) { | ||
2254 | write_lock_irqsave(&cpufreq_driver_lock, flags); | ||
2255 | cpufreq_driver->boost_enabled = !state; | ||
2256 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
2257 | |||
2258 | pr_err("%s: Cannot %s BOOST\n", __func__, | ||
2259 | state ? "enable" : "disable"); | ||
2260 | } | ||
2261 | |||
2262 | return ret; | ||
2263 | } | ||
2264 | |||
2265 | int cpufreq_boost_supported(void) | ||
2266 | { | ||
2267 | if (likely(cpufreq_driver)) | ||
2268 | return cpufreq_driver->boost_supported; | ||
2269 | |||
2270 | return 0; | ||
2271 | } | ||
2272 | EXPORT_SYMBOL_GPL(cpufreq_boost_supported); | ||
2273 | |||
2274 | int cpufreq_boost_enabled(void) | ||
2275 | { | ||
2276 | return cpufreq_driver->boost_enabled; | ||
2277 | } | ||
2278 | EXPORT_SYMBOL_GPL(cpufreq_boost_enabled); | ||
2279 | |||
2280 | /********************************************************************* | ||
2123 | * REGISTER / UNREGISTER CPUFREQ DRIVER * | 2281 | * REGISTER / UNREGISTER CPUFREQ DRIVER * |
2124 | *********************************************************************/ | 2282 | *********************************************************************/ |
2125 | 2283 | ||
@@ -2159,9 +2317,25 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2159 | cpufreq_driver = driver_data; | 2317 | cpufreq_driver = driver_data; |
2160 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2318 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
2161 | 2319 | ||
2320 | if (cpufreq_boost_supported()) { | ||
2321 | /* | ||
2322 | * Check if driver provides function to enable boost - | ||
2323 | * if not, use cpufreq_boost_set_sw as default | ||
2324 | */ | ||
2325 | if (!cpufreq_driver->set_boost) | ||
2326 | cpufreq_driver->set_boost = cpufreq_boost_set_sw; | ||
2327 | |||
2328 | ret = cpufreq_sysfs_create_file(&boost.attr); | ||
2329 | if (ret) { | ||
2330 | pr_err("%s: cannot register global BOOST sysfs file\n", | ||
2331 | __func__); | ||
2332 | goto err_null_driver; | ||
2333 | } | ||
2334 | } | ||
2335 | |||
2162 | ret = subsys_interface_register(&cpufreq_interface); | 2336 | ret = subsys_interface_register(&cpufreq_interface); |
2163 | if (ret) | 2337 | if (ret) |
2164 | goto err_null_driver; | 2338 | goto err_boost_unreg; |
2165 | 2339 | ||
2166 | if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { | 2340 | if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { |
2167 | int i; | 2341 | int i; |
@@ -2188,6 +2362,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2188 | return 0; | 2362 | return 0; |
2189 | err_if_unreg: | 2363 | err_if_unreg: |
2190 | subsys_interface_unregister(&cpufreq_interface); | 2364 | subsys_interface_unregister(&cpufreq_interface); |
2365 | err_boost_unreg: | ||
2366 | if (cpufreq_boost_supported()) | ||
2367 | cpufreq_sysfs_remove_file(&boost.attr); | ||
2191 | err_null_driver: | 2368 | err_null_driver: |
2192 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 2369 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
2193 | cpufreq_driver = NULL; | 2370 | cpufreq_driver = NULL; |
@@ -2214,6 +2391,9 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) | |||
2214 | pr_debug("unregistering driver %s\n", driver->name); | 2391 | pr_debug("unregistering driver %s\n", driver->name); |
2215 | 2392 | ||
2216 | subsys_interface_unregister(&cpufreq_interface); | 2393 | subsys_interface_unregister(&cpufreq_interface); |
2394 | if (cpufreq_boost_supported()) | ||
2395 | cpufreq_sysfs_remove_file(&boost.attr); | ||
2396 | |||
2217 | unregister_hotcpu_notifier(&cpufreq_cpu_notifier); | 2397 | unregister_hotcpu_notifier(&cpufreq_cpu_notifier); |
2218 | 2398 | ||
2219 | down_write(&cpufreq_rwsem); | 2399 | down_write(&cpufreq_rwsem); |
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index e6be63561fa6..ba43991ba98a 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c | |||
@@ -119,8 +119,9 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, | |||
119 | { | 119 | { |
120 | int i; | 120 | int i; |
121 | 121 | ||
122 | mutex_lock(&cpufreq_governor_lock); | ||
122 | if (!policy->governor_enabled) | 123 | if (!policy->governor_enabled) |
123 | return; | 124 | goto out_unlock; |
124 | 125 | ||
125 | if (!all_cpus) { | 126 | if (!all_cpus) { |
126 | /* | 127 | /* |
@@ -135,6 +136,9 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, | |||
135 | for_each_cpu(i, policy->cpus) | 136 | for_each_cpu(i, policy->cpus) |
136 | __gov_queue_work(i, dbs_data, delay); | 137 | __gov_queue_work(i, dbs_data, delay); |
137 | } | 138 | } |
139 | |||
140 | out_unlock: | ||
141 | mutex_unlock(&cpufreq_governor_lock); | ||
138 | } | 142 | } |
139 | EXPORT_SYMBOL_GPL(gov_queue_work); | 143 | EXPORT_SYMBOL_GPL(gov_queue_work); |
140 | 144 | ||
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index b5f2b8618949..bfb9ae14142c 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h | |||
@@ -257,6 +257,8 @@ static ssize_t show_sampling_rate_min_gov_pol \ | |||
257 | return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ | 257 | return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ |
258 | } | 258 | } |
259 | 259 | ||
260 | extern struct mutex cpufreq_governor_lock; | ||
261 | |||
260 | void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); | 262 | void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); |
261 | bool need_load_eval(struct cpu_dbs_common_info *cdbs, | 263 | bool need_load_eval(struct cpu_dbs_common_info *cdbs, |
262 | unsigned int sampling_rate); | 264 | unsigned int sampling_rate); |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 4cf0d2805cb2..5793e1447fb1 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -151,44 +151,36 @@ static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) | |||
151 | return -1; | 151 | return -1; |
152 | } | 152 | } |
153 | 153 | ||
154 | /* should be called late in the CPU removal sequence so that the stats | 154 | static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) |
155 | * memory is still available in case someone tries to use it. | ||
156 | */ | ||
157 | static void cpufreq_stats_free_table(unsigned int cpu) | ||
158 | { | 155 | { |
159 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu); | 156 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); |
160 | 157 | ||
161 | if (stat) { | 158 | if (!stat) |
162 | pr_debug("%s: Free stat table\n", __func__); | 159 | return; |
163 | kfree(stat->time_in_state); | 160 | |
164 | kfree(stat); | 161 | pr_debug("%s: Free stat table\n", __func__); |
165 | per_cpu(cpufreq_stats_table, cpu) = NULL; | 162 | |
166 | } | 163 | sysfs_remove_group(&policy->kobj, &stats_attr_group); |
164 | kfree(stat->time_in_state); | ||
165 | kfree(stat); | ||
166 | per_cpu(cpufreq_stats_table, policy->cpu) = NULL; | ||
167 | } | 167 | } |
168 | 168 | ||
169 | /* must be called early in the CPU removal sequence (before | 169 | static void cpufreq_stats_free_table(unsigned int cpu) |
170 | * cpufreq_remove_dev) so that policy is still valid. | ||
171 | */ | ||
172 | static void cpufreq_stats_free_sysfs(unsigned int cpu) | ||
173 | { | 170 | { |
174 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | 171 | struct cpufreq_policy *policy; |
175 | 172 | ||
173 | policy = cpufreq_cpu_get(cpu); | ||
176 | if (!policy) | 174 | if (!policy) |
177 | return; | 175 | return; |
178 | 176 | ||
179 | if (!cpufreq_frequency_get_table(cpu)) | 177 | if (cpufreq_frequency_get_table(policy->cpu)) |
180 | goto put_ref; | 178 | __cpufreq_stats_free_table(policy); |
181 | |||
182 | if (!policy_is_shared(policy)) { | ||
183 | pr_debug("%s: Free sysfs stat\n", __func__); | ||
184 | sysfs_remove_group(&policy->kobj, &stats_attr_group); | ||
185 | } | ||
186 | 179 | ||
187 | put_ref: | ||
188 | cpufreq_cpu_put(policy); | 180 | cpufreq_cpu_put(policy); |
189 | } | 181 | } |
190 | 182 | ||
191 | static int cpufreq_stats_create_table(struct cpufreq_policy *policy, | 183 | static int __cpufreq_stats_create_table(struct cpufreq_policy *policy, |
192 | struct cpufreq_frequency_table *table) | 184 | struct cpufreq_frequency_table *table) |
193 | { | 185 | { |
194 | unsigned int i, j, count = 0, ret = 0; | 186 | unsigned int i, j, count = 0, ret = 0; |
@@ -261,6 +253,26 @@ error_get_fail: | |||
261 | return ret; | 253 | return ret; |
262 | } | 254 | } |
263 | 255 | ||
256 | static void cpufreq_stats_create_table(unsigned int cpu) | ||
257 | { | ||
258 | struct cpufreq_policy *policy; | ||
259 | struct cpufreq_frequency_table *table; | ||
260 | |||
261 | /* | ||
262 | * "likely(!policy)" because normally cpufreq_stats will be registered | ||
263 | * before cpufreq driver | ||
264 | */ | ||
265 | policy = cpufreq_cpu_get(cpu); | ||
266 | if (likely(!policy)) | ||
267 | return; | ||
268 | |||
269 | table = cpufreq_frequency_get_table(policy->cpu); | ||
270 | if (likely(table)) | ||
271 | __cpufreq_stats_create_table(policy, table); | ||
272 | |||
273 | cpufreq_cpu_put(policy); | ||
274 | } | ||
275 | |||
264 | static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) | 276 | static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) |
265 | { | 277 | { |
266 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, | 278 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, |
@@ -277,7 +289,7 @@ static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) | |||
277 | static int cpufreq_stat_notifier_policy(struct notifier_block *nb, | 289 | static int cpufreq_stat_notifier_policy(struct notifier_block *nb, |
278 | unsigned long val, void *data) | 290 | unsigned long val, void *data) |
279 | { | 291 | { |
280 | int ret; | 292 | int ret = 0; |
281 | struct cpufreq_policy *policy = data; | 293 | struct cpufreq_policy *policy = data; |
282 | struct cpufreq_frequency_table *table; | 294 | struct cpufreq_frequency_table *table; |
283 | unsigned int cpu = policy->cpu; | 295 | unsigned int cpu = policy->cpu; |
@@ -287,15 +299,16 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb, | |||
287 | return 0; | 299 | return 0; |
288 | } | 300 | } |
289 | 301 | ||
290 | if (val != CPUFREQ_NOTIFY) | ||
291 | return 0; | ||
292 | table = cpufreq_frequency_get_table(cpu); | 302 | table = cpufreq_frequency_get_table(cpu); |
293 | if (!table) | 303 | if (!table) |
294 | return 0; | 304 | return 0; |
295 | ret = cpufreq_stats_create_table(policy, table); | 305 | |
296 | if (ret) | 306 | if (val == CPUFREQ_CREATE_POLICY) |
297 | return ret; | 307 | ret = __cpufreq_stats_create_table(policy, table); |
298 | return 0; | 308 | else if (val == CPUFREQ_REMOVE_POLICY) |
309 | __cpufreq_stats_free_table(policy); | ||
310 | |||
311 | return ret; | ||
299 | } | 312 | } |
300 | 313 | ||
301 | static int cpufreq_stat_notifier_trans(struct notifier_block *nb, | 314 | static int cpufreq_stat_notifier_trans(struct notifier_block *nb, |
@@ -334,29 +347,6 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, | |||
334 | return 0; | 347 | return 0; |
335 | } | 348 | } |
336 | 349 | ||
337 | static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, | ||
338 | unsigned long action, | ||
339 | void *hcpu) | ||
340 | { | ||
341 | unsigned int cpu = (unsigned long)hcpu; | ||
342 | |||
343 | switch (action) { | ||
344 | case CPU_DOWN_PREPARE: | ||
345 | cpufreq_stats_free_sysfs(cpu); | ||
346 | break; | ||
347 | case CPU_DEAD: | ||
348 | cpufreq_stats_free_table(cpu); | ||
349 | break; | ||
350 | } | ||
351 | return NOTIFY_OK; | ||
352 | } | ||
353 | |||
354 | /* priority=1 so this will get called before cpufreq_remove_dev */ | ||
355 | static struct notifier_block cpufreq_stat_cpu_notifier __refdata = { | ||
356 | .notifier_call = cpufreq_stat_cpu_callback, | ||
357 | .priority = 1, | ||
358 | }; | ||
359 | |||
360 | static struct notifier_block notifier_policy_block = { | 350 | static struct notifier_block notifier_policy_block = { |
361 | .notifier_call = cpufreq_stat_notifier_policy | 351 | .notifier_call = cpufreq_stat_notifier_policy |
362 | }; | 352 | }; |
@@ -376,14 +366,14 @@ static int __init cpufreq_stats_init(void) | |||
376 | if (ret) | 366 | if (ret) |
377 | return ret; | 367 | return ret; |
378 | 368 | ||
379 | register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); | 369 | for_each_online_cpu(cpu) |
370 | cpufreq_stats_create_table(cpu); | ||
380 | 371 | ||
381 | ret = cpufreq_register_notifier(¬ifier_trans_block, | 372 | ret = cpufreq_register_notifier(¬ifier_trans_block, |
382 | CPUFREQ_TRANSITION_NOTIFIER); | 373 | CPUFREQ_TRANSITION_NOTIFIER); |
383 | if (ret) { | 374 | if (ret) { |
384 | cpufreq_unregister_notifier(¬ifier_policy_block, | 375 | cpufreq_unregister_notifier(¬ifier_policy_block, |
385 | CPUFREQ_POLICY_NOTIFIER); | 376 | CPUFREQ_POLICY_NOTIFIER); |
386 | unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); | ||
387 | for_each_online_cpu(cpu) | 377 | for_each_online_cpu(cpu) |
388 | cpufreq_stats_free_table(cpu); | 378 | cpufreq_stats_free_table(cpu); |
389 | return ret; | 379 | return ret; |
@@ -399,11 +389,8 @@ static void __exit cpufreq_stats_exit(void) | |||
399 | CPUFREQ_POLICY_NOTIFIER); | 389 | CPUFREQ_POLICY_NOTIFIER); |
400 | cpufreq_unregister_notifier(¬ifier_trans_block, | 390 | cpufreq_unregister_notifier(¬ifier_trans_block, |
401 | CPUFREQ_TRANSITION_NOTIFIER); | 391 | CPUFREQ_TRANSITION_NOTIFIER); |
402 | unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); | 392 | for_each_online_cpu(cpu) |
403 | for_each_online_cpu(cpu) { | ||
404 | cpufreq_stats_free_table(cpu); | 393 | cpufreq_stats_free_table(cpu); |
405 | cpufreq_stats_free_sysfs(cpu); | ||
406 | } | ||
407 | } | 394 | } |
408 | 395 | ||
409 | MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>"); | 396 | MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>"); |
diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index 5e8a854381b7..2cf33848d86e 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c | |||
@@ -58,14 +58,6 @@ static int davinci_verify_speed(struct cpufreq_policy *policy) | |||
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
60 | 60 | ||
61 | static unsigned int davinci_getspeed(unsigned int cpu) | ||
62 | { | ||
63 | if (cpu) | ||
64 | return 0; | ||
65 | |||
66 | return clk_get_rate(cpufreq.armclk) / 1000; | ||
67 | } | ||
68 | |||
69 | static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) | 61 | static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) |
70 | { | 62 | { |
71 | struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | 63 | struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; |
@@ -73,7 +65,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) | |||
73 | unsigned int old_freq, new_freq; | 65 | unsigned int old_freq, new_freq; |
74 | int ret = 0; | 66 | int ret = 0; |
75 | 67 | ||
76 | old_freq = davinci_getspeed(0); | 68 | old_freq = policy->cur; |
77 | new_freq = pdata->freq_table[idx].frequency; | 69 | new_freq = pdata->freq_table[idx].frequency; |
78 | 70 | ||
79 | /* if moving to higher frequency, up the voltage beforehand */ | 71 | /* if moving to higher frequency, up the voltage beforehand */ |
@@ -116,6 +108,8 @@ static int davinci_cpu_init(struct cpufreq_policy *policy) | |||
116 | return result; | 108 | return result; |
117 | } | 109 | } |
118 | 110 | ||
111 | policy->clk = cpufreq.armclk; | ||
112 | |||
119 | /* | 113 | /* |
120 | * Time measurement across the target() function yields ~1500-1800us | 114 | * Time measurement across the target() function yields ~1500-1800us |
121 | * time taken with no drivers on notification list. | 115 | * time taken with no drivers on notification list. |
@@ -126,10 +120,10 @@ static int davinci_cpu_init(struct cpufreq_policy *policy) | |||
126 | } | 120 | } |
127 | 121 | ||
128 | static struct cpufreq_driver davinci_driver = { | 122 | static struct cpufreq_driver davinci_driver = { |
129 | .flags = CPUFREQ_STICKY, | 123 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
130 | .verify = davinci_verify_speed, | 124 | .verify = davinci_verify_speed, |
131 | .target_index = davinci_target, | 125 | .target_index = davinci_target, |
132 | .get = davinci_getspeed, | 126 | .get = cpufreq_generic_get, |
133 | .init = davinci_cpu_init, | 127 | .init = davinci_cpu_init, |
134 | .exit = cpufreq_generic_exit, | 128 | .exit = cpufreq_generic_exit, |
135 | .name = "davinci", | 129 | .name = "davinci", |
diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c index 0e67ab96321a..412a78bb0c94 100644 --- a/drivers/cpufreq/dbx500-cpufreq.c +++ b/drivers/cpufreq/dbx500-cpufreq.c | |||
@@ -26,32 +26,18 @@ static int dbx500_cpufreq_target(struct cpufreq_policy *policy, | |||
26 | return clk_set_rate(armss_clk, freq_table[index].frequency * 1000); | 26 | return clk_set_rate(armss_clk, freq_table[index].frequency * 1000); |
27 | } | 27 | } |
28 | 28 | ||
29 | static unsigned int dbx500_cpufreq_getspeed(unsigned int cpu) | ||
30 | { | ||
31 | int i = 0; | ||
32 | unsigned long freq = clk_get_rate(armss_clk) / 1000; | ||
33 | |||
34 | /* The value is rounded to closest frequency in the defined table. */ | ||
35 | while (freq_table[i + 1].frequency != CPUFREQ_TABLE_END) { | ||
36 | if (freq < freq_table[i].frequency + | ||
37 | (freq_table[i + 1].frequency - freq_table[i].frequency) / 2) | ||
38 | return freq_table[i].frequency; | ||
39 | i++; | ||
40 | } | ||
41 | |||
42 | return freq_table[i].frequency; | ||
43 | } | ||
44 | |||
45 | static int dbx500_cpufreq_init(struct cpufreq_policy *policy) | 29 | static int dbx500_cpufreq_init(struct cpufreq_policy *policy) |
46 | { | 30 | { |
31 | policy->clk = armss_clk; | ||
47 | return cpufreq_generic_init(policy, freq_table, 20 * 1000); | 32 | return cpufreq_generic_init(policy, freq_table, 20 * 1000); |
48 | } | 33 | } |
49 | 34 | ||
50 | static struct cpufreq_driver dbx500_cpufreq_driver = { | 35 | static struct cpufreq_driver dbx500_cpufreq_driver = { |
51 | .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS, | 36 | .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS | |
37 | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
52 | .verify = cpufreq_generic_frequency_table_verify, | 38 | .verify = cpufreq_generic_frequency_table_verify, |
53 | .target_index = dbx500_cpufreq_target, | 39 | .target_index = dbx500_cpufreq_target, |
54 | .get = dbx500_cpufreq_getspeed, | 40 | .get = cpufreq_generic_get, |
55 | .init = dbx500_cpufreq_init, | 41 | .init = dbx500_cpufreq_init, |
56 | .name = "DBX500", | 42 | .name = "DBX500", |
57 | .attr = cpufreq_generic_attr, | 43 | .attr = cpufreq_generic_attr, |
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index f3c22874da75..fcd2914d081a 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/regulator/consumer.h> | 17 | #include <linux/regulator/consumer.h> |
18 | #include <linux/cpufreq.h> | 18 | #include <linux/cpufreq.h> |
19 | #include <linux/suspend.h> | 19 | #include <linux/suspend.h> |
20 | #include <linux/platform_device.h> | ||
20 | 21 | ||
21 | #include <plat/cpu.h> | 22 | #include <plat/cpu.h> |
22 | 23 | ||
@@ -30,11 +31,6 @@ static unsigned int locking_frequency; | |||
30 | static bool frequency_locked; | 31 | static bool frequency_locked; |
31 | static DEFINE_MUTEX(cpufreq_lock); | 32 | static DEFINE_MUTEX(cpufreq_lock); |
32 | 33 | ||
33 | static unsigned int exynos_getspeed(unsigned int cpu) | ||
34 | { | ||
35 | return clk_get_rate(exynos_info->cpu_clk) / 1000; | ||
36 | } | ||
37 | |||
38 | static int exynos_cpufreq_get_index(unsigned int freq) | 34 | static int exynos_cpufreq_get_index(unsigned int freq) |
39 | { | 35 | { |
40 | struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; | 36 | struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; |
@@ -214,25 +210,29 @@ static struct notifier_block exynos_cpufreq_nb = { | |||
214 | 210 | ||
215 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 211 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) |
216 | { | 212 | { |
213 | policy->clk = exynos_info->cpu_clk; | ||
217 | return cpufreq_generic_init(policy, exynos_info->freq_table, 100000); | 214 | return cpufreq_generic_init(policy, exynos_info->freq_table, 100000); |
218 | } | 215 | } |
219 | 216 | ||
220 | static struct cpufreq_driver exynos_driver = { | 217 | static struct cpufreq_driver exynos_driver = { |
221 | .flags = CPUFREQ_STICKY, | 218 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
222 | .verify = cpufreq_generic_frequency_table_verify, | 219 | .verify = cpufreq_generic_frequency_table_verify, |
223 | .target_index = exynos_target, | 220 | .target_index = exynos_target, |
224 | .get = exynos_getspeed, | 221 | .get = cpufreq_generic_get, |
225 | .init = exynos_cpufreq_cpu_init, | 222 | .init = exynos_cpufreq_cpu_init, |
226 | .exit = cpufreq_generic_exit, | 223 | .exit = cpufreq_generic_exit, |
227 | .name = "exynos_cpufreq", | 224 | .name = "exynos_cpufreq", |
228 | .attr = cpufreq_generic_attr, | 225 | .attr = cpufreq_generic_attr, |
226 | #ifdef CONFIG_ARM_EXYNOS_CPU_FREQ_BOOST_SW | ||
227 | .boost_supported = true, | ||
228 | #endif | ||
229 | #ifdef CONFIG_PM | 229 | #ifdef CONFIG_PM |
230 | .suspend = exynos_cpufreq_suspend, | 230 | .suspend = exynos_cpufreq_suspend, |
231 | .resume = exynos_cpufreq_resume, | 231 | .resume = exynos_cpufreq_resume, |
232 | #endif | 232 | #endif |
233 | }; | 233 | }; |
234 | 234 | ||
235 | static int __init exynos_cpufreq_init(void) | 235 | static int exynos_cpufreq_probe(struct platform_device *pdev) |
236 | { | 236 | { |
237 | int ret = -EINVAL; | 237 | int ret = -EINVAL; |
238 | 238 | ||
@@ -263,7 +263,7 @@ static int __init exynos_cpufreq_init(void) | |||
263 | goto err_vdd_arm; | 263 | goto err_vdd_arm; |
264 | } | 264 | } |
265 | 265 | ||
266 | locking_frequency = exynos_getspeed(0); | 266 | locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000; |
267 | 267 | ||
268 | register_pm_notifier(&exynos_cpufreq_nb); | 268 | register_pm_notifier(&exynos_cpufreq_nb); |
269 | 269 | ||
@@ -281,4 +281,12 @@ err_vdd_arm: | |||
281 | kfree(exynos_info); | 281 | kfree(exynos_info); |
282 | return -EINVAL; | 282 | return -EINVAL; |
283 | } | 283 | } |
284 | late_initcall(exynos_cpufreq_init); | 284 | |
285 | static struct platform_driver exynos_cpufreq_platdrv = { | ||
286 | .driver = { | ||
287 | .name = "exynos-cpufreq", | ||
288 | .owner = THIS_MODULE, | ||
289 | }, | ||
290 | .probe = exynos_cpufreq_probe, | ||
291 | }; | ||
292 | module_platform_driver(exynos_cpufreq_platdrv); | ||
diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c index 869e48297e28..7c11ace3b3fc 100644 --- a/drivers/cpufreq/exynos4x12-cpufreq.c +++ b/drivers/cpufreq/exynos4x12-cpufreq.c | |||
@@ -30,7 +30,7 @@ static unsigned int exynos4x12_volt_table[] = { | |||
30 | }; | 30 | }; |
31 | 31 | ||
32 | static struct cpufreq_frequency_table exynos4x12_freq_table[] = { | 32 | static struct cpufreq_frequency_table exynos4x12_freq_table[] = { |
33 | {L0, CPUFREQ_ENTRY_INVALID}, | 33 | {CPUFREQ_BOOST_FREQ, 1500 * 1000}, |
34 | {L1, 1400 * 1000}, | 34 | {L1, 1400 * 1000}, |
35 | {L2, 1300 * 1000}, | 35 | {L2, 1300 * 1000}, |
36 | {L3, 1200 * 1000}, | 36 | {L3, 1200 * 1000}, |
diff --git a/drivers/cpufreq/exynos5250-cpufreq.c b/drivers/cpufreq/exynos5250-cpufreq.c index 5ee2ce1ad424..5f90b82a4082 100644 --- a/drivers/cpufreq/exynos5250-cpufreq.c +++ b/drivers/cpufreq/exynos5250-cpufreq.c | |||
@@ -101,12 +101,12 @@ static void set_clkdiv(unsigned int div_index) | |||
101 | cpu_relax(); | 101 | cpu_relax(); |
102 | } | 102 | } |
103 | 103 | ||
104 | static void set_apll(unsigned int new_index, | 104 | static void set_apll(unsigned int index) |
105 | unsigned int old_index) | ||
106 | { | 105 | { |
107 | unsigned int tmp, pdiv; | 106 | unsigned int tmp; |
107 | unsigned int freq = apll_freq_5250[index].freq; | ||
108 | 108 | ||
109 | /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ | 109 | /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ |
110 | clk_set_parent(moutcore, mout_mpll); | 110 | clk_set_parent(moutcore, mout_mpll); |
111 | 111 | ||
112 | do { | 112 | do { |
@@ -115,24 +115,9 @@ static void set_apll(unsigned int new_index, | |||
115 | tmp &= 0x7; | 115 | tmp &= 0x7; |
116 | } while (tmp != 0x2); | 116 | } while (tmp != 0x2); |
117 | 117 | ||
118 | /* 2. Set APLL Lock time */ | 118 | clk_set_rate(mout_apll, freq * 1000); |
119 | pdiv = ((apll_freq_5250[new_index].mps >> 8) & 0x3f); | ||
120 | |||
121 | __raw_writel((pdiv * 250), EXYNOS5_APLL_LOCK); | ||
122 | 119 | ||
123 | /* 3. Change PLL PMS values */ | 120 | /* MUX_CORE_SEL = APLL */ |
124 | tmp = __raw_readl(EXYNOS5_APLL_CON0); | ||
125 | tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); | ||
126 | tmp |= apll_freq_5250[new_index].mps; | ||
127 | __raw_writel(tmp, EXYNOS5_APLL_CON0); | ||
128 | |||
129 | /* 4. wait_lock_time */ | ||
130 | do { | ||
131 | cpu_relax(); | ||
132 | tmp = __raw_readl(EXYNOS5_APLL_CON0); | ||
133 | } while (!(tmp & (0x1 << 29))); | ||
134 | |||
135 | /* 5. MUX_CORE_SEL = APLL */ | ||
136 | clk_set_parent(moutcore, mout_apll); | 121 | clk_set_parent(moutcore, mout_apll); |
137 | 122 | ||
138 | do { | 123 | do { |
@@ -140,55 +125,17 @@ static void set_apll(unsigned int new_index, | |||
140 | tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU); | 125 | tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU); |
141 | tmp &= (0x7 << 16); | 126 | tmp &= (0x7 << 16); |
142 | } while (tmp != (0x1 << 16)); | 127 | } while (tmp != (0x1 << 16)); |
143 | |||
144 | } | ||
145 | |||
146 | static bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index) | ||
147 | { | ||
148 | unsigned int old_pm = apll_freq_5250[old_index].mps >> 8; | ||
149 | unsigned int new_pm = apll_freq_5250[new_index].mps >> 8; | ||
150 | |||
151 | return (old_pm == new_pm) ? 0 : 1; | ||
152 | } | 128 | } |
153 | 129 | ||
154 | static void exynos5250_set_frequency(unsigned int old_index, | 130 | static void exynos5250_set_frequency(unsigned int old_index, |
155 | unsigned int new_index) | 131 | unsigned int new_index) |
156 | { | 132 | { |
157 | unsigned int tmp; | ||
158 | |||
159 | if (old_index > new_index) { | 133 | if (old_index > new_index) { |
160 | if (!exynos5250_pms_change(old_index, new_index)) { | 134 | set_clkdiv(new_index); |
161 | /* 1. Change the system clock divider values */ | 135 | set_apll(new_index); |
162 | set_clkdiv(new_index); | ||
163 | /* 2. Change just s value in apll m,p,s value */ | ||
164 | tmp = __raw_readl(EXYNOS5_APLL_CON0); | ||
165 | tmp &= ~(0x7 << 0); | ||
166 | tmp |= apll_freq_5250[new_index].mps & 0x7; | ||
167 | __raw_writel(tmp, EXYNOS5_APLL_CON0); | ||
168 | |||
169 | } else { | ||
170 | /* Clock Configuration Procedure */ | ||
171 | /* 1. Change the system clock divider values */ | ||
172 | set_clkdiv(new_index); | ||
173 | /* 2. Change the apll m,p,s value */ | ||
174 | set_apll(new_index, old_index); | ||
175 | } | ||
176 | } else if (old_index < new_index) { | 136 | } else if (old_index < new_index) { |
177 | if (!exynos5250_pms_change(old_index, new_index)) { | 137 | set_apll(new_index); |
178 | /* 1. Change just s value in apll m,p,s value */ | 138 | set_clkdiv(new_index); |
179 | tmp = __raw_readl(EXYNOS5_APLL_CON0); | ||
180 | tmp &= ~(0x7 << 0); | ||
181 | tmp |= apll_freq_5250[new_index].mps & 0x7; | ||
182 | __raw_writel(tmp, EXYNOS5_APLL_CON0); | ||
183 | /* 2. Change the system clock divider values */ | ||
184 | set_clkdiv(new_index); | ||
185 | } else { | ||
186 | /* Clock Configuration Procedure */ | ||
187 | /* 1. Change the apll m,p,s value */ | ||
188 | set_apll(new_index, old_index); | ||
189 | /* 2. Change the system clock divider values */ | ||
190 | set_clkdiv(new_index); | ||
191 | } | ||
192 | } | 139 | } |
193 | } | 140 | } |
194 | 141 | ||
@@ -221,7 +168,6 @@ int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) | |||
221 | info->volt_table = exynos5250_volt_table; | 168 | info->volt_table = exynos5250_volt_table; |
222 | info->freq_table = exynos5250_freq_table; | 169 | info->freq_table = exynos5250_freq_table; |
223 | info->set_freq = exynos5250_set_frequency; | 170 | info->set_freq = exynos5250_set_frequency; |
224 | info->need_apll_change = exynos5250_pms_change; | ||
225 | 171 | ||
226 | return 0; | 172 | return 0; |
227 | 173 | ||
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index 76bef8b078cb..49b756015316 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c | |||
@@ -100,7 +100,6 @@ struct exynos_dvfs_data { | |||
100 | struct resource *mem; | 100 | struct resource *mem; |
101 | int irq; | 101 | int irq; |
102 | struct clk *cpu_clk; | 102 | struct clk *cpu_clk; |
103 | unsigned int cur_frequency; | ||
104 | unsigned int latency; | 103 | unsigned int latency; |
105 | struct cpufreq_frequency_table *freq_table; | 104 | struct cpufreq_frequency_table *freq_table; |
106 | unsigned int freq_count; | 105 | unsigned int freq_count; |
@@ -165,7 +164,7 @@ static int init_div_table(void) | |||
165 | return 0; | 164 | return 0; |
166 | } | 165 | } |
167 | 166 | ||
168 | static void exynos_enable_dvfs(void) | 167 | static void exynos_enable_dvfs(unsigned int cur_frequency) |
169 | { | 168 | { |
170 | unsigned int tmp, i, cpu; | 169 | unsigned int tmp, i, cpu; |
171 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; | 170 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; |
@@ -184,18 +183,18 @@ static void exynos_enable_dvfs(void) | |||
184 | 183 | ||
185 | /* Set initial performance index */ | 184 | /* Set initial performance index */ |
186 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) | 185 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) |
187 | if (freq_table[i].frequency == dvfs_info->cur_frequency) | 186 | if (freq_table[i].frequency == cur_frequency) |
188 | break; | 187 | break; |
189 | 188 | ||
190 | if (freq_table[i].frequency == CPUFREQ_TABLE_END) { | 189 | if (freq_table[i].frequency == CPUFREQ_TABLE_END) { |
191 | dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); | 190 | dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); |
192 | /* Assign the highest frequency */ | 191 | /* Assign the highest frequency */ |
193 | i = 0; | 192 | i = 0; |
194 | dvfs_info->cur_frequency = freq_table[i].frequency; | 193 | cur_frequency = freq_table[i].frequency; |
195 | } | 194 | } |
196 | 195 | ||
197 | dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", | 196 | dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", |
198 | dvfs_info->cur_frequency); | 197 | cur_frequency); |
199 | 198 | ||
200 | for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { | 199 | for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { |
201 | tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); | 200 | tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); |
@@ -209,11 +208,6 @@ static void exynos_enable_dvfs(void) | |||
209 | dvfs_info->base + XMU_DVFS_CTRL); | 208 | dvfs_info->base + XMU_DVFS_CTRL); |
210 | } | 209 | } |
211 | 210 | ||
212 | static unsigned int exynos_getspeed(unsigned int cpu) | ||
213 | { | ||
214 | return dvfs_info->cur_frequency; | ||
215 | } | ||
216 | |||
217 | static int exynos_target(struct cpufreq_policy *policy, unsigned int index) | 211 | static int exynos_target(struct cpufreq_policy *policy, unsigned int index) |
218 | { | 212 | { |
219 | unsigned int tmp; | 213 | unsigned int tmp; |
@@ -222,7 +216,7 @@ static int exynos_target(struct cpufreq_policy *policy, unsigned int index) | |||
222 | 216 | ||
223 | mutex_lock(&cpufreq_lock); | 217 | mutex_lock(&cpufreq_lock); |
224 | 218 | ||
225 | freqs.old = dvfs_info->cur_frequency; | 219 | freqs.old = policy->cur; |
226 | freqs.new = freq_table[index].frequency; | 220 | freqs.new = freq_table[index].frequency; |
227 | 221 | ||
228 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 222 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
@@ -250,7 +244,7 @@ static void exynos_cpufreq_work(struct work_struct *work) | |||
250 | goto skip_work; | 244 | goto skip_work; |
251 | 245 | ||
252 | mutex_lock(&cpufreq_lock); | 246 | mutex_lock(&cpufreq_lock); |
253 | freqs.old = dvfs_info->cur_frequency; | 247 | freqs.old = policy->cur; |
254 | 248 | ||
255 | cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); | 249 | cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); |
256 | if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) | 250 | if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) |
@@ -260,10 +254,9 @@ static void exynos_cpufreq_work(struct work_struct *work) | |||
260 | 254 | ||
261 | if (likely(index < dvfs_info->freq_count)) { | 255 | if (likely(index < dvfs_info->freq_count)) { |
262 | freqs.new = freq_table[index].frequency; | 256 | freqs.new = freq_table[index].frequency; |
263 | dvfs_info->cur_frequency = freqs.new; | ||
264 | } else { | 257 | } else { |
265 | dev_crit(dvfs_info->dev, "New frequency out of range\n"); | 258 | dev_crit(dvfs_info->dev, "New frequency out of range\n"); |
266 | freqs.new = dvfs_info->cur_frequency; | 259 | freqs.new = freqs.old; |
267 | } | 260 | } |
268 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | 261 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); |
269 | 262 | ||
@@ -307,15 +300,17 @@ static void exynos_sort_descend_freq_table(void) | |||
307 | 300 | ||
308 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 301 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) |
309 | { | 302 | { |
303 | policy->clk = dvfs_info->cpu_clk; | ||
310 | return cpufreq_generic_init(policy, dvfs_info->freq_table, | 304 | return cpufreq_generic_init(policy, dvfs_info->freq_table, |
311 | dvfs_info->latency); | 305 | dvfs_info->latency); |
312 | } | 306 | } |
313 | 307 | ||
314 | static struct cpufreq_driver exynos_driver = { | 308 | static struct cpufreq_driver exynos_driver = { |
315 | .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION, | 309 | .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION | |
310 | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
316 | .verify = cpufreq_generic_frequency_table_verify, | 311 | .verify = cpufreq_generic_frequency_table_verify, |
317 | .target_index = exynos_target, | 312 | .target_index = exynos_target, |
318 | .get = exynos_getspeed, | 313 | .get = cpufreq_generic_get, |
319 | .init = exynos_cpufreq_cpu_init, | 314 | .init = exynos_cpufreq_cpu_init, |
320 | .exit = cpufreq_generic_exit, | 315 | .exit = cpufreq_generic_exit, |
321 | .name = CPUFREQ_NAME, | 316 | .name = CPUFREQ_NAME, |
@@ -335,6 +330,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
335 | int ret = -EINVAL; | 330 | int ret = -EINVAL; |
336 | struct device_node *np; | 331 | struct device_node *np; |
337 | struct resource res; | 332 | struct resource res; |
333 | unsigned int cur_frequency; | ||
338 | 334 | ||
339 | np = pdev->dev.of_node; | 335 | np = pdev->dev.of_node; |
340 | if (!np) | 336 | if (!np) |
@@ -391,13 +387,13 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
391 | goto err_free_table; | 387 | goto err_free_table; |
392 | } | 388 | } |
393 | 389 | ||
394 | dvfs_info->cur_frequency = clk_get_rate(dvfs_info->cpu_clk); | 390 | cur_frequency = clk_get_rate(dvfs_info->cpu_clk); |
395 | if (!dvfs_info->cur_frequency) { | 391 | if (!cur_frequency) { |
396 | dev_err(dvfs_info->dev, "Failed to get clock rate\n"); | 392 | dev_err(dvfs_info->dev, "Failed to get clock rate\n"); |
397 | ret = -EINVAL; | 393 | ret = -EINVAL; |
398 | goto err_free_table; | 394 | goto err_free_table; |
399 | } | 395 | } |
400 | dvfs_info->cur_frequency /= 1000; | 396 | cur_frequency /= 1000; |
401 | 397 | ||
402 | INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); | 398 | INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); |
403 | ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, | 399 | ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, |
@@ -414,7 +410,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
414 | goto err_free_table; | 410 | goto err_free_table; |
415 | } | 411 | } |
416 | 412 | ||
417 | exynos_enable_dvfs(); | 413 | exynos_enable_dvfs(cur_frequency); |
418 | ret = cpufreq_register_driver(&exynos_driver); | 414 | ret = cpufreq_register_driver(&exynos_driver); |
419 | if (ret) { | 415 | if (ret) { |
420 | dev_err(dvfs_info->dev, | 416 | dev_err(dvfs_info->dev, |
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 3458d27f63b4..8e54f97899ba 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
@@ -32,6 +32,10 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, | |||
32 | 32 | ||
33 | continue; | 33 | continue; |
34 | } | 34 | } |
35 | if (!cpufreq_boost_enabled() | ||
36 | && table[i].driver_data == CPUFREQ_BOOST_FREQ) | ||
37 | continue; | ||
38 | |||
35 | pr_debug("table entry %u: %u kHz, %u driver_data\n", | 39 | pr_debug("table entry %u: %u kHz, %u driver_data\n", |
36 | i, freq, table[i].driver_data); | 40 | i, freq, table[i].driver_data); |
37 | if (freq < min_freq) | 41 | if (freq < min_freq) |
@@ -178,11 +182,34 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, | |||
178 | } | 182 | } |
179 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); | 183 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); |
180 | 184 | ||
185 | int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, | ||
186 | unsigned int freq) | ||
187 | { | ||
188 | struct cpufreq_frequency_table *table; | ||
189 | int i; | ||
190 | |||
191 | table = cpufreq_frequency_get_table(policy->cpu); | ||
192 | if (unlikely(!table)) { | ||
193 | pr_debug("%s: Unable to find frequency table\n", __func__); | ||
194 | return -ENOENT; | ||
195 | } | ||
196 | |||
197 | for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { | ||
198 | if (table[i].frequency == freq) | ||
199 | return i; | ||
200 | } | ||
201 | |||
202 | return -EINVAL; | ||
203 | } | ||
204 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index); | ||
205 | |||
181 | static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); | 206 | static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); |
207 | |||
182 | /** | 208 | /** |
183 | * show_available_freqs - show available frequencies for the specified CPU | 209 | * show_available_freqs - show available frequencies for the specified CPU |
184 | */ | 210 | */ |
185 | static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf) | 211 | static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf, |
212 | bool show_boost) | ||
186 | { | 213 | { |
187 | unsigned int i = 0; | 214 | unsigned int i = 0; |
188 | unsigned int cpu = policy->cpu; | 215 | unsigned int cpu = policy->cpu; |
@@ -197,6 +224,20 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf) | |||
197 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 224 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
198 | if (table[i].frequency == CPUFREQ_ENTRY_INVALID) | 225 | if (table[i].frequency == CPUFREQ_ENTRY_INVALID) |
199 | continue; | 226 | continue; |
227 | /* | ||
228 | * show_boost = true and driver_data = BOOST freq | ||
229 | * display BOOST freqs | ||
230 | * | ||
231 | * show_boost = false and driver_data = BOOST freq | ||
232 | * show_boost = true and driver_data != BOOST freq | ||
233 | * continue - do not display anything | ||
234 | * | ||
235 | * show_boost = false and driver_data != BOOST freq | ||
236 | * display NON BOOST freqs | ||
237 | */ | ||
238 | if (show_boost ^ (table[i].driver_data == CPUFREQ_BOOST_FREQ)) | ||
239 | continue; | ||
240 | |||
200 | count += sprintf(&buf[count], "%d ", table[i].frequency); | 241 | count += sprintf(&buf[count], "%d ", table[i].frequency); |
201 | } | 242 | } |
202 | count += sprintf(&buf[count], "\n"); | 243 | count += sprintf(&buf[count], "\n"); |
@@ -205,16 +246,39 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf) | |||
205 | 246 | ||
206 | } | 247 | } |
207 | 248 | ||
208 | struct freq_attr cpufreq_freq_attr_scaling_available_freqs = { | 249 | #define cpufreq_attr_available_freq(_name) \ |
209 | .attr = { .name = "scaling_available_frequencies", | 250 | struct freq_attr cpufreq_freq_attr_##_name##_freqs = \ |
210 | .mode = 0444, | 251 | __ATTR_RO(_name##_frequencies) |
211 | }, | 252 | |
212 | .show = show_available_freqs, | 253 | /** |
213 | }; | 254 | * show_scaling_available_frequencies - show available normal frequencies for |
255 | * the specified CPU | ||
256 | */ | ||
257 | static ssize_t scaling_available_frequencies_show(struct cpufreq_policy *policy, | ||
258 | char *buf) | ||
259 | { | ||
260 | return show_available_freqs(policy, buf, false); | ||
261 | } | ||
262 | cpufreq_attr_available_freq(scaling_available); | ||
214 | EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); | 263 | EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); |
215 | 264 | ||
265 | /** | ||
266 | * show_available_boost_freqs - show available boost frequencies for | ||
267 | * the specified CPU | ||
268 | */ | ||
269 | static ssize_t scaling_boost_frequencies_show(struct cpufreq_policy *policy, | ||
270 | char *buf) | ||
271 | { | ||
272 | return show_available_freqs(policy, buf, true); | ||
273 | } | ||
274 | cpufreq_attr_available_freq(scaling_boost); | ||
275 | EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_boost_freqs); | ||
276 | |||
216 | struct freq_attr *cpufreq_generic_attr[] = { | 277 | struct freq_attr *cpufreq_generic_attr[] = { |
217 | &cpufreq_freq_attr_scaling_available_freqs, | 278 | &cpufreq_freq_attr_scaling_available_freqs, |
279 | #ifdef CONFIG_CPU_FREQ_BOOST_SW | ||
280 | &cpufreq_freq_attr_scaling_boost_freqs, | ||
281 | #endif | ||
218 | NULL, | 282 | NULL, |
219 | }; | 283 | }; |
220 | EXPORT_SYMBOL_GPL(cpufreq_generic_attr); | 284 | EXPORT_SYMBOL_GPL(cpufreq_generic_attr); |
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 4b3f18e5f36b..ce69059be1fc 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c | |||
@@ -35,10 +35,8 @@ static struct device *cpu_dev; | |||
35 | static struct cpufreq_frequency_table *freq_table; | 35 | static struct cpufreq_frequency_table *freq_table; |
36 | static unsigned int transition_latency; | 36 | static unsigned int transition_latency; |
37 | 37 | ||
38 | static unsigned int imx6q_get_speed(unsigned int cpu) | 38 | static u32 *imx6_soc_volt; |
39 | { | 39 | static u32 soc_opp_count; |
40 | return clk_get_rate(arm_clk) / 1000; | ||
41 | } | ||
42 | 40 | ||
43 | static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) | 41 | static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) |
44 | { | 42 | { |
@@ -69,23 +67,22 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
69 | 67 | ||
70 | /* scaling up? scale voltage before frequency */ | 68 | /* scaling up? scale voltage before frequency */ |
71 | if (new_freq > old_freq) { | 69 | if (new_freq > old_freq) { |
70 | ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0); | ||
71 | if (ret) { | ||
72 | dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret); | ||
73 | return ret; | ||
74 | } | ||
75 | ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0); | ||
76 | if (ret) { | ||
77 | dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret); | ||
78 | return ret; | ||
79 | } | ||
72 | ret = regulator_set_voltage_tol(arm_reg, volt, 0); | 80 | ret = regulator_set_voltage_tol(arm_reg, volt, 0); |
73 | if (ret) { | 81 | if (ret) { |
74 | dev_err(cpu_dev, | 82 | dev_err(cpu_dev, |
75 | "failed to scale vddarm up: %d\n", ret); | 83 | "failed to scale vddarm up: %d\n", ret); |
76 | return ret; | 84 | return ret; |
77 | } | 85 | } |
78 | |||
79 | /* | ||
80 | * Need to increase vddpu and vddsoc for safety | ||
81 | * if we are about to run at 1.2 GHz. | ||
82 | */ | ||
83 | if (new_freq == FREQ_1P2_GHZ / 1000) { | ||
84 | regulator_set_voltage_tol(pu_reg, | ||
85 | PU_SOC_VOLTAGE_HIGH, 0); | ||
86 | regulator_set_voltage_tol(soc_reg, | ||
87 | PU_SOC_VOLTAGE_HIGH, 0); | ||
88 | } | ||
89 | } | 86 | } |
90 | 87 | ||
91 | /* | 88 | /* |
@@ -120,12 +117,15 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
120 | "failed to scale vddarm down: %d\n", ret); | 117 | "failed to scale vddarm down: %d\n", ret); |
121 | ret = 0; | 118 | ret = 0; |
122 | } | 119 | } |
123 | 120 | ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0); | |
124 | if (old_freq == FREQ_1P2_GHZ / 1000) { | 121 | if (ret) { |
125 | regulator_set_voltage_tol(pu_reg, | 122 | dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret); |
126 | PU_SOC_VOLTAGE_NORMAL, 0); | 123 | ret = 0; |
127 | regulator_set_voltage_tol(soc_reg, | 124 | } |
128 | PU_SOC_VOLTAGE_NORMAL, 0); | 125 | ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0); |
126 | if (ret) { | ||
127 | dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret); | ||
128 | ret = 0; | ||
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
@@ -134,13 +134,15 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
134 | 134 | ||
135 | static int imx6q_cpufreq_init(struct cpufreq_policy *policy) | 135 | static int imx6q_cpufreq_init(struct cpufreq_policy *policy) |
136 | { | 136 | { |
137 | policy->clk = arm_clk; | ||
137 | return cpufreq_generic_init(policy, freq_table, transition_latency); | 138 | return cpufreq_generic_init(policy, freq_table, transition_latency); |
138 | } | 139 | } |
139 | 140 | ||
140 | static struct cpufreq_driver imx6q_cpufreq_driver = { | 141 | static struct cpufreq_driver imx6q_cpufreq_driver = { |
142 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
141 | .verify = cpufreq_generic_frequency_table_verify, | 143 | .verify = cpufreq_generic_frequency_table_verify, |
142 | .target_index = imx6q_set_target, | 144 | .target_index = imx6q_set_target, |
143 | .get = imx6q_get_speed, | 145 | .get = cpufreq_generic_get, |
144 | .init = imx6q_cpufreq_init, | 146 | .init = imx6q_cpufreq_init, |
145 | .exit = cpufreq_generic_exit, | 147 | .exit = cpufreq_generic_exit, |
146 | .name = "imx6q-cpufreq", | 148 | .name = "imx6q-cpufreq", |
@@ -153,6 +155,9 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
153 | struct dev_pm_opp *opp; | 155 | struct dev_pm_opp *opp; |
154 | unsigned long min_volt, max_volt; | 156 | unsigned long min_volt, max_volt; |
155 | int num, ret; | 157 | int num, ret; |
158 | const struct property *prop; | ||
159 | const __be32 *val; | ||
160 | u32 nr, i, j; | ||
156 | 161 | ||
157 | cpu_dev = get_cpu_device(0); | 162 | cpu_dev = get_cpu_device(0); |
158 | if (!cpu_dev) { | 163 | if (!cpu_dev) { |
@@ -187,12 +192,25 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
187 | goto put_node; | 192 | goto put_node; |
188 | } | 193 | } |
189 | 194 | ||
190 | /* We expect an OPP table supplied by platform */ | 195 | /* |
196 | * We expect an OPP table supplied by platform. | ||
197 | * Just, incase the platform did not supply the OPP | ||
198 | * table, it will try to get it. | ||
199 | */ | ||
191 | num = dev_pm_opp_get_opp_count(cpu_dev); | 200 | num = dev_pm_opp_get_opp_count(cpu_dev); |
192 | if (num < 0) { | 201 | if (num < 0) { |
193 | ret = num; | 202 | ret = of_init_opp_table(cpu_dev); |
194 | dev_err(cpu_dev, "no OPP table is found: %d\n", ret); | 203 | if (ret < 0) { |
195 | goto put_node; | 204 | dev_err(cpu_dev, "failed to init OPP table: %d\n", ret); |
205 | goto put_node; | ||
206 | } | ||
207 | |||
208 | num = dev_pm_opp_get_opp_count(cpu_dev); | ||
209 | if (num < 0) { | ||
210 | ret = num; | ||
211 | dev_err(cpu_dev, "no OPP table is found: %d\n", ret); | ||
212 | goto put_node; | ||
213 | } | ||
196 | } | 214 | } |
197 | 215 | ||
198 | ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); | 216 | ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); |
@@ -201,10 +219,62 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
201 | goto put_node; | 219 | goto put_node; |
202 | } | 220 | } |
203 | 221 | ||
222 | /* Make imx6_soc_volt array's size same as arm opp number */ | ||
223 | imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL); | ||
224 | if (imx6_soc_volt == NULL) { | ||
225 | ret = -ENOMEM; | ||
226 | goto free_freq_table; | ||
227 | } | ||
228 | |||
229 | prop = of_find_property(np, "fsl,soc-operating-points", NULL); | ||
230 | if (!prop || !prop->value) | ||
231 | goto soc_opp_out; | ||
232 | |||
233 | /* | ||
234 | * Each OPP is a set of tuples consisting of frequency and | ||
235 | * voltage like <freq-kHz vol-uV>. | ||
236 | */ | ||
237 | nr = prop->length / sizeof(u32); | ||
238 | if (nr % 2 || (nr / 2) < num) | ||
239 | goto soc_opp_out; | ||
240 | |||
241 | for (j = 0; j < num; j++) { | ||
242 | val = prop->value; | ||
243 | for (i = 0; i < nr / 2; i++) { | ||
244 | unsigned long freq = be32_to_cpup(val++); | ||
245 | unsigned long volt = be32_to_cpup(val++); | ||
246 | if (freq_table[j].frequency == freq) { | ||
247 | imx6_soc_volt[soc_opp_count++] = volt; | ||
248 | break; | ||
249 | } | ||
250 | } | ||
251 | } | ||
252 | |||
253 | soc_opp_out: | ||
254 | /* use fixed soc opp volt if no valid soc opp info found in dtb */ | ||
255 | if (soc_opp_count != num) { | ||
256 | dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n"); | ||
257 | for (j = 0; j < num; j++) | ||
258 | imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL; | ||
259 | if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ) | ||
260 | imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH; | ||
261 | } | ||
262 | |||
204 | if (of_property_read_u32(np, "clock-latency", &transition_latency)) | 263 | if (of_property_read_u32(np, "clock-latency", &transition_latency)) |
205 | transition_latency = CPUFREQ_ETERNAL; | 264 | transition_latency = CPUFREQ_ETERNAL; |
206 | 265 | ||
207 | /* | 266 | /* |
267 | * Calculate the ramp time for max voltage change in the | ||
268 | * VDDSOC and VDDPU regulators. | ||
269 | */ | ||
270 | ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]); | ||
271 | if (ret > 0) | ||
272 | transition_latency += ret * 1000; | ||
273 | ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]); | ||
274 | if (ret > 0) | ||
275 | transition_latency += ret * 1000; | ||
276 | |||
277 | /* | ||
208 | * OPP is maintained in order of increasing frequency, and | 278 | * OPP is maintained in order of increasing frequency, and |
209 | * freq_table initialised from OPP is therefore sorted in the | 279 | * freq_table initialised from OPP is therefore sorted in the |
210 | * same order. | 280 | * same order. |
@@ -221,18 +291,6 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
221 | if (ret > 0) | 291 | if (ret > 0) |
222 | transition_latency += ret * 1000; | 292 | transition_latency += ret * 1000; |
223 | 293 | ||
224 | /* Count vddpu and vddsoc latency in for 1.2 GHz support */ | ||
225 | if (freq_table[num].frequency == FREQ_1P2_GHZ / 1000) { | ||
226 | ret = regulator_set_voltage_time(pu_reg, PU_SOC_VOLTAGE_NORMAL, | ||
227 | PU_SOC_VOLTAGE_HIGH); | ||
228 | if (ret > 0) | ||
229 | transition_latency += ret * 1000; | ||
230 | ret = regulator_set_voltage_time(soc_reg, PU_SOC_VOLTAGE_NORMAL, | ||
231 | PU_SOC_VOLTAGE_HIGH); | ||
232 | if (ret > 0) | ||
233 | transition_latency += ret * 1000; | ||
234 | } | ||
235 | |||
236 | ret = cpufreq_register_driver(&imx6q_cpufreq_driver); | 294 | ret = cpufreq_register_driver(&imx6q_cpufreq_driver); |
237 | if (ret) { | 295 | if (ret) { |
238 | dev_err(cpu_dev, "failed register driver: %d\n", ret); | 296 | dev_err(cpu_dev, "failed register driver: %d\n", ret); |
diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c index 7d8ab000d317..0e27844e8c2d 100644 --- a/drivers/cpufreq/integrator-cpufreq.c +++ b/drivers/cpufreq/integrator-cpufreq.c | |||
@@ -190,6 +190,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy) | |||
190 | } | 190 | } |
191 | 191 | ||
192 | static struct cpufreq_driver integrator_driver = { | 192 | static struct cpufreq_driver integrator_driver = { |
193 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
193 | .verify = integrator_verify_policy, | 194 | .verify = integrator_verify_policy, |
194 | .target = integrator_set_target, | 195 | .target = integrator_set_target, |
195 | .get = integrator_get, | 196 | .get = integrator_get, |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index d51f17ed691e..7e257b233602 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #define SAMPLE_COUNT 3 | 35 | #define SAMPLE_COUNT 3 |
36 | 36 | ||
37 | #define BYT_RATIOS 0x66a | 37 | #define BYT_RATIOS 0x66a |
38 | #define BYT_VIDS 0x66b | ||
38 | 39 | ||
39 | #define FRAC_BITS 8 | 40 | #define FRAC_BITS 8 |
40 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 41 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
@@ -50,6 +51,8 @@ static inline int32_t div_fp(int32_t x, int32_t y) | |||
50 | return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); | 51 | return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); |
51 | } | 52 | } |
52 | 53 | ||
54 | static u64 energy_divisor; | ||
55 | |||
53 | struct sample { | 56 | struct sample { |
54 | int32_t core_pct_busy; | 57 | int32_t core_pct_busy; |
55 | u64 aperf; | 58 | u64 aperf; |
@@ -64,6 +67,12 @@ struct pstate_data { | |||
64 | int turbo_pstate; | 67 | int turbo_pstate; |
65 | }; | 68 | }; |
66 | 69 | ||
70 | struct vid_data { | ||
71 | int32_t min; | ||
72 | int32_t max; | ||
73 | int32_t ratio; | ||
74 | }; | ||
75 | |||
67 | struct _pid { | 76 | struct _pid { |
68 | int setpoint; | 77 | int setpoint; |
69 | int32_t integral; | 78 | int32_t integral; |
@@ -82,10 +91,9 @@ struct cpudata { | |||
82 | struct timer_list timer; | 91 | struct timer_list timer; |
83 | 92 | ||
84 | struct pstate_data pstate; | 93 | struct pstate_data pstate; |
94 | struct vid_data vid; | ||
85 | struct _pid pid; | 95 | struct _pid pid; |
86 | 96 | ||
87 | int min_pstate_count; | ||
88 | |||
89 | u64 prev_aperf; | 97 | u64 prev_aperf; |
90 | u64 prev_mperf; | 98 | u64 prev_mperf; |
91 | int sample_ptr; | 99 | int sample_ptr; |
@@ -106,7 +114,8 @@ struct pstate_funcs { | |||
106 | int (*get_max)(void); | 114 | int (*get_max)(void); |
107 | int (*get_min)(void); | 115 | int (*get_min)(void); |
108 | int (*get_turbo)(void); | 116 | int (*get_turbo)(void); |
109 | void (*set)(int pstate); | 117 | void (*set)(struct cpudata*, int pstate); |
118 | void (*get_vid)(struct cpudata *); | ||
110 | }; | 119 | }; |
111 | 120 | ||
112 | struct cpu_defaults { | 121 | struct cpu_defaults { |
@@ -358,6 +367,42 @@ static int byt_get_max_pstate(void) | |||
358 | return (value >> 16) & 0xFF; | 367 | return (value >> 16) & 0xFF; |
359 | } | 368 | } |
360 | 369 | ||
370 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) | ||
371 | { | ||
372 | u64 val; | ||
373 | int32_t vid_fp; | ||
374 | u32 vid; | ||
375 | |||
376 | val = pstate << 8; | ||
377 | if (limits.no_turbo) | ||
378 | val |= (u64)1 << 32; | ||
379 | |||
380 | vid_fp = cpudata->vid.min + mul_fp( | ||
381 | int_tofp(pstate - cpudata->pstate.min_pstate), | ||
382 | cpudata->vid.ratio); | ||
383 | |||
384 | vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max); | ||
385 | vid = fp_toint(vid_fp); | ||
386 | |||
387 | val |= vid; | ||
388 | |||
389 | wrmsrl(MSR_IA32_PERF_CTL, val); | ||
390 | } | ||
391 | |||
392 | static void byt_get_vid(struct cpudata *cpudata) | ||
393 | { | ||
394 | u64 value; | ||
395 | |||
396 | rdmsrl(BYT_VIDS, value); | ||
397 | cpudata->vid.min = int_tofp((value >> 8) & 0x7f); | ||
398 | cpudata->vid.max = int_tofp((value >> 16) & 0x7f); | ||
399 | cpudata->vid.ratio = div_fp( | ||
400 | cpudata->vid.max - cpudata->vid.min, | ||
401 | int_tofp(cpudata->pstate.max_pstate - | ||
402 | cpudata->pstate.min_pstate)); | ||
403 | } | ||
404 | |||
405 | |||
361 | static int core_get_min_pstate(void) | 406 | static int core_get_min_pstate(void) |
362 | { | 407 | { |
363 | u64 value; | 408 | u64 value; |
@@ -384,7 +429,7 @@ static int core_get_turbo_pstate(void) | |||
384 | return ret; | 429 | return ret; |
385 | } | 430 | } |
386 | 431 | ||
387 | static void core_set_pstate(int pstate) | 432 | static void core_set_pstate(struct cpudata *cpudata, int pstate) |
388 | { | 433 | { |
389 | u64 val; | 434 | u64 val; |
390 | 435 | ||
@@ -425,7 +470,8 @@ static struct cpu_defaults byt_params = { | |||
425 | .get_max = byt_get_max_pstate, | 470 | .get_max = byt_get_max_pstate, |
426 | .get_min = byt_get_min_pstate, | 471 | .get_min = byt_get_min_pstate, |
427 | .get_turbo = byt_get_max_pstate, | 472 | .get_turbo = byt_get_max_pstate, |
428 | .set = core_set_pstate, | 473 | .set = byt_set_pstate, |
474 | .get_vid = byt_get_vid, | ||
429 | }, | 475 | }, |
430 | }; | 476 | }; |
431 | 477 | ||
@@ -462,7 +508,7 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) | |||
462 | 508 | ||
463 | cpu->pstate.current_pstate = pstate; | 509 | cpu->pstate.current_pstate = pstate; |
464 | 510 | ||
465 | pstate_funcs.set(pstate); | 511 | pstate_funcs.set(cpu, pstate); |
466 | } | 512 | } |
467 | 513 | ||
468 | static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) | 514 | static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) |
@@ -488,6 +534,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
488 | cpu->pstate.max_pstate = pstate_funcs.get_max(); | 534 | cpu->pstate.max_pstate = pstate_funcs.get_max(); |
489 | cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); | 535 | cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); |
490 | 536 | ||
537 | if (pstate_funcs.get_vid) | ||
538 | pstate_funcs.get_vid(cpu); | ||
539 | |||
491 | /* | 540 | /* |
492 | * goto max pstate so we don't slow up boot if we are built-in if we are | 541 | * goto max pstate so we don't slow up boot if we are built-in if we are |
493 | * a module we will take care of it during normal operation | 542 | * a module we will take care of it during normal operation |
@@ -512,6 +561,7 @@ static inline void intel_pstate_sample(struct cpudata *cpu) | |||
512 | 561 | ||
513 | rdmsrl(MSR_IA32_APERF, aperf); | 562 | rdmsrl(MSR_IA32_APERF, aperf); |
514 | rdmsrl(MSR_IA32_MPERF, mperf); | 563 | rdmsrl(MSR_IA32_MPERF, mperf); |
564 | |||
515 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; | 565 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; |
516 | cpu->samples[cpu->sample_ptr].aperf = aperf; | 566 | cpu->samples[cpu->sample_ptr].aperf = aperf; |
517 | cpu->samples[cpu->sample_ptr].mperf = mperf; | 567 | cpu->samples[cpu->sample_ptr].mperf = mperf; |
@@ -556,6 +606,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | |||
556 | ctl = pid_calc(pid, busy_scaled); | 606 | ctl = pid_calc(pid, busy_scaled); |
557 | 607 | ||
558 | steps = abs(ctl); | 608 | steps = abs(ctl); |
609 | |||
559 | if (ctl < 0) | 610 | if (ctl < 0) |
560 | intel_pstate_pstate_increase(cpu, steps); | 611 | intel_pstate_pstate_increase(cpu, steps); |
561 | else | 612 | else |
@@ -565,17 +616,23 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | |||
565 | static void intel_pstate_timer_func(unsigned long __data) | 616 | static void intel_pstate_timer_func(unsigned long __data) |
566 | { | 617 | { |
567 | struct cpudata *cpu = (struct cpudata *) __data; | 618 | struct cpudata *cpu = (struct cpudata *) __data; |
619 | struct sample *sample; | ||
620 | u64 energy; | ||
568 | 621 | ||
569 | intel_pstate_sample(cpu); | 622 | intel_pstate_sample(cpu); |
623 | |||
624 | sample = &cpu->samples[cpu->sample_ptr]; | ||
625 | rdmsrl(MSR_PKG_ENERGY_STATUS, energy); | ||
626 | |||
570 | intel_pstate_adjust_busy_pstate(cpu); | 627 | intel_pstate_adjust_busy_pstate(cpu); |
571 | 628 | ||
572 | if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) { | 629 | trace_pstate_sample(fp_toint(sample->core_pct_busy), |
573 | cpu->min_pstate_count++; | 630 | fp_toint(intel_pstate_get_scaled_busy(cpu)), |
574 | if (!(cpu->min_pstate_count % 5)) { | 631 | cpu->pstate.current_pstate, |
575 | intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); | 632 | sample->mperf, |
576 | } | 633 | sample->aperf, |
577 | } else | 634 | div64_u64(energy, energy_divisor), |
578 | cpu->min_pstate_count = 0; | 635 | sample->freq); |
579 | 636 | ||
580 | intel_pstate_set_sample_time(cpu); | 637 | intel_pstate_set_sample_time(cpu); |
581 | } | 638 | } |
@@ -782,6 +839,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs) | |||
782 | pstate_funcs.get_min = funcs->get_min; | 839 | pstate_funcs.get_min = funcs->get_min; |
783 | pstate_funcs.get_turbo = funcs->get_turbo; | 840 | pstate_funcs.get_turbo = funcs->get_turbo; |
784 | pstate_funcs.set = funcs->set; | 841 | pstate_funcs.set = funcs->set; |
842 | pstate_funcs.get_vid = funcs->get_vid; | ||
785 | } | 843 | } |
786 | 844 | ||
787 | #if IS_ENABLED(CONFIG_ACPI) | 845 | #if IS_ENABLED(CONFIG_ACPI) |
@@ -855,6 +913,7 @@ static int __init intel_pstate_init(void) | |||
855 | int cpu, rc = 0; | 913 | int cpu, rc = 0; |
856 | const struct x86_cpu_id *id; | 914 | const struct x86_cpu_id *id; |
857 | struct cpu_defaults *cpu_info; | 915 | struct cpu_defaults *cpu_info; |
916 | u64 units; | ||
858 | 917 | ||
859 | if (no_load) | 918 | if (no_load) |
860 | return -ENODEV; | 919 | return -ENODEV; |
@@ -888,8 +947,12 @@ static int __init intel_pstate_init(void) | |||
888 | if (rc) | 947 | if (rc) |
889 | goto out; | 948 | goto out; |
890 | 949 | ||
950 | rdmsrl(MSR_RAPL_POWER_UNIT, units); | ||
951 | energy_divisor = 1 << ((units >> 8) & 0x1f); /* bits{12:8} */ | ||
952 | |||
891 | intel_pstate_debug_expose_params(); | 953 | intel_pstate_debug_expose_params(); |
892 | intel_pstate_sysfs_expose_params(); | 954 | intel_pstate_sysfs_expose_params(); |
955 | |||
893 | return rc; | 956 | return rc; |
894 | out: | 957 | out: |
895 | get_online_cpus(); | 958 | get_online_cpus(); |
diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index 0767a4e29dfe..eb7abe345b50 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c | |||
@@ -97,6 +97,7 @@ static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | static struct cpufreq_driver kirkwood_cpufreq_driver = { | 99 | static struct cpufreq_driver kirkwood_cpufreq_driver = { |
100 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
100 | .get = kirkwood_cpufreq_get_cpu_frequency, | 101 | .get = kirkwood_cpufreq_get_cpu_frequency, |
101 | .verify = cpufreq_generic_frequency_table_verify, | 102 | .verify = cpufreq_generic_frequency_table_verify, |
102 | .target_index = kirkwood_cpufreq_target, | 103 | .target_index = kirkwood_cpufreq_target, |
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index a43609218105..b6581abc9207 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c | |||
@@ -24,8 +24,6 @@ | |||
24 | 24 | ||
25 | static uint nowait; | 25 | static uint nowait; |
26 | 26 | ||
27 | static struct clk *cpuclk; | ||
28 | |||
29 | static void (*saved_cpu_wait) (void); | 27 | static void (*saved_cpu_wait) (void); |
30 | 28 | ||
31 | static int loongson2_cpu_freq_notifier(struct notifier_block *nb, | 29 | static int loongson2_cpu_freq_notifier(struct notifier_block *nb, |
@@ -44,11 +42,6 @@ static int loongson2_cpu_freq_notifier(struct notifier_block *nb, | |||
44 | return 0; | 42 | return 0; |
45 | } | 43 | } |
46 | 44 | ||
47 | static unsigned int loongson2_cpufreq_get(unsigned int cpu) | ||
48 | { | ||
49 | return clk_get_rate(cpuclk); | ||
50 | } | ||
51 | |||
52 | /* | 45 | /* |
53 | * Here we notify other drivers of the proposed change and the final change. | 46 | * Here we notify other drivers of the proposed change and the final change. |
54 | */ | 47 | */ |
@@ -69,13 +62,14 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, | |||
69 | set_cpus_allowed_ptr(current, &cpus_allowed); | 62 | set_cpus_allowed_ptr(current, &cpus_allowed); |
70 | 63 | ||
71 | /* setting the cpu frequency */ | 64 | /* setting the cpu frequency */ |
72 | clk_set_rate(cpuclk, freq); | 65 | clk_set_rate(policy->clk, freq); |
73 | 66 | ||
74 | return 0; | 67 | return 0; |
75 | } | 68 | } |
76 | 69 | ||
77 | static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) | 70 | static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) |
78 | { | 71 | { |
72 | static struct clk *cpuclk; | ||
79 | int i; | 73 | int i; |
80 | unsigned long rate; | 74 | unsigned long rate; |
81 | int ret; | 75 | int ret; |
@@ -104,13 +98,14 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
104 | return ret; | 98 | return ret; |
105 | } | 99 | } |
106 | 100 | ||
101 | policy->clk = cpuclk; | ||
107 | return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0); | 102 | return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0); |
108 | } | 103 | } |
109 | 104 | ||
110 | static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) | 105 | static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) |
111 | { | 106 | { |
112 | cpufreq_frequency_table_put_attr(policy->cpu); | 107 | cpufreq_frequency_table_put_attr(policy->cpu); |
113 | clk_put(cpuclk); | 108 | clk_put(policy->clk); |
114 | return 0; | 109 | return 0; |
115 | } | 110 | } |
116 | 111 | ||
@@ -119,7 +114,7 @@ static struct cpufreq_driver loongson2_cpufreq_driver = { | |||
119 | .init = loongson2_cpufreq_cpu_init, | 114 | .init = loongson2_cpufreq_cpu_init, |
120 | .verify = cpufreq_generic_frequency_table_verify, | 115 | .verify = cpufreq_generic_frequency_table_verify, |
121 | .target_index = loongson2_cpufreq_target, | 116 | .target_index = loongson2_cpufreq_target, |
122 | .get = loongson2_cpufreq_get, | 117 | .get = cpufreq_generic_get, |
123 | .exit = loongson2_cpufreq_exit, | 118 | .exit = loongson2_cpufreq_exit, |
124 | .attr = cpufreq_generic_attr, | 119 | .attr = cpufreq_generic_attr, |
125 | }; | 120 | }; |
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index a0acd0bfba40..590f5b66d181 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c | |||
@@ -36,21 +36,9 @@ | |||
36 | 36 | ||
37 | static struct cpufreq_frequency_table *freq_table; | 37 | static struct cpufreq_frequency_table *freq_table; |
38 | static atomic_t freq_table_users = ATOMIC_INIT(0); | 38 | static atomic_t freq_table_users = ATOMIC_INIT(0); |
39 | static struct clk *mpu_clk; | ||
40 | static struct device *mpu_dev; | 39 | static struct device *mpu_dev; |
41 | static struct regulator *mpu_reg; | 40 | static struct regulator *mpu_reg; |
42 | 41 | ||
43 | static unsigned int omap_getspeed(unsigned int cpu) | ||
44 | { | ||
45 | unsigned long rate; | ||
46 | |||
47 | if (cpu >= NR_CPUS) | ||
48 | return 0; | ||
49 | |||
50 | rate = clk_get_rate(mpu_clk) / 1000; | ||
51 | return rate; | ||
52 | } | ||
53 | |||
54 | static int omap_target(struct cpufreq_policy *policy, unsigned int index) | 42 | static int omap_target(struct cpufreq_policy *policy, unsigned int index) |
55 | { | 43 | { |
56 | int r, ret; | 44 | int r, ret; |
@@ -58,11 +46,11 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) | |||
58 | unsigned long freq, volt = 0, volt_old = 0, tol = 0; | 46 | unsigned long freq, volt = 0, volt_old = 0, tol = 0; |
59 | unsigned int old_freq, new_freq; | 47 | unsigned int old_freq, new_freq; |
60 | 48 | ||
61 | old_freq = omap_getspeed(policy->cpu); | 49 | old_freq = policy->cur; |
62 | new_freq = freq_table[index].frequency; | 50 | new_freq = freq_table[index].frequency; |
63 | 51 | ||
64 | freq = new_freq * 1000; | 52 | freq = new_freq * 1000; |
65 | ret = clk_round_rate(mpu_clk, freq); | 53 | ret = clk_round_rate(policy->clk, freq); |
66 | if (IS_ERR_VALUE(ret)) { | 54 | if (IS_ERR_VALUE(ret)) { |
67 | dev_warn(mpu_dev, | 55 | dev_warn(mpu_dev, |
68 | "CPUfreq: Cannot find matching frequency for %lu\n", | 56 | "CPUfreq: Cannot find matching frequency for %lu\n", |
@@ -100,7 +88,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) | |||
100 | } | 88 | } |
101 | } | 89 | } |
102 | 90 | ||
103 | ret = clk_set_rate(mpu_clk, new_freq * 1000); | 91 | ret = clk_set_rate(policy->clk, new_freq * 1000); |
104 | 92 | ||
105 | /* scaling down? scale voltage after frequency */ | 93 | /* scaling down? scale voltage after frequency */ |
106 | if (mpu_reg && (new_freq < old_freq)) { | 94 | if (mpu_reg && (new_freq < old_freq)) { |
@@ -108,7 +96,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) | |||
108 | if (r < 0) { | 96 | if (r < 0) { |
109 | dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", | 97 | dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", |
110 | __func__); | 98 | __func__); |
111 | clk_set_rate(mpu_clk, old_freq * 1000); | 99 | clk_set_rate(policy->clk, old_freq * 1000); |
112 | return r; | 100 | return r; |
113 | } | 101 | } |
114 | } | 102 | } |
@@ -126,9 +114,9 @@ static int omap_cpu_init(struct cpufreq_policy *policy) | |||
126 | { | 114 | { |
127 | int result; | 115 | int result; |
128 | 116 | ||
129 | mpu_clk = clk_get(NULL, "cpufreq_ck"); | 117 | policy->clk = clk_get(NULL, "cpufreq_ck"); |
130 | if (IS_ERR(mpu_clk)) | 118 | if (IS_ERR(policy->clk)) |
131 | return PTR_ERR(mpu_clk); | 119 | return PTR_ERR(policy->clk); |
132 | 120 | ||
133 | if (!freq_table) { | 121 | if (!freq_table) { |
134 | result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table); | 122 | result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table); |
@@ -149,7 +137,7 @@ static int omap_cpu_init(struct cpufreq_policy *policy) | |||
149 | 137 | ||
150 | freq_table_free(); | 138 | freq_table_free(); |
151 | fail: | 139 | fail: |
152 | clk_put(mpu_clk); | 140 | clk_put(policy->clk); |
153 | return result; | 141 | return result; |
154 | } | 142 | } |
155 | 143 | ||
@@ -157,15 +145,15 @@ static int omap_cpu_exit(struct cpufreq_policy *policy) | |||
157 | { | 145 | { |
158 | cpufreq_frequency_table_put_attr(policy->cpu); | 146 | cpufreq_frequency_table_put_attr(policy->cpu); |
159 | freq_table_free(); | 147 | freq_table_free(); |
160 | clk_put(mpu_clk); | 148 | clk_put(policy->clk); |
161 | return 0; | 149 | return 0; |
162 | } | 150 | } |
163 | 151 | ||
164 | static struct cpufreq_driver omap_driver = { | 152 | static struct cpufreq_driver omap_driver = { |
165 | .flags = CPUFREQ_STICKY, | 153 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
166 | .verify = cpufreq_generic_frequency_table_verify, | 154 | .verify = cpufreq_generic_frequency_table_verify, |
167 | .target_index = omap_target, | 155 | .target_index = omap_target, |
168 | .get = omap_getspeed, | 156 | .get = cpufreq_generic_get, |
169 | .init = omap_cpu_init, | 157 | .init = omap_cpu_init, |
170 | .exit = omap_cpu_exit, | 158 | .exit = omap_cpu_exit, |
171 | .name = "omap", | 159 | .name = "omap", |
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index e2b4f40ff69a..1c0f1067af73 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c | |||
@@ -213,6 +213,7 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy, | |||
213 | cpu, target_freq, | 213 | cpu, target_freq, |
214 | (pcch_virt_addr + pcc_cpu_data->input_offset)); | 214 | (pcch_virt_addr + pcc_cpu_data->input_offset)); |
215 | 215 | ||
216 | freqs.old = policy->cur; | ||
216 | freqs.new = target_freq; | 217 | freqs.new = target_freq; |
217 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 218 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
218 | 219 | ||
@@ -228,25 +229,20 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy, | |||
228 | memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); | 229 | memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); |
229 | 230 | ||
230 | status = ioread16(&pcch_hdr->status); | 231 | status = ioread16(&pcch_hdr->status); |
232 | iowrite16(0, &pcch_hdr->status); | ||
233 | |||
234 | cpufreq_notify_post_transition(policy, &freqs, status != CMD_COMPLETE); | ||
235 | spin_unlock(&pcc_lock); | ||
236 | |||
231 | if (status != CMD_COMPLETE) { | 237 | if (status != CMD_COMPLETE) { |
232 | pr_debug("target: FAILED for cpu %d, with status: 0x%x\n", | 238 | pr_debug("target: FAILED for cpu %d, with status: 0x%x\n", |
233 | cpu, status); | 239 | cpu, status); |
234 | goto cmd_incomplete; | 240 | return -EINVAL; |
235 | } | 241 | } |
236 | iowrite16(0, &pcch_hdr->status); | ||
237 | 242 | ||
238 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
239 | pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu); | 243 | pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu); |
240 | spin_unlock(&pcc_lock); | ||
241 | 244 | ||
242 | return 0; | 245 | return 0; |
243 | |||
244 | cmd_incomplete: | ||
245 | freqs.new = freqs.old; | ||
246 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
247 | iowrite16(0, &pcch_hdr->status); | ||
248 | spin_unlock(&pcc_lock); | ||
249 | return -EINVAL; | ||
250 | } | 246 | } |
251 | 247 | ||
252 | static int pcc_get_offset(int cpu) | 248 | static int pcc_get_offset(int cpu) |
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index 643e7952cad3..b9a444e358b5 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c | |||
@@ -26,41 +26,108 @@ | |||
26 | static unsigned int busfreq; /* FSB, in 10 kHz */ | 26 | static unsigned int busfreq; /* FSB, in 10 kHz */ |
27 | static unsigned int max_multiplier; | 27 | static unsigned int max_multiplier; |
28 | 28 | ||
29 | static unsigned int param_busfreq = 0; | ||
30 | static unsigned int param_max_multiplier = 0; | ||
31 | |||
32 | module_param_named(max_multiplier, param_max_multiplier, uint, S_IRUGO); | ||
33 | MODULE_PARM_DESC(max_multiplier, "Maximum multiplier (allowed values: 20 30 35 40 45 50 55 60)"); | ||
34 | |||
35 | module_param_named(bus_frequency, param_busfreq, uint, S_IRUGO); | ||
36 | MODULE_PARM_DESC(bus_frequency, "Bus frequency in kHz"); | ||
29 | 37 | ||
30 | /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */ | 38 | /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */ |
31 | static struct cpufreq_frequency_table clock_ratio[] = { | 39 | static struct cpufreq_frequency_table clock_ratio[] = { |
32 | {45, /* 000 -> 4.5x */ 0}, | 40 | {60, /* 110 -> 6.0x */ 0}, |
41 | {55, /* 011 -> 5.5x */ 0}, | ||
33 | {50, /* 001 -> 5.0x */ 0}, | 42 | {50, /* 001 -> 5.0x */ 0}, |
43 | {45, /* 000 -> 4.5x */ 0}, | ||
34 | {40, /* 010 -> 4.0x */ 0}, | 44 | {40, /* 010 -> 4.0x */ 0}, |
35 | {55, /* 011 -> 5.5x */ 0}, | ||
36 | {20, /* 100 -> 2.0x */ 0}, | ||
37 | {30, /* 101 -> 3.0x */ 0}, | ||
38 | {60, /* 110 -> 6.0x */ 0}, | ||
39 | {35, /* 111 -> 3.5x */ 0}, | 45 | {35, /* 111 -> 3.5x */ 0}, |
46 | {30, /* 101 -> 3.0x */ 0}, | ||
47 | {20, /* 100 -> 2.0x */ 0}, | ||
40 | {0, CPUFREQ_TABLE_END} | 48 | {0, CPUFREQ_TABLE_END} |
41 | }; | 49 | }; |
42 | 50 | ||
51 | static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 }; | ||
52 | static const u8 register_to_index[8] = { 3, 2, 4, 1, 7, 6, 0, 5 }; | ||
53 | |||
54 | static const struct { | ||
55 | unsigned freq; | ||
56 | unsigned mult; | ||
57 | } usual_frequency_table[] = { | ||
58 | { 400000, 40 }, // 100 * 4 | ||
59 | { 450000, 45 }, // 100 * 4.5 | ||
60 | { 475000, 50 }, // 95 * 5 | ||
61 | { 500000, 50 }, // 100 * 5 | ||
62 | { 506250, 45 }, // 112.5 * 4.5 | ||
63 | { 533500, 55 }, // 97 * 5.5 | ||
64 | { 550000, 55 }, // 100 * 5.5 | ||
65 | { 562500, 50 }, // 112.5 * 5 | ||
66 | { 570000, 60 }, // 95 * 6 | ||
67 | { 600000, 60 }, // 100 * 6 | ||
68 | { 618750, 55 }, // 112.5 * 5.5 | ||
69 | { 660000, 55 }, // 120 * 5.5 | ||
70 | { 675000, 60 }, // 112.5 * 6 | ||
71 | { 720000, 60 }, // 120 * 6 | ||
72 | }; | ||
73 | |||
74 | #define FREQ_RANGE 3000 | ||
43 | 75 | ||
44 | /** | 76 | /** |
45 | * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier | 77 | * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier |
46 | * | 78 | * |
47 | * Returns the current setting of the frequency multiplier. Core clock | 79 | * Returns the current setting of the frequency multiplier. Core clock |
48 | * speed is frequency of the Front-Side Bus multiplied with this value. | 80 | * speed is frequency of the Front-Side Bus multiplied with this value. |
49 | */ | 81 | */ |
50 | static int powernow_k6_get_cpu_multiplier(void) | 82 | static int powernow_k6_get_cpu_multiplier(void) |
51 | { | 83 | { |
52 | u64 invalue = 0; | 84 | unsigned long invalue = 0; |
53 | u32 msrval; | 85 | u32 msrval; |
54 | 86 | ||
87 | local_irq_disable(); | ||
88 | |||
55 | msrval = POWERNOW_IOPORT + 0x1; | 89 | msrval = POWERNOW_IOPORT + 0x1; |
56 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ | 90 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ |
57 | invalue = inl(POWERNOW_IOPORT + 0x8); | 91 | invalue = inl(POWERNOW_IOPORT + 0x8); |
58 | msrval = POWERNOW_IOPORT + 0x0; | 92 | msrval = POWERNOW_IOPORT + 0x0; |
59 | wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ | 93 | wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ |
60 | 94 | ||
61 | return clock_ratio[(invalue >> 5)&7].driver_data; | 95 | local_irq_enable(); |
96 | |||
97 | return clock_ratio[register_to_index[(invalue >> 5)&7]].driver_data; | ||
62 | } | 98 | } |
63 | 99 | ||
100 | static void powernow_k6_set_cpu_multiplier(unsigned int best_i) | ||
101 | { | ||
102 | unsigned long outvalue, invalue; | ||
103 | unsigned long msrval; | ||
104 | unsigned long cr0; | ||
105 | |||
106 | /* we now need to transform best_i to the BVC format, see AMD#23446 */ | ||
107 | |||
108 | /* | ||
109 | * The processor doesn't respond to inquiry cycles while changing the | ||
110 | * frequency, so we must disable cache. | ||
111 | */ | ||
112 | local_irq_disable(); | ||
113 | cr0 = read_cr0(); | ||
114 | write_cr0(cr0 | X86_CR0_CD); | ||
115 | wbinvd(); | ||
116 | |||
117 | outvalue = (1<<12) | (1<<10) | (1<<9) | (index_to_register[best_i]<<5); | ||
118 | |||
119 | msrval = POWERNOW_IOPORT + 0x1; | ||
120 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ | ||
121 | invalue = inl(POWERNOW_IOPORT + 0x8); | ||
122 | invalue = invalue & 0x1f; | ||
123 | outvalue = outvalue | invalue; | ||
124 | outl(outvalue, (POWERNOW_IOPORT + 0x8)); | ||
125 | msrval = POWERNOW_IOPORT + 0x0; | ||
126 | wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ | ||
127 | |||
128 | write_cr0(cr0); | ||
129 | local_irq_enable(); | ||
130 | } | ||
64 | 131 | ||
65 | /** | 132 | /** |
66 | * powernow_k6_target - set the PowerNow! multiplier | 133 | * powernow_k6_target - set the PowerNow! multiplier |
@@ -71,8 +138,6 @@ static int powernow_k6_get_cpu_multiplier(void) | |||
71 | static int powernow_k6_target(struct cpufreq_policy *policy, | 138 | static int powernow_k6_target(struct cpufreq_policy *policy, |
72 | unsigned int best_i) | 139 | unsigned int best_i) |
73 | { | 140 | { |
74 | unsigned long outvalue = 0, invalue = 0; | ||
75 | unsigned long msrval; | ||
76 | struct cpufreq_freqs freqs; | 141 | struct cpufreq_freqs freqs; |
77 | 142 | ||
78 | if (clock_ratio[best_i].driver_data > max_multiplier) { | 143 | if (clock_ratio[best_i].driver_data > max_multiplier) { |
@@ -85,35 +150,63 @@ static int powernow_k6_target(struct cpufreq_policy *policy, | |||
85 | 150 | ||
86 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 151 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
87 | 152 | ||
88 | /* we now need to transform best_i to the BVC format, see AMD#23446 */ | 153 | powernow_k6_set_cpu_multiplier(best_i); |
89 | |||
90 | outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5); | ||
91 | |||
92 | msrval = POWERNOW_IOPORT + 0x1; | ||
93 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ | ||
94 | invalue = inl(POWERNOW_IOPORT + 0x8); | ||
95 | invalue = invalue & 0xf; | ||
96 | outvalue = outvalue | invalue; | ||
97 | outl(outvalue , (POWERNOW_IOPORT + 0x8)); | ||
98 | msrval = POWERNOW_IOPORT + 0x0; | ||
99 | wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ | ||
100 | 154 | ||
101 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | 155 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); |
102 | 156 | ||
103 | return 0; | 157 | return 0; |
104 | } | 158 | } |
105 | 159 | ||
106 | |||
107 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | 160 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) |
108 | { | 161 | { |
109 | unsigned int i, f; | 162 | unsigned int i, f; |
163 | unsigned khz; | ||
110 | 164 | ||
111 | if (policy->cpu != 0) | 165 | if (policy->cpu != 0) |
112 | return -ENODEV; | 166 | return -ENODEV; |
113 | 167 | ||
114 | /* get frequencies */ | 168 | max_multiplier = 0; |
115 | max_multiplier = powernow_k6_get_cpu_multiplier(); | 169 | khz = cpu_khz; |
116 | busfreq = cpu_khz / max_multiplier; | 170 | for (i = 0; i < ARRAY_SIZE(usual_frequency_table); i++) { |
171 | if (khz >= usual_frequency_table[i].freq - FREQ_RANGE && | ||
172 | khz <= usual_frequency_table[i].freq + FREQ_RANGE) { | ||
173 | khz = usual_frequency_table[i].freq; | ||
174 | max_multiplier = usual_frequency_table[i].mult; | ||
175 | break; | ||
176 | } | ||
177 | } | ||
178 | if (param_max_multiplier) { | ||
179 | for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { | ||
180 | if (clock_ratio[i].driver_data == param_max_multiplier) { | ||
181 | max_multiplier = param_max_multiplier; | ||
182 | goto have_max_multiplier; | ||
183 | } | ||
184 | } | ||
185 | printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n"); | ||
186 | return -EINVAL; | ||
187 | } | ||
188 | |||
189 | if (!max_multiplier) { | ||
190 | printk(KERN_WARNING "powernow-k6: unknown frequency %u, cannot determine current multiplier\n", khz); | ||
191 | printk(KERN_WARNING "powernow-k6: use module parameters max_multiplier and bus_frequency\n"); | ||
192 | return -EOPNOTSUPP; | ||
193 | } | ||
194 | |||
195 | have_max_multiplier: | ||
196 | param_max_multiplier = max_multiplier; | ||
197 | |||
198 | if (param_busfreq) { | ||
199 | if (param_busfreq >= 50000 && param_busfreq <= 150000) { | ||
200 | busfreq = param_busfreq / 10; | ||
201 | goto have_busfreq; | ||
202 | } | ||
203 | printk(KERN_ERR "powernow-k6: invalid bus_frequency parameter, allowed range 50000 - 150000 kHz\n"); | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | busfreq = khz / max_multiplier; | ||
208 | have_busfreq: | ||
209 | param_busfreq = busfreq * 10; | ||
117 | 210 | ||
118 | /* table init */ | 211 | /* table init */ |
119 | for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { | 212 | for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { |
@@ -125,7 +218,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
125 | } | 218 | } |
126 | 219 | ||
127 | /* cpuinfo and default policy values */ | 220 | /* cpuinfo and default policy values */ |
128 | policy->cpuinfo.transition_latency = 200000; | 221 | policy->cpuinfo.transition_latency = 500000; |
129 | 222 | ||
130 | return cpufreq_table_validate_and_show(policy, clock_ratio); | 223 | return cpufreq_table_validate_and_show(policy, clock_ratio); |
131 | } | 224 | } |
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 0023c7d40a51..e10b646634d7 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -964,14 +964,9 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, | |||
964 | cpufreq_cpu_put(policy); | 964 | cpufreq_cpu_put(policy); |
965 | 965 | ||
966 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 966 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
967 | |||
968 | res = transition_fid_vid(data, fid, vid); | 967 | res = transition_fid_vid(data, fid, vid); |
969 | if (res) | 968 | cpufreq_notify_post_transition(policy, &freqs, res); |
970 | freqs.new = freqs.old; | ||
971 | else | ||
972 | freqs.new = find_khz_freq_from_fid(data->currfid); | ||
973 | 969 | ||
974 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
975 | return res; | 970 | return res; |
976 | } | 971 | } |
977 | 972 | ||
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index 3f7be46d2b27..051000f44ca2 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c | |||
@@ -24,12 +24,10 @@ | |||
24 | 24 | ||
25 | /** | 25 | /** |
26 | * struct cpu_data - per CPU data struct | 26 | * struct cpu_data - per CPU data struct |
27 | * @clk: the clk of CPU | ||
28 | * @parent: the parent node of cpu clock | 27 | * @parent: the parent node of cpu clock |
29 | * @table: frequency table | 28 | * @table: frequency table |
30 | */ | 29 | */ |
31 | struct cpu_data { | 30 | struct cpu_data { |
32 | struct clk *clk; | ||
33 | struct device_node *parent; | 31 | struct device_node *parent; |
34 | struct cpufreq_frequency_table *table; | 32 | struct cpufreq_frequency_table *table; |
35 | }; | 33 | }; |
@@ -81,13 +79,6 @@ static inline const struct cpumask *cpu_core_mask(int cpu) | |||
81 | } | 79 | } |
82 | #endif | 80 | #endif |
83 | 81 | ||
84 | static unsigned int corenet_cpufreq_get_speed(unsigned int cpu) | ||
85 | { | ||
86 | struct cpu_data *data = per_cpu(cpu_data, cpu); | ||
87 | |||
88 | return clk_get_rate(data->clk) / 1000; | ||
89 | } | ||
90 | |||
91 | /* reduce the duplicated frequencies in frequency table */ | 82 | /* reduce the duplicated frequencies in frequency table */ |
92 | static void freq_table_redup(struct cpufreq_frequency_table *freq_table, | 83 | static void freq_table_redup(struct cpufreq_frequency_table *freq_table, |
93 | int count) | 84 | int count) |
@@ -158,8 +149,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
158 | goto err_np; | 149 | goto err_np; |
159 | } | 150 | } |
160 | 151 | ||
161 | data->clk = of_clk_get(np, 0); | 152 | policy->clk = of_clk_get(np, 0); |
162 | if (IS_ERR(data->clk)) { | 153 | if (IS_ERR(policy->clk)) { |
163 | pr_err("%s: no clock information\n", __func__); | 154 | pr_err("%s: no clock information\n", __func__); |
164 | goto err_nomem2; | 155 | goto err_nomem2; |
165 | } | 156 | } |
@@ -255,7 +246,7 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy, | |||
255 | struct cpu_data *data = per_cpu(cpu_data, policy->cpu); | 246 | struct cpu_data *data = per_cpu(cpu_data, policy->cpu); |
256 | 247 | ||
257 | parent = of_clk_get(data->parent, data->table[index].driver_data); | 248 | parent = of_clk_get(data->parent, data->table[index].driver_data); |
258 | return clk_set_parent(data->clk, parent); | 249 | return clk_set_parent(policy->clk, parent); |
259 | } | 250 | } |
260 | 251 | ||
261 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | 252 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { |
@@ -265,7 +256,7 @@ static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | |||
265 | .exit = __exit_p(corenet_cpufreq_cpu_exit), | 256 | .exit = __exit_p(corenet_cpufreq_cpu_exit), |
266 | .verify = cpufreq_generic_frequency_table_verify, | 257 | .verify = cpufreq_generic_frequency_table_verify, |
267 | .target_index = corenet_cpufreq_target, | 258 | .target_index = corenet_cpufreq_target, |
268 | .get = corenet_cpufreq_get_speed, | 259 | .get = cpufreq_generic_get, |
269 | .attr = cpufreq_generic_attr, | 260 | .attr = cpufreq_generic_attr, |
270 | }; | 261 | }; |
271 | 262 | ||
diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 0a0f4369636a..a9195a86b069 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c | |||
@@ -423,6 +423,7 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
423 | } | 423 | } |
424 | 424 | ||
425 | static struct cpufreq_driver pxa_cpufreq_driver = { | 425 | static struct cpufreq_driver pxa_cpufreq_driver = { |
426 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
426 | .verify = cpufreq_generic_frequency_table_verify, | 427 | .verify = cpufreq_generic_frequency_table_verify, |
427 | .target_index = pxa_set_target, | 428 | .target_index = pxa_set_target, |
428 | .init = pxa_cpufreq_init, | 429 | .init = pxa_cpufreq_init, |
diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index 93840048dd11..3785687e9d70 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c | |||
@@ -201,6 +201,7 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) | |||
201 | } | 201 | } |
202 | 202 | ||
203 | static struct cpufreq_driver pxa3xx_cpufreq_driver = { | 203 | static struct cpufreq_driver pxa3xx_cpufreq_driver = { |
204 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
204 | .verify = cpufreq_generic_frequency_table_verify, | 205 | .verify = cpufreq_generic_frequency_table_verify, |
205 | .target_index = pxa3xx_cpufreq_set, | 206 | .target_index = pxa3xx_cpufreq_set, |
206 | .init = pxa3xx_cpufreq_init, | 207 | .init = pxa3xx_cpufreq_init, |
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index 8d904a00027b..826b8be23099 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c | |||
@@ -481,7 +481,7 @@ err_hclk: | |||
481 | } | 481 | } |
482 | 482 | ||
483 | static struct cpufreq_driver s3c2416_cpufreq_driver = { | 483 | static struct cpufreq_driver s3c2416_cpufreq_driver = { |
484 | .flags = 0, | 484 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
485 | .verify = cpufreq_generic_frequency_table_verify, | 485 | .verify = cpufreq_generic_frequency_table_verify, |
486 | .target_index = s3c2416_cpufreq_set_target, | 486 | .target_index = s3c2416_cpufreq_set_target, |
487 | .get = s3c2416_cpufreq_get_speed, | 487 | .get = s3c2416_cpufreq_get_speed, |
diff --git a/drivers/cpufreq/s3c2440-cpufreq.c b/drivers/cpufreq/s3c2440-cpufreq.c index 72b2cc8a5a85..f84ed10755b5 100644 --- a/drivers/cpufreq/s3c2440-cpufreq.c +++ b/drivers/cpufreq/s3c2440-cpufreq.c | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | 24 | ||
25 | #include <mach/hardware.h> | ||
26 | |||
27 | #include <asm/mach/arch.h> | 25 | #include <asm/mach/arch.h> |
28 | #include <asm/mach/map.h> | 26 | #include <asm/mach/map.h> |
29 | 27 | ||
@@ -55,7 +53,7 @@ static inline int within_khz(unsigned long a, unsigned long b) | |||
55 | * specified in @cfg. The values are stored in @cfg for later use | 53 | * specified in @cfg. The values are stored in @cfg for later use |
56 | * by the relevant set routine if the request settings can be reached. | 54 | * by the relevant set routine if the request settings can be reached. |
57 | */ | 55 | */ |
58 | int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) | 56 | static int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) |
59 | { | 57 | { |
60 | unsigned int hdiv, pdiv; | 58 | unsigned int hdiv, pdiv; |
61 | unsigned long hclk, fclk, armclk; | 59 | unsigned long hclk, fclk, armclk; |
@@ -242,7 +240,7 @@ static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg, | |||
242 | return ret; | 240 | return ret; |
243 | } | 241 | } |
244 | 242 | ||
245 | struct s3c_cpufreq_info s3c2440_cpufreq_info = { | 243 | static struct s3c_cpufreq_info s3c2440_cpufreq_info = { |
246 | .max = { | 244 | .max = { |
247 | .fclk = 400000000, | 245 | .fclk = 400000000, |
248 | .hclk = 133333333, | 246 | .hclk = 133333333, |
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 485088253358..25069741b507 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c | |||
@@ -355,11 +355,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, | |||
355 | return -EINVAL; | 355 | return -EINVAL; |
356 | } | 356 | } |
357 | 357 | ||
358 | static unsigned int s3c_cpufreq_get(unsigned int cpu) | ||
359 | { | ||
360 | return clk_get_rate(clk_arm) / 1000; | ||
361 | } | ||
362 | |||
363 | struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) | 358 | struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) |
364 | { | 359 | { |
365 | struct clk *clk; | 360 | struct clk *clk; |
@@ -373,6 +368,7 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) | |||
373 | 368 | ||
374 | static int s3c_cpufreq_init(struct cpufreq_policy *policy) | 369 | static int s3c_cpufreq_init(struct cpufreq_policy *policy) |
375 | { | 370 | { |
371 | policy->clk = clk_arm; | ||
376 | return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency); | 372 | return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency); |
377 | } | 373 | } |
378 | 374 | ||
@@ -408,7 +404,7 @@ static int s3c_cpufreq_suspend(struct cpufreq_policy *policy) | |||
408 | { | 404 | { |
409 | suspend_pll.frequency = clk_get_rate(_clk_mpll); | 405 | suspend_pll.frequency = clk_get_rate(_clk_mpll); |
410 | suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON); | 406 | suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON); |
411 | suspend_freq = s3c_cpufreq_get(0) * 1000; | 407 | suspend_freq = clk_get_rate(clk_arm); |
412 | 408 | ||
413 | return 0; | 409 | return 0; |
414 | } | 410 | } |
@@ -448,9 +444,9 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy) | |||
448 | #endif | 444 | #endif |
449 | 445 | ||
450 | static struct cpufreq_driver s3c24xx_driver = { | 446 | static struct cpufreq_driver s3c24xx_driver = { |
451 | .flags = CPUFREQ_STICKY, | 447 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
452 | .target = s3c_cpufreq_target, | 448 | .target = s3c_cpufreq_target, |
453 | .get = s3c_cpufreq_get, | 449 | .get = cpufreq_generic_get, |
454 | .init = s3c_cpufreq_init, | 450 | .init = s3c_cpufreq_init, |
455 | .suspend = s3c_cpufreq_suspend, | 451 | .suspend = s3c_cpufreq_suspend, |
456 | .resume = s3c_cpufreq_resume, | 452 | .resume = s3c_cpufreq_resume, |
@@ -509,7 +505,7 @@ int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) | |||
509 | return 0; | 505 | return 0; |
510 | } | 506 | } |
511 | 507 | ||
512 | int __init s3c_cpufreq_auto_io(void) | 508 | static int __init s3c_cpufreq_auto_io(void) |
513 | { | 509 | { |
514 | int ret; | 510 | int ret; |
515 | 511 | ||
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index 67e302eeefec..c4226de079ab 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/regulator/consumer.h> | 19 | #include <linux/regulator/consumer.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | 21 | ||
22 | static struct clk *armclk; | ||
23 | static struct regulator *vddarm; | 22 | static struct regulator *vddarm; |
24 | static unsigned long regulator_latency; | 23 | static unsigned long regulator_latency; |
25 | 24 | ||
@@ -54,14 +53,6 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = { | |||
54 | }; | 53 | }; |
55 | #endif | 54 | #endif |
56 | 55 | ||
57 | static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) | ||
58 | { | ||
59 | if (cpu != 0) | ||
60 | return 0; | ||
61 | |||
62 | return clk_get_rate(armclk) / 1000; | ||
63 | } | ||
64 | |||
65 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | 56 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, |
66 | unsigned int index) | 57 | unsigned int index) |
67 | { | 58 | { |
@@ -69,7 +60,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | |||
69 | unsigned int old_freq, new_freq; | 60 | unsigned int old_freq, new_freq; |
70 | int ret; | 61 | int ret; |
71 | 62 | ||
72 | old_freq = clk_get_rate(armclk) / 1000; | 63 | old_freq = clk_get_rate(policy->clk) / 1000; |
73 | new_freq = s3c64xx_freq_table[index].frequency; | 64 | new_freq = s3c64xx_freq_table[index].frequency; |
74 | dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; | 65 | dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; |
75 | 66 | ||
@@ -86,7 +77,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | |||
86 | } | 77 | } |
87 | #endif | 78 | #endif |
88 | 79 | ||
89 | ret = clk_set_rate(armclk, new_freq * 1000); | 80 | ret = clk_set_rate(policy->clk, new_freq * 1000); |
90 | if (ret < 0) { | 81 | if (ret < 0) { |
91 | pr_err("Failed to set rate %dkHz: %d\n", | 82 | pr_err("Failed to set rate %dkHz: %d\n", |
92 | new_freq, ret); | 83 | new_freq, ret); |
@@ -101,7 +92,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | |||
101 | if (ret != 0) { | 92 | if (ret != 0) { |
102 | pr_err("Failed to set VDDARM for %dkHz: %d\n", | 93 | pr_err("Failed to set VDDARM for %dkHz: %d\n", |
103 | new_freq, ret); | 94 | new_freq, ret); |
104 | if (clk_set_rate(armclk, old_freq * 1000) < 0) | 95 | if (clk_set_rate(policy->clk, old_freq * 1000) < 0) |
105 | pr_err("Failed to restore original clock rate\n"); | 96 | pr_err("Failed to restore original clock rate\n"); |
106 | 97 | ||
107 | return ret; | 98 | return ret; |
@@ -110,7 +101,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | |||
110 | #endif | 101 | #endif |
111 | 102 | ||
112 | pr_debug("Set actual frequency %lukHz\n", | 103 | pr_debug("Set actual frequency %lukHz\n", |
113 | clk_get_rate(armclk) / 1000); | 104 | clk_get_rate(policy->clk) / 1000); |
114 | 105 | ||
115 | return 0; | 106 | return 0; |
116 | } | 107 | } |
@@ -169,11 +160,11 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
169 | return -ENODEV; | 160 | return -ENODEV; |
170 | } | 161 | } |
171 | 162 | ||
172 | armclk = clk_get(NULL, "armclk"); | 163 | policy->clk = clk_get(NULL, "armclk"); |
173 | if (IS_ERR(armclk)) { | 164 | if (IS_ERR(policy->clk)) { |
174 | pr_err("Unable to obtain ARMCLK: %ld\n", | 165 | pr_err("Unable to obtain ARMCLK: %ld\n", |
175 | PTR_ERR(armclk)); | 166 | PTR_ERR(policy->clk)); |
176 | return PTR_ERR(armclk); | 167 | return PTR_ERR(policy->clk); |
177 | } | 168 | } |
178 | 169 | ||
179 | #ifdef CONFIG_REGULATOR | 170 | #ifdef CONFIG_REGULATOR |
@@ -193,7 +184,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
193 | unsigned long r; | 184 | unsigned long r; |
194 | 185 | ||
195 | /* Check for frequencies we can generate */ | 186 | /* Check for frequencies we can generate */ |
196 | r = clk_round_rate(armclk, freq->frequency * 1000); | 187 | r = clk_round_rate(policy->clk, freq->frequency * 1000); |
197 | r /= 1000; | 188 | r /= 1000; |
198 | if (r != freq->frequency) { | 189 | if (r != freq->frequency) { |
199 | pr_debug("%dkHz unsupported by clock\n", | 190 | pr_debug("%dkHz unsupported by clock\n", |
@@ -203,7 +194,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
203 | 194 | ||
204 | /* If we have no regulator then assume startup | 195 | /* If we have no regulator then assume startup |
205 | * frequency is the maximum we can support. */ | 196 | * frequency is the maximum we can support. */ |
206 | if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0)) | 197 | if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000) |
207 | freq->frequency = CPUFREQ_ENTRY_INVALID; | 198 | freq->frequency = CPUFREQ_ENTRY_INVALID; |
208 | 199 | ||
209 | freq++; | 200 | freq++; |
@@ -219,17 +210,17 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
219 | pr_err("Failed to configure frequency table: %d\n", | 210 | pr_err("Failed to configure frequency table: %d\n", |
220 | ret); | 211 | ret); |
221 | regulator_put(vddarm); | 212 | regulator_put(vddarm); |
222 | clk_put(armclk); | 213 | clk_put(policy->clk); |
223 | } | 214 | } |
224 | 215 | ||
225 | return ret; | 216 | return ret; |
226 | } | 217 | } |
227 | 218 | ||
228 | static struct cpufreq_driver s3c64xx_cpufreq_driver = { | 219 | static struct cpufreq_driver s3c64xx_cpufreq_driver = { |
229 | .flags = 0, | 220 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
230 | .verify = cpufreq_generic_frequency_table_verify, | 221 | .verify = cpufreq_generic_frequency_table_verify, |
231 | .target_index = s3c64xx_cpufreq_set_target, | 222 | .target_index = s3c64xx_cpufreq_set_target, |
232 | .get = s3c64xx_cpufreq_get_speed, | 223 | .get = cpufreq_generic_get, |
233 | .init = s3c64xx_cpufreq_driver_init, | 224 | .init = s3c64xx_cpufreq_driver_init, |
234 | .name = "s3c", | 225 | .name = "s3c", |
235 | }; | 226 | }; |
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index e3973dae28a7..55a8e9fa9435 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <mach/map.h> | 23 | #include <mach/map.h> |
24 | #include <mach/regs-clock.h> | 24 | #include <mach/regs-clock.h> |
25 | 25 | ||
26 | static struct clk *cpu_clk; | ||
27 | static struct clk *dmc0_clk; | 26 | static struct clk *dmc0_clk; |
28 | static struct clk *dmc1_clk; | 27 | static struct clk *dmc1_clk; |
29 | static DEFINE_MUTEX(set_freq_lock); | 28 | static DEFINE_MUTEX(set_freq_lock); |
@@ -164,14 +163,6 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq) | |||
164 | __raw_writel(tmp1, reg); | 163 | __raw_writel(tmp1, reg); |
165 | } | 164 | } |
166 | 165 | ||
167 | static unsigned int s5pv210_getspeed(unsigned int cpu) | ||
168 | { | ||
169 | if (cpu) | ||
170 | return 0; | ||
171 | |||
172 | return clk_get_rate(cpu_clk) / 1000; | ||
173 | } | ||
174 | |||
175 | static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) | 166 | static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) |
176 | { | 167 | { |
177 | unsigned long reg; | 168 | unsigned long reg; |
@@ -193,7 +184,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) | |||
193 | goto exit; | 184 | goto exit; |
194 | } | 185 | } |
195 | 186 | ||
196 | old_freq = s5pv210_getspeed(0); | 187 | old_freq = policy->cur; |
197 | new_freq = s5pv210_freq_table[index].frequency; | 188 | new_freq = s5pv210_freq_table[index].frequency; |
198 | 189 | ||
199 | /* Finding current running level index */ | 190 | /* Finding current running level index */ |
@@ -471,9 +462,9 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) | |||
471 | unsigned long mem_type; | 462 | unsigned long mem_type; |
472 | int ret; | 463 | int ret; |
473 | 464 | ||
474 | cpu_clk = clk_get(NULL, "armclk"); | 465 | policy->clk = clk_get(NULL, "armclk"); |
475 | if (IS_ERR(cpu_clk)) | 466 | if (IS_ERR(policy->clk)) |
476 | return PTR_ERR(cpu_clk); | 467 | return PTR_ERR(policy->clk); |
477 | 468 | ||
478 | dmc0_clk = clk_get(NULL, "sclk_dmc0"); | 469 | dmc0_clk = clk_get(NULL, "sclk_dmc0"); |
479 | if (IS_ERR(dmc0_clk)) { | 470 | if (IS_ERR(dmc0_clk)) { |
@@ -516,7 +507,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) | |||
516 | out_dmc1: | 507 | out_dmc1: |
517 | clk_put(dmc0_clk); | 508 | clk_put(dmc0_clk); |
518 | out_dmc0: | 509 | out_dmc0: |
519 | clk_put(cpu_clk); | 510 | clk_put(policy->clk); |
520 | return ret; | 511 | return ret; |
521 | } | 512 | } |
522 | 513 | ||
@@ -560,10 +551,10 @@ static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this, | |||
560 | } | 551 | } |
561 | 552 | ||
562 | static struct cpufreq_driver s5pv210_driver = { | 553 | static struct cpufreq_driver s5pv210_driver = { |
563 | .flags = CPUFREQ_STICKY, | 554 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
564 | .verify = cpufreq_generic_frequency_table_verify, | 555 | .verify = cpufreq_generic_frequency_table_verify, |
565 | .target_index = s5pv210_target, | 556 | .target_index = s5pv210_target, |
566 | .get = s5pv210_getspeed, | 557 | .get = cpufreq_generic_get, |
567 | .init = s5pv210_cpu_init, | 558 | .init = s5pv210_cpu_init, |
568 | .name = "s5pv210", | 559 | .name = "s5pv210", |
569 | #ifdef CONFIG_PM | 560 | #ifdef CONFIG_PM |
diff --git a/drivers/cpufreq/sa1100-cpufreq.c b/drivers/cpufreq/sa1100-cpufreq.c index 623da742f8e7..728eab77e8e0 100644 --- a/drivers/cpufreq/sa1100-cpufreq.c +++ b/drivers/cpufreq/sa1100-cpufreq.c | |||
@@ -201,7 +201,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy) | |||
201 | } | 201 | } |
202 | 202 | ||
203 | static struct cpufreq_driver sa1100_driver __refdata = { | 203 | static struct cpufreq_driver sa1100_driver __refdata = { |
204 | .flags = CPUFREQ_STICKY, | 204 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
205 | .verify = cpufreq_generic_frequency_table_verify, | 205 | .verify = cpufreq_generic_frequency_table_verify, |
206 | .target_index = sa1100_target, | 206 | .target_index = sa1100_target, |
207 | .get = sa11x0_getspeed, | 207 | .get = sa11x0_getspeed, |
diff --git a/drivers/cpufreq/sa1110-cpufreq.c b/drivers/cpufreq/sa1110-cpufreq.c index 2c2b2e601d13..546376719d8f 100644 --- a/drivers/cpufreq/sa1110-cpufreq.c +++ b/drivers/cpufreq/sa1110-cpufreq.c | |||
@@ -312,7 +312,7 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy) | |||
312 | /* sa1110_driver needs __refdata because it must remain after init registers | 312 | /* sa1110_driver needs __refdata because it must remain after init registers |
313 | * it with cpufreq_register_driver() */ | 313 | * it with cpufreq_register_driver() */ |
314 | static struct cpufreq_driver sa1110_driver __refdata = { | 314 | static struct cpufreq_driver sa1110_driver __refdata = { |
315 | .flags = CPUFREQ_STICKY, | 315 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
316 | .verify = cpufreq_generic_frequency_table_verify, | 316 | .verify = cpufreq_generic_frequency_table_verify, |
317 | .target_index = sa1110_target, | 317 | .target_index = sa1110_target, |
318 | .get = sa11x0_getspeed, | 318 | .get = sa11x0_getspeed, |
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index d02ccd19c9c4..5c86e3fa5593 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c | |||
@@ -30,11 +30,6 @@ static struct { | |||
30 | u32 cnt; | 30 | u32 cnt; |
31 | } spear_cpufreq; | 31 | } spear_cpufreq; |
32 | 32 | ||
33 | static unsigned int spear_cpufreq_get(unsigned int cpu) | ||
34 | { | ||
35 | return clk_get_rate(spear_cpufreq.clk) / 1000; | ||
36 | } | ||
37 | |||
38 | static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq) | 33 | static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq) |
39 | { | 34 | { |
40 | struct clk *sys_pclk; | 35 | struct clk *sys_pclk; |
@@ -138,7 +133,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy, | |||
138 | } | 133 | } |
139 | 134 | ||
140 | newfreq = clk_round_rate(srcclk, newfreq * mult); | 135 | newfreq = clk_round_rate(srcclk, newfreq * mult); |
141 | if (newfreq < 0) { | 136 | if (newfreq <= 0) { |
142 | pr_err("clk_round_rate failed for cpu src clock\n"); | 137 | pr_err("clk_round_rate failed for cpu src clock\n"); |
143 | return newfreq; | 138 | return newfreq; |
144 | } | 139 | } |
@@ -156,16 +151,17 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy, | |||
156 | 151 | ||
157 | static int spear_cpufreq_init(struct cpufreq_policy *policy) | 152 | static int spear_cpufreq_init(struct cpufreq_policy *policy) |
158 | { | 153 | { |
154 | policy->clk = spear_cpufreq.clk; | ||
159 | return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl, | 155 | return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl, |
160 | spear_cpufreq.transition_latency); | 156 | spear_cpufreq.transition_latency); |
161 | } | 157 | } |
162 | 158 | ||
163 | static struct cpufreq_driver spear_cpufreq_driver = { | 159 | static struct cpufreq_driver spear_cpufreq_driver = { |
164 | .name = "cpufreq-spear", | 160 | .name = "cpufreq-spear", |
165 | .flags = CPUFREQ_STICKY, | 161 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
166 | .verify = cpufreq_generic_frequency_table_verify, | 162 | .verify = cpufreq_generic_frequency_table_verify, |
167 | .target_index = spear_cpufreq_target, | 163 | .target_index = spear_cpufreq_target, |
168 | .get = spear_cpufreq_get, | 164 | .get = cpufreq_generic_get, |
169 | .init = spear_cpufreq_init, | 165 | .init = spear_cpufreq_init, |
170 | .exit = cpufreq_generic_exit, | 166 | .exit = cpufreq_generic_exit, |
171 | .attr = cpufreq_generic_attr, | 167 | .attr = cpufreq_generic_attr, |
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index 0f5326d6f79f..998c17b42200 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c | |||
@@ -141,38 +141,6 @@ static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high) | |||
141 | } | 141 | } |
142 | 142 | ||
143 | /** | 143 | /** |
144 | * speedstep_get_state - set the SpeedStep state | ||
145 | * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) | ||
146 | * | ||
147 | */ | ||
148 | static int speedstep_get_state(void) | ||
149 | { | ||
150 | u32 function = GET_SPEEDSTEP_STATE; | ||
151 | u32 result, state, edi, command, dummy; | ||
152 | |||
153 | command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); | ||
154 | |||
155 | pr_debug("trying to determine current setting with command %x " | ||
156 | "at port %x\n", command, smi_port); | ||
157 | |||
158 | __asm__ __volatile__( | ||
159 | "push %%ebp\n" | ||
160 | "out %%al, (%%dx)\n" | ||
161 | "pop %%ebp\n" | ||
162 | : "=a" (result), | ||
163 | "=b" (state), "=D" (edi), | ||
164 | "=c" (dummy), "=d" (dummy), "=S" (dummy) | ||
165 | : "a" (command), "b" (function), "c" (0), | ||
166 | "d" (smi_port), "S" (0), "D" (0) | ||
167 | ); | ||
168 | |||
169 | pr_debug("state is %x, result is %x\n", state, result); | ||
170 | |||
171 | return state & 1; | ||
172 | } | ||
173 | |||
174 | |||
175 | /** | ||
176 | * speedstep_set_state - set the SpeedStep state | 144 | * speedstep_set_state - set the SpeedStep state |
177 | * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) | 145 | * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) |
178 | * | 146 | * |
diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index b7309c37033d..e652c1bd8d0f 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c | |||
@@ -47,21 +47,9 @@ static struct clk *pll_x_clk; | |||
47 | static struct clk *pll_p_clk; | 47 | static struct clk *pll_p_clk; |
48 | static struct clk *emc_clk; | 48 | static struct clk *emc_clk; |
49 | 49 | ||
50 | static unsigned long target_cpu_speed[NUM_CPUS]; | ||
51 | static DEFINE_MUTEX(tegra_cpu_lock); | 50 | static DEFINE_MUTEX(tegra_cpu_lock); |
52 | static bool is_suspended; | 51 | static bool is_suspended; |
53 | 52 | ||
54 | static unsigned int tegra_getspeed(unsigned int cpu) | ||
55 | { | ||
56 | unsigned long rate; | ||
57 | |||
58 | if (cpu >= NUM_CPUS) | ||
59 | return 0; | ||
60 | |||
61 | rate = clk_get_rate(cpu_clk) / 1000; | ||
62 | return rate; | ||
63 | } | ||
64 | |||
65 | static int tegra_cpu_clk_set_rate(unsigned long rate) | 53 | static int tegra_cpu_clk_set_rate(unsigned long rate) |
66 | { | 54 | { |
67 | int ret; | 55 | int ret; |
@@ -103,9 +91,6 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, | |||
103 | { | 91 | { |
104 | int ret = 0; | 92 | int ret = 0; |
105 | 93 | ||
106 | if (tegra_getspeed(0) == rate) | ||
107 | return ret; | ||
108 | |||
109 | /* | 94 | /* |
110 | * Vote on memory bus frequency based on cpu frequency | 95 | * Vote on memory bus frequency based on cpu frequency |
111 | * This sets the minimum frequency, display or avp may request higher | 96 | * This sets the minimum frequency, display or avp may request higher |
@@ -125,33 +110,16 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, | |||
125 | return ret; | 110 | return ret; |
126 | } | 111 | } |
127 | 112 | ||
128 | static unsigned long tegra_cpu_highest_speed(void) | ||
129 | { | ||
130 | unsigned long rate = 0; | ||
131 | int i; | ||
132 | |||
133 | for_each_online_cpu(i) | ||
134 | rate = max(rate, target_cpu_speed[i]); | ||
135 | return rate; | ||
136 | } | ||
137 | |||
138 | static int tegra_target(struct cpufreq_policy *policy, unsigned int index) | 113 | static int tegra_target(struct cpufreq_policy *policy, unsigned int index) |
139 | { | 114 | { |
140 | unsigned int freq; | 115 | int ret = -EBUSY; |
141 | int ret = 0; | ||
142 | 116 | ||
143 | mutex_lock(&tegra_cpu_lock); | 117 | mutex_lock(&tegra_cpu_lock); |
144 | 118 | ||
145 | if (is_suspended) | 119 | if (!is_suspended) |
146 | goto out; | 120 | ret = tegra_update_cpu_speed(policy, |
147 | 121 | freq_table[index].frequency); | |
148 | freq = freq_table[index].frequency; | ||
149 | 122 | ||
150 | target_cpu_speed[policy->cpu] = freq; | ||
151 | |||
152 | ret = tegra_update_cpu_speed(policy, tegra_cpu_highest_speed()); | ||
153 | |||
154 | out: | ||
155 | mutex_unlock(&tegra_cpu_lock); | 123 | mutex_unlock(&tegra_cpu_lock); |
156 | return ret; | 124 | return ret; |
157 | } | 125 | } |
@@ -165,7 +133,8 @@ static int tegra_pm_notify(struct notifier_block *nb, unsigned long event, | |||
165 | is_suspended = true; | 133 | is_suspended = true; |
166 | pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n", | 134 | pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n", |
167 | freq_table[0].frequency); | 135 | freq_table[0].frequency); |
168 | tegra_update_cpu_speed(policy, freq_table[0].frequency); | 136 | if (clk_get_rate(cpu_clk) / 1000 != freq_table[0].frequency) |
137 | tegra_update_cpu_speed(policy, freq_table[0].frequency); | ||
169 | cpufreq_cpu_put(policy); | 138 | cpufreq_cpu_put(policy); |
170 | } else if (event == PM_POST_SUSPEND) { | 139 | } else if (event == PM_POST_SUSPEND) { |
171 | is_suspended = false; | 140 | is_suspended = false; |
@@ -189,8 +158,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) | |||
189 | clk_prepare_enable(emc_clk); | 158 | clk_prepare_enable(emc_clk); |
190 | clk_prepare_enable(cpu_clk); | 159 | clk_prepare_enable(cpu_clk); |
191 | 160 | ||
192 | target_cpu_speed[policy->cpu] = tegra_getspeed(policy->cpu); | ||
193 | |||
194 | /* FIXME: what's the actual transition time? */ | 161 | /* FIXME: what's the actual transition time? */ |
195 | ret = cpufreq_generic_init(policy, freq_table, 300 * 1000); | 162 | ret = cpufreq_generic_init(policy, freq_table, 300 * 1000); |
196 | if (ret) { | 163 | if (ret) { |
@@ -202,6 +169,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) | |||
202 | if (policy->cpu == 0) | 169 | if (policy->cpu == 0) |
203 | register_pm_notifier(&tegra_cpu_pm_notifier); | 170 | register_pm_notifier(&tegra_cpu_pm_notifier); |
204 | 171 | ||
172 | policy->clk = cpu_clk; | ||
205 | return 0; | 173 | return 0; |
206 | } | 174 | } |
207 | 175 | ||
@@ -214,9 +182,10 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy) | |||
214 | } | 182 | } |
215 | 183 | ||
216 | static struct cpufreq_driver tegra_cpufreq_driver = { | 184 | static struct cpufreq_driver tegra_cpufreq_driver = { |
185 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
217 | .verify = cpufreq_generic_frequency_table_verify, | 186 | .verify = cpufreq_generic_frequency_table_verify, |
218 | .target_index = tegra_target, | 187 | .target_index = tegra_target, |
219 | .get = tegra_getspeed, | 188 | .get = cpufreq_generic_get, |
220 | .init = tegra_cpu_init, | 189 | .init = tegra_cpu_init, |
221 | .exit = tegra_cpu_exit, | 190 | .exit = tegra_cpu_exit, |
222 | .name = "tegra", | 191 | .name = "tegra", |
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index 653ae2955b55..36cc330b8747 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/err.h> | ||
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -33,42 +34,34 @@ static int ucv2_verify_speed(struct cpufreq_policy *policy) | |||
33 | return 0; | 34 | return 0; |
34 | } | 35 | } |
35 | 36 | ||
36 | static unsigned int ucv2_getspeed(unsigned int cpu) | ||
37 | { | ||
38 | struct clk *mclk = clk_get(NULL, "MAIN_CLK"); | ||
39 | |||
40 | if (cpu) | ||
41 | return 0; | ||
42 | return clk_get_rate(mclk)/1000; | ||
43 | } | ||
44 | |||
45 | static int ucv2_target(struct cpufreq_policy *policy, | 37 | static int ucv2_target(struct cpufreq_policy *policy, |
46 | unsigned int target_freq, | 38 | unsigned int target_freq, |
47 | unsigned int relation) | 39 | unsigned int relation) |
48 | { | 40 | { |
49 | unsigned int cur = ucv2_getspeed(0); | ||
50 | struct cpufreq_freqs freqs; | 41 | struct cpufreq_freqs freqs; |
51 | struct clk *mclk = clk_get(NULL, "MAIN_CLK"); | 42 | int ret; |
52 | 43 | ||
53 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 44 | freqs.old = policy->cur; |
45 | freqs.new = target_freq; | ||
54 | 46 | ||
55 | if (!clk_set_rate(mclk, target_freq * 1000)) { | 47 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
56 | freqs.old = cur; | 48 | ret = clk_set_rate(policy->mclk, target_freq * 1000); |
57 | freqs.new = target_freq; | 49 | cpufreq_notify_post_transition(policy, &freqs, ret); |
58 | } | ||
59 | |||
60 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
61 | 50 | ||
62 | return 0; | 51 | return ret; |
63 | } | 52 | } |
64 | 53 | ||
65 | static int __init ucv2_cpu_init(struct cpufreq_policy *policy) | 54 | static int __init ucv2_cpu_init(struct cpufreq_policy *policy) |
66 | { | 55 | { |
67 | if (policy->cpu != 0) | 56 | if (policy->cpu != 0) |
68 | return -EINVAL; | 57 | return -EINVAL; |
58 | |||
69 | policy->min = policy->cpuinfo.min_freq = 250000; | 59 | policy->min = policy->cpuinfo.min_freq = 250000; |
70 | policy->max = policy->cpuinfo.max_freq = 1000000; | 60 | policy->max = policy->cpuinfo.max_freq = 1000000; |
71 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 61 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
62 | policy->clk = clk_get(NULL, "MAIN_CLK"); | ||
63 | if (IS_ERR(policy->clk)) | ||
64 | return PTR_ERR(policy->clk); | ||
72 | return 0; | 65 | return 0; |
73 | } | 66 | } |
74 | 67 | ||
@@ -76,7 +69,7 @@ static struct cpufreq_driver ucv2_driver = { | |||
76 | .flags = CPUFREQ_STICKY, | 69 | .flags = CPUFREQ_STICKY, |
77 | .verify = ucv2_verify_speed, | 70 | .verify = ucv2_verify_speed, |
78 | .target = ucv2_target, | 71 | .target = ucv2_target, |
79 | .get = ucv2_getspeed, | 72 | .get = cpufreq_generic_get, |
80 | .init = ucv2_cpu_init, | 73 | .init = ucv2_cpu_init, |
81 | .name = "UniCore-II", | 74 | .name = "UniCore-II", |
82 | }; | 75 | }; |
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 5a29fac951ec..41983883cef4 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig | |||
@@ -113,7 +113,7 @@ config DMI_SCAN_MACHINE_NON_EFI_FALLBACK | |||
113 | 113 | ||
114 | config ISCSI_IBFT_FIND | 114 | config ISCSI_IBFT_FIND |
115 | bool "iSCSI Boot Firmware Table Attributes" | 115 | bool "iSCSI Boot Firmware Table Attributes" |
116 | depends on X86 | 116 | depends on X86 && ACPI |
117 | default n | 117 | default n |
118 | help | 118 | help |
119 | This option enables the kernel to find the region of memory | 119 | This option enables the kernel to find the region of memory |
diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c index ad0d6de938f3..13ec6283bf59 100644 --- a/drivers/gpu/drm/gma500/opregion.c +++ b/drivers/gpu/drm/gma500/opregion.c | |||
@@ -22,7 +22,6 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | #include <linux/acpi.h> | 24 | #include <linux/acpi.h> |
25 | #include <linux/acpi_io.h> | ||
26 | #include "psb_drv.h" | 25 | #include "psb_drv.h" |
27 | #include "psb_intel_reg.h" | 26 | #include "psb_intel_reg.h" |
28 | 27 | ||
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 41838eaa799c..d4ae48b04cf2 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -38,7 +38,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ | |||
38 | intel_ringbuffer.o \ | 38 | intel_ringbuffer.o \ |
39 | intel_overlay.o \ | 39 | intel_overlay.o \ |
40 | intel_sprite.o \ | 40 | intel_sprite.o \ |
41 | intel_opregion.o \ | ||
42 | intel_sideband.o \ | 41 | intel_sideband.o \ |
43 | intel_uncore.o \ | 42 | intel_uncore.o \ |
44 | dvo_ch7xxx.o \ | 43 | dvo_ch7xxx.o \ |
@@ -51,7 +50,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ | |||
51 | 50 | ||
52 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 51 | i915-$(CONFIG_COMPAT) += i915_ioc32.o |
53 | 52 | ||
54 | i915-$(CONFIG_ACPI) += intel_acpi.o | 53 | i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o |
55 | 54 | ||
56 | i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o | 55 | i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o |
57 | 56 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 90fcccba17b0..1caa5e34fbe3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -2339,8 +2339,8 @@ extern void intel_i2c_reset(struct drm_device *dev); | |||
2339 | 2339 | ||
2340 | /* intel_opregion.c */ | 2340 | /* intel_opregion.c */ |
2341 | struct intel_encoder; | 2341 | struct intel_encoder; |
2342 | extern int intel_opregion_setup(struct drm_device *dev); | ||
2343 | #ifdef CONFIG_ACPI | 2342 | #ifdef CONFIG_ACPI |
2343 | extern int intel_opregion_setup(struct drm_device *dev); | ||
2344 | extern void intel_opregion_init(struct drm_device *dev); | 2344 | extern void intel_opregion_init(struct drm_device *dev); |
2345 | extern void intel_opregion_fini(struct drm_device *dev); | 2345 | extern void intel_opregion_fini(struct drm_device *dev); |
2346 | extern void intel_opregion_asle_intr(struct drm_device *dev); | 2346 | extern void intel_opregion_asle_intr(struct drm_device *dev); |
@@ -2349,6 +2349,7 @@ extern int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, | |||
2349 | extern int intel_opregion_notify_adapter(struct drm_device *dev, | 2349 | extern int intel_opregion_notify_adapter(struct drm_device *dev, |
2350 | pci_power_t state); | 2350 | pci_power_t state); |
2351 | #else | 2351 | #else |
2352 | static inline int intel_opregion_setup(struct drm_device *dev) { return 0; } | ||
2352 | static inline void intel_opregion_init(struct drm_device *dev) { return; } | 2353 | static inline void intel_opregion_init(struct drm_device *dev) { return; } |
2353 | static inline void intel_opregion_fini(struct drm_device *dev) { return; } | 2354 | static inline void intel_opregion_fini(struct drm_device *dev) { return; } |
2354 | static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } | 2355 | static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } |
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index dfff0907f70e..d96eee1ae9c5 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
@@ -6,14 +6,10 @@ | |||
6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
7 | #include <linux/acpi.h> | 7 | #include <linux/acpi.h> |
8 | #include <linux/vga_switcheroo.h> | 8 | #include <linux/vga_switcheroo.h> |
9 | #include <acpi/acpi_drivers.h> | ||
10 | |||
11 | #include <drm/drmP.h> | 9 | #include <drm/drmP.h> |
12 | #include "i915_drv.h" | 10 | #include "i915_drv.h" |
13 | 11 | ||
14 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ | 12 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ |
15 | |||
16 | #define INTEL_DSM_FN_SUPPORTED_FUNCTIONS 0 /* No args */ | ||
17 | #define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ | 13 | #define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ |
18 | 14 | ||
19 | static struct intel_dsm_priv { | 15 | static struct intel_dsm_priv { |
@@ -28,61 +24,6 @@ static const u8 intel_dsm_guid[] = { | |||
28 | 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c | 24 | 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c |
29 | }; | 25 | }; |
30 | 26 | ||
31 | static int intel_dsm(acpi_handle handle, int func) | ||
32 | { | ||
33 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
34 | struct acpi_object_list input; | ||
35 | union acpi_object params[4]; | ||
36 | union acpi_object *obj; | ||
37 | u32 result; | ||
38 | int ret = 0; | ||
39 | |||
40 | input.count = 4; | ||
41 | input.pointer = params; | ||
42 | params[0].type = ACPI_TYPE_BUFFER; | ||
43 | params[0].buffer.length = sizeof(intel_dsm_guid); | ||
44 | params[0].buffer.pointer = (char *)intel_dsm_guid; | ||
45 | params[1].type = ACPI_TYPE_INTEGER; | ||
46 | params[1].integer.value = INTEL_DSM_REVISION_ID; | ||
47 | params[2].type = ACPI_TYPE_INTEGER; | ||
48 | params[2].integer.value = func; | ||
49 | params[3].type = ACPI_TYPE_PACKAGE; | ||
50 | params[3].package.count = 0; | ||
51 | params[3].package.elements = NULL; | ||
52 | |||
53 | ret = acpi_evaluate_object(handle, "_DSM", &input, &output); | ||
54 | if (ret) { | ||
55 | DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | obj = (union acpi_object *)output.pointer; | ||
60 | |||
61 | result = 0; | ||
62 | switch (obj->type) { | ||
63 | case ACPI_TYPE_INTEGER: | ||
64 | result = obj->integer.value; | ||
65 | break; | ||
66 | |||
67 | case ACPI_TYPE_BUFFER: | ||
68 | if (obj->buffer.length == 4) { | ||
69 | result = (obj->buffer.pointer[0] | | ||
70 | (obj->buffer.pointer[1] << 8) | | ||
71 | (obj->buffer.pointer[2] << 16) | | ||
72 | (obj->buffer.pointer[3] << 24)); | ||
73 | break; | ||
74 | } | ||
75 | default: | ||
76 | ret = -EINVAL; | ||
77 | break; | ||
78 | } | ||
79 | if (result == 0x80000002) | ||
80 | ret = -ENODEV; | ||
81 | |||
82 | kfree(output.pointer); | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | static char *intel_dsm_port_name(u8 id) | 27 | static char *intel_dsm_port_name(u8 id) |
87 | { | 28 | { |
88 | switch (id) { | 29 | switch (id) { |
@@ -137,83 +78,56 @@ static char *intel_dsm_mux_type(u8 type) | |||
137 | 78 | ||
138 | static void intel_dsm_platform_mux_info(void) | 79 | static void intel_dsm_platform_mux_info(void) |
139 | { | 80 | { |
140 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 81 | int i; |
141 | struct acpi_object_list input; | 82 | union acpi_object *pkg, *connector_count; |
142 | union acpi_object params[4]; | 83 | |
143 | union acpi_object *pkg; | 84 | pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid, |
144 | int i, ret; | 85 | INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO, |
145 | 86 | NULL, ACPI_TYPE_PACKAGE); | |
146 | input.count = 4; | 87 | if (!pkg) { |
147 | input.pointer = params; | 88 | DRM_DEBUG_DRIVER("failed to evaluate _DSM\n"); |
148 | params[0].type = ACPI_TYPE_BUFFER; | 89 | return; |
149 | params[0].buffer.length = sizeof(intel_dsm_guid); | ||
150 | params[0].buffer.pointer = (char *)intel_dsm_guid; | ||
151 | params[1].type = ACPI_TYPE_INTEGER; | ||
152 | params[1].integer.value = INTEL_DSM_REVISION_ID; | ||
153 | params[2].type = ACPI_TYPE_INTEGER; | ||
154 | params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO; | ||
155 | params[3].type = ACPI_TYPE_PACKAGE; | ||
156 | params[3].package.count = 0; | ||
157 | params[3].package.elements = NULL; | ||
158 | |||
159 | ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input, | ||
160 | &output); | ||
161 | if (ret) { | ||
162 | DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret); | ||
163 | goto out; | ||
164 | } | 90 | } |
165 | 91 | ||
166 | pkg = (union acpi_object *)output.pointer; | 92 | connector_count = &pkg->package.elements[0]; |
167 | 93 | DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", | |
168 | if (pkg->type == ACPI_TYPE_PACKAGE) { | 94 | (unsigned long long)connector_count->integer.value); |
169 | union acpi_object *connector_count = &pkg->package.elements[0]; | 95 | for (i = 1; i < pkg->package.count; i++) { |
170 | DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", | 96 | union acpi_object *obj = &pkg->package.elements[i]; |
171 | (unsigned long long)connector_count->integer.value); | 97 | union acpi_object *connector_id = &obj->package.elements[0]; |
172 | for (i = 1; i < pkg->package.count; i++) { | 98 | union acpi_object *info = &obj->package.elements[1]; |
173 | union acpi_object *obj = &pkg->package.elements[i]; | 99 | DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", |
174 | union acpi_object *connector_id = | 100 | (unsigned long long)connector_id->integer.value); |
175 | &obj->package.elements[0]; | 101 | DRM_DEBUG_DRIVER(" port id: %s\n", |
176 | union acpi_object *info = &obj->package.elements[1]; | 102 | intel_dsm_port_name(info->buffer.pointer[0])); |
177 | DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", | 103 | DRM_DEBUG_DRIVER(" display mux info: %s\n", |
178 | (unsigned long long)connector_id->integer.value); | 104 | intel_dsm_mux_type(info->buffer.pointer[1])); |
179 | DRM_DEBUG_DRIVER(" port id: %s\n", | 105 | DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n", |
180 | intel_dsm_port_name(info->buffer.pointer[0])); | 106 | intel_dsm_mux_type(info->buffer.pointer[2])); |
181 | DRM_DEBUG_DRIVER(" display mux info: %s\n", | 107 | DRM_DEBUG_DRIVER(" hpd mux info: %s\n", |
182 | intel_dsm_mux_type(info->buffer.pointer[1])); | 108 | intel_dsm_mux_type(info->buffer.pointer[3])); |
183 | DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n", | ||
184 | intel_dsm_mux_type(info->buffer.pointer[2])); | ||
185 | DRM_DEBUG_DRIVER(" hpd mux info: %s\n", | ||
186 | intel_dsm_mux_type(info->buffer.pointer[3])); | ||
187 | } | ||
188 | } | 109 | } |
189 | 110 | ||
190 | out: | 111 | ACPI_FREE(pkg); |
191 | kfree(output.pointer); | ||
192 | } | 112 | } |
193 | 113 | ||
194 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) | 114 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) |
195 | { | 115 | { |
196 | acpi_handle dhandle; | 116 | acpi_handle dhandle; |
197 | int ret; | ||
198 | 117 | ||
199 | dhandle = ACPI_HANDLE(&pdev->dev); | 118 | dhandle = ACPI_HANDLE(&pdev->dev); |
200 | if (!dhandle) | 119 | if (!dhandle) |
201 | return false; | 120 | return false; |
202 | 121 | ||
203 | if (!acpi_has_method(dhandle, "_DSM")) { | 122 | if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID, |
123 | 1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) { | ||
204 | DRM_DEBUG_KMS("no _DSM method for intel device\n"); | 124 | DRM_DEBUG_KMS("no _DSM method for intel device\n"); |
205 | return false; | 125 | return false; |
206 | } | 126 | } |
207 | 127 | ||
208 | ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS); | ||
209 | if (ret < 0) { | ||
210 | DRM_DEBUG_KMS("failed to get supported _DSM functions\n"); | ||
211 | return false; | ||
212 | } | ||
213 | |||
214 | intel_dsm_priv.dhandle = dhandle; | 128 | intel_dsm_priv.dhandle = dhandle; |
215 | |||
216 | intel_dsm_platform_mux_info(); | 129 | intel_dsm_platform_mux_info(); |
130 | |||
217 | return true; | 131 | return true; |
218 | } | 132 | } |
219 | 133 | ||
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 6d69a9bad865..9a8804bee5cd 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
29 | 29 | ||
30 | #include <linux/acpi.h> | 30 | #include <linux/acpi.h> |
31 | #include <linux/acpi_io.h> | ||
32 | #include <acpi/video.h> | 31 | #include <acpi/video.h> |
33 | 32 | ||
34 | #include <drm/drmP.h> | 33 | #include <drm/drmP.h> |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c index 129120473f6c..13c5af88a601 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c | |||
@@ -87,55 +87,39 @@ mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version) | |||
87 | 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65 | 87 | 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65 |
88 | }; | 88 | }; |
89 | u32 mxms_args[] = { 0x00000000 }; | 89 | u32 mxms_args[] = { 0x00000000 }; |
90 | union acpi_object args[4] = { | 90 | union acpi_object argv4 = { |
91 | /* _DSM MUID */ | 91 | .buffer.type = ACPI_TYPE_BUFFER, |
92 | { .buffer.type = 3, | 92 | .buffer.length = sizeof(mxms_args), |
93 | .buffer.length = sizeof(muid), | 93 | .buffer.pointer = (char *)mxms_args, |
94 | .buffer.pointer = muid, | ||
95 | }, | ||
96 | /* spec says this can be zero to mean "highest revision", but | ||
97 | * of course there's at least one bios out there which fails | ||
98 | * unless you pass in exactly the version it supports.. | ||
99 | */ | ||
100 | { .integer.type = ACPI_TYPE_INTEGER, | ||
101 | .integer.value = (version & 0xf0) << 4 | (version & 0x0f), | ||
102 | }, | ||
103 | /* MXMS function */ | ||
104 | { .integer.type = ACPI_TYPE_INTEGER, | ||
105 | .integer.value = 0x00000010, | ||
106 | }, | ||
107 | /* Pointer to MXMS arguments */ | ||
108 | { .buffer.type = ACPI_TYPE_BUFFER, | ||
109 | .buffer.length = sizeof(mxms_args), | ||
110 | .buffer.pointer = (char *)mxms_args, | ||
111 | }, | ||
112 | }; | 94 | }; |
113 | struct acpi_object_list list = { ARRAY_SIZE(args), args }; | ||
114 | struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
115 | union acpi_object *obj; | 95 | union acpi_object *obj; |
116 | acpi_handle handle; | 96 | acpi_handle handle; |
117 | int ret; | 97 | int rev; |
118 | 98 | ||
119 | handle = ACPI_HANDLE(&device->pdev->dev); | 99 | handle = ACPI_HANDLE(&device->pdev->dev); |
120 | if (!handle) | 100 | if (!handle) |
121 | return false; | 101 | return false; |
122 | 102 | ||
123 | ret = acpi_evaluate_object(handle, "_DSM", &list, &retn); | 103 | /* |
124 | if (ret) { | 104 | * spec says this can be zero to mean "highest revision", but |
125 | nv_debug(mxm, "DSM MXMS failed: %d\n", ret); | 105 | * of course there's at least one bios out there which fails |
106 | * unless you pass in exactly the version it supports.. | ||
107 | */ | ||
108 | rev = (version & 0xf0) << 4 | (version & 0x0f); | ||
109 | obj = acpi_evaluate_dsm(handle, muid, rev, 0x00000010, &argv4); | ||
110 | if (!obj) { | ||
111 | nv_debug(mxm, "DSM MXMS failed\n"); | ||
126 | return false; | 112 | return false; |
127 | } | 113 | } |
128 | 114 | ||
129 | obj = retn.pointer; | ||
130 | if (obj->type == ACPI_TYPE_BUFFER) { | 115 | if (obj->type == ACPI_TYPE_BUFFER) { |
131 | mxm->mxms = kmemdup(obj->buffer.pointer, | 116 | mxm->mxms = kmemdup(obj->buffer.pointer, |
132 | obj->buffer.length, GFP_KERNEL); | 117 | obj->buffer.length, GFP_KERNEL); |
133 | } else | 118 | } else if (obj->type == ACPI_TYPE_INTEGER) { |
134 | if (obj->type == ACPI_TYPE_INTEGER) { | ||
135 | nv_debug(mxm, "DSM MXMS returned 0x%llx\n", obj->integer.value); | 119 | nv_debug(mxm, "DSM MXMS returned 0x%llx\n", obj->integer.value); |
136 | } | 120 | } |
137 | 121 | ||
138 | kfree(obj); | 122 | ACPI_FREE(obj); |
139 | return mxm->mxms != NULL; | 123 | return mxm->mxms != NULL; |
140 | } | 124 | } |
141 | #endif | 125 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index ba0183fb84f3..3c149617cfcb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -1,15 +1,10 @@ | |||
1 | #include <linux/pci.h> | 1 | #include <linux/pci.h> |
2 | #include <linux/acpi.h> | 2 | #include <linux/acpi.h> |
3 | #include <linux/slab.h> | 3 | #include <linux/slab.h> |
4 | #include <acpi/acpi_drivers.h> | ||
5 | #include <acpi/acpi_bus.h> | ||
6 | #include <acpi/video.h> | ||
7 | #include <acpi/acpi.h> | ||
8 | #include <linux/mxm-wmi.h> | 4 | #include <linux/mxm-wmi.h> |
9 | |||
10 | #include <linux/vga_switcheroo.h> | 5 | #include <linux/vga_switcheroo.h> |
11 | |||
12 | #include <drm/drm_edid.h> | 6 | #include <drm/drm_edid.h> |
7 | #include <acpi/video.h> | ||
13 | 8 | ||
14 | #include "nouveau_drm.h" | 9 | #include "nouveau_drm.h" |
15 | #include "nouveau_acpi.h" | 10 | #include "nouveau_acpi.h" |
@@ -78,124 +73,66 @@ static const char nouveau_op_dsm_muid[] = { | |||
78 | 73 | ||
79 | static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) | 74 | static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) |
80 | { | 75 | { |
81 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 76 | int i; |
82 | struct acpi_object_list input; | ||
83 | union acpi_object params[4]; | ||
84 | union acpi_object *obj; | 77 | union acpi_object *obj; |
85 | int i, err; | ||
86 | char args_buff[4]; | 78 | char args_buff[4]; |
79 | union acpi_object argv4 = { | ||
80 | .buffer.type = ACPI_TYPE_BUFFER, | ||
81 | .buffer.length = 4, | ||
82 | .buffer.pointer = args_buff | ||
83 | }; | ||
87 | 84 | ||
88 | input.count = 4; | ||
89 | input.pointer = params; | ||
90 | params[0].type = ACPI_TYPE_BUFFER; | ||
91 | params[0].buffer.length = sizeof(nouveau_op_dsm_muid); | ||
92 | params[0].buffer.pointer = (char *)nouveau_op_dsm_muid; | ||
93 | params[1].type = ACPI_TYPE_INTEGER; | ||
94 | params[1].integer.value = 0x00000100; | ||
95 | params[2].type = ACPI_TYPE_INTEGER; | ||
96 | params[2].integer.value = func; | ||
97 | params[3].type = ACPI_TYPE_BUFFER; | ||
98 | params[3].buffer.length = 4; | ||
99 | /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ | 85 | /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ |
100 | for (i = 0; i < 4; i++) | 86 | for (i = 0; i < 4; i++) |
101 | args_buff[i] = (arg >> i * 8) & 0xFF; | 87 | args_buff[i] = (arg >> i * 8) & 0xFF; |
102 | params[3].buffer.pointer = args_buff; | ||
103 | |||
104 | err = acpi_evaluate_object(handle, "_DSM", &input, &output); | ||
105 | if (err) { | ||
106 | printk(KERN_INFO "failed to evaluate _DSM: %d\n", err); | ||
107 | return err; | ||
108 | } | ||
109 | |||
110 | obj = (union acpi_object *)output.pointer; | ||
111 | 88 | ||
112 | if (obj->type == ACPI_TYPE_INTEGER) | 89 | *result = 0; |
113 | if (obj->integer.value == 0x80000002) { | 90 | obj = acpi_evaluate_dsm_typed(handle, nouveau_op_dsm_muid, 0x00000100, |
114 | return -ENODEV; | 91 | func, &argv4, ACPI_TYPE_BUFFER); |
115 | } | 92 | if (!obj) { |
116 | 93 | acpi_handle_info(handle, "failed to evaluate _DSM\n"); | |
117 | if (obj->type == ACPI_TYPE_BUFFER) { | 94 | return AE_ERROR; |
118 | if (obj->buffer.length == 4 && result) { | 95 | } else { |
119 | *result = 0; | 96 | if (obj->buffer.length == 4) { |
120 | *result |= obj->buffer.pointer[0]; | 97 | *result |= obj->buffer.pointer[0]; |
121 | *result |= (obj->buffer.pointer[1] << 8); | 98 | *result |= (obj->buffer.pointer[1] << 8); |
122 | *result |= (obj->buffer.pointer[2] << 16); | 99 | *result |= (obj->buffer.pointer[2] << 16); |
123 | *result |= (obj->buffer.pointer[3] << 24); | 100 | *result |= (obj->buffer.pointer[3] << 24); |
124 | } | 101 | } |
102 | ACPI_FREE(obj); | ||
125 | } | 103 | } |
126 | 104 | ||
127 | kfree(output.pointer); | ||
128 | return 0; | 105 | return 0; |
129 | } | 106 | } |
130 | 107 | ||
131 | static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) | 108 | static int nouveau_dsm(acpi_handle handle, int func, int arg) |
132 | { | 109 | { |
133 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 110 | int ret = 0; |
134 | struct acpi_object_list input; | ||
135 | union acpi_object params[4]; | ||
136 | union acpi_object *obj; | 111 | union acpi_object *obj; |
137 | int err; | 112 | union acpi_object argv4 = { |
138 | 113 | .integer.type = ACPI_TYPE_INTEGER, | |
139 | input.count = 4; | 114 | .integer.value = arg, |
140 | input.pointer = params; | 115 | }; |
141 | params[0].type = ACPI_TYPE_BUFFER; | 116 | |
142 | params[0].buffer.length = sizeof(nouveau_dsm_muid); | 117 | obj = acpi_evaluate_dsm_typed(handle, nouveau_dsm_muid, 0x00000102, |
143 | params[0].buffer.pointer = (char *)nouveau_dsm_muid; | 118 | func, &argv4, ACPI_TYPE_INTEGER); |
144 | params[1].type = ACPI_TYPE_INTEGER; | 119 | if (!obj) { |
145 | params[1].integer.value = 0x00000102; | 120 | acpi_handle_info(handle, "failed to evaluate _DSM\n"); |
146 | params[2].type = ACPI_TYPE_INTEGER; | 121 | return AE_ERROR; |
147 | params[2].integer.value = func; | 122 | } else { |
148 | params[3].type = ACPI_TYPE_INTEGER; | ||
149 | params[3].integer.value = arg; | ||
150 | |||
151 | err = acpi_evaluate_object(handle, "_DSM", &input, &output); | ||
152 | if (err) { | ||
153 | printk(KERN_INFO "failed to evaluate _DSM: %d\n", err); | ||
154 | return err; | ||
155 | } | ||
156 | |||
157 | obj = (union acpi_object *)output.pointer; | ||
158 | |||
159 | if (obj->type == ACPI_TYPE_INTEGER) | ||
160 | if (obj->integer.value == 0x80000002) | 123 | if (obj->integer.value == 0x80000002) |
161 | return -ENODEV; | 124 | ret = -ENODEV; |
162 | 125 | ACPI_FREE(obj); | |
163 | if (obj->type == ACPI_TYPE_BUFFER) { | ||
164 | if (obj->buffer.length == 4 && result) { | ||
165 | *result = 0; | ||
166 | *result |= obj->buffer.pointer[0]; | ||
167 | *result |= (obj->buffer.pointer[1] << 8); | ||
168 | *result |= (obj->buffer.pointer[2] << 16); | ||
169 | *result |= (obj->buffer.pointer[3] << 24); | ||
170 | } | ||
171 | } | 126 | } |
172 | 127 | ||
173 | kfree(output.pointer); | 128 | return ret; |
174 | return 0; | ||
175 | } | ||
176 | |||
177 | /* Returns 1 if a DSM function is usable and 0 otherwise */ | ||
178 | static int nouveau_test_dsm(acpi_handle test_handle, | ||
179 | int (*dsm_func)(acpi_handle, int, int, uint32_t *), | ||
180 | int sfnc) | ||
181 | { | ||
182 | u32 result = 0; | ||
183 | |||
184 | /* Function 0 returns a Buffer containing available functions. The args | ||
185 | * parameter is ignored for function 0, so just put 0 in it */ | ||
186 | if (dsm_func(test_handle, 0, 0, &result)) | ||
187 | return 0; | ||
188 | |||
189 | /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If | ||
190 | * the n-th bit is enabled, function n is supported */ | ||
191 | return result & 1 && result & (1 << sfnc); | ||
192 | } | 129 | } |
193 | 130 | ||
194 | static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) | 131 | static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) |
195 | { | 132 | { |
196 | mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); | 133 | mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); |
197 | mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); | 134 | mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); |
198 | return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL); | 135 | return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id); |
199 | } | 136 | } |
200 | 137 | ||
201 | static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state) | 138 | static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state) |
@@ -205,7 +142,7 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero | |||
205 | arg = NOUVEAU_DSM_POWER_SPEED; | 142 | arg = NOUVEAU_DSM_POWER_SPEED; |
206 | else | 143 | else |
207 | arg = NOUVEAU_DSM_POWER_STAMINA; | 144 | arg = NOUVEAU_DSM_POWER_STAMINA; |
208 | nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg, NULL); | 145 | nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg); |
209 | return 0; | 146 | return 0; |
210 | } | 147 | } |
211 | 148 | ||
@@ -265,11 +202,12 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) | |||
265 | nouveau_dsm_priv.other_handle = dhandle; | 202 | nouveau_dsm_priv.other_handle = dhandle; |
266 | return false; | 203 | return false; |
267 | } | 204 | } |
268 | if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) | 205 | if (acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102, |
206 | 1 << NOUVEAU_DSM_POWER)) | ||
269 | retval |= NOUVEAU_DSM_HAS_MUX; | 207 | retval |= NOUVEAU_DSM_HAS_MUX; |
270 | 208 | ||
271 | if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm, | 209 | if (acpi_check_dsm(dhandle, nouveau_op_dsm_muid, 0x00000100, |
272 | NOUVEAU_DSM_OPTIMUS_CAPS)) | 210 | 1 << NOUVEAU_DSM_OPTIMUS_CAPS)) |
273 | retval |= NOUVEAU_DSM_HAS_OPT; | 211 | retval |= NOUVEAU_DSM_HAS_OPT; |
274 | 212 | ||
275 | if (retval & NOUVEAU_DSM_HAS_OPT) { | 213 | if (retval & NOUVEAU_DSM_HAS_OPT) { |
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 98a9074b306b..77e9d07c55b6 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c | |||
@@ -25,18 +25,14 @@ | |||
25 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/power_supply.h> | 27 | #include <linux/power_supply.h> |
28 | #include <acpi/acpi_drivers.h> | 28 | #include <linux/vga_switcheroo.h> |
29 | #include <acpi/acpi_bus.h> | ||
30 | #include <acpi/video.h> | 29 | #include <acpi/video.h> |
31 | |||
32 | #include <drm/drmP.h> | 30 | #include <drm/drmP.h> |
33 | #include <drm/drm_crtc_helper.h> | 31 | #include <drm/drm_crtc_helper.h> |
34 | #include "radeon.h" | 32 | #include "radeon.h" |
35 | #include "radeon_acpi.h" | 33 | #include "radeon_acpi.h" |
36 | #include "atom.h" | 34 | #include "atom.h" |
37 | 35 | ||
38 | #include <linux/vga_switcheroo.h> | ||
39 | |||
40 | #define ACPI_AC_CLASS "ac_adapter" | 36 | #define ACPI_AC_CLASS "ac_adapter" |
41 | 37 | ||
42 | extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev); | 38 | extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev); |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index e914f2755491..d1f81f52481a 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -850,37 +850,23 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client, | |||
850 | 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45, | 850 | 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45, |
851 | 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE, | 851 | 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE, |
852 | }; | 852 | }; |
853 | union acpi_object params[4]; | 853 | union acpi_object *obj; |
854 | struct acpi_object_list input; | ||
855 | struct acpi_device *adev; | 854 | struct acpi_device *adev; |
856 | unsigned long long value; | ||
857 | acpi_handle handle; | 855 | acpi_handle handle; |
858 | 856 | ||
859 | handle = ACPI_HANDLE(&client->dev); | 857 | handle = ACPI_HANDLE(&client->dev); |
860 | if (!handle || acpi_bus_get_device(handle, &adev)) | 858 | if (!handle || acpi_bus_get_device(handle, &adev)) |
861 | return -ENODEV; | 859 | return -ENODEV; |
862 | 860 | ||
863 | input.count = ARRAY_SIZE(params); | 861 | obj = acpi_evaluate_dsm_typed(handle, i2c_hid_guid, 1, 1, NULL, |
864 | input.pointer = params; | 862 | ACPI_TYPE_INTEGER); |
865 | 863 | if (!obj) { | |
866 | params[0].type = ACPI_TYPE_BUFFER; | ||
867 | params[0].buffer.length = sizeof(i2c_hid_guid); | ||
868 | params[0].buffer.pointer = i2c_hid_guid; | ||
869 | params[1].type = ACPI_TYPE_INTEGER; | ||
870 | params[1].integer.value = 1; | ||
871 | params[2].type = ACPI_TYPE_INTEGER; | ||
872 | params[2].integer.value = 1; /* HID function */ | ||
873 | params[3].type = ACPI_TYPE_PACKAGE; | ||
874 | params[3].package.count = 0; | ||
875 | params[3].package.elements = NULL; | ||
876 | |||
877 | if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_DSM", &input, | ||
878 | &value))) { | ||
879 | dev_err(&client->dev, "device _DSM execution failed\n"); | 864 | dev_err(&client->dev, "device _DSM execution failed\n"); |
880 | return -ENODEV; | 865 | return -ENODEV; |
881 | } | 866 | } |
882 | 867 | ||
883 | pdata->hid_descriptor_address = value; | 868 | pdata->hid_descriptor_address = obj->integer.value; |
869 | ACPI_FREE(obj); | ||
884 | 870 | ||
885 | return 0; | 871 | return 0; |
886 | } | 872 | } |
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 48aad4faea06..077bb1bdac34 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/sysctl.h> | 30 | #include <linux/sysctl.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/acpi.h> | 32 | #include <linux/acpi.h> |
33 | #include <acpi/acpi_bus.h> | ||
34 | #include <linux/completion.h> | 33 | #include <linux/completion.h> |
35 | #include <linux/hyperv.h> | 34 | #include <linux/hyperv.h> |
36 | #include <linux/kernel_stat.h> | 35 | #include <linux/kernel_stat.h> |
@@ -39,7 +38,6 @@ | |||
39 | #include <asm/mshyperv.h> | 38 | #include <asm/mshyperv.h> |
40 | #include "hyperv_vmbus.h" | 39 | #include "hyperv_vmbus.h" |
41 | 40 | ||
42 | |||
43 | static struct acpi_device *hv_acpi_dev; | 41 | static struct acpi_device *hv_acpi_dev; |
44 | 42 | ||
45 | static struct tasklet_struct msg_dpc; | 43 | static struct tasklet_struct msg_dpc; |
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 6a34f7f48eb9..579bdf93be43 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c | |||
@@ -30,8 +30,7 @@ | |||
30 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
31 | #include <linux/time.h> | 31 | #include <linux/time.h> |
32 | #include <linux/err.h> | 32 | #include <linux/err.h> |
33 | #include <acpi/acpi_drivers.h> | 33 | #include <linux/acpi.h> |
34 | #include <acpi/acpi_bus.h> | ||
35 | 34 | ||
36 | #define ACPI_POWER_METER_NAME "power_meter" | 35 | #define ACPI_POWER_METER_NAME "power_meter" |
37 | ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); | 36 | ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); |
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index dafc63c6932d..ae208f612198 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c | |||
@@ -16,11 +16,7 @@ | |||
16 | #include <linux/dmi.h> | 16 | #include <linux/dmi.h> |
17 | #include <linux/jiffies.h> | 17 | #include <linux/jiffies.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | 19 | #include <linux/acpi.h> | |
20 | #include <acpi/acpi.h> | ||
21 | #include <acpi/acpi_drivers.h> | ||
22 | #include <acpi/acpi_bus.h> | ||
23 | |||
24 | 20 | ||
25 | #define ATK_HID "ATK0110" | 21 | #define ATK_HID "ATK0110" |
26 | 22 | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d74c0b34248e..c4c5588ec0fb 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -104,6 +104,11 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv) | |||
104 | static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) | 104 | static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
105 | { | 105 | { |
106 | struct i2c_client *client = to_i2c_client(dev); | 106 | struct i2c_client *client = to_i2c_client(dev); |
107 | int rc; | ||
108 | |||
109 | rc = acpi_device_uevent_modalias(dev, env); | ||
110 | if (rc != -ENODEV) | ||
111 | return rc; | ||
107 | 112 | ||
108 | if (add_uevent_var(env, "MODALIAS=%s%s", | 113 | if (add_uevent_var(env, "MODALIAS=%s%s", |
109 | I2C_MODULE_PREFIX, client->name)) | 114 | I2C_MODULE_PREFIX, client->name)) |
@@ -409,6 +414,12 @@ static ssize_t | |||
409 | show_modalias(struct device *dev, struct device_attribute *attr, char *buf) | 414 | show_modalias(struct device *dev, struct device_attribute *attr, char *buf) |
410 | { | 415 | { |
411 | struct i2c_client *client = to_i2c_client(dev); | 416 | struct i2c_client *client = to_i2c_client(dev); |
417 | int len; | ||
418 | |||
419 | len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); | ||
420 | if (len != -ENODEV) | ||
421 | return len; | ||
422 | |||
412 | return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); | 423 | return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); |
413 | } | 424 | } |
414 | 425 | ||
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index d9e1f7ccfe6f..b6940992a6ff 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <acpi/acpi.h> | ||
18 | #include <linux/ide.h> | 17 | #include <linux/ide.h> |
19 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
20 | #include <linux/dmi.h> | 19 | #include <linux/dmi.h> |
@@ -98,6 +97,17 @@ bool ide_port_acpi(ide_hwif_t *hwif) | |||
98 | return ide_noacpi == 0 && hwif->acpidata; | 97 | return ide_noacpi == 0 && hwif->acpidata; |
99 | } | 98 | } |
100 | 99 | ||
100 | static acpi_handle acpi_get_child(acpi_handle handle, u64 addr) | ||
101 | { | ||
102 | struct acpi_device *adev; | ||
103 | |||
104 | if (!handle || acpi_bus_get_device(handle, &adev)) | ||
105 | return NULL; | ||
106 | |||
107 | adev = acpi_find_child_device(adev, addr, false); | ||
108 | return adev ? adev->handle : NULL; | ||
109 | } | ||
110 | |||
101 | /** | 111 | /** |
102 | * ide_get_dev_handle - finds acpi_handle and PCI device.function | 112 | * ide_get_dev_handle - finds acpi_handle and PCI device.function |
103 | * @dev: device to locate | 113 | * @dev: device to locate |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 6c0e0452dd9b..8e1939f564f4 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -635,39 +635,10 @@ static int __init intel_idle_cpuidle_driver_init(void) | |||
635 | */ | 635 | */ |
636 | static int intel_idle_cpu_init(int cpu) | 636 | static int intel_idle_cpu_init(int cpu) |
637 | { | 637 | { |
638 | int cstate; | ||
639 | struct cpuidle_device *dev; | 638 | struct cpuidle_device *dev; |
640 | 639 | ||
641 | dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); | 640 | dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); |
642 | 641 | ||
643 | dev->state_count = 1; | ||
644 | |||
645 | for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { | ||
646 | int num_substates, mwait_hint, mwait_cstate, mwait_substate; | ||
647 | |||
648 | if (cpuidle_state_table[cstate].enter == NULL) | ||
649 | break; | ||
650 | |||
651 | if (cstate + 1 > max_cstate) { | ||
652 | printk(PREFIX "max_cstate %d reached\n", max_cstate); | ||
653 | break; | ||
654 | } | ||
655 | |||
656 | mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); | ||
657 | mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint); | ||
658 | mwait_substate = MWAIT_HINT2SUBSTATE(mwait_hint); | ||
659 | |||
660 | /* does the state exist in CPUID.MWAIT? */ | ||
661 | num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4)) | ||
662 | & MWAIT_SUBSTATE_MASK; | ||
663 | |||
664 | /* if sub-state in table is not enumerated by CPUID */ | ||
665 | if ((mwait_substate + 1) > num_substates) | ||
666 | continue; | ||
667 | |||
668 | dev->state_count += 1; | ||
669 | } | ||
670 | |||
671 | dev->cpu = cpu; | 642 | dev->cpu = cpu; |
672 | 643 | ||
673 | if (cpuidle_register_device(dev)) { | 644 | if (cpuidle_register_device(dev)) { |
@@ -679,6 +650,9 @@ static int intel_idle_cpu_init(int cpu) | |||
679 | if (icpu->auto_demotion_disable_flags) | 650 | if (icpu->auto_demotion_disable_flags) |
680 | smp_call_function_single(cpu, auto_demotion_disable, NULL, 1); | 651 | smp_call_function_single(cpu, auto_demotion_disable, NULL, 1); |
681 | 652 | ||
653 | if (icpu->disable_promotion_to_c1e) | ||
654 | smp_call_function_single(cpu, c1e_promotion_disable, NULL, 1); | ||
655 | |||
682 | return 0; | 656 | return 0; |
683 | } | 657 | } |
684 | 658 | ||
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 5d4402365a52..d781b5e52065 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c | |||
@@ -28,8 +28,8 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/acpi.h> | ||
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
32 | #include <acpi/acpi_drivers.h> | ||
33 | 33 | ||
34 | #define ACPI_ATLAS_NAME "Atlas ACPI" | 34 | #define ACPI_ATLAS_NAME "Atlas ACPI" |
35 | #define ACPI_ATLAS_CLASS "Atlas" | 35 | #define ACPI_ATLAS_CLASS "Atlas" |
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 8f798be6e398..28b4bea7c109 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/msi.h> | 26 | #include <linux/msi.h> |
27 | #include <linux/amd-iommu.h> | 27 | #include <linux/amd-iommu.h> |
28 | #include <linux/export.h> | 28 | #include <linux/export.h> |
29 | #include <acpi/acpi.h> | ||
30 | #include <asm/pci-direct.h> | 29 | #include <asm/pci-direct.h> |
31 | #include <asm/iommu.h> | 30 | #include <asm/iommu.h> |
32 | #include <asm/gart.h> | 31 | #include <asm/gart.h> |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index bab10b1002fb..0cb7528b30a1 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
@@ -6,11 +6,11 @@ | |||
6 | #include <linux/hpet.h> | 6 | #include <linux/hpet.h> |
7 | #include <linux/pci.h> | 7 | #include <linux/pci.h> |
8 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
9 | #include <linux/intel-iommu.h> | ||
10 | #include <linux/acpi.h> | ||
9 | #include <asm/io_apic.h> | 11 | #include <asm/io_apic.h> |
10 | #include <asm/smp.h> | 12 | #include <asm/smp.h> |
11 | #include <asm/cpu.h> | 13 | #include <asm/cpu.h> |
12 | #include <linux/intel-iommu.h> | ||
13 | #include <acpi/acpi.h> | ||
14 | #include <asm/irq_remapping.h> | 14 | #include <asm/irq_remapping.h> |
15 | #include <asm/pci-direct.h> | 15 | #include <asm/pci-direct.h> |
16 | #include <asm/msidef.h> | 16 | #include <asm/msidef.h> |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 157b570ba343..92d1ba8e8153 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -308,7 +308,7 @@ static void sdio_acpi_set_handle(struct sdio_func *func) | |||
308 | struct mmc_host *host = func->card->host; | 308 | struct mmc_host *host = func->card->host; |
309 | u64 addr = (host->slotno << 16) | func->num; | 309 | u64 addr = (host->slotno << 16) | func->num; |
310 | 310 | ||
311 | acpi_preset_companion(&func->dev, ACPI_HANDLE(host->parent), addr); | 311 | acpi_preset_companion(&func->dev, ACPI_COMPANION(host->parent), addr); |
312 | } | 312 | } |
313 | #else | 313 | #else |
314 | static inline void sdio_acpi_set_handle(struct sdio_func *func) {} | 314 | static inline void sdio_acpi_set_handle(struct sdio_func *func) {} |
diff --git a/drivers/of/device.c b/drivers/of/device.c index f685e55e0717..dafb9736ab9b 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
@@ -85,6 +85,9 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) | |||
85 | int cplen, i; | 85 | int cplen, i; |
86 | ssize_t tsize, csize, repend; | 86 | ssize_t tsize, csize, repend; |
87 | 87 | ||
88 | if ((!dev) || (!dev->of_node)) | ||
89 | return -ENODEV; | ||
90 | |||
88 | /* Name & Type */ | 91 | /* Name & Type */ |
89 | csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, | 92 | csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, |
90 | dev->of_node->type); | 93 | dev->of_node->type); |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index ee26bac2d378..cd929aed3613 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -494,7 +494,7 @@ static void acpiphp_bus_add(acpi_handle handle) | |||
494 | 494 | ||
495 | acpi_bus_scan(handle); | 495 | acpi_bus_scan(handle); |
496 | acpi_bus_get_device(handle, &adev); | 496 | acpi_bus_get_device(handle, &adev); |
497 | if (adev) | 497 | if (acpi_device_enumerated(adev)) |
498 | acpi_device_set_power(adev, ACPI_STATE_D0); | 498 | acpi_device_set_power(adev, ACPI_STATE_D0); |
499 | } | 499 | } |
500 | 500 | ||
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index ecfac7e72d91..8dcccffd6e21 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -31,12 +31,11 @@ | |||
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <acpi/acpi_bus.h> | ||
35 | #include <linux/sysfs.h> | 34 | #include <linux/sysfs.h> |
36 | #include <linux/kobject.h> | 35 | #include <linux/kobject.h> |
37 | #include <asm/uaccess.h> | ||
38 | #include <linux/moduleparam.h> | 36 | #include <linux/moduleparam.h> |
39 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <asm/uaccess.h> | ||
40 | 39 | ||
41 | #include "acpiphp.h" | 40 | #include "acpiphp.h" |
42 | #include "../pci.h" | 41 | #include "../pci.h" |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index ccb0925bcd7b..88b37cad4b35 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -162,8 +162,6 @@ static inline const char *slot_name(struct slot *slot) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | #ifdef CONFIG_ACPI | 164 | #ifdef CONFIG_ACPI |
165 | #include <acpi/acpi.h> | ||
166 | #include <acpi/acpi_bus.h> | ||
167 | #include <linux/pci-acpi.h> | 165 | #include <linux/pci-acpi.h> |
168 | 166 | ||
169 | void __init pciehp_acpi_slot_detection_init(void); | 167 | void __init pciehp_acpi_slot_detection_init(void); |
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c index 2c2930ea06ad..6b2b7dddbbdb 100644 --- a/drivers/pci/ioapic.c +++ b/drivers/pci/ioapic.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/acpi.h> | 21 | #include <linux/acpi.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <acpi/acpi_bus.h> | ||
24 | 23 | ||
25 | struct ioapic { | 24 | struct ioapic { |
26 | acpi_handle handle; | 25 | acpi_handle handle; |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 2bdbc0080204..f49abef88485 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -12,9 +12,6 @@ | |||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/pci-aspm.h> | 14 | #include <linux/pci-aspm.h> |
15 | #include <acpi/acpi.h> | ||
16 | #include <acpi/acpi_bus.h> | ||
17 | |||
18 | #include <linux/pci-acpi.h> | 15 | #include <linux/pci-acpi.h> |
19 | #include <linux/pm_runtime.h> | 16 | #include <linux/pm_runtime.h> |
20 | #include <linux/pm_qos.h> | 17 | #include <linux/pm_qos.h> |
@@ -306,10 +303,10 @@ void acpi_pci_remove_bus(struct pci_bus *bus) | |||
306 | } | 303 | } |
307 | 304 | ||
308 | /* ACPI bus type */ | 305 | /* ACPI bus type */ |
309 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) | 306 | static struct acpi_device *acpi_pci_find_companion(struct device *dev) |
310 | { | 307 | { |
311 | struct pci_dev *pci_dev = to_pci_dev(dev); | 308 | struct pci_dev *pci_dev = to_pci_dev(dev); |
312 | bool is_bridge; | 309 | bool check_children; |
313 | u64 addr; | 310 | u64 addr; |
314 | 311 | ||
315 | /* | 312 | /* |
@@ -317,14 +314,12 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) | |||
317 | * is set only after acpi_pci_find_device() has been called for the | 314 | * is set only after acpi_pci_find_device() has been called for the |
318 | * given device. | 315 | * given device. |
319 | */ | 316 | */ |
320 | is_bridge = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE | 317 | check_children = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE |
321 | || pci_dev->hdr_type == PCI_HEADER_TYPE_CARDBUS; | 318 | || pci_dev->hdr_type == PCI_HEADER_TYPE_CARDBUS; |
322 | /* Please ref to ACPI spec for the syntax of _ADR */ | 319 | /* Please ref to ACPI spec for the syntax of _ADR */ |
323 | addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); | 320 | addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); |
324 | *handle = acpi_find_child(ACPI_HANDLE(dev->parent), addr, is_bridge); | 321 | return acpi_find_child_device(ACPI_COMPANION(dev->parent), addr, |
325 | if (!*handle) | 322 | check_children); |
326 | return -ENODEV; | ||
327 | return 0; | ||
328 | } | 323 | } |
329 | 324 | ||
330 | static void pci_acpi_setup(struct device *dev) | 325 | static void pci_acpi_setup(struct device *dev) |
@@ -367,7 +362,7 @@ static bool pci_acpi_bus_match(struct device *dev) | |||
367 | static struct acpi_bus_type acpi_pci_bus = { | 362 | static struct acpi_bus_type acpi_pci_bus = { |
368 | .name = "PCI", | 363 | .name = "PCI", |
369 | .match = pci_acpi_bus_match, | 364 | .match = pci_acpi_bus_match, |
370 | .find_device = acpi_pci_find_device, | 365 | .find_companion = acpi_pci_find_companion, |
371 | .setup = pci_acpi_setup, | 366 | .setup = pci_acpi_setup, |
372 | .cleanup = pci_acpi_cleanup, | 367 | .cleanup = pci_acpi_cleanup, |
373 | }; | 368 | }; |
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 6f5d343d251c..45113daaa778 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/nls.h> | 29 | #include <linux/nls.h> |
30 | #include <linux/acpi.h> | 30 | #include <linux/acpi.h> |
31 | #include <linux/pci-acpi.h> | 31 | #include <linux/pci-acpi.h> |
32 | #include <acpi/acpi_bus.h> | ||
33 | #include "pci.h" | 32 | #include "pci.h" |
34 | 33 | ||
35 | #define DEVICE_LABEL_DSM 0x07 | 34 | #define DEVICE_LABEL_DSM 0x07 |
@@ -162,7 +161,6 @@ static const char device_label_dsm_uuid[] = { | |||
162 | }; | 161 | }; |
163 | 162 | ||
164 | enum acpi_attr_enum { | 163 | enum acpi_attr_enum { |
165 | ACPI_ATTR_NONE = 0, | ||
166 | ACPI_ATTR_LABEL_SHOW, | 164 | ACPI_ATTR_LABEL_SHOW, |
167 | ACPI_ATTR_INDEX_SHOW, | 165 | ACPI_ATTR_INDEX_SHOW, |
168 | }; | 166 | }; |
@@ -170,84 +168,61 @@ enum acpi_attr_enum { | |||
170 | static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) | 168 | static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) |
171 | { | 169 | { |
172 | int len; | 170 | int len; |
173 | len = utf16s_to_utf8s((const wchar_t *)obj-> | 171 | len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer, |
174 | package.elements[1].string.pointer, | 172 | obj->string.length, |
175 | obj->package.elements[1].string.length, | ||
176 | UTF16_LITTLE_ENDIAN, | 173 | UTF16_LITTLE_ENDIAN, |
177 | buf, PAGE_SIZE); | 174 | buf, PAGE_SIZE); |
178 | buf[len] = '\n'; | 175 | buf[len] = '\n'; |
179 | } | 176 | } |
180 | 177 | ||
181 | static int | 178 | static int |
182 | dsm_get_label(acpi_handle handle, int func, | 179 | dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr) |
183 | struct acpi_buffer *output, | ||
184 | char *buf, enum acpi_attr_enum attribute) | ||
185 | { | 180 | { |
186 | struct acpi_object_list input; | 181 | acpi_handle handle; |
187 | union acpi_object params[4]; | 182 | union acpi_object *obj, *tmp; |
188 | union acpi_object *obj; | 183 | int len = -1; |
189 | int len = 0; | 184 | |
190 | 185 | handle = ACPI_HANDLE(dev); | |
191 | int err; | 186 | if (!handle) |
192 | |||
193 | input.count = 4; | ||
194 | input.pointer = params; | ||
195 | params[0].type = ACPI_TYPE_BUFFER; | ||
196 | params[0].buffer.length = sizeof(device_label_dsm_uuid); | ||
197 | params[0].buffer.pointer = (char *)device_label_dsm_uuid; | ||
198 | params[1].type = ACPI_TYPE_INTEGER; | ||
199 | params[1].integer.value = 0x02; | ||
200 | params[2].type = ACPI_TYPE_INTEGER; | ||
201 | params[2].integer.value = func; | ||
202 | params[3].type = ACPI_TYPE_PACKAGE; | ||
203 | params[3].package.count = 0; | ||
204 | params[3].package.elements = NULL; | ||
205 | |||
206 | err = acpi_evaluate_object(handle, "_DSM", &input, output); | ||
207 | if (err) | ||
208 | return -1; | 187 | return -1; |
209 | 188 | ||
210 | obj = (union acpi_object *)output->pointer; | 189 | obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2, |
211 | 190 | DEVICE_LABEL_DSM, NULL); | |
212 | switch (obj->type) { | 191 | if (!obj) |
213 | case ACPI_TYPE_PACKAGE: | 192 | return -1; |
214 | if (obj->package.count != 2) | 193 | |
215 | break; | 194 | tmp = obj->package.elements; |
216 | len = obj->package.elements[0].integer.value; | 195 | if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 && |
217 | if (buf) { | 196 | tmp[0].type == ACPI_TYPE_INTEGER && |
218 | if (attribute == ACPI_ATTR_INDEX_SHOW) | 197 | tmp[1].type == ACPI_TYPE_STRING) { |
219 | scnprintf(buf, PAGE_SIZE, "%llu\n", | 198 | /* |
220 | obj->package.elements[0].integer.value); | 199 | * The second string element is optional even when |
221 | else if (attribute == ACPI_ATTR_LABEL_SHOW) | 200 | * this _DSM is implemented; when not implemented, |
222 | dsm_label_utf16s_to_utf8s(obj, buf); | 201 | * this entry must return a null string. |
223 | kfree(output->pointer); | 202 | */ |
224 | return strlen(buf); | 203 | if (attr == ACPI_ATTR_INDEX_SHOW) |
225 | } | 204 | scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value); |
226 | kfree(output->pointer); | 205 | else if (attr == ACPI_ATTR_LABEL_SHOW) |
227 | return len; | 206 | dsm_label_utf16s_to_utf8s(tmp + 1, buf); |
228 | break; | 207 | len = strlen(buf) > 0 ? strlen(buf) : -1; |
229 | default: | ||
230 | kfree(output->pointer); | ||
231 | } | 208 | } |
232 | return -1; | 209 | |
210 | ACPI_FREE(obj); | ||
211 | |||
212 | return len; | ||
233 | } | 213 | } |
234 | 214 | ||
235 | static bool | 215 | static bool |
236 | device_has_dsm(struct device *dev) | 216 | device_has_dsm(struct device *dev) |
237 | { | 217 | { |
238 | acpi_handle handle; | 218 | acpi_handle handle; |
239 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
240 | 219 | ||
241 | handle = ACPI_HANDLE(dev); | 220 | handle = ACPI_HANDLE(dev); |
242 | |||
243 | if (!handle) | 221 | if (!handle) |
244 | return FALSE; | 222 | return false; |
245 | 223 | ||
246 | if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL, | 224 | return !!acpi_check_dsm(handle, device_label_dsm_uuid, 0x2, |
247 | ACPI_ATTR_NONE) > 0) | 225 | 1 << DEVICE_LABEL_DSM); |
248 | return TRUE; | ||
249 | |||
250 | return FALSE; | ||
251 | } | 226 | } |
252 | 227 | ||
253 | static umode_t | 228 | static umode_t |
@@ -266,44 +241,13 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n) | |||
266 | static ssize_t | 241 | static ssize_t |
267 | acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf) | 242 | acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf) |
268 | { | 243 | { |
269 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | 244 | return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW); |
270 | acpi_handle handle; | ||
271 | int length; | ||
272 | |||
273 | handle = ACPI_HANDLE(dev); | ||
274 | |||
275 | if (!handle) | ||
276 | return -1; | ||
277 | |||
278 | length = dsm_get_label(handle, DEVICE_LABEL_DSM, | ||
279 | &output, buf, ACPI_ATTR_LABEL_SHOW); | ||
280 | |||
281 | if (length < 1) | ||
282 | return -1; | ||
283 | |||
284 | return length; | ||
285 | } | 245 | } |
286 | 246 | ||
287 | static ssize_t | 247 | static ssize_t |
288 | acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf) | 248 | acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf) |
289 | { | 249 | { |
290 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | 250 | return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW); |
291 | acpi_handle handle; | ||
292 | int length; | ||
293 | |||
294 | handle = ACPI_HANDLE(dev); | ||
295 | |||
296 | if (!handle) | ||
297 | return -1; | ||
298 | |||
299 | length = dsm_get_label(handle, DEVICE_LABEL_DSM, | ||
300 | &output, buf, ACPI_ATTR_INDEX_SHOW); | ||
301 | |||
302 | if (length < 0) | ||
303 | return -1; | ||
304 | |||
305 | return length; | ||
306 | |||
307 | } | 251 | } |
308 | 252 | ||
309 | static struct device_attribute acpi_attr_label = { | 253 | static struct device_attribute acpi_attr_label = { |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index c9076bdaf2c1..c91f69b39db4 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -41,8 +41,6 @@ | |||
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/input.h> | 42 | #include <linux/input.h> |
43 | #include <linux/input/sparse-keymap.h> | 43 | #include <linux/input/sparse-keymap.h> |
44 | |||
45 | #include <acpi/acpi_drivers.h> | ||
46 | #include <acpi/video.h> | 44 | #include <acpi/video.h> |
47 | 45 | ||
48 | MODULE_AUTHOR("Carlos Corbacho"); | 46 | MODULE_AUTHOR("Carlos Corbacho"); |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 594323a926cf..7f4dc6f51f8a 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -53,8 +53,7 @@ | |||
53 | #include <linux/rfkill.h> | 53 | #include <linux/rfkill.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/dmi.h> | 55 | #include <linux/dmi.h> |
56 | #include <acpi/acpi_drivers.h> | 56 | #include <linux/acpi.h> |
57 | #include <acpi/acpi_bus.h> | ||
58 | 57 | ||
59 | #define ASUS_LAPTOP_VERSION "0.42" | 58 | #define ASUS_LAPTOP_VERSION "0.42" |
60 | 59 | ||
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 6fe268f6af91..109f6383040c 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -45,8 +45,7 @@ | |||
45 | #include <linux/seq_file.h> | 45 | #include <linux/seq_file.h> |
46 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
47 | #include <linux/thermal.h> | 47 | #include <linux/thermal.h> |
48 | #include <acpi/acpi_bus.h> | 48 | #include <linux/acpi.h> |
49 | #include <acpi/acpi_drivers.h> | ||
50 | #include <acpi/video.h> | 49 | #include <acpi/video.h> |
51 | 50 | ||
52 | #include "asus-wmi.h" | 51 | #include "asus-wmi.h" |
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 6dfa8d3b4eec..70d355a9ae2c 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
@@ -21,14 +21,13 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <acpi/acpi_drivers.h> | 24 | #include <linux/acpi.h> |
25 | #include <linux/backlight.h> | 25 | #include <linux/backlight.h> |
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/rfkill.h> | 27 | #include <linux/rfkill.h> |
28 | 28 | ||
29 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
30 | 30 | ||
31 | |||
32 | struct cmpc_accel { | 31 | struct cmpc_accel { |
33 | int sensitivity; | 32 | int sensitivity; |
34 | int g_select; | 33 | int g_select; |
diff --git a/drivers/platform/x86/dell-wmi-aio.c b/drivers/platform/x86/dell-wmi-aio.c index bcf8cc6b5537..dbc97a33bbc8 100644 --- a/drivers/platform/x86/dell-wmi-aio.c +++ b/drivers/platform/x86/dell-wmi-aio.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
26 | #include <linux/input/sparse-keymap.h> | 26 | #include <linux/input/sparse-keymap.h> |
27 | #include <acpi/acpi_drivers.h> | ||
28 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
29 | #include <linux/string.h> | 28 | #include <linux/string.h> |
30 | 29 | ||
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 60e0900bc117..390e8e33d5e3 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/input.h> | 33 | #include <linux/input.h> |
34 | #include <linux/input/sparse-keymap.h> | 34 | #include <linux/input/sparse-keymap.h> |
35 | #include <acpi/acpi_drivers.h> | ||
36 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
37 | #include <linux/string.h> | 36 | #include <linux/string.h> |
38 | #include <linux/dmi.h> | 37 | #include <linux/dmi.h> |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 7029cba7025b..ed69ec5f36f7 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -28,8 +28,7 @@ | |||
28 | #include <linux/hwmon.h> | 28 | #include <linux/hwmon.h> |
29 | #include <linux/hwmon-sysfs.h> | 29 | #include <linux/hwmon-sysfs.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <acpi/acpi_drivers.h> | 31 | #include <linux/acpi.h> |
32 | #include <acpi/acpi_bus.h> | ||
33 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
34 | #include <linux/input.h> | 33 | #include <linux/input.h> |
35 | #include <linux/input/sparse-keymap.h> | 34 | #include <linux/input/sparse-keymap.h> |
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index af67e6e56ebb..6112933f6278 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/input/sparse-keymap.h> | 33 | #include <linux/input/sparse-keymap.h> |
34 | #include <linux/dmi.h> | 34 | #include <linux/dmi.h> |
35 | #include <linux/fb.h> | 35 | #include <linux/fb.h> |
36 | #include <acpi/acpi_bus.h> | 36 | #include <linux/acpi.h> |
37 | 37 | ||
38 | #include "asus-wmi.h" | 38 | #include "asus-wmi.h" |
39 | 39 | ||
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index a8e43cf70fac..aff4d0670edf 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/uaccess.h> | 36 | #include <linux/uaccess.h> |
37 | #include <linux/leds.h> | 37 | #include <linux/leds.h> |
38 | #include <linux/atomic.h> | 38 | #include <linux/atomic.h> |
39 | #include <acpi/acpi_drivers.h> | 39 | #include <linux/acpi.h> |
40 | #include "../../misc/lis3lv02d/lis3lv02d.h" | 40 | #include "../../misc/lis3lv02d/lis3lv02d.h" |
41 | 41 | ||
42 | #define DRIVER_NAME "hp_accel" | 42 | #define DRIVER_NAME "hp_accel" |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 19ec95147f69..6dd060a0bb65 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -26,8 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <acpi/acpi_bus.h> | 29 | #include <linux/acpi.h> |
30 | #include <acpi/acpi_drivers.h> | ||
31 | #include <linux/rfkill.h> | 30 | #include <linux/rfkill.h> |
32 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
33 | #include <linux/input.h> | 32 | #include <linux/input.h> |
diff --git a/drivers/platform/x86/intel-rst.c b/drivers/platform/x86/intel-rst.c index a2083a9e5662..d45bca34bf1b 100644 --- a/drivers/platform/x86/intel-rst.c +++ b/drivers/platform/x86/intel-rst.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <acpi/acpi_drivers.h> | 23 | #include <linux/acpi.h> |
24 | 24 | ||
25 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
26 | 26 | ||
diff --git a/drivers/platform/x86/intel-smartconnect.c b/drivers/platform/x86/intel-smartconnect.c index 1838400dc036..04cf5dffdfd9 100644 --- a/drivers/platform/x86/intel-smartconnect.c +++ b/drivers/platform/x86/intel-smartconnect.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <acpi/acpi_drivers.h> | 22 | #include <linux/acpi.h> |
23 | 23 | ||
24 | MODULE_LICENSE("GPL"); | 24 | MODULE_LICENSE("GPL"); |
25 | 25 | ||
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index 11244f8703c4..e8b46d2c468c 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c | |||
@@ -36,10 +36,8 @@ | |||
36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/pm.h> | 38 | #include <linux/pm.h> |
39 | |||
40 | #include <linux/thermal.h> | 39 | #include <linux/thermal.h> |
41 | #include <acpi/acpi_bus.h> | 40 | #include <linux/acpi.h> |
42 | #include <acpi/acpi_drivers.h> | ||
43 | 41 | ||
44 | MODULE_AUTHOR("Thomas Sujith"); | 42 | MODULE_AUTHOR("Thomas Sujith"); |
45 | MODULE_AUTHOR("Zhang Rui"); | 43 | MODULE_AUTHOR("Zhang Rui"); |
diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c index f6f18cde0f11..4bc960416785 100644 --- a/drivers/platform/x86/intel_oaktrail.c +++ b/drivers/platform/x86/intel_oaktrail.c | |||
@@ -50,9 +50,6 @@ | |||
50 | #include <linux/platform_device.h> | 50 | #include <linux/platform_device.h> |
51 | #include <linux/dmi.h> | 51 | #include <linux/dmi.h> |
52 | #include <linux/rfkill.h> | 52 | #include <linux/rfkill.h> |
53 | #include <acpi/acpi_bus.h> | ||
54 | #include <acpi/acpi_drivers.h> | ||
55 | |||
56 | 53 | ||
57 | #define DRIVER_NAME "intel_oaktrail" | 54 | #define DRIVER_NAME "intel_oaktrail" |
58 | #define DRIVER_VERSION "0.4ac1" | 55 | #define DRIVER_VERSION "0.4ac1" |
diff --git a/drivers/platform/x86/mxm-wmi.c b/drivers/platform/x86/mxm-wmi.c index 0aea63b3729a..3c59c0a3ee0f 100644 --- a/drivers/platform/x86/mxm-wmi.c +++ b/drivers/platform/x86/mxm-wmi.c | |||
@@ -20,8 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <acpi/acpi_bus.h> | 23 | #include <linux/acpi.h> |
24 | #include <acpi/acpi_drivers.h> | ||
25 | 24 | ||
26 | MODULE_AUTHOR("Dave Airlie"); | 25 | MODULE_AUTHOR("Dave Airlie"); |
27 | MODULE_DESCRIPTION("MXM WMI Driver"); | 26 | MODULE_DESCRIPTION("MXM WMI Driver"); |
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 3008fd20572e..609d38779b26 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
@@ -125,12 +125,10 @@ | |||
125 | #include <linux/seq_file.h> | 125 | #include <linux/seq_file.h> |
126 | #include <linux/uaccess.h> | 126 | #include <linux/uaccess.h> |
127 | #include <linux/slab.h> | 127 | #include <linux/slab.h> |
128 | #include <acpi/acpi_bus.h> | 128 | #include <linux/acpi.h> |
129 | #include <acpi/acpi_drivers.h> | ||
130 | #include <linux/input.h> | 129 | #include <linux/input.h> |
131 | #include <linux/input/sparse-keymap.h> | 130 | #include <linux/input/sparse-keymap.h> |
132 | 131 | ||
133 | |||
134 | #ifndef ACPI_HOTKEY_COMPONENT | 132 | #ifndef ACPI_HOTKEY_COMPONENT |
135 | #define ACPI_HOTKEY_COMPONENT 0x10000000 | 133 | #define ACPI_HOTKEY_COMPONENT 0x10000000 |
136 | #endif | 134 | #endif |
diff --git a/drivers/platform/x86/pvpanic.c b/drivers/platform/x86/pvpanic.c index 47ae0c47d4b5..c9f6e511daa6 100644 --- a/drivers/platform/x86/pvpanic.c +++ b/drivers/platform/x86/pvpanic.c | |||
@@ -24,8 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <acpi/acpi_bus.h> | 27 | #include <linux/acpi.h> |
28 | #include <acpi/acpi_drivers.h> | ||
29 | 28 | ||
30 | MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>"); | 29 | MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>"); |
31 | MODULE_DESCRIPTION("pvpanic device driver"); | 30 | MODULE_DESCRIPTION("pvpanic device driver"); |
diff --git a/drivers/platform/x86/samsung-q10.c b/drivers/platform/x86/samsung-q10.c index cae7098e9b0d..5413f62d2e61 100644 --- a/drivers/platform/x86/samsung-q10.c +++ b/drivers/platform/x86/samsung-q10.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/backlight.h> | 16 | #include <linux/backlight.h> |
17 | #include <linux/dmi.h> | 17 | #include <linux/dmi.h> |
18 | #include <acpi/acpi_drivers.h> | 18 | #include <linux/acpi.h> |
19 | 19 | ||
20 | #define SAMSUNGQ10_BL_MAX_INTENSITY 7 | 20 | #define SAMSUNGQ10_BL_MAX_INTENSITY 7 |
21 | 21 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index fb233ae7bb0e..563e4f595f83 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -61,9 +61,6 @@ | |||
61 | #include <linux/workqueue.h> | 61 | #include <linux/workqueue.h> |
62 | #include <linux/acpi.h> | 62 | #include <linux/acpi.h> |
63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
64 | #include <acpi/acpi_drivers.h> | ||
65 | #include <acpi/acpi_bus.h> | ||
66 | #include <asm/uaccess.h> | ||
67 | #include <linux/sonypi.h> | 64 | #include <linux/sonypi.h> |
68 | #include <linux/sony-laptop.h> | 65 | #include <linux/sony-laptop.h> |
69 | #include <linux/rfkill.h> | 66 | #include <linux/rfkill.h> |
@@ -71,6 +68,7 @@ | |||
71 | #include <linux/poll.h> | 68 | #include <linux/poll.h> |
72 | #include <linux/miscdevice.h> | 69 | #include <linux/miscdevice.h> |
73 | #endif | 70 | #endif |
71 | #include <asm/uaccess.h> | ||
74 | 72 | ||
75 | #define dprintk(fmt, ...) \ | 73 | #define dprintk(fmt, ...) \ |
76 | do { \ | 74 | do { \ |
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 9b93fdb61ed7..6a6ea28a7e51 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c | |||
@@ -32,9 +32,7 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
35 | #include <acpi/acpi.h> | 35 | #include <linux/acpi.h> |
36 | #include <acpi/acpi_bus.h> | ||
37 | #include <acpi/acpi_drivers.h> | ||
38 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
39 | 37 | ||
40 | #define GUID "C364AC71-36DB-495A-8494-B439D472A505" | 38 | #define GUID "C364AC71-36DB-495A-8494-B439D472A505" |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 58b0274d24cc..defb6afc1409 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -61,7 +61,6 @@ | |||
61 | #include <linux/freezer.h> | 61 | #include <linux/freezer.h> |
62 | #include <linux/delay.h> | 62 | #include <linux/delay.h> |
63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
64 | |||
65 | #include <linux/nvram.h> | 64 | #include <linux/nvram.h> |
66 | #include <linux/proc_fs.h> | 65 | #include <linux/proc_fs.h> |
67 | #include <linux/seq_file.h> | 66 | #include <linux/seq_file.h> |
@@ -74,21 +73,16 @@ | |||
74 | #include <linux/input.h> | 73 | #include <linux/input.h> |
75 | #include <linux/leds.h> | 74 | #include <linux/leds.h> |
76 | #include <linux/rfkill.h> | 75 | #include <linux/rfkill.h> |
77 | #include <asm/uaccess.h> | ||
78 | |||
79 | #include <linux/dmi.h> | 76 | #include <linux/dmi.h> |
80 | #include <linux/jiffies.h> | 77 | #include <linux/jiffies.h> |
81 | #include <linux/workqueue.h> | 78 | #include <linux/workqueue.h> |
82 | 79 | #include <linux/acpi.h> | |
80 | #include <linux/pci_ids.h> | ||
81 | #include <linux/thinkpad_acpi.h> | ||
83 | #include <sound/core.h> | 82 | #include <sound/core.h> |
84 | #include <sound/control.h> | 83 | #include <sound/control.h> |
85 | #include <sound/initval.h> | 84 | #include <sound/initval.h> |
86 | 85 | #include <asm/uaccess.h> | |
87 | #include <acpi/acpi_drivers.h> | ||
88 | |||
89 | #include <linux/pci_ids.h> | ||
90 | |||
91 | #include <linux/thinkpad_acpi.h> | ||
92 | 86 | ||
93 | /* ThinkPad CMOS commands */ | 87 | /* ThinkPad CMOS commands */ |
94 | #define TP_CMOS_VOLUME_DOWN 0 | 88 | #define TP_CMOS_VOLUME_DOWN 0 |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 7fce391818d3..7ad1ed091f92 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -54,11 +54,9 @@ | |||
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/workqueue.h> | 55 | #include <linux/workqueue.h> |
56 | #include <linux/i8042.h> | 56 | #include <linux/i8042.h> |
57 | 57 | #include <linux/acpi.h> | |
58 | #include <asm/uaccess.h> | 58 | #include <asm/uaccess.h> |
59 | 59 | ||
60 | #include <acpi/acpi_drivers.h> | ||
61 | |||
62 | MODULE_AUTHOR("John Belmonte"); | 60 | MODULE_AUTHOR("John Belmonte"); |
63 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); | 61 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); |
64 | MODULE_LICENSE("GPL"); | 62 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index 74dd01ae343b..2cb1ea62b4a7 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c | |||
@@ -23,14 +23,12 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | #include <acpi/acpi_bus.h> | 26 | #include <linux/acpi.h> |
27 | #include <acpi/acpi_drivers.h> | ||
28 | 27 | ||
29 | MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>"); | 28 | MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>"); |
30 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver"); | 29 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver"); |
31 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
32 | 31 | ||
33 | |||
34 | static int toshiba_bt_rfkill_add(struct acpi_device *device); | 32 | static int toshiba_bt_rfkill_add(struct acpi_device *device); |
35 | static int toshiba_bt_rfkill_remove(struct acpi_device *device); | 33 | static int toshiba_bt_rfkill_remove(struct acpi_device *device); |
36 | static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); | 34 | static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); |
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index c2e7b2657aeb..43d13295e63d 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include <linux/acpi.h> | 37 | #include <linux/acpi.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <acpi/acpi_bus.h> | ||
41 | #include <acpi/acpi_drivers.h> | ||
42 | 40 | ||
43 | ACPI_MODULE_NAME("wmi"); | 41 | ACPI_MODULE_NAME("wmi"); |
44 | MODULE_AUTHOR("Carlos Corbacho"); | 42 | MODULE_AUTHOR("Carlos Corbacho"); |
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index 4b1377bd5944..49cbccec6e2d 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c | |||
@@ -18,8 +18,7 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <acpi/acpi_bus.h> | 21 | #include <linux/acpi.h> |
22 | #include <acpi/acpi_drivers.h> | ||
23 | 22 | ||
24 | #define MODULE_NAME "xo15-ebook" | 23 | #define MODULE_NAME "xo15-ebook" |
25 | 24 | ||
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index bc00693d0c79..874c236ac1a7 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c | |||
@@ -239,6 +239,7 @@ int pnp_add_card(struct pnp_card *card) | |||
239 | error = device_register(&card->dev); | 239 | error = device_register(&card->dev); |
240 | if (error) { | 240 | if (error) { |
241 | dev_err(&card->dev, "could not register (err=%d)\n", error); | 241 | dev_err(&card->dev, "could not register (err=%d)\n", error); |
242 | put_device(&card->dev); | ||
242 | return error; | 243 | return error; |
243 | } | 244 | } |
244 | 245 | ||
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 14655a0f0431..9f611cbbc294 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/pnp.h> | 24 | #include <linux/pnp.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/mod_devicetable.h> | 26 | #include <linux/mod_devicetable.h> |
27 | #include <acpi/acpi_bus.h> | ||
28 | 27 | ||
29 | #include "../base.h" | 28 | #include "../base.h" |
30 | #include "pnpacpi.h" | 29 | #include "pnpacpi.h" |
@@ -242,6 +241,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
242 | struct pnp_dev *dev; | 241 | struct pnp_dev *dev; |
243 | char *pnpid; | 242 | char *pnpid; |
244 | struct acpi_hardware_id *id; | 243 | struct acpi_hardware_id *id; |
244 | int error; | ||
245 | 245 | ||
246 | /* Skip devices that are already bound */ | 246 | /* Skip devices that are already bound */ |
247 | if (device->physical_node_count) | 247 | if (device->physical_node_count) |
@@ -300,10 +300,16 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
300 | /* clear out the damaged flags */ | 300 | /* clear out the damaged flags */ |
301 | if (!dev->active) | 301 | if (!dev->active) |
302 | pnp_init_resources(dev); | 302 | pnp_init_resources(dev); |
303 | pnp_add_device(dev); | 303 | |
304 | error = pnp_add_device(dev); | ||
305 | if (error) { | ||
306 | put_device(&dev->dev); | ||
307 | return error; | ||
308 | } | ||
309 | |||
304 | num++; | 310 | num++; |
305 | 311 | ||
306 | return AE_OK; | 312 | return 0; |
307 | } | 313 | } |
308 | 314 | ||
309 | static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, | 315 | static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, |
@@ -329,20 +335,15 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp) | |||
329 | && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); | 335 | && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); |
330 | } | 336 | } |
331 | 337 | ||
332 | static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle) | 338 | static struct acpi_device * __init acpi_pnp_find_companion(struct device *dev) |
333 | { | 339 | { |
334 | struct device *adev; | 340 | dev = bus_find_device(&acpi_bus_type, NULL, to_pnp_dev(dev), |
335 | struct acpi_device *acpi; | 341 | acpi_pnp_match); |
336 | 342 | if (!dev) | |
337 | adev = bus_find_device(&acpi_bus_type, NULL, | 343 | return NULL; |
338 | to_pnp_dev(dev), acpi_pnp_match); | ||
339 | if (!adev) | ||
340 | return -ENODEV; | ||
341 | 344 | ||
342 | acpi = to_acpi_device(adev); | 345 | put_device(dev); |
343 | *handle = acpi->handle; | 346 | return to_acpi_device(dev); |
344 | put_device(adev); | ||
345 | return 0; | ||
346 | } | 347 | } |
347 | 348 | ||
348 | /* complete initialization of a PNPACPI device includes having | 349 | /* complete initialization of a PNPACPI device includes having |
@@ -356,7 +357,7 @@ static bool acpi_pnp_bus_match(struct device *dev) | |||
356 | static struct acpi_bus_type __initdata acpi_pnp_bus = { | 357 | static struct acpi_bus_type __initdata acpi_pnp_bus = { |
357 | .name = "PNP", | 358 | .name = "PNP", |
358 | .match = acpi_pnp_bus_match, | 359 | .match = acpi_pnp_bus_match, |
359 | .find_device = acpi_pnp_find_device, | 360 | .find_companion = acpi_pnp_find_companion, |
360 | }; | 361 | }; |
361 | 362 | ||
362 | int pnpacpi_disabled __initdata; | 363 | int pnpacpi_disabled __initdata; |
diff --git a/drivers/pnp/pnpacpi/pnpacpi.h b/drivers/pnp/pnpacpi/pnpacpi.h index 3e60225b0227..051ef9699777 100644 --- a/drivers/pnp/pnpacpi/pnpacpi.h +++ b/drivers/pnp/pnpacpi/pnpacpi.h | |||
@@ -1,7 +1,6 @@ | |||
1 | #ifndef ACPI_PNP_H | 1 | #ifndef ACPI_PNP_H |
2 | #define ACPI_PNP_H | 2 | #define ACPI_PNP_H |
3 | 3 | ||
4 | #include <acpi/acpi_bus.h> | ||
5 | #include <linux/acpi.h> | 4 | #include <linux/acpi.h> |
6 | #include <linux/pnp.h> | 5 | #include <linux/pnp.h> |
7 | 6 | ||
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 9b86a01af631..074569e77d22 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -312,18 +312,19 @@ static int __init insert_device(struct pnp_bios_node *node) | |||
312 | struct list_head *pos; | 312 | struct list_head *pos; |
313 | struct pnp_dev *dev; | 313 | struct pnp_dev *dev; |
314 | char id[8]; | 314 | char id[8]; |
315 | int error; | ||
315 | 316 | ||
316 | /* check if the device is already added */ | 317 | /* check if the device is already added */ |
317 | list_for_each(pos, &pnpbios_protocol.devices) { | 318 | list_for_each(pos, &pnpbios_protocol.devices) { |
318 | dev = list_entry(pos, struct pnp_dev, protocol_list); | 319 | dev = list_entry(pos, struct pnp_dev, protocol_list); |
319 | if (dev->number == node->handle) | 320 | if (dev->number == node->handle) |
320 | return -1; | 321 | return -EEXIST; |
321 | } | 322 | } |
322 | 323 | ||
323 | pnp_eisa_id_to_string(node->eisa_id & PNP_EISA_ID_MASK, id); | 324 | pnp_eisa_id_to_string(node->eisa_id & PNP_EISA_ID_MASK, id); |
324 | dev = pnp_alloc_dev(&pnpbios_protocol, node->handle, id); | 325 | dev = pnp_alloc_dev(&pnpbios_protocol, node->handle, id); |
325 | if (!dev) | 326 | if (!dev) |
326 | return -1; | 327 | return -ENOMEM; |
327 | 328 | ||
328 | pnpbios_parse_data_stream(dev, node); | 329 | pnpbios_parse_data_stream(dev, node); |
329 | dev->active = pnp_is_active(dev); | 330 | dev->active = pnp_is_active(dev); |
@@ -342,7 +343,12 @@ static int __init insert_device(struct pnp_bios_node *node) | |||
342 | if (!dev->active) | 343 | if (!dev->active) |
343 | pnp_init_resources(dev); | 344 | pnp_init_resources(dev); |
344 | 345 | ||
345 | pnp_add_device(dev); | 346 | error = pnp_add_device(dev); |
347 | if (error) { | ||
348 | put_device(&dev->dev); | ||
349 | return error; | ||
350 | } | ||
351 | |||
346 | pnpbios_interface_attach_device(node); | 352 | pnpbios_interface_attach_device(node); |
347 | 353 | ||
348 | return 0; | 354 | return 0; |
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index d95e101ffb43..bacddd102ae9 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
@@ -31,7 +31,7 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some | |||
31 | * option registration | 31 | * option registration |
32 | */ | 32 | */ |
33 | 33 | ||
34 | struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type, | 34 | static struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type, |
35 | unsigned int option_flags) | 35 | unsigned int option_flags) |
36 | { | 36 | { |
37 | struct pnp_option *option; | 37 | struct pnp_option *option; |
diff --git a/drivers/sfi/sfi_acpi.c b/drivers/sfi/sfi_acpi.c index f5b4ca581541..d277b36eb389 100644 --- a/drivers/sfi/sfi_acpi.c +++ b/drivers/sfi/sfi_acpi.c | |||
@@ -60,9 +60,7 @@ | |||
60 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 60 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
61 | 61 | ||
62 | #include <linux/kernel.h> | 62 | #include <linux/kernel.h> |
63 | #include <acpi/acpi.h> | 63 | #include <linux/sfi_acpi.h> |
64 | |||
65 | #include <linux/sfi.h> | ||
66 | #include "sfi_core.h" | 64 | #include "sfi_core.h" |
67 | 65 | ||
68 | /* | 66 | /* |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 349ebba4b199..827ff49d3d4f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -58,6 +58,11 @@ static ssize_t | |||
58 | modalias_show(struct device *dev, struct device_attribute *a, char *buf) | 58 | modalias_show(struct device *dev, struct device_attribute *a, char *buf) |
59 | { | 59 | { |
60 | const struct spi_device *spi = to_spi_device(dev); | 60 | const struct spi_device *spi = to_spi_device(dev); |
61 | int len; | ||
62 | |||
63 | len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1); | ||
64 | if (len != -ENODEV) | ||
65 | return len; | ||
61 | 66 | ||
62 | return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias); | 67 | return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias); |
63 | } | 68 | } |
@@ -114,6 +119,11 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) | |||
114 | static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) | 119 | static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) |
115 | { | 120 | { |
116 | const struct spi_device *spi = to_spi_device(dev); | 121 | const struct spi_device *spi = to_spi_device(dev); |
122 | int rc; | ||
123 | |||
124 | rc = acpi_device_uevent_modalias(dev, env); | ||
125 | if (rc != -ENODEV) | ||
126 | return rc; | ||
117 | 127 | ||
118 | add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias); | 128 | add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias); |
119 | return 0; | 129 | return 0; |
diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 9f6ebdb23740..a85c3d68c462 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/types.h> | 33 | #include <linux/types.h> |
34 | #include <acpi/acpi_drivers.h> | 34 | #include <linux/acpi.h> |
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/input.h> | 36 | #include <linux/input.h> |
37 | 37 | ||
diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 073c292baa53..476b768c633e 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c | |||
@@ -131,8 +131,8 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { | |||
131 | 131 | ||
132 | #define EXYNOS4412_TMU_DATA \ | 132 | #define EXYNOS4412_TMU_DATA \ |
133 | .threshold_falling = 10, \ | 133 | .threshold_falling = 10, \ |
134 | .trigger_levels[0] = 85, \ | 134 | .trigger_levels[0] = 70, \ |
135 | .trigger_levels[1] = 103, \ | 135 | .trigger_levels[1] = 95, \ |
136 | .trigger_levels[2] = 110, \ | 136 | .trigger_levels[2] = 110, \ |
137 | .trigger_levels[3] = 120, \ | 137 | .trigger_levels[3] = 120, \ |
138 | .trigger_enable[0] = true, \ | 138 | .trigger_enable[0] = true, \ |
@@ -155,12 +155,12 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { | |||
155 | .second_point_trim = 85, \ | 155 | .second_point_trim = 85, \ |
156 | .default_temp_offset = 50, \ | 156 | .default_temp_offset = 50, \ |
157 | .freq_tab[0] = { \ | 157 | .freq_tab[0] = { \ |
158 | .freq_clip_max = 800 * 1000, \ | 158 | .freq_clip_max = 1400 * 1000, \ |
159 | .temp_level = 85, \ | 159 | .temp_level = 70, \ |
160 | }, \ | 160 | }, \ |
161 | .freq_tab[1] = { \ | 161 | .freq_tab[1] = { \ |
162 | .freq_clip_max = 200 * 1000, \ | 162 | .freq_clip_max = 400 * 1000, \ |
163 | .temp_level = 103, \ | 163 | .temp_level = 95, \ |
164 | }, \ | 164 | }, \ |
165 | .freq_tab_count = 2, \ | 165 | .freq_tab_count = 2, \ |
166 | .registers = &exynos4412_tmu_registers, \ | 166 | .registers = &exynos4412_tmu_registers, \ |
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index d7cb822d6eab..5ca4070b1f38 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/usb/hcd.h> | 18 | #include <linux/usb/hcd.h> |
19 | #include <acpi/acpi_bus.h> | ||
20 | 19 | ||
21 | #include "usb.h" | 20 | #include "usb.h" |
22 | 21 | ||
@@ -127,7 +126,7 @@ out: | |||
127 | return ret; | 126 | return ret; |
128 | } | 127 | } |
129 | 128 | ||
130 | static int usb_acpi_find_device(struct device *dev, acpi_handle *handle) | 129 | static struct acpi_device *usb_acpi_find_companion(struct device *dev) |
131 | { | 130 | { |
132 | struct usb_device *udev; | 131 | struct usb_device *udev; |
133 | acpi_handle *parent_handle; | 132 | acpi_handle *parent_handle; |
@@ -169,16 +168,15 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle) | |||
169 | break; | 168 | break; |
170 | } | 169 | } |
171 | 170 | ||
172 | return -ENODEV; | 171 | return NULL; |
173 | } | 172 | } |
174 | 173 | ||
175 | /* root hub's parent is the usb hcd. */ | 174 | /* root hub's parent is the usb hcd. */ |
176 | parent_handle = ACPI_HANDLE(dev->parent); | 175 | return acpi_find_child_device(ACPI_COMPANION(dev->parent), |
177 | *handle = acpi_get_child(parent_handle, udev->portnum); | 176 | udev->portnum, false); |
178 | if (!*handle) | ||
179 | return -ENODEV; | ||
180 | return 0; | ||
181 | } else if (is_usb_port(dev)) { | 177 | } else if (is_usb_port(dev)) { |
178 | struct acpi_device *adev = NULL; | ||
179 | |||
182 | sscanf(dev_name(dev), "port%d", &port_num); | 180 | sscanf(dev_name(dev), "port%d", &port_num); |
183 | /* Get the struct usb_device point of port's hub */ | 181 | /* Get the struct usb_device point of port's hub */ |
184 | udev = to_usb_device(dev->parent->parent); | 182 | udev = to_usb_device(dev->parent->parent); |
@@ -194,26 +192,27 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle) | |||
194 | 192 | ||
195 | raw_port_num = usb_hcd_find_raw_port_number(hcd, | 193 | raw_port_num = usb_hcd_find_raw_port_number(hcd, |
196 | port_num); | 194 | port_num); |
197 | *handle = acpi_get_child(ACPI_HANDLE(&udev->dev), | 195 | adev = acpi_find_child_device(ACPI_COMPANION(&udev->dev), |
198 | raw_port_num); | 196 | raw_port_num, false); |
199 | if (!*handle) | 197 | if (!adev) |
200 | return -ENODEV; | 198 | return NULL; |
201 | } else { | 199 | } else { |
202 | parent_handle = | 200 | parent_handle = |
203 | usb_get_hub_port_acpi_handle(udev->parent, | 201 | usb_get_hub_port_acpi_handle(udev->parent, |
204 | udev->portnum); | 202 | udev->portnum); |
205 | if (!parent_handle) | 203 | if (!parent_handle) |
206 | return -ENODEV; | 204 | return NULL; |
207 | 205 | ||
208 | *handle = acpi_get_child(parent_handle, port_num); | 206 | acpi_bus_get_device(parent_handle, &adev); |
209 | if (!*handle) | 207 | adev = acpi_find_child_device(adev, port_num, false); |
210 | return -ENODEV; | 208 | if (!adev) |
209 | return NULL; | ||
211 | } | 210 | } |
212 | usb_acpi_check_port_connect_type(udev, *handle, port_num); | 211 | usb_acpi_check_port_connect_type(udev, adev->handle, port_num); |
213 | } else | 212 | return adev; |
214 | return -ENODEV; | 213 | } |
215 | 214 | ||
216 | return 0; | 215 | return NULL; |
217 | } | 216 | } |
218 | 217 | ||
219 | static bool usb_acpi_bus_match(struct device *dev) | 218 | static bool usb_acpi_bus_match(struct device *dev) |
@@ -224,7 +223,7 @@ static bool usb_acpi_bus_match(struct device *dev) | |||
224 | static struct acpi_bus_type usb_acpi_bus = { | 223 | static struct acpi_bus_type usb_acpi_bus = { |
225 | .name = "USB", | 224 | .name = "USB", |
226 | .match = usb_acpi_bus_match, | 225 | .match = usb_acpi_bus_match, |
227 | .find_device = usb_acpi_find_device, | 226 | .find_companion = usb_acpi_find_companion, |
228 | }; | 227 | }; |
229 | 228 | ||
230 | int usb_acpi_register(void) | 229 | int usb_acpi_register(void) |
diff --git a/drivers/xen/xen-acpi-cpuhotplug.c b/drivers/xen/xen-acpi-cpuhotplug.c index 8dae6c13063a..80875fb770ed 100644 --- a/drivers/xen/xen-acpi-cpuhotplug.c +++ b/drivers/xen/xen-acpi-cpuhotplug.c | |||
@@ -24,10 +24,7 @@ | |||
24 | #include <linux/cpu.h> | 24 | #include <linux/cpu.h> |
25 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
27 | #include <acpi/acpi_bus.h> | ||
28 | #include <acpi/acpi_drivers.h> | ||
29 | #include <acpi/processor.h> | 27 | #include <acpi/processor.h> |
30 | |||
31 | #include <xen/acpi.h> | 28 | #include <xen/acpi.h> |
32 | #include <xen/interface/platform.h> | 29 | #include <xen/interface/platform.h> |
33 | #include <asm/xen/hypercall.h> | 30 | #include <asm/xen/hypercall.h> |
@@ -269,7 +266,8 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, | |||
269 | if (!is_processor_present(handle)) | 266 | if (!is_processor_present(handle)) |
270 | break; | 267 | break; |
271 | 268 | ||
272 | if (!acpi_bus_get_device(handle, &device)) | 269 | acpi_bus_get_device(handle, &device); |
270 | if (acpi_device_enumerated(device)) | ||
273 | break; | 271 | break; |
274 | 272 | ||
275 | result = acpi_bus_scan(handle); | 273 | result = acpi_bus_scan(handle); |
@@ -277,8 +275,9 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, | |||
277 | pr_err(PREFIX "Unable to add the device\n"); | 275 | pr_err(PREFIX "Unable to add the device\n"); |
278 | break; | 276 | break; |
279 | } | 277 | } |
280 | result = acpi_bus_get_device(handle, &device); | 278 | device = NULL; |
281 | if (result) { | 279 | acpi_bus_get_device(handle, &device); |
280 | if (!acpi_device_enumerated(device)) { | ||
282 | pr_err(PREFIX "Missing device object\n"); | 281 | pr_err(PREFIX "Missing device object\n"); |
283 | break; | 282 | break; |
284 | } | 283 | } |
diff --git a/drivers/xen/xen-acpi-memhotplug.c b/drivers/xen/xen-acpi-memhotplug.c index 9083f1e474f8..f8d18626969a 100644 --- a/drivers/xen/xen-acpi-memhotplug.c +++ b/drivers/xen/xen-acpi-memhotplug.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/acpi.h> | 24 | #include <linux/acpi.h> |
25 | #include <acpi/acpi_drivers.h> | ||
26 | #include <xen/acpi.h> | 25 | #include <xen/acpi.h> |
27 | #include <xen/interface/platform.h> | 26 | #include <xen/interface/platform.h> |
28 | #include <asm/xen/hypercall.h> | 27 | #include <asm/xen/hypercall.h> |
@@ -169,7 +168,7 @@ static int acpi_memory_get_device(acpi_handle handle, | |||
169 | acpi_scan_lock_acquire(); | 168 | acpi_scan_lock_acquire(); |
170 | 169 | ||
171 | acpi_bus_get_device(handle, &device); | 170 | acpi_bus_get_device(handle, &device); |
172 | if (device) | 171 | if (acpi_device_enumerated(device)) |
173 | goto end; | 172 | goto end; |
174 | 173 | ||
175 | /* | 174 | /* |
@@ -182,8 +181,9 @@ static int acpi_memory_get_device(acpi_handle handle, | |||
182 | result = -EINVAL; | 181 | result = -EINVAL; |
183 | goto out; | 182 | goto out; |
184 | } | 183 | } |
185 | result = acpi_bus_get_device(handle, &device); | 184 | device = NULL; |
186 | if (result) { | 185 | acpi_bus_get_device(handle, &device); |
186 | if (!acpi_device_enumerated(device)) { | ||
187 | pr_warn(PREFIX "Missing device object\n"); | 187 | pr_warn(PREFIX "Missing device object\n"); |
188 | result = -EINVAL; | 188 | result = -EINVAL; |
189 | goto out; | 189 | goto out; |
diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c index 59708fdd068b..40c4bc06b5fa 100644 --- a/drivers/xen/xen-acpi-pad.c +++ b/drivers/xen/xen-acpi-pad.c | |||
@@ -18,11 +18,10 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <acpi/acpi_bus.h> | 21 | #include <linux/acpi.h> |
22 | #include <acpi/acpi_drivers.h> | ||
23 | #include <asm/xen/hypercall.h> | ||
24 | #include <xen/interface/version.h> | 22 | #include <xen/interface/version.h> |
25 | #include <xen/xen-ops.h> | 23 | #include <xen/xen-ops.h> |
24 | #include <asm/xen/hypercall.h> | ||
26 | 25 | ||
27 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" | 26 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" |
28 | #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" | 27 | #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" |
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 13bc6c31c060..7231859119f1 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c | |||
@@ -28,10 +28,8 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/syscore_ops.h> | 30 | #include <linux/syscore_ops.h> |
31 | #include <acpi/acpi_bus.h> | 31 | #include <linux/acpi.h> |
32 | #include <acpi/acpi_drivers.h> | ||
33 | #include <acpi/processor.h> | 32 | #include <acpi/processor.h> |
34 | |||
35 | #include <xen/xen.h> | 33 | #include <xen/xen.h> |
36 | #include <xen/interface/platform.h> | 34 | #include <xen/interface/platform.h> |
37 | #include <asm/xen/hypercall.h> | 35 | #include <asm/xen/hypercall.h> |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index ddabed1f51c2..8256eb4ad057 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -28,8 +28,6 @@ | |||
28 | 28 | ||
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | 30 | ||
31 | #include <acpi/acpi.h> | ||
32 | |||
33 | /* TBD: Make dynamic */ | 31 | /* TBD: Make dynamic */ |
34 | #define ACPI_MAX_HANDLES 10 | 32 | #define ACPI_MAX_HANDLES 10 |
35 | struct acpi_handle_list { | 33 | struct acpi_handle_list { |
@@ -66,6 +64,32 @@ bool acpi_ata_match(acpi_handle handle); | |||
66 | bool acpi_bay_match(acpi_handle handle); | 64 | bool acpi_bay_match(acpi_handle handle); |
67 | bool acpi_dock_match(acpi_handle handle); | 65 | bool acpi_dock_match(acpi_handle handle); |
68 | 66 | ||
67 | bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs); | ||
68 | union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, | ||
69 | int rev, int func, union acpi_object *argv4); | ||
70 | |||
71 | static inline union acpi_object * | ||
72 | acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, int rev, int func, | ||
73 | union acpi_object *argv4, acpi_object_type type) | ||
74 | { | ||
75 | union acpi_object *obj; | ||
76 | |||
77 | obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4); | ||
78 | if (obj && obj->type != type) { | ||
79 | ACPI_FREE(obj); | ||
80 | obj = NULL; | ||
81 | } | ||
82 | |||
83 | return obj; | ||
84 | } | ||
85 | |||
86 | #define ACPI_INIT_DSM_ARGV4(cnt, eles) \ | ||
87 | { \ | ||
88 | .package.type = ACPI_TYPE_PACKAGE, \ | ||
89 | .package.count = (cnt), \ | ||
90 | .package.elements = (eles) \ | ||
91 | } | ||
92 | |||
69 | #ifdef CONFIG_ACPI | 93 | #ifdef CONFIG_ACPI |
70 | 94 | ||
71 | #include <linux/proc_fs.h> | 95 | #include <linux/proc_fs.h> |
@@ -91,17 +115,11 @@ struct acpi_device; | |||
91 | * ----------------- | 115 | * ----------------- |
92 | */ | 116 | */ |
93 | 117 | ||
94 | enum acpi_hotplug_mode { | ||
95 | AHM_GENERIC = 0, | ||
96 | AHM_CONTAINER, | ||
97 | AHM_COUNT | ||
98 | }; | ||
99 | |||
100 | struct acpi_hotplug_profile { | 118 | struct acpi_hotplug_profile { |
101 | struct kobject kobj; | 119 | struct kobject kobj; |
120 | int (*scan_dependent)(struct acpi_device *adev); | ||
102 | bool enabled:1; | 121 | bool enabled:1; |
103 | bool ignore:1; | 122 | bool demand_offline:1; |
104 | enum acpi_hotplug_mode mode; | ||
105 | }; | 123 | }; |
106 | 124 | ||
107 | static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile( | 125 | static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile( |
@@ -169,8 +187,10 @@ struct acpi_device_flags { | |||
169 | u32 ejectable:1; | 187 | u32 ejectable:1; |
170 | u32 power_manageable:1; | 188 | u32 power_manageable:1; |
171 | u32 match_driver:1; | 189 | u32 match_driver:1; |
190 | u32 initialized:1; | ||
191 | u32 visited:1; | ||
172 | u32 no_hotplug:1; | 192 | u32 no_hotplug:1; |
173 | u32 reserved:26; | 193 | u32 reserved:24; |
174 | }; | 194 | }; |
175 | 195 | ||
176 | /* File System */ | 196 | /* File System */ |
@@ -300,6 +320,7 @@ struct acpi_device { | |||
300 | struct list_head children; | 320 | struct list_head children; |
301 | struct list_head node; | 321 | struct list_head node; |
302 | struct list_head wakeup_list; | 322 | struct list_head wakeup_list; |
323 | struct list_head del_list; | ||
303 | struct acpi_device_status status; | 324 | struct acpi_device_status status; |
304 | struct acpi_device_flags flags; | 325 | struct acpi_device_flags flags; |
305 | struct acpi_device_pnp pnp; | 326 | struct acpi_device_pnp pnp; |
@@ -325,6 +346,11 @@ static inline void *acpi_driver_data(struct acpi_device *d) | |||
325 | #define to_acpi_device(d) container_of(d, struct acpi_device, dev) | 346 | #define to_acpi_device(d) container_of(d, struct acpi_device, dev) |
326 | #define to_acpi_driver(d) container_of(d, struct acpi_driver, drv) | 347 | #define to_acpi_driver(d) container_of(d, struct acpi_driver, drv) |
327 | 348 | ||
349 | static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta) | ||
350 | { | ||
351 | *((u32 *)&adev->status) = sta; | ||
352 | } | ||
353 | |||
328 | /* acpi_device.dev.bus == &acpi_bus_type */ | 354 | /* acpi_device.dev.bus == &acpi_bus_type */ |
329 | extern struct bus_type acpi_bus_type; | 355 | extern struct bus_type acpi_bus_type; |
330 | 356 | ||
@@ -387,6 +413,11 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
387 | int acpi_create_dir(struct acpi_device *); | 413 | int acpi_create_dir(struct acpi_device *); |
388 | void acpi_remove_dir(struct acpi_device *); | 414 | void acpi_remove_dir(struct acpi_device *); |
389 | 415 | ||
416 | static inline bool acpi_device_enumerated(struct acpi_device *adev) | ||
417 | { | ||
418 | return adev && adev->flags.initialized && adev->flags.visited; | ||
419 | } | ||
420 | |||
390 | typedef void (*acpi_hp_callback)(void *data, u32 src); | 421 | typedef void (*acpi_hp_callback)(void *data, u32 src); |
391 | 422 | ||
392 | acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src); | 423 | acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src); |
@@ -410,7 +441,7 @@ struct acpi_bus_type { | |||
410 | struct list_head list; | 441 | struct list_head list; |
411 | const char *name; | 442 | const char *name; |
412 | bool (*match)(struct device *dev); | 443 | bool (*match)(struct device *dev); |
413 | int (*find_device) (struct device *, acpi_handle *); | 444 | struct acpi_device * (*find_companion)(struct device *); |
414 | void (*setup)(struct device *); | 445 | void (*setup)(struct device *); |
415 | void (*cleanup)(struct device *); | 446 | void (*cleanup)(struct device *); |
416 | }; | 447 | }; |
@@ -429,12 +460,9 @@ struct acpi_pci_root { | |||
429 | }; | 460 | }; |
430 | 461 | ||
431 | /* helper */ | 462 | /* helper */ |
432 | acpi_handle acpi_find_child(acpi_handle, u64, bool); | 463 | |
433 | static inline acpi_handle acpi_get_child(acpi_handle handle, u64 addr) | 464 | struct acpi_device *acpi_find_child_device(struct acpi_device *parent, |
434 | { | 465 | u64 address, bool check_children); |
435 | return acpi_find_child(handle, addr, false); | ||
436 | } | ||
437 | void acpi_preset_companion(struct device *dev, acpi_handle parent, u64 addr); | ||
438 | int acpi_is_root_bridge(acpi_handle); | 466 | int acpi_is_root_bridge(acpi_handle); |
439 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); | 467 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); |
440 | 468 | ||
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 1cedfcb1bd88..b124fdb26046 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
@@ -26,9 +26,6 @@ | |||
26 | #ifndef __ACPI_DRIVERS_H__ | 26 | #ifndef __ACPI_DRIVERS_H__ |
27 | #define __ACPI_DRIVERS_H__ | 27 | #define __ACPI_DRIVERS_H__ |
28 | 28 | ||
29 | #include <linux/acpi.h> | ||
30 | #include <acpi/acpi_bus.h> | ||
31 | |||
32 | #define ACPI_MAX_STRING 80 | 29 | #define ACPI_MAX_STRING 80 |
33 | 30 | ||
34 | /* | 31 | /* |
diff --git a/include/linux/acpi_io.h b/include/acpi/acpi_io.h index b0ffa219993e..2be858018c7f 100644 --- a/include/linux/acpi_io.h +++ b/include/acpi/acpi_io.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #define _ACPI_IO_H_ | 2 | #define _ACPI_IO_H_ |
3 | 3 | ||
4 | #include <linux/io.h> | 4 | #include <linux/io.h> |
5 | #include <acpi/acpi.h> | ||
6 | 5 | ||
7 | static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys, | 6 | static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys, |
8 | acpi_size size) | 7 | acpi_size size) |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 4278aba96503..d2f16f14b419 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 47 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
48 | 48 | ||
49 | #define ACPI_CA_VERSION 0x20131115 | 49 | #define ACPI_CA_VERSION 0x20131218 |
50 | 50 | ||
51 | #include <acpi/acconfig.h> | 51 | #include <acpi/acconfig.h> |
52 | #include <acpi/actypes.h> | 52 | #include <acpi/actypes.h> |
@@ -54,7 +54,6 @@ | |||
54 | #include <acpi/acbuffer.h> | 54 | #include <acpi/acbuffer.h> |
55 | 55 | ||
56 | extern u8 acpi_gbl_permanent_mmap; | 56 | extern u8 acpi_gbl_permanent_mmap; |
57 | extern u32 acpi_rsdt_forced; | ||
58 | 57 | ||
59 | /* | 58 | /* |
60 | * Globals that are publically available | 59 | * Globals that are publically available |
@@ -72,17 +71,19 @@ extern u32 acpi_dbg_layer; | |||
72 | 71 | ||
73 | /* ACPICA runtime options */ | 72 | /* ACPICA runtime options */ |
74 | 73 | ||
75 | extern u8 acpi_gbl_enable_interpreter_slack; | ||
76 | extern u8 acpi_gbl_all_methods_serialized; | 74 | extern u8 acpi_gbl_all_methods_serialized; |
77 | extern u8 acpi_gbl_create_osi_method; | ||
78 | extern u8 acpi_gbl_use_default_register_widths; | ||
79 | extern acpi_name acpi_gbl_trace_method_name; | ||
80 | extern u32 acpi_gbl_trace_flags; | ||
81 | extern bool acpi_gbl_enable_aml_debug_object; | ||
82 | extern u8 acpi_gbl_copy_dsdt_locally; | 75 | extern u8 acpi_gbl_copy_dsdt_locally; |
83 | extern u8 acpi_gbl_truncate_io_addresses; | 76 | extern u8 acpi_gbl_create_osi_method; |
84 | extern u8 acpi_gbl_disable_auto_repair; | 77 | extern u8 acpi_gbl_disable_auto_repair; |
85 | extern u8 acpi_gbl_disable_ssdt_table_load; | 78 | extern u8 acpi_gbl_disable_ssdt_table_load; |
79 | extern u8 acpi_gbl_do_not_use_xsdt; | ||
80 | extern bool acpi_gbl_enable_aml_debug_object; | ||
81 | extern u8 acpi_gbl_enable_interpreter_slack; | ||
82 | extern u32 acpi_gbl_trace_flags; | ||
83 | extern acpi_name acpi_gbl_trace_method_name; | ||
84 | extern u8 acpi_gbl_truncate_io_addresses; | ||
85 | extern u8 acpi_gbl_use32_bit_fadt_addresses; | ||
86 | extern u8 acpi_gbl_use_default_register_widths; | ||
86 | 87 | ||
87 | /* | 88 | /* |
88 | * Hardware-reduced prototypes. All interfaces that use these macros will | 89 | * Hardware-reduced prototypes. All interfaces that use these macros will |
@@ -130,10 +131,9 @@ acpi_status __init acpi_terminate(void); | |||
130 | * Miscellaneous global interfaces | 131 | * Miscellaneous global interfaces |
131 | */ | 132 | */ |
132 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void)) | 133 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void)) |
133 | |||
134 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void)) | 134 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void)) |
135 | #ifdef ACPI_FUTURE_USAGE | 135 | #ifdef ACPI_FUTURE_USAGE |
136 | acpi_status acpi_subsystem_status(void); | 136 | acpi_status acpi_subsystem_status(void); |
137 | #endif | 137 | #endif |
138 | 138 | ||
139 | #ifdef ACPI_FUTURE_USAGE | 139 | #ifdef ACPI_FUTURE_USAGE |
@@ -278,16 +278,13 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
278 | acpi_install_sci_handler(acpi_sci_handler | 278 | acpi_install_sci_handler(acpi_sci_handler |
279 | address, | 279 | address, |
280 | void *context)) | 280 | void *context)) |
281 | |||
282 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 281 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
283 | acpi_remove_sci_handler(acpi_sci_handler | 282 | acpi_remove_sci_handler(acpi_sci_handler |
284 | address)) | 283 | address)) |
285 | |||
286 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 284 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
287 | acpi_install_global_event_handler | 285 | acpi_install_global_event_handler |
288 | (acpi_gbl_event_handler handler, | 286 | (acpi_gbl_event_handler handler, |
289 | void *context)) | 287 | void *context)) |
290 | |||
291 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 288 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
292 | acpi_install_fixed_event_handler(u32 | 289 | acpi_install_fixed_event_handler(u32 |
293 | acpi_event, | 290 | acpi_event, |
@@ -295,12 +292,10 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
295 | handler, | 292 | handler, |
296 | void | 293 | void |
297 | *context)) | 294 | *context)) |
298 | |||
299 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 295 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
300 | acpi_remove_fixed_event_handler(u32 acpi_event, | 296 | acpi_remove_fixed_event_handler(u32 acpi_event, |
301 | acpi_event_handler | 297 | acpi_event_handler |
302 | handler)) | 298 | handler)) |
303 | |||
304 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 299 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
305 | acpi_install_gpe_handler(acpi_handle | 300 | acpi_install_gpe_handler(acpi_handle |
306 | gpe_device, | 301 | gpe_device, |
@@ -309,15 +304,14 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
309 | acpi_gpe_handler | 304 | acpi_gpe_handler |
310 | address, | 305 | address, |
311 | void *context)) | 306 | void *context)) |
312 | |||
313 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 307 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
314 | acpi_remove_gpe_handler(acpi_handle gpe_device, | 308 | acpi_remove_gpe_handler(acpi_handle gpe_device, |
315 | u32 gpe_number, | 309 | u32 gpe_number, |
316 | acpi_gpe_handler | 310 | acpi_gpe_handler |
317 | address)) | 311 | address)) |
318 | acpi_status acpi_install_notify_handler(acpi_handle device, u32 handler_type, | 312 | acpi_status acpi_install_notify_handler(acpi_handle device, u32 handler_type, |
319 | acpi_notify_handler handler, | 313 | acpi_notify_handler handler, |
320 | void *context); | 314 | void *context); |
321 | 315 | ||
322 | acpi_status | 316 | acpi_status |
323 | acpi_remove_notify_handler(acpi_handle device, | 317 | acpi_remove_notify_handler(acpi_handle device, |
@@ -366,7 +360,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
366 | 360 | ||
367 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 361 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
368 | acpi_disable_event(u32 event, u32 flags)) | 362 | acpi_disable_event(u32 event, u32 flags)) |
369 | |||
370 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_clear_event(u32 event)) | 363 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_clear_event(u32 event)) |
371 | 364 | ||
372 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 365 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
@@ -404,20 +397,16 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
404 | parent_device, | 397 | parent_device, |
405 | acpi_handle gpe_device, | 398 | acpi_handle gpe_device, |
406 | u32 gpe_number)) | 399 | u32 gpe_number)) |
407 | |||
408 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 400 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
409 | acpi_set_gpe_wake_mask(acpi_handle gpe_device, | 401 | acpi_set_gpe_wake_mask(acpi_handle gpe_device, |
410 | u32 gpe_number, | 402 | u32 gpe_number, |
411 | u8 action)) | 403 | u8 action)) |
412 | |||
413 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 404 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
414 | acpi_get_gpe_status(acpi_handle gpe_device, | 405 | acpi_get_gpe_status(acpi_handle gpe_device, |
415 | u32 gpe_number, | 406 | u32 gpe_number, |
416 | acpi_event_status | 407 | acpi_event_status |
417 | *event_status)) | 408 | *event_status)) |
418 | |||
419 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void)) | 409 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void)) |
420 | |||
421 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void)) | 410 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void)) |
422 | 411 | ||
423 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 412 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
@@ -431,7 +420,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
431 | *gpe_block_address, | 420 | *gpe_block_address, |
432 | u32 register_count, | 421 | u32 register_count, |
433 | u32 interrupt_number)) | 422 | u32 interrupt_number)) |
434 | |||
435 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 423 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
436 | acpi_remove_gpe_block(acpi_handle gpe_device)) | 424 | acpi_remove_gpe_block(acpi_handle gpe_device)) |
437 | 425 | ||
@@ -532,7 +520,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
532 | #ifdef ACPI_FUTURE_USAGE | 520 | #ifdef ACPI_FUTURE_USAGE |
533 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 521 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
534 | acpi_get_timer_resolution(u32 *resolution)) | 522 | acpi_get_timer_resolution(u32 *resolution)) |
535 | |||
536 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks)) | 523 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks)) |
537 | 524 | ||
538 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 525 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 94970880126f..325aeae1fa99 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h | |||
@@ -182,6 +182,9 @@ struct acpi_table_xsdt { | |||
182 | u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */ | 182 | u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */ |
183 | }; | 183 | }; |
184 | 184 | ||
185 | #define ACPI_RSDT_ENTRY_SIZE (sizeof (u32)) | ||
186 | #define ACPI_XSDT_ENTRY_SIZE (sizeof (u64)) | ||
187 | |||
185 | /******************************************************************************* | 188 | /******************************************************************************* |
186 | * | 189 | * |
187 | * FACS - Firmware ACPI Control Structure (FACS) | 190 | * FACS - Firmware ACPI Control Structure (FACS) |
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index 40f7ed115452..094a906a0e98 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h | |||
@@ -327,6 +327,11 @@ struct acpi_table_dbg2 { | |||
327 | u32 info_count; | 327 | u32 info_count; |
328 | }; | 328 | }; |
329 | 329 | ||
330 | struct acpi_dbg2_header { | ||
331 | u32 info_offset; | ||
332 | u32 info_count; | ||
333 | }; | ||
334 | |||
330 | /* Debug Device Information Subtable */ | 335 | /* Debug Device Information Subtable */ |
331 | 336 | ||
332 | struct acpi_dbg2_device { | 337 | struct acpi_dbg2_device { |
diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h index e2c0931a3d67..01c2a9013e40 100644 --- a/include/acpi/actbl3.h +++ b/include/acpi/actbl3.h | |||
@@ -374,16 +374,22 @@ struct acpi_mpst_shared { | |||
374 | struct acpi_table_pcct { | 374 | struct acpi_table_pcct { |
375 | struct acpi_table_header header; /* Common ACPI table header */ | 375 | struct acpi_table_header header; /* Common ACPI table header */ |
376 | u32 flags; | 376 | u32 flags; |
377 | u32 latency; | 377 | u64 reserved; |
378 | u32 reserved; | ||
379 | }; | 378 | }; |
380 | 379 | ||
381 | /* Values for Flags field above */ | 380 | /* Values for Flags field above */ |
382 | 381 | ||
383 | #define ACPI_PCCT_DOORBELL 1 | 382 | #define ACPI_PCCT_DOORBELL 1 |
384 | 383 | ||
384 | /* Values for subtable type in struct acpi_subtable_header */ | ||
385 | |||
386 | enum acpi_pcct_type { | ||
387 | ACPI_PCCT_TYPE_GENERIC_SUBSPACE = 0, | ||
388 | ACPI_PCCT_TYPE_RESERVED = 1 /* 1 and greater are reserved */ | ||
389 | }; | ||
390 | |||
385 | /* | 391 | /* |
386 | * PCCT subtables | 392 | * PCCT Subtables, correspond to Type in struct acpi_subtable_header |
387 | */ | 393 | */ |
388 | 394 | ||
389 | /* 0: Generic Communications Subspace */ | 395 | /* 0: Generic Communications Subspace */ |
@@ -396,6 +402,9 @@ struct acpi_pcct_subspace { | |||
396 | struct acpi_generic_address doorbell_register; | 402 | struct acpi_generic_address doorbell_register; |
397 | u64 preserve_mask; | 403 | u64 preserve_mask; |
398 | u64 write_mask; | 404 | u64 write_mask; |
405 | u32 latency; | ||
406 | u32 max_access_rate; | ||
407 | u16 min_turnaround_time; | ||
399 | }; | 408 | }; |
400 | 409 | ||
401 | /* | 410 | /* |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 809b1a0fee7f..68a3ada689c9 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -928,8 +928,8 @@ struct acpi_object_list { | |||
928 | * Miscellaneous common Data Structures used by the interfaces | 928 | * Miscellaneous common Data Structures used by the interfaces |
929 | */ | 929 | */ |
930 | #define ACPI_NO_BUFFER 0 | 930 | #define ACPI_NO_BUFFER 0 |
931 | #define ACPI_ALLOCATE_BUFFER (acpi_size) (-1) | 931 | #define ACPI_ALLOCATE_BUFFER (acpi_size) (-1) /* Let ACPICA allocate buffer */ |
932 | #define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2) | 932 | #define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2) /* For internal use only (enables tracking) */ |
933 | 933 | ||
934 | struct acpi_buffer { | 934 | struct acpi_buffer { |
935 | acpi_size length; /* Length in bytes of the buffer */ | 935 | acpi_size length; /* Length in bytes of the buffer */ |
@@ -937,14 +937,6 @@ struct acpi_buffer { | |||
937 | }; | 937 | }; |
938 | 938 | ||
939 | /* | 939 | /* |
940 | * Free a buffer created in an struct acpi_buffer via ACPI_ALLOCATE_BUFFER. | ||
941 | * Note: We use acpi_os_free here because acpi_os_allocate was used to allocate | ||
942 | * the buffer. This purposefully bypasses the internal allocation tracking | ||
943 | * mechanism (if it is enabled). | ||
944 | */ | ||
945 | #define ACPI_FREE_BUFFER(b) acpi_os_free((b).pointer) | ||
946 | |||
947 | /* | ||
948 | * name_type for acpi_get_name | 940 | * name_type for acpi_get_name |
949 | */ | 941 | */ |
950 | #define ACPI_FULL_PATHNAME 0 | 942 | #define ACPI_FULL_PATHNAME 0 |
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 974d3ef7c141..b402eb67af83 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h | |||
@@ -96,13 +96,14 @@ | |||
96 | #endif | 96 | #endif |
97 | 97 | ||
98 | /* | 98 | /* |
99 | * acpi_bin/acpi_dump/acpi_src/acpi_xtract configuration. All single | 99 | * acpi_bin/acpi_dump/acpi_src/acpi_xtract/Example configuration. All single |
100 | * threaded, with no debug output. | 100 | * threaded, with no debug output. |
101 | */ | 101 | */ |
102 | #if (defined ACPI_BIN_APP) || \ | 102 | #if (defined ACPI_BIN_APP) || \ |
103 | (defined ACPI_DUMP_APP) || \ | 103 | (defined ACPI_DUMP_APP) || \ |
104 | (defined ACPI_SRC_APP) || \ | 104 | (defined ACPI_SRC_APP) || \ |
105 | (defined ACPI_XTRACT_APP) | 105 | (defined ACPI_XTRACT_APP) || \ |
106 | (defined ACPI_EXAMPLE_APP) | ||
106 | #define ACPI_APPLICATION | 107 | #define ACPI_APPLICATION |
107 | #define ACPI_SINGLE_THREADED | 108 | #define ACPI_SINGLE_THREADED |
108 | #endif | 109 | #endif |
@@ -394,4 +395,13 @@ typedef char *va_list; | |||
394 | 395 | ||
395 | #endif /* ACPI_USE_SYSTEM_CLIBRARY */ | 396 | #endif /* ACPI_USE_SYSTEM_CLIBRARY */ |
396 | 397 | ||
398 | #ifndef ACPI_FILE | ||
399 | #ifdef ACPI_APPLICATION | ||
400 | #include <stdio.h> | ||
401 | #define ACPI_FILE FILE * | ||
402 | #else | ||
403 | #define ACPI_FILE void * | ||
404 | #endif /* ACPI_APPLICATION */ | ||
405 | #endif /* ACPI_FILE */ | ||
406 | |||
397 | #endif /* __ACENV_H__ */ | 407 | #endif /* __ACENV_H__ */ |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 28f4f4dba0b6..008aa287c7a9 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -239,10 +239,6 @@ void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size); | |||
239 | */ | 239 | */ |
240 | void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size); | 240 | void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size); |
241 | 241 | ||
242 | void acpi_os_gpe_count(u32 gpe_number); | ||
243 | |||
244 | void acpi_os_fixed_event_count(u32 fixed_event_number); | ||
245 | |||
246 | #endif /* __KERNEL__ */ | 242 | #endif /* __KERNEL__ */ |
247 | 243 | ||
248 | #endif /* __ACLINUX_H__ */ | 244 | #endif /* __ACLINUX_H__ */ |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d9099b15b472..1151a1dcfe41 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <acpi/acpi_bus.h> | 42 | #include <acpi/acpi_bus.h> |
43 | #include <acpi/acpi_drivers.h> | 43 | #include <acpi/acpi_drivers.h> |
44 | #include <acpi/acpi_numa.h> | 44 | #include <acpi/acpi_numa.h> |
45 | #include <acpi/acpi_io.h> | ||
45 | #include <asm/acpi.h> | 46 | #include <asm/acpi.h> |
46 | 47 | ||
47 | static inline acpi_handle acpi_device_handle(struct acpi_device *adev) | 48 | static inline acpi_handle acpi_device_handle(struct acpi_device *adev) |
@@ -53,6 +54,12 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev) | |||
53 | #define ACPI_COMPANION_SET(dev, adev) ACPI_COMPANION(dev) = (adev) | 54 | #define ACPI_COMPANION_SET(dev, adev) ACPI_COMPANION(dev) = (adev) |
54 | #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) | 55 | #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) |
55 | 56 | ||
57 | static inline void acpi_preset_companion(struct device *dev, | ||
58 | struct acpi_device *parent, u64 addr) | ||
59 | { | ||
60 | ACPI_COMPANION_SET(dev, acpi_find_child_device(parent, addr, NULL)); | ||
61 | } | ||
62 | |||
56 | static inline const char *acpi_dev_name(struct acpi_device *adev) | 63 | static inline const char *acpi_dev_name(struct acpi_device *adev) |
57 | { | 64 | { |
58 | return dev_name(&adev->dev); | 65 | return dev_name(&adev->dev); |
@@ -409,6 +416,9 @@ static inline bool acpi_driver_match_device(struct device *dev, | |||
409 | return !!acpi_match_device(drv->acpi_match_table, dev); | 416 | return !!acpi_match_device(drv->acpi_match_table, dev); |
410 | } | 417 | } |
411 | 418 | ||
419 | int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *); | ||
420 | int acpi_device_modalias(struct device *, char *, int); | ||
421 | |||
412 | #define ACPI_PTR(_ptr) (_ptr) | 422 | #define ACPI_PTR(_ptr) (_ptr) |
413 | 423 | ||
414 | #else /* !CONFIG_ACPI */ | 424 | #else /* !CONFIG_ACPI */ |
@@ -460,7 +470,7 @@ struct acpi_table_header; | |||
460 | static inline int acpi_table_parse(char *id, | 470 | static inline int acpi_table_parse(char *id, |
461 | int (*handler)(struct acpi_table_header *)) | 471 | int (*handler)(struct acpi_table_header *)) |
462 | { | 472 | { |
463 | return -1; | 473 | return -ENODEV; |
464 | } | 474 | } |
465 | 475 | ||
466 | static inline int acpi_nvs_register(__u64 start, __u64 size) | 476 | static inline int acpi_nvs_register(__u64 start, __u64 size) |
@@ -488,6 +498,18 @@ static inline bool acpi_driver_match_device(struct device *dev, | |||
488 | return false; | 498 | return false; |
489 | } | 499 | } |
490 | 500 | ||
501 | static inline int acpi_device_uevent_modalias(struct device *dev, | ||
502 | struct kobj_uevent_env *env) | ||
503 | { | ||
504 | return -ENODEV; | ||
505 | } | ||
506 | |||
507 | static inline int acpi_device_modalias(struct device *dev, | ||
508 | char *buf, int size) | ||
509 | { | ||
510 | return -ENODEV; | ||
511 | } | ||
512 | |||
491 | #define ACPI_PTR(_ptr) (NULL) | 513 | #define ACPI_PTR(_ptr) (NULL) |
492 | 514 | ||
493 | #endif /* !CONFIG_ACPI */ | 515 | #endif /* !CONFIG_ACPI */ |
diff --git a/include/linux/container.h b/include/linux/container.h new file mode 100644 index 000000000000..3c03e6fd2035 --- /dev/null +++ b/include/linux/container.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Definitions for container bus type. | ||
3 | * | ||
4 | * Copyright (C) 2013, Intel Corporation | ||
5 | * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/device.h> | ||
13 | |||
14 | /* drivers/base/power/container.c */ | ||
15 | extern struct bus_type container_subsys; | ||
16 | |||
17 | struct container_dev { | ||
18 | struct device dev; | ||
19 | int (*offline)(struct container_dev *cdev); | ||
20 | }; | ||
21 | |||
22 | static inline struct container_dev *to_container_dev(struct device *dev) | ||
23 | { | ||
24 | return container_of(dev, struct container_dev, dev); | ||
25 | } | ||
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index dc196bbcf227..4d89e0e6f9cc 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #ifndef _LINUX_CPUFREQ_H | 11 | #ifndef _LINUX_CPUFREQ_H |
12 | #define _LINUX_CPUFREQ_H | 12 | #define _LINUX_CPUFREQ_H |
13 | 13 | ||
14 | #include <linux/clk.h> | ||
14 | #include <linux/cpumask.h> | 15 | #include <linux/cpumask.h> |
15 | #include <linux/completion.h> | 16 | #include <linux/completion.h> |
16 | #include <linux/kobject.h> | 17 | #include <linux/kobject.h> |
@@ -66,6 +67,7 @@ struct cpufreq_policy { | |||
66 | unsigned int cpu; /* cpu nr of CPU managing this policy */ | 67 | unsigned int cpu; /* cpu nr of CPU managing this policy */ |
67 | unsigned int last_cpu; /* cpu nr of previous CPU that managed | 68 | unsigned int last_cpu; /* cpu nr of previous CPU that managed |
68 | * this policy */ | 69 | * this policy */ |
70 | struct clk *clk; | ||
69 | struct cpufreq_cpuinfo cpuinfo;/* see above */ | 71 | struct cpufreq_cpuinfo cpuinfo;/* see above */ |
70 | 72 | ||
71 | unsigned int min; /* in kHz */ | 73 | unsigned int min; /* in kHz */ |
@@ -225,6 +227,11 @@ struct cpufreq_driver { | |||
225 | int (*suspend) (struct cpufreq_policy *policy); | 227 | int (*suspend) (struct cpufreq_policy *policy); |
226 | int (*resume) (struct cpufreq_policy *policy); | 228 | int (*resume) (struct cpufreq_policy *policy); |
227 | struct freq_attr **attr; | 229 | struct freq_attr **attr; |
230 | |||
231 | /* platform specific boost support code */ | ||
232 | bool boost_supported; | ||
233 | bool boost_enabled; | ||
234 | int (*set_boost) (int state); | ||
228 | }; | 235 | }; |
229 | 236 | ||
230 | /* flags */ | 237 | /* flags */ |
@@ -252,6 +259,15 @@ struct cpufreq_driver { | |||
252 | */ | 259 | */ |
253 | #define CPUFREQ_ASYNC_NOTIFICATION (1 << 4) | 260 | #define CPUFREQ_ASYNC_NOTIFICATION (1 << 4) |
254 | 261 | ||
262 | /* | ||
263 | * Set by drivers which want cpufreq core to check if CPU is running at a | ||
264 | * frequency present in freq-table exposed by the driver. For these drivers if | ||
265 | * CPU is found running at an out of table freq, we will try to set it to a freq | ||
266 | * from the table. And if that fails, we will stop further boot process by | ||
267 | * issuing a BUG_ON(). | ||
268 | */ | ||
269 | #define CPUFREQ_NEED_INITIAL_FREQ_CHECK (1 << 5) | ||
270 | |||
255 | int cpufreq_register_driver(struct cpufreq_driver *driver_data); | 271 | int cpufreq_register_driver(struct cpufreq_driver *driver_data); |
256 | int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); | 272 | int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); |
257 | 273 | ||
@@ -299,6 +315,8 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy) | |||
299 | #define CPUFREQ_NOTIFY (2) | 315 | #define CPUFREQ_NOTIFY (2) |
300 | #define CPUFREQ_START (3) | 316 | #define CPUFREQ_START (3) |
301 | #define CPUFREQ_UPDATE_POLICY_CPU (4) | 317 | #define CPUFREQ_UPDATE_POLICY_CPU (4) |
318 | #define CPUFREQ_CREATE_POLICY (5) | ||
319 | #define CPUFREQ_REMOVE_POLICY (6) | ||
302 | 320 | ||
303 | #ifdef CONFIG_CPU_FREQ | 321 | #ifdef CONFIG_CPU_FREQ |
304 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); | 322 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); |
@@ -306,6 +324,8 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); | |||
306 | 324 | ||
307 | void cpufreq_notify_transition(struct cpufreq_policy *policy, | 325 | void cpufreq_notify_transition(struct cpufreq_policy *policy, |
308 | struct cpufreq_freqs *freqs, unsigned int state); | 326 | struct cpufreq_freqs *freqs, unsigned int state); |
327 | void cpufreq_notify_post_transition(struct cpufreq_policy *policy, | ||
328 | struct cpufreq_freqs *freqs, int transition_failed); | ||
309 | 329 | ||
310 | #else /* CONFIG_CPU_FREQ */ | 330 | #else /* CONFIG_CPU_FREQ */ |
311 | static inline int cpufreq_register_notifier(struct notifier_block *nb, | 331 | static inline int cpufreq_register_notifier(struct notifier_block *nb, |
@@ -420,6 +440,7 @@ extern struct cpufreq_governor cpufreq_gov_conservative; | |||
420 | 440 | ||
421 | #define CPUFREQ_ENTRY_INVALID ~0 | 441 | #define CPUFREQ_ENTRY_INVALID ~0 |
422 | #define CPUFREQ_TABLE_END ~1 | 442 | #define CPUFREQ_TABLE_END ~1 |
443 | #define CPUFREQ_BOOST_FREQ ~2 | ||
423 | 444 | ||
424 | struct cpufreq_frequency_table { | 445 | struct cpufreq_frequency_table { |
425 | unsigned int driver_data; /* driver specific data, not used by core */ | 446 | unsigned int driver_data; /* driver specific data, not used by core */ |
@@ -439,10 +460,30 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, | |||
439 | unsigned int target_freq, | 460 | unsigned int target_freq, |
440 | unsigned int relation, | 461 | unsigned int relation, |
441 | unsigned int *index); | 462 | unsigned int *index); |
463 | int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, | ||
464 | unsigned int freq); | ||
442 | 465 | ||
443 | void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); | 466 | void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); |
444 | ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf); | 467 | ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf); |
445 | 468 | ||
469 | #ifdef CONFIG_CPU_FREQ | ||
470 | int cpufreq_boost_trigger_state(int state); | ||
471 | int cpufreq_boost_supported(void); | ||
472 | int cpufreq_boost_enabled(void); | ||
473 | #else | ||
474 | static inline int cpufreq_boost_trigger_state(int state) | ||
475 | { | ||
476 | return 0; | ||
477 | } | ||
478 | static inline int cpufreq_boost_supported(void) | ||
479 | { | ||
480 | return 0; | ||
481 | } | ||
482 | static inline int cpufreq_boost_enabled(void) | ||
483 | { | ||
484 | return 0; | ||
485 | } | ||
486 | #endif | ||
446 | /* the following funtion is for cpufreq core use only */ | 487 | /* the following funtion is for cpufreq core use only */ |
447 | struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu); | 488 | struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu); |
448 | 489 | ||
@@ -455,6 +496,7 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu); | |||
455 | int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, | 496 | int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, |
456 | struct cpufreq_frequency_table *table); | 497 | struct cpufreq_frequency_table *table); |
457 | 498 | ||
499 | unsigned int cpufreq_generic_get(unsigned int cpu); | ||
458 | int cpufreq_generic_init(struct cpufreq_policy *policy, | 500 | int cpufreq_generic_init(struct cpufreq_policy *policy, |
459 | struct cpufreq_frequency_table *table, | 501 | struct cpufreq_frequency_table *table, |
460 | unsigned int transition_latency); | 502 | unsigned int transition_latency); |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 46a14229a162..93b5ca754b5b 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -18,14 +18,10 @@ | |||
18 | #include <linux/completion.h> | 18 | #include <linux/completion.h> |
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #ifdef CONFIG_BLK_DEV_IDEACPI | ||
22 | #include <acpi/acpi.h> | ||
23 | #endif | ||
24 | #include <asm/byteorder.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | /* for request_sense */ | 21 | /* for request_sense */ |
28 | #include <linux/cdrom.h> | 22 | #include <linux/cdrom.h> |
23 | #include <asm/byteorder.h> | ||
24 | #include <asm/io.h> | ||
29 | 25 | ||
30 | #if defined(CONFIG_CRIS) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) | 26 | #if defined(CONFIG_CRIS) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) |
31 | # define SUPPORT_VLB_SYNC 0 | 27 | # define SUPPORT_VLB_SYNC 0 |
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h index 8ba7e5b9d62c..605cc5c333d9 100644 --- a/include/linux/iscsi_ibft.h +++ b/include/linux/iscsi_ibft.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #ifndef ISCSI_IBFT_H | 21 | #ifndef ISCSI_IBFT_H |
22 | #define ISCSI_IBFT_H | 22 | #define ISCSI_IBFT_H |
23 | 23 | ||
24 | #include <acpi/acpi.h> | 24 | #include <linux/acpi.h> |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Logical location of iSCSI Boot Format Table. | 27 | * Logical location of iSCSI Boot Format Table. |
diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 82ce324fdce7..8d7dd6768cb7 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h | |||
@@ -64,6 +64,12 @@ static inline int of_driver_match_device(struct device *dev, | |||
64 | static inline void of_device_uevent(struct device *dev, | 64 | static inline void of_device_uevent(struct device *dev, |
65 | struct kobj_uevent_env *env) { } | 65 | struct kobj_uevent_env *env) { } |
66 | 66 | ||
67 | static inline int of_device_get_modalias(struct device *dev, | ||
68 | char *str, ssize_t len) | ||
69 | { | ||
70 | return -ENODEV; | ||
71 | } | ||
72 | |||
67 | static inline int of_device_uevent_modalias(struct device *dev, | 73 | static inline int of_device_uevent_modalias(struct device *dev, |
68 | struct kobj_uevent_env *env) | 74 | struct kobj_uevent_env *env) |
69 | { | 75 | { |
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index a2e2f1d17e16..5f2e559af6b0 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h | |||
@@ -175,8 +175,7 @@ struct hotplug_params { | |||
175 | }; | 175 | }; |
176 | 176 | ||
177 | #ifdef CONFIG_ACPI | 177 | #ifdef CONFIG_ACPI |
178 | #include <acpi/acpi.h> | 178 | #include <linux/acpi.h> |
179 | #include <acpi/acpi_bus.h> | ||
180 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp); | 179 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp); |
181 | int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags); | 180 | int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags); |
182 | int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle); | 181 | int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle); |
diff --git a/include/linux/pm.h b/include/linux/pm.h index a224c7f5c377..8c6583a53a06 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -311,6 +311,18 @@ struct dev_pm_ops { | |||
311 | #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) | 311 | #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) |
312 | #endif | 312 | #endif |
313 | 313 | ||
314 | #ifdef CONFIG_PM_SLEEP | ||
315 | #define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ | ||
316 | .suspend_late = suspend_fn, \ | ||
317 | .resume_early = resume_fn, \ | ||
318 | .freeze_late = suspend_fn, \ | ||
319 | .thaw_early = resume_fn, \ | ||
320 | .poweroff_late = suspend_fn, \ | ||
321 | .restore_early = resume_fn, | ||
322 | #else | ||
323 | #define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) | ||
324 | #endif | ||
325 | |||
314 | #ifdef CONFIG_PM_RUNTIME | 326 | #ifdef CONFIG_PM_RUNTIME |
315 | #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ | 327 | #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ |
316 | .runtime_suspend = suspend_fn, \ | 328 | .runtime_suspend = suspend_fn, \ |
@@ -320,6 +332,15 @@ struct dev_pm_ops { | |||
320 | #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) | 332 | #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) |
321 | #endif | 333 | #endif |
322 | 334 | ||
335 | #ifdef CONFIG_PM | ||
336 | #define SET_PM_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ | ||
337 | .runtime_suspend = suspend_fn, \ | ||
338 | .runtime_resume = resume_fn, \ | ||
339 | .runtime_idle = idle_fn, | ||
340 | #else | ||
341 | #define SET_PM_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) | ||
342 | #endif | ||
343 | |||
323 | /* | 344 | /* |
324 | * Use this if you want to use the same suspend and resume callbacks for suspend | 345 | * Use this if you want to use the same suspend and resume callbacks for suspend |
325 | * to RAM and hibernation. | 346 | * to RAM and hibernation. |
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 6fa7cea25da9..16c9a62fa1c0 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h | |||
@@ -23,6 +23,14 @@ | |||
23 | usage_count */ | 23 | usage_count */ |
24 | #define RPM_AUTO 0x08 /* Use autosuspend_delay */ | 24 | #define RPM_AUTO 0x08 /* Use autosuspend_delay */ |
25 | 25 | ||
26 | #ifdef CONFIG_PM | ||
27 | extern int pm_generic_runtime_suspend(struct device *dev); | ||
28 | extern int pm_generic_runtime_resume(struct device *dev); | ||
29 | #else | ||
30 | static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } | ||
31 | static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } | ||
32 | #endif | ||
33 | |||
26 | #ifdef CONFIG_PM_RUNTIME | 34 | #ifdef CONFIG_PM_RUNTIME |
27 | 35 | ||
28 | extern struct workqueue_struct *pm_wq; | 36 | extern struct workqueue_struct *pm_wq; |
@@ -37,8 +45,6 @@ extern void pm_runtime_enable(struct device *dev); | |||
37 | extern void __pm_runtime_disable(struct device *dev, bool check_resume); | 45 | extern void __pm_runtime_disable(struct device *dev, bool check_resume); |
38 | extern void pm_runtime_allow(struct device *dev); | 46 | extern void pm_runtime_allow(struct device *dev); |
39 | extern void pm_runtime_forbid(struct device *dev); | 47 | extern void pm_runtime_forbid(struct device *dev); |
40 | extern int pm_generic_runtime_suspend(struct device *dev); | ||
41 | extern int pm_generic_runtime_resume(struct device *dev); | ||
42 | extern void pm_runtime_no_callbacks(struct device *dev); | 48 | extern void pm_runtime_no_callbacks(struct device *dev); |
43 | extern void pm_runtime_irq_safe(struct device *dev); | 49 | extern void pm_runtime_irq_safe(struct device *dev); |
44 | extern void __pm_runtime_use_autosuspend(struct device *dev, bool use); | 50 | extern void __pm_runtime_use_autosuspend(struct device *dev, bool use); |
@@ -142,8 +148,6 @@ static inline bool pm_runtime_active(struct device *dev) { return true; } | |||
142 | static inline bool pm_runtime_status_suspended(struct device *dev) { return false; } | 148 | static inline bool pm_runtime_status_suspended(struct device *dev) { return false; } |
143 | static inline bool pm_runtime_enabled(struct device *dev) { return false; } | 149 | static inline bool pm_runtime_enabled(struct device *dev) { return false; } |
144 | 150 | ||
145 | static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } | ||
146 | static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } | ||
147 | static inline void pm_runtime_no_callbacks(struct device *dev) {} | 151 | static inline void pm_runtime_no_callbacks(struct device *dev) {} |
148 | static inline void pm_runtime_irq_safe(struct device *dev) {} | 152 | static inline void pm_runtime_irq_safe(struct device *dev) {} |
149 | 153 | ||
diff --git a/include/linux/sfi_acpi.h b/include/linux/sfi_acpi.h index 631af63af42d..4723bbfa1c26 100644 --- a/include/linux/sfi_acpi.h +++ b/include/linux/sfi_acpi.h | |||
@@ -59,8 +59,11 @@ | |||
59 | #ifndef _LINUX_SFI_ACPI_H | 59 | #ifndef _LINUX_SFI_ACPI_H |
60 | #define _LINUX_SFI_ACPI_H | 60 | #define _LINUX_SFI_ACPI_H |
61 | 61 | ||
62 | #include <linux/acpi.h> | ||
63 | #include <linux/sfi.h> | ||
64 | |||
62 | #ifdef CONFIG_SFI | 65 | #ifdef CONFIG_SFI |
63 | #include <acpi/acpi.h> /* struct acpi_table_header */ | 66 | #include <acpi/acpi.h> /* FIXME: inclusion should be removed */ |
64 | 67 | ||
65 | extern int sfi_acpi_table_parse(char *signature, char *oem_id, | 68 | extern int sfi_acpi_table_parse(char *signature, char *oem_id, |
66 | char *oem_table_id, | 69 | char *oem_table_id, |
diff --git a/include/linux/tboot.h b/include/linux/tboot.h index c75128bed5fa..9a54b331f938 100644 --- a/include/linux/tboot.h +++ b/include/linux/tboot.h | |||
@@ -34,7 +34,7 @@ enum { | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | #ifdef CONFIG_INTEL_TXT | 36 | #ifdef CONFIG_INTEL_TXT |
37 | #include <acpi/acpi.h> | 37 | #include <linux/acpi.h> |
38 | /* used to communicate between tboot and the launched kernel */ | 38 | /* used to communicate between tboot and the launched kernel */ |
39 | 39 | ||
40 | #define TB_KEY_SIZE 64 /* 512 bits */ | 40 | #define TB_KEY_SIZE 64 /* 512 bits */ |
diff --git a/include/trace/events/power.h b/include/trace/events/power.h index cda100d6762d..9e9475c85de5 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h | |||
@@ -35,6 +35,59 @@ DEFINE_EVENT(cpu, cpu_idle, | |||
35 | TP_ARGS(state, cpu_id) | 35 | TP_ARGS(state, cpu_id) |
36 | ); | 36 | ); |
37 | 37 | ||
38 | TRACE_EVENT(pstate_sample, | ||
39 | |||
40 | TP_PROTO(u32 core_busy, | ||
41 | u32 scaled_busy, | ||
42 | u32 state, | ||
43 | u64 mperf, | ||
44 | u64 aperf, | ||
45 | u32 energy, | ||
46 | u32 freq | ||
47 | ), | ||
48 | |||
49 | TP_ARGS(core_busy, | ||
50 | scaled_busy, | ||
51 | state, | ||
52 | mperf, | ||
53 | aperf, | ||
54 | energy, | ||
55 | freq | ||
56 | ), | ||
57 | |||
58 | TP_STRUCT__entry( | ||
59 | __field(u32, core_busy) | ||
60 | __field(u32, scaled_busy) | ||
61 | __field(u32, state) | ||
62 | __field(u64, mperf) | ||
63 | __field(u64, aperf) | ||
64 | __field(u32, energy) | ||
65 | __field(u32, freq) | ||
66 | |||
67 | ), | ||
68 | |||
69 | TP_fast_assign( | ||
70 | __entry->core_busy = core_busy; | ||
71 | __entry->scaled_busy = scaled_busy; | ||
72 | __entry->state = state; | ||
73 | __entry->mperf = mperf; | ||
74 | __entry->aperf = aperf; | ||
75 | __entry->energy = energy; | ||
76 | __entry->freq = freq; | ||
77 | ), | ||
78 | |||
79 | TP_printk("core_busy=%lu scaled=%lu state=%lu mperf=%llu aperf=%llu energy=%lu freq=%lu ", | ||
80 | (unsigned long)__entry->core_busy, | ||
81 | (unsigned long)__entry->scaled_busy, | ||
82 | (unsigned long)__entry->state, | ||
83 | (unsigned long long)__entry->mperf, | ||
84 | (unsigned long long)__entry->aperf, | ||
85 | (unsigned long)__entry->energy, | ||
86 | (unsigned long)__entry->freq | ||
87 | ) | ||
88 | |||
89 | ); | ||
90 | |||
38 | /* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ | 91 | /* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ |
39 | #ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING | 92 | #ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING |
40 | #define _PWR_EVENT_AVOID_DOUBLE_DEFINING | 93 | #define _PWR_EVENT_AVOID_DOUBLE_DEFINING |
diff --git a/include/uapi/linux/apm_bios.h b/include/uapi/linux/apm_bios.h index 724f409adae0..df79bca1b898 100644 --- a/include/uapi/linux/apm_bios.h +++ b/include/uapi/linux/apm_bios.h | |||
@@ -67,6 +67,8 @@ struct apm_bios_info { | |||
67 | #define APM_USER_SUSPEND 0x000a | 67 | #define APM_USER_SUSPEND 0x000a |
68 | #define APM_STANDBY_RESUME 0x000b | 68 | #define APM_STANDBY_RESUME 0x000b |
69 | #define APM_CAPABILITY_CHANGE 0x000c | 69 | #define APM_CAPABILITY_CHANGE 0x000c |
70 | #define APM_USER_HIBERNATION 0x000d | ||
71 | #define APM_HIBERNATION_RESUME 0x000e | ||
70 | 72 | ||
71 | /* | 73 | /* |
72 | * Error codes | 74 | * Error codes |
diff --git a/init/main.c b/init/main.c index f333385d9a4f..3f1f4e4b61f7 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -563,6 +563,7 @@ asmlinkage void __init start_kernel(void) | |||
563 | init_timers(); | 563 | init_timers(); |
564 | hrtimers_init(); | 564 | hrtimers_init(); |
565 | softirq_init(); | 565 | softirq_init(); |
566 | acpi_early_init(); | ||
566 | timekeeping_init(); | 567 | timekeeping_init(); |
567 | time_init(); | 568 | time_init(); |
568 | sched_clock_postinit(); | 569 | sched_clock_postinit(); |
@@ -640,7 +641,6 @@ asmlinkage void __init start_kernel(void) | |||
640 | 641 | ||
641 | check_bugs(); | 642 | check_bugs(); |
642 | 643 | ||
643 | acpi_early_init(); /* before LAPIC and SMP init */ | ||
644 | sfi_init_late(); | 644 | sfi_init_late(); |
645 | 645 | ||
646 | if (efi_enabled(EFI_RUNTIME_SERVICES)) { | 646 | if (efi_enabled(EFI_RUNTIME_SERVICES)) { |
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 0121dab83f43..37170d4dd9a6 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
@@ -82,6 +82,7 @@ void hibernation_set_ops(const struct platform_hibernation_ops *ops) | |||
82 | 82 | ||
83 | unlock_system_sleep(); | 83 | unlock_system_sleep(); |
84 | } | 84 | } |
85 | EXPORT_SYMBOL_GPL(hibernation_set_ops); | ||
85 | 86 | ||
86 | static bool entering_platform_hibernation; | 87 | static bool entering_platform_hibernation; |
87 | 88 | ||
@@ -293,10 +294,10 @@ static int create_image(int platform_mode) | |||
293 | error); | 294 | error); |
294 | /* Restore control flow magically appears here */ | 295 | /* Restore control flow magically appears here */ |
295 | restore_processor_state(); | 296 | restore_processor_state(); |
296 | if (!in_suspend) { | 297 | if (!in_suspend) |
297 | events_check_enabled = false; | 298 | events_check_enabled = false; |
298 | platform_leave(platform_mode); | 299 | |
299 | } | 300 | platform_leave(platform_mode); |
300 | 301 | ||
301 | Power_up: | 302 | Power_up: |
302 | syscore_resume(); | 303 | syscore_resume(); |
diff --git a/scripts/analyze_suspend.py b/scripts/analyze_suspend.py new file mode 100755 index 000000000000..4f2cc12dc7c7 --- /dev/null +++ b/scripts/analyze_suspend.py | |||
@@ -0,0 +1,1446 @@ | |||
1 | #!/usr/bin/python | ||
2 | # | ||
3 | # Tool for analyzing suspend/resume timing | ||
4 | # Copyright (c) 2013, Intel Corporation. | ||
5 | # | ||
6 | # This program is free software; you can redistribute it and/or modify it | ||
7 | # under the terms and conditions of the GNU General Public License, | ||
8 | # version 2, as published by the Free Software Foundation. | ||
9 | # | ||
10 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | # more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License along with | ||
16 | # this program; if not, write to the Free Software Foundation, Inc., | ||
17 | # 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | # | ||
19 | # Authors: | ||
20 | # Todd Brandt <todd.e.brandt@linux.intel.com> | ||
21 | # | ||
22 | # Description: | ||
23 | # This tool is designed to assist kernel and OS developers in optimizing | ||
24 | # their linux stack's suspend/resume time. Using a kernel image built | ||
25 | # with a few extra options enabled, the tool will execute a suspend and | ||
26 | # will capture dmesg and ftrace data until resume is complete. This data | ||
27 | # is transformed into a device timeline and a callgraph to give a quick | ||
28 | # and detailed view of which devices and callbacks are taking the most | ||
29 | # time in suspend/resume. The output is a single html file which can be | ||
30 | # viewed in firefox or chrome. | ||
31 | # | ||
32 | # The following kernel build options are required: | ||
33 | # CONFIG_PM_DEBUG=y | ||
34 | # CONFIG_PM_SLEEP_DEBUG=y | ||
35 | # CONFIG_FTRACE=y | ||
36 | # CONFIG_FUNCTION_TRACER=y | ||
37 | # CONFIG_FUNCTION_GRAPH_TRACER=y | ||
38 | # | ||
39 | # The following additional kernel parameters are required: | ||
40 | # (e.g. in file /etc/default/grub) | ||
41 | # GRUB_CMDLINE_LINUX_DEFAULT="... initcall_debug log_buf_len=16M ..." | ||
42 | # | ||
43 | |||
44 | import sys | ||
45 | import time | ||
46 | import os | ||
47 | import string | ||
48 | import re | ||
49 | import array | ||
50 | import platform | ||
51 | import datetime | ||
52 | import struct | ||
53 | |||
54 | # -- classes -- | ||
55 | |||
56 | class SystemValues: | ||
57 | testdir = "." | ||
58 | tpath = "/sys/kernel/debug/tracing/" | ||
59 | mempath = "/dev/mem" | ||
60 | powerfile = "/sys/power/state" | ||
61 | suspendmode = "mem" | ||
62 | prefix = "test" | ||
63 | teststamp = "" | ||
64 | dmesgfile = "" | ||
65 | ftracefile = "" | ||
66 | htmlfile = "" | ||
67 | rtcwake = False | ||
68 | def setOutputFile(self): | ||
69 | if((self.htmlfile == "") and (self.dmesgfile != "")): | ||
70 | m = re.match(r"(?P<name>.*)_dmesg\.txt$", self.dmesgfile) | ||
71 | if(m): | ||
72 | self.htmlfile = m.group("name")+".html" | ||
73 | if((self.htmlfile == "") and (self.ftracefile != "")): | ||
74 | m = re.match(r"(?P<name>.*)_ftrace\.txt$", self.ftracefile) | ||
75 | if(m): | ||
76 | self.htmlfile = m.group("name")+".html" | ||
77 | if(self.htmlfile == ""): | ||
78 | self.htmlfile = "output.html" | ||
79 | def initTestOutput(self): | ||
80 | hostname = platform.node() | ||
81 | if(hostname != ""): | ||
82 | self.prefix = hostname | ||
83 | v = os.popen("cat /proc/version").read().strip() | ||
84 | kver = string.split(v)[2] | ||
85 | self.testdir = os.popen("date \"+suspend-%m%d%y-%H%M%S\"").read().strip() | ||
86 | self.teststamp = "# "+self.testdir+" "+self.prefix+" "+self.suspendmode+" "+kver | ||
87 | self.dmesgfile = self.testdir+"/"+self.prefix+"_"+self.suspendmode+"_dmesg.txt" | ||
88 | self.ftracefile = self.testdir+"/"+self.prefix+"_"+self.suspendmode+"_ftrace.txt" | ||
89 | self.htmlfile = self.testdir+"/"+self.prefix+"_"+self.suspendmode+".html" | ||
90 | os.mkdir(self.testdir) | ||
91 | |||
92 | class Data: | ||
93 | altdevname = dict() | ||
94 | usedmesg = False | ||
95 | useftrace = False | ||
96 | notestrun = False | ||
97 | verbose = False | ||
98 | phases = [] | ||
99 | dmesg = {} # root data structure | ||
100 | start = 0.0 | ||
101 | end = 0.0 | ||
102 | stamp = {'time': "", 'host': "", 'mode': ""} | ||
103 | id = 0 | ||
104 | tSuspended = 0.0 | ||
105 | fwValid = False | ||
106 | fwSuspend = 0 | ||
107 | fwResume = 0 | ||
108 | def initialize(self): | ||
109 | self.dmesg = { # dmesg log data | ||
110 | 'suspend_general': {'list': dict(), 'start': -1.0, 'end': -1.0, | ||
111 | 'row': 0, 'color': "#CCFFCC", 'order': 0}, | ||
112 | 'suspend_early': {'list': dict(), 'start': -1.0, 'end': -1.0, | ||
113 | 'row': 0, 'color': "green", 'order': 1}, | ||
114 | 'suspend_noirq': {'list': dict(), 'start': -1.0, 'end': -1.0, | ||
115 | 'row': 0, 'color': "#00FFFF", 'order': 2}, | ||
116 | 'suspend_cpu': {'list': dict(), 'start': -1.0, 'end': -1.0, | ||
117 | 'row': 0, 'color': "blue", 'order': 3}, | ||
118 | 'resume_cpu': {'list': dict(), 'start': -1.0, 'end': -1.0, | ||
119 | 'row': 0, 'color': "red", 'order': 4}, | ||
120 | 'resume_noirq': {'list': dict(), 'start': -1.0, 'end': -1.0, | ||
121 | 'row': 0, 'color': "orange", 'order': 5}, | ||
122 | 'resume_early': {'list': dict(), 'start': -1.0, 'end': -1.0, | ||
123 | 'row': 0, 'color': "yellow", 'order': 6}, | ||
124 | 'resume_general': {'list': dict(), 'start': -1.0, 'end': -1.0, | ||
125 | 'row': 0, 'color': "#FFFFCC", 'order': 7} | ||
126 | } | ||
127 | self.phases = self.sortedPhases() | ||
128 | def normalizeTime(self): | ||
129 | tSus = tRes = self.tSuspended | ||
130 | if self.fwValid: | ||
131 | tSus -= -self.fwSuspend / 1000000000.0 | ||
132 | tRes -= self.fwResume / 1000000000.0 | ||
133 | self.tSuspended = 0.0 | ||
134 | self.start -= tSus | ||
135 | self.end -= tRes | ||
136 | for phase in self.phases: | ||
137 | zero = tRes | ||
138 | if "suspend" in phase: | ||
139 | zero = tSus | ||
140 | p = self.dmesg[phase] | ||
141 | p['start'] -= zero | ||
142 | p['end'] -= zero | ||
143 | list = p['list'] | ||
144 | for name in list: | ||
145 | d = list[name] | ||
146 | d['start'] -= zero | ||
147 | d['end'] -= zero | ||
148 | if('ftrace' in d): | ||
149 | cg = d['ftrace'] | ||
150 | cg.start -= zero | ||
151 | cg.end -= zero | ||
152 | for line in cg.list: | ||
153 | line.time -= zero | ||
154 | if self.fwValid: | ||
155 | fws = -self.fwSuspend / 1000000000.0 | ||
156 | fwr = self.fwResume / 1000000000.0 | ||
157 | list = dict() | ||
158 | self.id += 1 | ||
159 | devid = "dc%d" % self.id | ||
160 | list["firmware-suspend"] = \ | ||
161 | {'start': fws, 'end': 0, 'pid': 0, 'par': "", | ||
162 | 'length': -fws, 'row': 0, 'id': devid }; | ||
163 | self.id += 1 | ||
164 | devid = "dc%d" % self.id | ||
165 | list["firmware-resume"] = \ | ||
166 | {'start': 0, 'end': fwr, 'pid': 0, 'par': "", | ||
167 | 'length': fwr, 'row': 0, 'id': devid }; | ||
168 | self.dmesg['BIOS'] = \ | ||
169 | {'list': list, 'start': fws, 'end': fwr, | ||
170 | 'row': 0, 'color': "purple", 'order': 4} | ||
171 | self.dmesg['resume_cpu']['order'] += 1 | ||
172 | self.dmesg['resume_noirq']['order'] += 1 | ||
173 | self.dmesg['resume_early']['order'] += 1 | ||
174 | self.dmesg['resume_general']['order'] += 1 | ||
175 | self.phases = self.sortedPhases() | ||
176 | def vprint(self, msg): | ||
177 | if(self.verbose): | ||
178 | print(msg) | ||
179 | def dmesgSortVal(self, phase): | ||
180 | return self.dmesg[phase]['order'] | ||
181 | def sortedPhases(self): | ||
182 | return sorted(self.dmesg, key=self.dmesgSortVal) | ||
183 | def sortedDevices(self, phase): | ||
184 | list = self.dmesg[phase]['list'] | ||
185 | slist = [] | ||
186 | tmp = dict() | ||
187 | for devname in list: | ||
188 | dev = list[devname] | ||
189 | tmp[dev['start']] = devname | ||
190 | for t in sorted(tmp): | ||
191 | slist.append(tmp[t]) | ||
192 | return slist | ||
193 | def fixupInitcalls(self, phase, end): | ||
194 | # if any calls never returned, clip them at system resume end | ||
195 | phaselist = self.dmesg[phase]['list'] | ||
196 | for devname in phaselist: | ||
197 | dev = phaselist[devname] | ||
198 | if(dev['end'] < 0): | ||
199 | dev['end'] = end | ||
200 | self.vprint("%s (%s): callback didn't return" % (devname, phase)) | ||
201 | def fixupInitcallsThatDidntReturn(self): | ||
202 | # if any calls never returned, clip them at system resume end | ||
203 | for phase in self.phases: | ||
204 | self.fixupInitcalls(phase, self.dmesg['resume_general']['end']) | ||
205 | if(phase == "resume_general"): | ||
206 | break | ||
207 | def newAction(self, phase, name, pid, parent, start, end): | ||
208 | self.id += 1 | ||
209 | devid = "dc%d" % self.id | ||
210 | list = self.dmesg[phase]['list'] | ||
211 | length = -1.0 | ||
212 | if(start >= 0 and end >= 0): | ||
213 | length = end - start | ||
214 | list[name] = {'start': start, 'end': end, 'pid': pid, 'par': parent, | ||
215 | 'length': length, 'row': 0, 'id': devid } | ||
216 | def deviceIDs(self, devlist, phase): | ||
217 | idlist = [] | ||
218 | for p in self.phases: | ||
219 | if(p[0] != phase[0]): | ||
220 | continue | ||
221 | list = data.dmesg[p]['list'] | ||
222 | for devname in list: | ||
223 | if devname in devlist: | ||
224 | idlist.append(list[devname]['id']) | ||
225 | return idlist | ||
226 | def deviceParentID(self, devname, phase): | ||
227 | pdev = "" | ||
228 | pdevid = "" | ||
229 | for p in self.phases: | ||
230 | if(p[0] != phase[0]): | ||
231 | continue | ||
232 | list = data.dmesg[p]['list'] | ||
233 | if devname in list: | ||
234 | pdev = list[devname]['par'] | ||
235 | for p in self.phases: | ||
236 | if(p[0] != phase[0]): | ||
237 | continue | ||
238 | list = data.dmesg[p]['list'] | ||
239 | if pdev in list: | ||
240 | return list[pdev]['id'] | ||
241 | return pdev | ||
242 | def deviceChildrenIDs(self, devname, phase): | ||
243 | devlist = [] | ||
244 | for p in self.phases: | ||
245 | if(p[0] != phase[0]): | ||
246 | continue | ||
247 | list = data.dmesg[p]['list'] | ||
248 | for child in list: | ||
249 | if(list[child]['par'] == devname): | ||
250 | devlist.append(child) | ||
251 | return self.deviceIDs(devlist, phase) | ||
252 | |||
253 | class FTraceLine: | ||
254 | time = 0.0 | ||
255 | length = 0.0 | ||
256 | fcall = False | ||
257 | freturn = False | ||
258 | fevent = False | ||
259 | depth = 0 | ||
260 | name = "" | ||
261 | def __init__(self, t, m, d): | ||
262 | self.time = float(t) | ||
263 | # check to see if this is a trace event | ||
264 | em = re.match(r"^ *\/\* *(?P<msg>.*) \*\/ *$", m) | ||
265 | if(em): | ||
266 | self.name = em.group("msg") | ||
267 | self.fevent = True | ||
268 | return | ||
269 | # convert the duration to seconds | ||
270 | if(d): | ||
271 | self.length = float(d)/1000000 | ||
272 | # the indentation determines the depth | ||
273 | match = re.match(r"^(?P<d> *)(?P<o>.*)$", m) | ||
274 | if(not match): | ||
275 | return | ||
276 | self.depth = self.getDepth(match.group('d')) | ||
277 | m = match.group('o') | ||
278 | # function return | ||
279 | if(m[0] == '}'): | ||
280 | self.freturn = True | ||
281 | if(len(m) > 1): | ||
282 | # includes comment with function name | ||
283 | match = re.match(r"^} *\/\* *(?P<n>.*) *\*\/$", m) | ||
284 | if(match): | ||
285 | self.name = match.group('n') | ||
286 | # function call | ||
287 | else: | ||
288 | self.fcall = True | ||
289 | # function call with children | ||
290 | if(m[-1] == '{'): | ||
291 | match = re.match(r"^(?P<n>.*) *\(.*", m) | ||
292 | if(match): | ||
293 | self.name = match.group('n') | ||
294 | # function call with no children (leaf) | ||
295 | elif(m[-1] == ';'): | ||
296 | self.freturn = True | ||
297 | match = re.match(r"^(?P<n>.*) *\(.*", m) | ||
298 | if(match): | ||
299 | self.name = match.group('n') | ||
300 | # something else (possibly a trace marker) | ||
301 | else: | ||
302 | self.name = m | ||
303 | def getDepth(self, str): | ||
304 | return len(str)/2 | ||
305 | |||
306 | class FTraceCallGraph: | ||
307 | start = -1.0 | ||
308 | end = -1.0 | ||
309 | list = [] | ||
310 | invalid = False | ||
311 | depth = 0 | ||
312 | def __init__(self): | ||
313 | self.start = -1.0 | ||
314 | self.end = -1.0 | ||
315 | self.list = [] | ||
316 | self.depth = 0 | ||
317 | def setDepth(self, line): | ||
318 | if(line.fcall and not line.freturn): | ||
319 | line.depth = self.depth | ||
320 | self.depth += 1 | ||
321 | elif(line.freturn and not line.fcall): | ||
322 | self.depth -= 1 | ||
323 | line.depth = self.depth | ||
324 | else: | ||
325 | line.depth = self.depth | ||
326 | def addLine(self, line, match): | ||
327 | if(not self.invalid): | ||
328 | self.setDepth(line) | ||
329 | if(line.depth == 0 and line.freturn): | ||
330 | self.end = line.time | ||
331 | self.list.append(line) | ||
332 | return True | ||
333 | if(self.invalid): | ||
334 | return False | ||
335 | if(len(self.list) >= 1000000 or self.depth < 0): | ||
336 | first = self.list[0] | ||
337 | self.list = [] | ||
338 | self.list.append(first) | ||
339 | self.invalid = True | ||
340 | id = "task %s cpu %s" % (match.group("pid"), match.group("cpu")) | ||
341 | window = "(%f - %f)" % (self.start, line.time) | ||
342 | data.vprint("Too much data for "+id+" "+window+", ignoring this callback") | ||
343 | return False | ||
344 | self.list.append(line) | ||
345 | if(self.start < 0): | ||
346 | self.start = line.time | ||
347 | return False | ||
348 | def sanityCheck(self): | ||
349 | stack = dict() | ||
350 | cnt = 0 | ||
351 | for l in self.list: | ||
352 | if(l.fcall and not l.freturn): | ||
353 | stack[l.depth] = l | ||
354 | cnt += 1 | ||
355 | elif(l.freturn and not l.fcall): | ||
356 | if(not stack[l.depth]): | ||
357 | return False | ||
358 | stack[l.depth].length = l.length | ||
359 | stack[l.depth] = 0 | ||
360 | l.length = 0 | ||
361 | cnt -= 1 | ||
362 | if(cnt == 0): | ||
363 | return True | ||
364 | return False | ||
365 | def debugPrint(self, filename): | ||
366 | if(filename == "stdout"): | ||
367 | print("[%f - %f]") % (self.start, self.end) | ||
368 | for l in self.list: | ||
369 | if(l.freturn and l.fcall): | ||
370 | print("%f (%02d): %s(); (%.3f us)" % (l.time, l.depth, l.name, l.length*1000000)) | ||
371 | elif(l.freturn): | ||
372 | print("%f (%02d): %s} (%.3f us)" % (l.time, l.depth, l.name, l.length*1000000)) | ||
373 | else: | ||
374 | print("%f (%02d): %s() { (%.3f us)" % (l.time, l.depth, l.name, l.length*1000000)) | ||
375 | print(" ") | ||
376 | else: | ||
377 | fp = open(filename, 'w') | ||
378 | print(filename) | ||
379 | for l in self.list: | ||
380 | if(l.freturn and l.fcall): | ||
381 | fp.write("%f (%02d): %s(); (%.3f us)\n" % (l.time, l.depth, l.name, l.length*1000000)) | ||
382 | elif(l.freturn): | ||
383 | fp.write("%f (%02d): %s} (%.3f us)\n" % (l.time, l.depth, l.name, l.length*1000000)) | ||
384 | else: | ||
385 | fp.write("%f (%02d): %s() { (%.3f us)\n" % (l.time, l.depth, l.name, l.length*1000000)) | ||
386 | fp.close() | ||
387 | |||
388 | class Timeline: | ||
389 | html = {} | ||
390 | scaleH = 0.0 # height of the timescale row as a percent of the timeline height | ||
391 | rowH = 0.0 # height of each row in percent of the timeline height | ||
392 | row_height_pixels = 30 | ||
393 | maxrows = 0 | ||
394 | height = 0 | ||
395 | def __init__(self): | ||
396 | self.html = { | ||
397 | 'timeline': "", | ||
398 | 'legend': "", | ||
399 | 'scale': "" | ||
400 | } | ||
401 | def setRows(self, rows): | ||
402 | self.maxrows = int(rows) | ||
403 | self.scaleH = 100.0/float(self.maxrows) | ||
404 | self.height = self.maxrows*self.row_height_pixels | ||
405 | r = float(self.maxrows - 1) | ||
406 | if(r < 1.0): | ||
407 | r = 1.0 | ||
408 | self.rowH = (100.0 - self.scaleH)/r | ||
409 | |||
410 | # -- global objects -- | ||
411 | |||
412 | sysvals = SystemValues() | ||
413 | data = Data() | ||
414 | |||
415 | # -- functions -- | ||
416 | |||
417 | # Function: initFtrace | ||
418 | # Description: | ||
419 | # Configure ftrace to capture a function trace during suspend/resume | ||
420 | def initFtrace(): | ||
421 | global sysvals | ||
422 | |||
423 | print("INITIALIZING FTRACE...") | ||
424 | # turn trace off | ||
425 | os.system("echo 0 > "+sysvals.tpath+"tracing_on") | ||
426 | # set the trace clock to global | ||
427 | os.system("echo global > "+sysvals.tpath+"trace_clock") | ||
428 | # set trace buffer to a huge value | ||
429 | os.system("echo nop > "+sysvals.tpath+"current_tracer") | ||
430 | os.system("echo 100000 > "+sysvals.tpath+"buffer_size_kb") | ||
431 | # clear the trace buffer | ||
432 | os.system("echo \"\" > "+sysvals.tpath+"trace") | ||
433 | # set trace type | ||
434 | os.system("echo function_graph > "+sysvals.tpath+"current_tracer") | ||
435 | os.system("echo \"\" > "+sysvals.tpath+"set_ftrace_filter") | ||
436 | # set trace format options | ||
437 | os.system("echo funcgraph-abstime > "+sysvals.tpath+"trace_options") | ||
438 | os.system("echo funcgraph-proc > "+sysvals.tpath+"trace_options") | ||
439 | # focus only on device suspend and resume | ||
440 | os.system("cat "+sysvals.tpath+"available_filter_functions | grep dpm_run_callback > "+sysvals.tpath+"set_graph_function") | ||
441 | |||
442 | # Function: verifyFtrace | ||
443 | # Description: | ||
444 | # Check that ftrace is working on the system | ||
445 | def verifyFtrace(): | ||
446 | global sysvals | ||
447 | files = ["available_filter_functions", "buffer_size_kb", | ||
448 | "current_tracer", "set_ftrace_filter", | ||
449 | "trace", "trace_marker"] | ||
450 | for f in files: | ||
451 | if(os.path.exists(sysvals.tpath+f) == False): | ||
452 | return False | ||
453 | return True | ||
454 | |||
455 | def parseStamp(line): | ||
456 | global data, sysvals | ||
457 | stampfmt = r"# suspend-(?P<m>[0-9]{2})(?P<d>[0-9]{2})(?P<y>[0-9]{2})-"+\ | ||
458 | "(?P<H>[0-9]{2})(?P<M>[0-9]{2})(?P<S>[0-9]{2})"+\ | ||
459 | " (?P<host>.*) (?P<mode>.*) (?P<kernel>.*)$" | ||
460 | m = re.match(stampfmt, line) | ||
461 | if(m): | ||
462 | dt = datetime.datetime(int(m.group("y"))+2000, int(m.group("m")), | ||
463 | int(m.group("d")), int(m.group("H")), int(m.group("M")), | ||
464 | int(m.group("S"))) | ||
465 | data.stamp['time'] = dt.strftime("%B %d %Y, %I:%M:%S %p") | ||
466 | data.stamp['host'] = m.group("host") | ||
467 | data.stamp['mode'] = m.group("mode") | ||
468 | data.stamp['kernel'] = m.group("kernel") | ||
469 | sysvals.suspendmode = data.stamp['mode'] | ||
470 | |||
471 | # Function: analyzeTraceLog | ||
472 | # Description: | ||
473 | # Analyse an ftrace log output file generated from this app during | ||
474 | # the execution phase. Create an "ftrace" structure in memory for | ||
475 | # subsequent formatting in the html output file | ||
476 | def analyzeTraceLog(): | ||
477 | global sysvals, data | ||
478 | |||
479 | # the ftrace data is tied to the dmesg data | ||
480 | if(not data.usedmesg): | ||
481 | return | ||
482 | |||
483 | # read through the ftrace and parse the data | ||
484 | data.vprint("Analyzing the ftrace data...") | ||
485 | ftrace_line_fmt = r"^ *(?P<time>[0-9\.]*) *\| *(?P<cpu>[0-9]*)\)"+\ | ||
486 | " *(?P<proc>.*)-(?P<pid>[0-9]*) *\|"+\ | ||
487 | "[ +!]*(?P<dur>[0-9\.]*) .*\| (?P<msg>.*)" | ||
488 | ftemp = dict() | ||
489 | inthepipe = False | ||
490 | tf = open(sysvals.ftracefile, 'r') | ||
491 | count = 0 | ||
492 | for line in tf: | ||
493 | count = count + 1 | ||
494 | # grab the time stamp if it's valid | ||
495 | if(count == 1): | ||
496 | parseStamp(line) | ||
497 | continue | ||
498 | # parse only valid lines | ||
499 | m = re.match(ftrace_line_fmt, line) | ||
500 | if(not m): | ||
501 | continue | ||
502 | m_time = m.group("time") | ||
503 | m_pid = m.group("pid") | ||
504 | m_msg = m.group("msg") | ||
505 | m_dur = m.group("dur") | ||
506 | if(m_time and m_pid and m_msg): | ||
507 | t = FTraceLine(m_time, m_msg, m_dur) | ||
508 | pid = int(m_pid) | ||
509 | else: | ||
510 | continue | ||
511 | # the line should be a call, return, or event | ||
512 | if(not t.fcall and not t.freturn and not t.fevent): | ||
513 | continue | ||
514 | # only parse the ftrace data during suspend/resume | ||
515 | if(not inthepipe): | ||
516 | # look for the suspend start marker | ||
517 | if(t.fevent): | ||
518 | if(t.name == "SUSPEND START"): | ||
519 | data.vprint("SUSPEND START %f %s:%d" % (t.time, sysvals.ftracefile, count)) | ||
520 | inthepipe = True | ||
521 | continue | ||
522 | else: | ||
523 | # look for the resume end marker | ||
524 | if(t.fevent): | ||
525 | if(t.name == "RESUME COMPLETE"): | ||
526 | data.vprint("RESUME COMPLETE %f %s:%d" % (t.time, sysvals.ftracefile, count)) | ||
527 | inthepipe = False | ||
528 | break | ||
529 | continue | ||
530 | # create a callgraph object for the data | ||
531 | if(pid not in ftemp): | ||
532 | ftemp[pid] = FTraceCallGraph() | ||
533 | # when the call is finished, see which device matches it | ||
534 | if(ftemp[pid].addLine(t, m)): | ||
535 | if(not ftemp[pid].sanityCheck()): | ||
536 | id = "task %s cpu %s" % (pid, m.group("cpu")) | ||
537 | data.vprint("Sanity check failed for "+id+", ignoring this callback") | ||
538 | continue | ||
539 | callstart = ftemp[pid].start | ||
540 | callend = ftemp[pid].end | ||
541 | for p in data.phases: | ||
542 | if(data.dmesg[p]['start'] <= callstart and callstart <= data.dmesg[p]['end']): | ||
543 | list = data.dmesg[p]['list'] | ||
544 | for devname in list: | ||
545 | dev = list[devname] | ||
546 | if(pid == dev['pid'] and callstart <= dev['start'] and callend >= dev['end']): | ||
547 | data.vprint("%15s [%f - %f] %s(%d)" % (p, callstart, callend, devname, pid)) | ||
548 | dev['ftrace'] = ftemp[pid] | ||
549 | break | ||
550 | ftemp[pid] = FTraceCallGraph() | ||
551 | tf.close() | ||
552 | |||
553 | # Function: sortKernelLog | ||
554 | # Description: | ||
555 | # The dmesg output log sometimes comes with with lines that have | ||
556 | # timestamps out of order. This could cause issues since a call | ||
557 | # could accidentally end up in the wrong phase | ||
558 | def sortKernelLog(): | ||
559 | global sysvals, data | ||
560 | lf = open(sysvals.dmesgfile, 'r') | ||
561 | dmesglist = [] | ||
562 | count = 0 | ||
563 | for line in lf: | ||
564 | line = line.replace("\r\n", "") | ||
565 | if(count == 0): | ||
566 | parseStamp(line) | ||
567 | elif(count == 1): | ||
568 | m = re.match(r"# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$", line) | ||
569 | if(m): | ||
570 | data.fwSuspend = int(m.group("s")) | ||
571 | data.fwResume = int(m.group("r")) | ||
572 | if(data.fwSuspend > 0 or data.fwResume > 0): | ||
573 | data.fwValid = True | ||
574 | if(re.match(r".*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)", line)): | ||
575 | dmesglist.append(line) | ||
576 | count += 1 | ||
577 | lf.close() | ||
578 | last = "" | ||
579 | |||
580 | # fix lines with the same time stamp and function with the call and return swapped | ||
581 | for line in dmesglist: | ||
582 | mc = re.match(r".*(\[ *)(?P<t>[0-9\.]*)(\]) calling (?P<f>.*)\+ @ .*, parent: .*", line) | ||
583 | mr = re.match(r".*(\[ *)(?P<t>[0-9\.]*)(\]) call (?P<f>.*)\+ returned .* after (?P<dt>.*) usecs", last) | ||
584 | if(mc and mr and (mc.group("t") == mr.group("t")) and (mc.group("f") == mr.group("f"))): | ||
585 | i = dmesglist.index(last) | ||
586 | j = dmesglist.index(line) | ||
587 | dmesglist[i] = line | ||
588 | dmesglist[j] = last | ||
589 | last = line | ||
590 | return dmesglist | ||
591 | |||
592 | # Function: analyzeKernelLog | ||
593 | # Description: | ||
594 | # Analyse a dmesg log output file generated from this app during | ||
595 | # the execution phase. Create a set of device structures in memory | ||
596 | # for subsequent formatting in the html output file | ||
597 | def analyzeKernelLog(): | ||
598 | global sysvals, data | ||
599 | |||
600 | print("PROCESSING DATA") | ||
601 | data.vprint("Analyzing the dmesg data...") | ||
602 | if(os.path.exists(sysvals.dmesgfile) == False): | ||
603 | print("ERROR: %s doesn't exist") % sysvals.dmesgfile | ||
604 | return False | ||
605 | |||
606 | lf = sortKernelLog() | ||
607 | phase = "suspend_runtime" | ||
608 | |||
609 | dm = { | ||
610 | 'suspend_general': r"PM: Syncing filesystems.*", | ||
611 | 'suspend_early': r"PM: suspend of devices complete after.*", | ||
612 | 'suspend_noirq': r"PM: late suspend of devices complete after.*", | ||
613 | 'suspend_cpu': r"PM: noirq suspend of devices complete after.*", | ||
614 | 'resume_cpu': r"ACPI: Low-level resume complete.*", | ||
615 | 'resume_noirq': r"ACPI: Waking up from system sleep state.*", | ||
616 | 'resume_early': r"PM: noirq resume of devices complete after.*", | ||
617 | 'resume_general': r"PM: early resume of devices complete after.*", | ||
618 | 'resume_complete': r".*Restarting tasks \.\.\..*", | ||
619 | } | ||
620 | if(sysvals.suspendmode == "standby"): | ||
621 | dm['resume_cpu'] = r"PM: Restoring platform NVS memory" | ||
622 | elif(sysvals.suspendmode == "disk"): | ||
623 | dm['suspend_early'] = r"PM: freeze of devices complete after.*" | ||
624 | dm['suspend_noirq'] = r"PM: late freeze of devices complete after.*" | ||
625 | dm['suspend_cpu'] = r"PM: noirq freeze of devices complete after.*" | ||
626 | dm['resume_cpu'] = r"PM: Restoring platform NVS memory" | ||
627 | dm['resume_early'] = r"PM: noirq restore of devices complete after.*" | ||
628 | dm['resume_general'] = r"PM: early restore of devices complete after.*" | ||
629 | |||
630 | action_start = 0.0 | ||
631 | for line in lf: | ||
632 | # -- preprocessing -- | ||
633 | # parse each dmesg line into the time and message | ||
634 | m = re.match(r".*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)", line) | ||
635 | if(m): | ||
636 | ktime = float(m.group("ktime")) | ||
637 | msg = m.group("msg") | ||
638 | else: | ||
639 | print line | ||
640 | continue | ||
641 | |||
642 | # -- phase changes -- | ||
643 | # suspend_general start | ||
644 | if(re.match(dm['suspend_general'], msg)): | ||
645 | phase = "suspend_general" | ||
646 | data.dmesg[phase]['start'] = ktime | ||
647 | data.start = ktime | ||
648 | # action start: syncing filesystems | ||
649 | action_start = ktime | ||
650 | # suspend_early start | ||
651 | elif(re.match(dm['suspend_early'], msg)): | ||
652 | data.dmesg["suspend_general"]['end'] = ktime | ||
653 | phase = "suspend_early" | ||
654 | data.dmesg[phase]['start'] = ktime | ||
655 | # suspend_noirq start | ||
656 | elif(re.match(dm['suspend_noirq'], msg)): | ||
657 | data.dmesg["suspend_early"]['end'] = ktime | ||
658 | phase = "suspend_noirq" | ||
659 | data.dmesg[phase]['start'] = ktime | ||
660 | # suspend_cpu start | ||
661 | elif(re.match(dm['suspend_cpu'], msg)): | ||
662 | data.dmesg["suspend_noirq"]['end'] = ktime | ||
663 | phase = "suspend_cpu" | ||
664 | data.dmesg[phase]['start'] = ktime | ||
665 | # resume_cpu start | ||
666 | elif(re.match(dm['resume_cpu'], msg)): | ||
667 | data.tSuspended = ktime | ||
668 | data.dmesg["suspend_cpu"]['end'] = ktime | ||
669 | phase = "resume_cpu" | ||
670 | data.dmesg[phase]['start'] = ktime | ||
671 | # resume_noirq start | ||
672 | elif(re.match(dm['resume_noirq'], msg)): | ||
673 | data.dmesg["resume_cpu"]['end'] = ktime | ||
674 | phase = "resume_noirq" | ||
675 | data.dmesg[phase]['start'] = ktime | ||
676 | # action end: ACPI resume | ||
677 | data.newAction("resume_cpu", "ACPI", -1, "", action_start, ktime) | ||
678 | # resume_early start | ||
679 | elif(re.match(dm['resume_early'], msg)): | ||
680 | data.dmesg["resume_noirq"]['end'] = ktime | ||
681 | phase = "resume_early" | ||
682 | data.dmesg[phase]['start'] = ktime | ||
683 | # resume_general start | ||
684 | elif(re.match(dm['resume_general'], msg)): | ||
685 | data.dmesg["resume_early"]['end'] = ktime | ||
686 | phase = "resume_general" | ||
687 | data.dmesg[phase]['start'] = ktime | ||
688 | # resume complete start | ||
689 | elif(re.match(dm['resume_complete'], msg)): | ||
690 | data.dmesg["resume_general"]['end'] = ktime | ||
691 | data.end = ktime | ||
692 | phase = "resume_runtime" | ||
693 | break | ||
694 | |||
695 | # -- device callbacks -- | ||
696 | if(phase in data.phases): | ||
697 | # device init call | ||
698 | if(re.match(r"calling (?P<f>.*)\+ @ .*, parent: .*", msg)): | ||
699 | sm = re.match(r"calling (?P<f>.*)\+ @ (?P<n>.*), parent: (?P<p>.*)", msg); | ||
700 | f = sm.group("f") | ||
701 | n = sm.group("n") | ||
702 | p = sm.group("p") | ||
703 | if(f and n and p): | ||
704 | data.newAction(phase, f, int(n), p, ktime, -1) | ||
705 | # device init return | ||
706 | elif(re.match(r"call (?P<f>.*)\+ returned .* after (?P<t>.*) usecs", msg)): | ||
707 | sm = re.match(r"call (?P<f>.*)\+ returned .* after (?P<t>.*) usecs(?P<a>.*)", msg); | ||
708 | f = sm.group("f") | ||
709 | t = sm.group("t") | ||
710 | list = data.dmesg[phase]['list'] | ||
711 | if(f in list): | ||
712 | dev = list[f] | ||
713 | dev['length'] = int(t) | ||
714 | dev['end'] = ktime | ||
715 | data.vprint("%15s [%f - %f] %s(%d) %s" % | ||
716 | (phase, dev['start'], dev['end'], f, dev['pid'], dev['par'])) | ||
717 | |||
718 | # -- phase specific actions -- | ||
719 | if(phase == "suspend_general"): | ||
720 | if(re.match(r"PM: Preparing system for mem sleep.*", msg)): | ||
721 | data.newAction(phase, "filesystem-sync", -1, "", action_start, ktime) | ||
722 | elif(re.match(r"Freezing user space processes .*", msg)): | ||
723 | action_start = ktime | ||
724 | elif(re.match(r"Freezing remaining freezable tasks.*", msg)): | ||
725 | data.newAction(phase, "freeze-user-processes", -1, "", action_start, ktime) | ||
726 | action_start = ktime | ||
727 | elif(re.match(r"PM: Entering (?P<mode>[a-z,A-Z]*) sleep.*", msg)): | ||
728 | data.newAction(phase, "freeze-tasks", -1, "", action_start, ktime) | ||
729 | elif(phase == "suspend_cpu"): | ||
730 | m = re.match(r"smpboot: CPU (?P<cpu>[0-9]*) is now offline", msg) | ||
731 | if(m): | ||
732 | cpu = "CPU"+m.group("cpu") | ||
733 | data.newAction(phase, cpu, -1, "", action_start, ktime) | ||
734 | action_start = ktime | ||
735 | elif(re.match(r"ACPI: Preparing to enter system sleep state.*", msg)): | ||
736 | action_start = ktime | ||
737 | elif(re.match(r"Disabling non-boot CPUs .*", msg)): | ||
738 | data.newAction(phase, "ACPI", -1, "", action_start, ktime) | ||
739 | action_start = ktime | ||
740 | elif(phase == "resume_cpu"): | ||
741 | m = re.match(r"CPU(?P<cpu>[0-9]*) is up", msg) | ||
742 | if(m): | ||
743 | cpu = "CPU"+m.group("cpu") | ||
744 | data.newAction(phase, cpu, -1, "", action_start, ktime) | ||
745 | action_start = ktime | ||
746 | elif(re.match(r"Enabling non-boot CPUs .*", msg)): | ||
747 | action_start = ktime | ||
748 | |||
749 | # fill in any missing phases | ||
750 | lp = "suspend_general" | ||
751 | for p in data.phases: | ||
752 | if(p == "suspend_general"): | ||
753 | continue | ||
754 | if(data.dmesg[p]['start'] < 0): | ||
755 | data.dmesg[p]['start'] = data.dmesg[lp]['end'] | ||
756 | if(p == "resume_cpu"): | ||
757 | data.tSuspended = data.dmesg[lp]['end'] | ||
758 | if(data.dmesg[p]['end'] < 0): | ||
759 | data.dmesg[p]['end'] = data.dmesg[p]['start'] | ||
760 | lp = p | ||
761 | |||
762 | data.fixupInitcallsThatDidntReturn() | ||
763 | return True | ||
764 | |||
765 | # Function: setTimelineRows | ||
766 | # Description: | ||
767 | # Organize the device or thread lists into the smallest | ||
768 | # number of rows possible, with no entry overlapping | ||
769 | # Arguments: | ||
770 | # list: the list to sort (dmesg or ftrace) | ||
771 | # sortedkeys: sorted key list to use | ||
772 | def setTimelineRows(list, sortedkeys): | ||
773 | global data | ||
774 | |||
775 | # clear all rows and set them to undefined | ||
776 | remaining = len(list) | ||
777 | rowdata = dict() | ||
778 | row = 0 | ||
779 | for item in list: | ||
780 | list[item]['row'] = -1 | ||
781 | |||
782 | # try to pack each row with as many ranges as possible | ||
783 | while(remaining > 0): | ||
784 | if(row not in rowdata): | ||
785 | rowdata[row] = [] | ||
786 | for item in sortedkeys: | ||
787 | if(list[item]['row'] < 0): | ||
788 | s = list[item]['start'] | ||
789 | e = list[item]['end'] | ||
790 | valid = True | ||
791 | for ritem in rowdata[row]: | ||
792 | rs = ritem['start'] | ||
793 | re = ritem['end'] | ||
794 | if(not (((s <= rs) and (e <= rs)) or ((s >= re) and (e >= re)))): | ||
795 | valid = False | ||
796 | break | ||
797 | if(valid): | ||
798 | rowdata[row].append(list[item]) | ||
799 | list[item]['row'] = row | ||
800 | remaining -= 1 | ||
801 | row += 1 | ||
802 | return row | ||
803 | |||
804 | # Function: createTimeScale | ||
805 | # Description: | ||
806 | # Create timescale lines for the dmesg and ftrace timelines | ||
807 | # Arguments: | ||
808 | # t0: start time (suspend begin) | ||
809 | # tMax: end time (resume end) | ||
810 | # tSuspend: time when suspend occurs | ||
811 | def createTimeScale(t0, tMax, tSuspended): | ||
812 | global data | ||
813 | timescale = "<div class=\"t\" style=\"right:{0}%\">{1}</div>\n" | ||
814 | output = '<div id="timescale">\n' | ||
815 | |||
816 | # set scale for timeline | ||
817 | tTotal = tMax - t0 | ||
818 | tS = 0.1 | ||
819 | if(tTotal <= 0): | ||
820 | return output | ||
821 | if(tTotal > 4): | ||
822 | tS = 1 | ||
823 | if(tSuspended < 0): | ||
824 | for i in range(int(tTotal/tS)+1): | ||
825 | pos = "%0.3f" % (100 - ((float(i)*tS*100)/tTotal)) | ||
826 | if(i > 0): | ||
827 | val = "%0.f" % (float(i)*tS*1000) | ||
828 | else: | ||
829 | val = "" | ||
830 | output += timescale.format(pos, val) | ||
831 | else: | ||
832 | tSuspend = tSuspended - t0 | ||
833 | divTotal = int(tTotal/tS) + 1 | ||
834 | divSuspend = int(tSuspend/tS) | ||
835 | s0 = (tSuspend - tS*divSuspend)*100/tTotal | ||
836 | for i in range(divTotal): | ||
837 | pos = "%0.3f" % (100 - ((float(i)*tS*100)/tTotal) - s0) | ||
838 | if((i == 0) and (s0 < 3)): | ||
839 | val = "" | ||
840 | elif(i == divSuspend): | ||
841 | val = "S/R" | ||
842 | else: | ||
843 | val = "%0.f" % (float(i-divSuspend)*tS*1000) | ||
844 | output += timescale.format(pos, val) | ||
845 | output += '</div>\n' | ||
846 | return output | ||
847 | |||
848 | # Function: createHTML | ||
849 | # Description: | ||
850 | # Create the output html file. | ||
851 | def createHTML(): | ||
852 | global sysvals, data | ||
853 | |||
854 | data.normalizeTime() | ||
855 | |||
856 | # html function templates | ||
857 | headline_stamp = '<div class="stamp">{0} {1} {2} {3}</div>\n' | ||
858 | html_zoombox = '<center><button id="zoomin">ZOOM IN</button><button id="zoomout">ZOOM OUT</button><button id="zoomdef">ZOOM 1:1</button></center>\n<div id="dmesgzoombox" class="zoombox">\n' | ||
859 | html_timeline = '<div id="{0}" class="timeline" style="height:{1}px">\n' | ||
860 | html_device = '<div id="{0}" title="{1}" class="thread" style="left:{2}%;top:{3}%;height:{4}%;width:{5}%;">{6}</div>\n' | ||
861 | html_phase = '<div class="phase" style="left:{0}%;width:{1}%;top:{2}%;height:{3}%;background-color:{4}">{5}</div>\n' | ||
862 | html_legend = '<div class="square" style="left:{0}%;background-color:{1}"> {2}</div>\n' | ||
863 | html_timetotal = '<table class="time1">\n<tr>'\ | ||
864 | '<td class="gray">{2} Suspend Time: <b>{0} ms</b></td>'\ | ||
865 | '<td class="gray">{2} Resume Time: <b>{1} ms</b></td>'\ | ||
866 | '</tr>\n</table>\n' | ||
867 | html_timegroups = '<table class="time2">\n<tr>'\ | ||
868 | '<td class="green">Kernel Suspend: {0} ms</td>'\ | ||
869 | '<td class="purple">Firmware Suspend: {1} ms</td>'\ | ||
870 | '<td class="purple">Firmware Resume: {2} ms</td>'\ | ||
871 | '<td class="yellow">Kernel Resume: {3} ms</td>'\ | ||
872 | '</tr>\n</table>\n' | ||
873 | |||
874 | # device timeline (dmesg) | ||
875 | if(data.usedmesg): | ||
876 | data.vprint("Creating Device Timeline...") | ||
877 | devtl = Timeline() | ||
878 | |||
879 | # Generate the header for this timeline | ||
880 | t0 = data.start | ||
881 | tMax = data.end | ||
882 | tTotal = tMax - t0 | ||
883 | if(tTotal == 0): | ||
884 | print("ERROR: No timeline data") | ||
885 | sys.exit() | ||
886 | suspend_time = "%.0f"%(-data.start*1000) | ||
887 | resume_time = "%.0f"%(data.end*1000) | ||
888 | if data.fwValid: | ||
889 | devtl.html['timeline'] = html_timetotal.format(suspend_time, resume_time, "Total") | ||
890 | sktime = "%.3f"%((data.dmesg['suspend_cpu']['end'] - data.dmesg['suspend_general']['start'])*1000) | ||
891 | sftime = "%.3f"%(data.fwSuspend / 1000000.0) | ||
892 | rftime = "%.3f"%(data.fwResume / 1000000.0) | ||
893 | rktime = "%.3f"%((data.dmesg['resume_general']['end'] - data.dmesg['resume_cpu']['start'])*1000) | ||
894 | devtl.html['timeline'] += html_timegroups.format(sktime, sftime, rftime, rktime) | ||
895 | else: | ||
896 | devtl.html['timeline'] = html_timetotal.format(suspend_time, resume_time, "Kernel") | ||
897 | |||
898 | # determine the maximum number of rows we need to draw | ||
899 | timelinerows = 0 | ||
900 | for phase in data.dmesg: | ||
901 | list = data.dmesg[phase]['list'] | ||
902 | rows = setTimelineRows(list, list) | ||
903 | data.dmesg[phase]['row'] = rows | ||
904 | if(rows > timelinerows): | ||
905 | timelinerows = rows | ||
906 | |||
907 | # calculate the timeline height and create its bounding box | ||
908 | devtl.setRows(timelinerows + 1) | ||
909 | devtl.html['timeline'] += html_zoombox; | ||
910 | devtl.html['timeline'] += html_timeline.format("dmesg", devtl.height); | ||
911 | |||
912 | # draw the colored boxes for each of the phases | ||
913 | for b in data.dmesg: | ||
914 | phase = data.dmesg[b] | ||
915 | left = "%.3f" % (((phase['start']-data.start)*100)/tTotal) | ||
916 | width = "%.3f" % (((phase['end']-phase['start'])*100)/tTotal) | ||
917 | devtl.html['timeline'] += html_phase.format(left, width, "%.3f"%devtl.scaleH, "%.3f"%(100-devtl.scaleH), data.dmesg[b]['color'], "") | ||
918 | |||
919 | # draw the time scale, try to make the number of labels readable | ||
920 | devtl.html['scale'] = createTimeScale(t0, tMax, data.tSuspended) | ||
921 | devtl.html['timeline'] += devtl.html['scale'] | ||
922 | for b in data.dmesg: | ||
923 | phaselist = data.dmesg[b]['list'] | ||
924 | for d in phaselist: | ||
925 | name = d | ||
926 | if(d in data.altdevname): | ||
927 | name = data.altdevname[d] | ||
928 | dev = phaselist[d] | ||
929 | height = (100.0 - devtl.scaleH)/data.dmesg[b]['row'] | ||
930 | top = "%.3f" % ((dev['row']*height) + devtl.scaleH) | ||
931 | left = "%.3f" % (((dev['start']-data.start)*100)/tTotal) | ||
932 | width = "%.3f" % (((dev['end']-dev['start'])*100)/tTotal) | ||
933 | len = " (%0.3f ms) " % ((dev['end']-dev['start'])*1000) | ||
934 | color = "rgba(204,204,204,0.5)" | ||
935 | devtl.html['timeline'] += html_device.format(dev['id'], name+len+b, left, top, "%.3f"%height, width, name) | ||
936 | |||
937 | # timeline is finished | ||
938 | devtl.html['timeline'] += "</div>\n</div>\n" | ||
939 | |||
940 | # draw a legend which describes the phases by color | ||
941 | devtl.html['legend'] = "<div class=\"legend\">\n" | ||
942 | pdelta = 100.0/data.phases.__len__() | ||
943 | pmargin = pdelta / 4.0 | ||
944 | for phase in data.phases: | ||
945 | order = "%.2f" % ((data.dmesg[phase]['order'] * pdelta) + pmargin) | ||
946 | name = string.replace(phase, "_", " ") | ||
947 | devtl.html['legend'] += html_legend.format(order, data.dmesg[phase]['color'], name) | ||
948 | devtl.html['legend'] += "</div>\n" | ||
949 | |||
950 | hf = open(sysvals.htmlfile, 'w') | ||
951 | thread_height = 0 | ||
952 | |||
953 | # write the html header first (html head, css code, everything up to the start of body) | ||
954 | html_header = "<!DOCTYPE html>\n<html>\n<head>\n\ | ||
955 | <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n\ | ||
956 | <title>AnalyzeSuspend</title>\n\ | ||
957 | <style type='text/css'>\n\ | ||
958 | body {overflow-y: scroll;}\n\ | ||
959 | .stamp {width: 100%;text-align:center;background-color:gray;line-height:30px;color:white;font: 25px Arial;}\n\ | ||
960 | .callgraph {margin-top: 30px;box-shadow: 5px 5px 20px black;}\n\ | ||
961 | .callgraph article * {padding-left: 28px;}\n\ | ||
962 | h1 {color:black;font: bold 30px Times;}\n\ | ||
963 | table {width:100%;}\n\ | ||
964 | .gray {background-color:rgba(80,80,80,0.1);}\n\ | ||
965 | .green {background-color:rgba(204,255,204,0.4);}\n\ | ||
966 | .purple {background-color:rgba(128,0,128,0.2);}\n\ | ||
967 | .yellow {background-color:rgba(255,255,204,0.4);}\n\ | ||
968 | .time1 {font: 22px Arial;border:1px solid;}\n\ | ||
969 | .time2 {font: 15px Arial;border-bottom:1px solid;border-left:1px solid;border-right:1px solid;}\n\ | ||
970 | td {text-align: center;}\n\ | ||
971 | .tdhl {color: red;}\n\ | ||
972 | .hide {display: none;}\n\ | ||
973 | .pf {display: none;}\n\ | ||
974 | .pf:checked + label {background: url(\'data:image/svg+xml;utf,<?xml version=\"1.0\" standalone=\"no\"?><svg xmlns=\"http://www.w3.org/2000/svg\" height=\"18\" width=\"18\" version=\"1.1\"><circle cx=\"9\" cy=\"9\" r=\"8\" stroke=\"black\" stroke-width=\"1\" fill=\"white\"/><rect x=\"4\" y=\"8\" width=\"10\" height=\"2\" style=\"fill:black;stroke-width:0\"/><rect x=\"8\" y=\"4\" width=\"2\" height=\"10\" style=\"fill:black;stroke-width:0\"/></svg>\') no-repeat left center;}\n\ | ||
975 | .pf:not(:checked) ~ label {background: url(\'data:image/svg+xml;utf,<?xml version=\"1.0\" standalone=\"no\"?><svg xmlns=\"http://www.w3.org/2000/svg\" height=\"18\" width=\"18\" version=\"1.1\"><circle cx=\"9\" cy=\"9\" r=\"8\" stroke=\"black\" stroke-width=\"1\" fill=\"white\"/><rect x=\"4\" y=\"8\" width=\"10\" height=\"2\" style=\"fill:black;stroke-width:0\"/></svg>\') no-repeat left center;}\n\ | ||
976 | .pf:checked ~ *:not(:nth-child(2)) {display: none;}\n\ | ||
977 | .zoombox {position: relative; width: 100%; overflow-x: scroll;}\n\ | ||
978 | .timeline {position: relative; font-size: 14px;cursor: pointer;width: 100%; overflow: hidden; background-color:#dddddd;}\n\ | ||
979 | .thread {position: absolute; height: "+"%.3f"%thread_height+"%; overflow: hidden; line-height: 30px; border:1px solid;text-align:center;white-space:nowrap;background-color:rgba(204,204,204,0.5);}\n\ | ||
980 | .thread:hover {background-color:white;border:1px solid red;z-index:10;}\n\ | ||
981 | .phase {position: absolute;overflow: hidden;border:0px;text-align:center;}\n\ | ||
982 | .t {position: absolute; top: 0%; height: 100%; border-right:1px solid black;}\n\ | ||
983 | .legend {position: relative; width: 100%; height: 40px; text-align: center;margin-bottom:20px}\n\ | ||
984 | .legend .square {position:absolute;top:10px; width: 0px;height: 20px;border:1px solid;padding-left:20px;}\n\ | ||
985 | button {height:40px;width:200px;margin-bottom:20px;margin-top:20px;font-size:24px;}\n\ | ||
986 | </style>\n</head>\n<body>\n" | ||
987 | hf.write(html_header) | ||
988 | |||
989 | # write the test title and general info header | ||
990 | if(data.stamp['time'] != ""): | ||
991 | hf.write(headline_stamp.format(data.stamp['host'], | ||
992 | data.stamp['kernel'], data.stamp['mode'], data.stamp['time'])) | ||
993 | |||
994 | # write the dmesg data (device timeline) | ||
995 | if(data.usedmesg): | ||
996 | hf.write(devtl.html['timeline']) | ||
997 | hf.write(devtl.html['legend']) | ||
998 | hf.write('<div id="devicedetail"></div>\n') | ||
999 | hf.write('<div id="devicetree"></div>\n') | ||
1000 | |||
1001 | # write the ftrace data (callgraph) | ||
1002 | if(data.useftrace): | ||
1003 | hf.write('<section id="callgraphs" class="callgraph">\n') | ||
1004 | # write out the ftrace data converted to html | ||
1005 | html_func_top = '<article id="{0}" class="atop" style="background-color:{1}">\n<input type="checkbox" class="pf" id="f{2}" checked/><label for="f{2}">{3} {4}</label>\n' | ||
1006 | html_func_start = '<article>\n<input type="checkbox" class="pf" id="f{0}" checked/><label for="f{0}">{1} {2}</label>\n' | ||
1007 | html_func_end = '</article>\n' | ||
1008 | html_func_leaf = '<article>{0} {1}</article>\n' | ||
1009 | num = 0 | ||
1010 | for p in data.phases: | ||
1011 | list = data.dmesg[p]['list'] | ||
1012 | for devname in data.sortedDevices(p): | ||
1013 | if('ftrace' not in list[devname]): | ||
1014 | continue | ||
1015 | name = devname | ||
1016 | if(devname in data.altdevname): | ||
1017 | name = data.altdevname[devname] | ||
1018 | devid = list[devname]['id'] | ||
1019 | cg = list[devname]['ftrace'] | ||
1020 | flen = "(%.3f ms)" % ((cg.end - cg.start)*1000) | ||
1021 | hf.write(html_func_top.format(devid, data.dmesg[p]['color'], num, name+" "+p, flen)) | ||
1022 | num += 1 | ||
1023 | for line in cg.list: | ||
1024 | if(line.length < 0.000000001): | ||
1025 | flen = "" | ||
1026 | else: | ||
1027 | flen = "(%.3f ms)" % (line.length*1000) | ||
1028 | if(line.freturn and line.fcall): | ||
1029 | hf.write(html_func_leaf.format(line.name, flen)) | ||
1030 | elif(line.freturn): | ||
1031 | hf.write(html_func_end) | ||
1032 | else: | ||
1033 | hf.write(html_func_start.format(num, line.name, flen)) | ||
1034 | num += 1 | ||
1035 | hf.write(html_func_end) | ||
1036 | hf.write("\n\n </section>\n") | ||
1037 | # write the footer and close | ||
1038 | addScriptCode(hf) | ||
1039 | hf.write("</body>\n</html>\n") | ||
1040 | hf.close() | ||
1041 | return True | ||
1042 | |||
1043 | def addScriptCode(hf): | ||
1044 | global data | ||
1045 | |||
1046 | t0 = (data.start - data.tSuspended) * 1000 | ||
1047 | tMax = (data.end - data.tSuspended) * 1000 | ||
1048 | # create an array in javascript memory with the device details | ||
1049 | detail = ' var bounds = [%f,%f];\n' % (t0, tMax) | ||
1050 | detail += ' var d = [];\n' | ||
1051 | dfmt = ' d["%s"] = { n:"%s", p:"%s", c:[%s] };\n'; | ||
1052 | for p in data.dmesg: | ||
1053 | list = data.dmesg[p]['list'] | ||
1054 | for d in list: | ||
1055 | parent = data.deviceParentID(d, p) | ||
1056 | idlist = data.deviceChildrenIDs(d, p) | ||
1057 | idstr = "" | ||
1058 | for i in idlist: | ||
1059 | if(idstr == ""): | ||
1060 | idstr += '"'+i+'"' | ||
1061 | else: | ||
1062 | idstr += ', '+'"'+i+'"' | ||
1063 | detail += dfmt % (list[d]['id'], d, parent, idstr) | ||
1064 | |||
1065 | # add the code which will manipulate the data in the browser | ||
1066 | script_code = \ | ||
1067 | '<script type="text/javascript">\n'+detail+\ | ||
1068 | ' var filter = [];\n'\ | ||
1069 | ' var table = [];\n'\ | ||
1070 | ' function deviceParent(devid) {\n'\ | ||
1071 | ' var devlist = [];\n'\ | ||
1072 | ' if(filter.indexOf(devid) < 0) filter[filter.length] = devid;\n'\ | ||
1073 | ' if(d[devid].p in d)\n'\ | ||
1074 | ' devlist = deviceParent(d[devid].p);\n'\ | ||
1075 | ' else if(d[devid].p != "")\n'\ | ||
1076 | ' devlist = [d[devid].p];\n'\ | ||
1077 | ' devlist[devlist.length] = d[devid].n;\n'\ | ||
1078 | ' return devlist;\n'\ | ||
1079 | ' }\n'\ | ||
1080 | ' function deviceChildren(devid, column, row) {\n'\ | ||
1081 | ' if(!(devid in d)) return;\n'\ | ||
1082 | ' if(filter.indexOf(devid) < 0) filter[filter.length] = devid;\n'\ | ||
1083 | ' var cell = {name: d[devid].n, span: 1};\n'\ | ||
1084 | ' var span = 0;\n'\ | ||
1085 | ' if(column >= table.length) table[column] = [];\n'\ | ||
1086 | ' table[column][row] = cell;\n'\ | ||
1087 | ' for(var i = 0; i < d[devid].c.length; i++) {\n'\ | ||
1088 | ' var cid = d[devid].c[i];\n'\ | ||
1089 | ' span += deviceChildren(cid, column+1, row+span);\n'\ | ||
1090 | ' }\n'\ | ||
1091 | ' if(span == 0) span = 1;\n'\ | ||
1092 | ' table[column][row].span = span;\n'\ | ||
1093 | ' return span;\n'\ | ||
1094 | ' }\n'\ | ||
1095 | ' function deviceTree(devid, resume) {\n'\ | ||
1096 | ' var html = "<table border=1>";\n'\ | ||
1097 | ' filter = [];\n'\ | ||
1098 | ' table = [];\n'\ | ||
1099 | ' plist = deviceParent(devid);\n'\ | ||
1100 | ' var devidx = plist.length - 1;\n'\ | ||
1101 | ' for(var i = 0; i < devidx; i++)\n'\ | ||
1102 | ' table[i] = [{name: plist[i], span: 1}];\n'\ | ||
1103 | ' deviceChildren(devid, devidx, 0);\n'\ | ||
1104 | ' for(var i = 0; i < devidx; i++)\n'\ | ||
1105 | ' table[i][0].span = table[devidx][0].span;\n'\ | ||
1106 | ' for(var row = 0; row < table[0][0].span; row++) {\n'\ | ||
1107 | ' html += "<tr>";\n'\ | ||
1108 | ' for(var col = 0; col < table.length; col++)\n'\ | ||
1109 | ' if(row in table[col]) {\n'\ | ||
1110 | ' var cell = table[col][row];\n'\ | ||
1111 | ' var args = "";\n'\ | ||
1112 | ' if(cell.span > 1)\n'\ | ||
1113 | ' args += " rowspan="+cell.span;\n'\ | ||
1114 | ' if((col == devidx) && (row == 0))\n'\ | ||
1115 | ' args += " class=tdhl";\n'\ | ||
1116 | ' if(resume)\n'\ | ||
1117 | ' html += "<td"+args+">"+cell.name+" →</td>";\n'\ | ||
1118 | ' else\n'\ | ||
1119 | ' html += "<td"+args+">← "+cell.name+"</td>";\n'\ | ||
1120 | ' }\n'\ | ||
1121 | ' html += "</tr>";\n'\ | ||
1122 | ' }\n'\ | ||
1123 | ' html += "</table>";\n'\ | ||
1124 | ' return html;\n'\ | ||
1125 | ' }\n'\ | ||
1126 | ' function zoomTimeline() {\n'\ | ||
1127 | ' var timescale = document.getElementById("timescale");\n'\ | ||
1128 | ' var dmesg = document.getElementById("dmesg");\n'\ | ||
1129 | ' var zoombox = document.getElementById("dmesgzoombox");\n'\ | ||
1130 | ' var val = parseFloat(dmesg.style.width);\n'\ | ||
1131 | ' var newval = 100;\n'\ | ||
1132 | ' var sh = window.outerWidth / 2;\n'\ | ||
1133 | ' if(this.id == "zoomin") {\n'\ | ||
1134 | ' newval = val * 1.2;\n'\ | ||
1135 | ' if(newval > 40000) newval = 40000;\n'\ | ||
1136 | ' dmesg.style.width = newval+"%";\n'\ | ||
1137 | ' zoombox.scrollLeft = ((zoombox.scrollLeft + sh) * newval / val) - sh;\n'\ | ||
1138 | ' } else if (this.id == "zoomout") {\n'\ | ||
1139 | ' newval = val / 1.2;\n'\ | ||
1140 | ' if(newval < 100) newval = 100;\n'\ | ||
1141 | ' dmesg.style.width = newval+"%";\n'\ | ||
1142 | ' zoombox.scrollLeft = ((zoombox.scrollLeft + sh) * newval / val) - sh;\n'\ | ||
1143 | ' } else {\n'\ | ||
1144 | ' zoombox.scrollLeft = 0;\n'\ | ||
1145 | ' dmesg.style.width = "100%";\n'\ | ||
1146 | ' }\n'\ | ||
1147 | ' var html = "";\n'\ | ||
1148 | ' var t0 = bounds[0];\n'\ | ||
1149 | ' var tMax = bounds[1];\n'\ | ||
1150 | ' var tTotal = tMax - t0;\n'\ | ||
1151 | ' var wTotal = tTotal * 100.0 / newval;\n'\ | ||
1152 | ' for(var tS = 1000; (wTotal / tS) < 3; tS /= 10);\n'\ | ||
1153 | ' if(tS < 1) tS = 1;\n'\ | ||
1154 | ' for(var s = ((t0 / tS)|0) * tS; s < tMax; s += tS) {\n'\ | ||
1155 | ' var pos = (tMax - s) * 100.0 / tTotal;\n'\ | ||
1156 | ' var name = (s == 0)?"S/R":(s+"ms");\n'\ | ||
1157 | ' html += \"<div class=\\\"t\\\" style=\\\"right:\"+pos+\"%\\\">\"+name+\"</div>\";\n'\ | ||
1158 | ' }\n'\ | ||
1159 | ' timescale.innerHTML = html;\n'\ | ||
1160 | ' }\n'\ | ||
1161 | ' function deviceDetail() {\n'\ | ||
1162 | ' var devtitle = document.getElementById("devicedetail");\n'\ | ||
1163 | ' devtitle.innerHTML = "<h1>"+this.title+"</h1>";\n'\ | ||
1164 | ' var devtree = document.getElementById("devicetree");\n'\ | ||
1165 | ' devtree.innerHTML = deviceTree(this.id, (this.title.indexOf("resume") >= 0));\n'\ | ||
1166 | ' var cglist = document.getElementById("callgraphs");\n'\ | ||
1167 | ' if(!cglist) return;\n'\ | ||
1168 | ' var cg = cglist.getElementsByClassName("atop");\n'\ | ||
1169 | ' for (var i = 0; i < cg.length; i++) {\n'\ | ||
1170 | ' if(filter.indexOf(cg[i].id) >= 0) {\n'\ | ||
1171 | ' cg[i].style.display = "block";\n'\ | ||
1172 | ' } else {\n'\ | ||
1173 | ' cg[i].style.display = "none";\n'\ | ||
1174 | ' }\n'\ | ||
1175 | ' }\n'\ | ||
1176 | ' }\n'\ | ||
1177 | ' window.addEventListener("load", function () {\n'\ | ||
1178 | ' var dmesg = document.getElementById("dmesg");\n'\ | ||
1179 | ' dmesg.style.width = "100%"\n'\ | ||
1180 | ' document.getElementById("zoomin").onclick = zoomTimeline;\n'\ | ||
1181 | ' document.getElementById("zoomout").onclick = zoomTimeline;\n'\ | ||
1182 | ' document.getElementById("zoomdef").onclick = zoomTimeline;\n'\ | ||
1183 | ' var dev = dmesg.getElementsByClassName("thread");\n'\ | ||
1184 | ' for (var i = 0; i < dev.length; i++) {\n'\ | ||
1185 | ' dev[i].onclick = deviceDetail;\n'\ | ||
1186 | ' }\n'\ | ||
1187 | ' zoomTimeline();\n'\ | ||
1188 | ' });\n'\ | ||
1189 | '</script>\n' | ||
1190 | hf.write(script_code); | ||
1191 | |||
1192 | # Function: executeSuspend | ||
1193 | # Description: | ||
1194 | # Execute system suspend through the sysfs interface | ||
1195 | def executeSuspend(): | ||
1196 | global sysvals, data | ||
1197 | |||
1198 | detectUSB() | ||
1199 | pf = open(sysvals.powerfile, 'w') | ||
1200 | # clear the kernel ring buffer just as we start | ||
1201 | os.system("dmesg -C") | ||
1202 | # start ftrace | ||
1203 | if(data.useftrace): | ||
1204 | print("START TRACING") | ||
1205 | os.system("echo 1 > "+sysvals.tpath+"tracing_on") | ||
1206 | os.system("echo SUSPEND START > "+sysvals.tpath+"trace_marker") | ||
1207 | # initiate suspend | ||
1208 | if(sysvals.rtcwake): | ||
1209 | print("SUSPEND START") | ||
1210 | os.system("rtcwake -s 10 -m "+sysvals.suspendmode) | ||
1211 | else: | ||
1212 | print("SUSPEND START (press a key to resume)") | ||
1213 | pf.write(sysvals.suspendmode) | ||
1214 | # execution will pause here | ||
1215 | pf.close() | ||
1216 | # return from suspend | ||
1217 | print("RESUME COMPLETE") | ||
1218 | # stop ftrace | ||
1219 | if(data.useftrace): | ||
1220 | os.system("echo RESUME COMPLETE > "+sysvals.tpath+"trace_marker") | ||
1221 | os.system("echo 0 > "+sysvals.tpath+"tracing_on") | ||
1222 | print("CAPTURING FTRACE") | ||
1223 | os.system("echo \""+sysvals.teststamp+"\" > "+sysvals.ftracefile) | ||
1224 | os.system("cat "+sysvals.tpath+"trace >> "+sysvals.ftracefile) | ||
1225 | # grab a copy of the dmesg output | ||
1226 | print("CAPTURING DMESG") | ||
1227 | os.system("echo \""+sysvals.teststamp+"\" > "+sysvals.dmesgfile) | ||
1228 | os.system("dmesg -c >> "+sysvals.dmesgfile) | ||
1229 | |||
1230 | # Function: detectUSB | ||
1231 | # Description: | ||
1232 | # Detect all the USB hosts and devices currently connected | ||
1233 | def detectUSB(): | ||
1234 | global sysvals, data | ||
1235 | |||
1236 | for dirname, dirnames, filenames in os.walk("/sys/devices"): | ||
1237 | if(re.match(r".*/usb[0-9]*.*", dirname) and | ||
1238 | "idVendor" in filenames and "idProduct" in filenames): | ||
1239 | vid = os.popen("cat %s/idVendor 2>/dev/null" % dirname).read().replace('\n', '') | ||
1240 | pid = os.popen("cat %s/idProduct 2>/dev/null" % dirname).read().replace('\n', '') | ||
1241 | product = os.popen("cat %s/product 2>/dev/null" % dirname).read().replace('\n', '') | ||
1242 | name = dirname.split('/')[-1] | ||
1243 | if(len(product) > 0): | ||
1244 | data.altdevname[name] = "%s [%s]" % (product, name) | ||
1245 | else: | ||
1246 | data.altdevname[name] = "%s:%s [%s]" % (vid, pid, name) | ||
1247 | |||
1248 | def getModes(): | ||
1249 | global sysvals | ||
1250 | modes = "" | ||
1251 | if(os.path.exists(sysvals.powerfile)): | ||
1252 | fp = open(sysvals.powerfile, 'r') | ||
1253 | modes = string.split(fp.read()) | ||
1254 | fp.close() | ||
1255 | return modes | ||
1256 | |||
1257 | # Function: statusCheck | ||
1258 | # Description: | ||
1259 | # Verify that the requested command and options will work | ||
1260 | def statusCheck(dryrun): | ||
1261 | global sysvals, data | ||
1262 | res = dict() | ||
1263 | |||
1264 | if(data.notestrun): | ||
1265 | print("SUCCESS: The command should run!") | ||
1266 | return | ||
1267 | |||
1268 | # check we have root access | ||
1269 | check = "YES" | ||
1270 | if(os.environ['USER'] != "root"): | ||
1271 | if(not dryrun): | ||
1272 | doError("root access is required", False) | ||
1273 | check = "NO" | ||
1274 | res[" have root access: "] = check | ||
1275 | |||
1276 | # check sysfs is mounted | ||
1277 | check = "YES" | ||
1278 | if(not os.path.exists(sysvals.powerfile)): | ||
1279 | if(not dryrun): | ||
1280 | doError("sysfs must be mounted", False) | ||
1281 | check = "NO" | ||
1282 | res[" is sysfs mounted: "] = check | ||
1283 | |||
1284 | # check target mode is a valid mode | ||
1285 | check = "YES" | ||
1286 | modes = getModes() | ||
1287 | if(sysvals.suspendmode not in modes): | ||
1288 | if(not dryrun): | ||
1289 | doError("%s is not a value power mode" % sysvals.suspendmode, False) | ||
1290 | check = "NO" | ||
1291 | res[" is "+sysvals.suspendmode+" a power mode: "] = check | ||
1292 | |||
1293 | # check if ftrace is available | ||
1294 | if(data.useftrace): | ||
1295 | check = "YES" | ||
1296 | if(not verifyFtrace()): | ||
1297 | if(not dryrun): | ||
1298 | doError("ftrace is not configured", False) | ||
1299 | check = "NO" | ||
1300 | res[" is ftrace usable: "] = check | ||
1301 | |||
1302 | # check if rtcwake | ||
1303 | if(sysvals.rtcwake): | ||
1304 | check = "YES" | ||
1305 | version = os.popen("rtcwake -V 2>/dev/null").read() | ||
1306 | if(not version.startswith("rtcwake")): | ||
1307 | if(not dryrun): | ||
1308 | doError("rtcwake is not installed", False) | ||
1309 | check = "NO" | ||
1310 | res[" is rtcwake usable: "] = check | ||
1311 | |||
1312 | if(dryrun): | ||
1313 | status = True | ||
1314 | print("Checking if system can run the current command:") | ||
1315 | for r in res: | ||
1316 | print("%s\t%s" % (r, res[r])) | ||
1317 | if(res[r] != "YES"): | ||
1318 | status = False | ||
1319 | if(status): | ||
1320 | print("SUCCESS: The command should run!") | ||
1321 | else: | ||
1322 | print("FAILURE: The command won't run!") | ||
1323 | |||
1324 | def printHelp(): | ||
1325 | global sysvals | ||
1326 | modes = getModes() | ||
1327 | |||
1328 | print("") | ||
1329 | print("AnalyzeSuspend") | ||
1330 | print("Usage: sudo analyze_suspend.py <options>") | ||
1331 | print("") | ||
1332 | print("Description:") | ||
1333 | print(" Initiates a system suspend/resume while capturing dmesg") | ||
1334 | print(" and (optionally) ftrace data to analyze device timing") | ||
1335 | print("") | ||
1336 | print(" Generates output files in subdirectory: suspend-mmddyy-HHMMSS") | ||
1337 | print(" HTML output: <hostname>_<mode>.html") | ||
1338 | print(" raw dmesg output: <hostname>_<mode>_dmesg.txt") | ||
1339 | print(" raw ftrace output (with -f): <hostname>_<mode>_ftrace.txt") | ||
1340 | print("") | ||
1341 | print("Options:") | ||
1342 | print(" [general]") | ||
1343 | print(" -h Print this help text") | ||
1344 | print(" -verbose Print extra information during execution and analysis") | ||
1345 | print(" -status Test to see if the system is enabled to run this tool") | ||
1346 | print(" -modes List available suspend modes") | ||
1347 | print(" -m mode Mode to initiate for suspend %s (default: %s)") % (modes, sysvals.suspendmode) | ||
1348 | print(" -rtcwake Use rtcwake to autoresume after 10 seconds (default: disabled)") | ||
1349 | print(" -f Use ftrace to create device callgraphs (default: disabled)") | ||
1350 | print(" [re-analyze data from previous runs]") | ||
1351 | print(" -dmesg dmesgfile Create HTML timeline from dmesg file") | ||
1352 | print(" -ftrace ftracefile Create HTML callgraph from ftrace file") | ||
1353 | print("") | ||
1354 | return True | ||
1355 | |||
1356 | def doError(msg, help): | ||
1357 | print("ERROR: %s") % msg | ||
1358 | if(help == True): | ||
1359 | printHelp() | ||
1360 | sys.exit() | ||
1361 | |||
1362 | # -- script main -- | ||
1363 | # loop through the command line arguments | ||
1364 | cmd = "" | ||
1365 | args = iter(sys.argv[1:]) | ||
1366 | for arg in args: | ||
1367 | if(arg == "-m"): | ||
1368 | try: | ||
1369 | val = args.next() | ||
1370 | except: | ||
1371 | doError("No mode supplied", True) | ||
1372 | sysvals.suspendmode = val | ||
1373 | elif(arg == "-f"): | ||
1374 | data.useftrace = True | ||
1375 | elif(arg == "-modes"): | ||
1376 | cmd = "modes" | ||
1377 | elif(arg == "-status"): | ||
1378 | cmd = "status" | ||
1379 | elif(arg == "-verbose"): | ||
1380 | data.verbose = True | ||
1381 | elif(arg == "-rtcwake"): | ||
1382 | sysvals.rtcwake = True | ||
1383 | elif(arg == "-dmesg"): | ||
1384 | try: | ||
1385 | val = args.next() | ||
1386 | except: | ||
1387 | doError("No dmesg file supplied", True) | ||
1388 | data.notestrun = True | ||
1389 | data.usedmesg = True | ||
1390 | sysvals.dmesgfile = val | ||
1391 | elif(arg == "-ftrace"): | ||
1392 | try: | ||
1393 | val = args.next() | ||
1394 | except: | ||
1395 | doError("No ftrace file supplied", True) | ||
1396 | data.notestrun = True | ||
1397 | data.useftrace = True | ||
1398 | sysvals.ftracefile = val | ||
1399 | elif(arg == "-h"): | ||
1400 | printHelp() | ||
1401 | sys.exit() | ||
1402 | else: | ||
1403 | doError("Invalid argument: "+arg, True) | ||
1404 | |||
1405 | # just run a utility command and exit | ||
1406 | if(cmd != ""): | ||
1407 | if(cmd == "status"): | ||
1408 | statusCheck(True) | ||
1409 | elif(cmd == "modes"): | ||
1410 | modes = getModes() | ||
1411 | print modes | ||
1412 | sys.exit() | ||
1413 | |||
1414 | data.initialize() | ||
1415 | |||
1416 | # if instructed, re-analyze existing data files | ||
1417 | if(data.notestrun): | ||
1418 | sysvals.setOutputFile() | ||
1419 | data.vprint("Output file: %s" % sysvals.htmlfile) | ||
1420 | if(sysvals.dmesgfile != ""): | ||
1421 | analyzeKernelLog() | ||
1422 | if(sysvals.ftracefile != ""): | ||
1423 | analyzeTraceLog() | ||
1424 | createHTML() | ||
1425 | sys.exit() | ||
1426 | |||
1427 | # verify that we can run a test | ||
1428 | data.usedmesg = True | ||
1429 | statusCheck(False) | ||
1430 | |||
1431 | # prepare for the test | ||
1432 | if(data.useftrace): | ||
1433 | initFtrace() | ||
1434 | sysvals.initTestOutput() | ||
1435 | |||
1436 | data.vprint("Output files:\n %s" % sysvals.dmesgfile) | ||
1437 | if(data.useftrace): | ||
1438 | data.vprint(" %s" % sysvals.ftracefile) | ||
1439 | data.vprint(" %s" % sysvals.htmlfile) | ||
1440 | |||
1441 | # execute the test | ||
1442 | executeSuspend() | ||
1443 | analyzeKernelLog() | ||
1444 | if(data.useftrace): | ||
1445 | analyzeTraceLog() | ||
1446 | createHTML() | ||
diff --git a/tools/Makefile b/tools/Makefile index 927cd46d36dc..feec3ad5fd09 100644 --- a/tools/Makefile +++ b/tools/Makefile | |||
@@ -3,6 +3,7 @@ include scripts/Makefile.include | |||
3 | help: | 3 | help: |
4 | @echo 'Possible targets:' | 4 | @echo 'Possible targets:' |
5 | @echo '' | 5 | @echo '' |
6 | @echo ' acpi - ACPI tools' | ||
6 | @echo ' cgroup - cgroup tools' | 7 | @echo ' cgroup - cgroup tools' |
7 | @echo ' cpupower - a tool for all things x86 CPU power' | 8 | @echo ' cpupower - a tool for all things x86 CPU power' |
8 | @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' | 9 | @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' |
@@ -33,6 +34,9 @@ help: | |||
33 | @echo ' the respective build directory.' | 34 | @echo ' the respective build directory.' |
34 | @echo ' clean: a summary clean target to clean _all_ folders' | 35 | @echo ' clean: a summary clean target to clean _all_ folders' |
35 | 36 | ||
37 | acpi: FORCE | ||
38 | $(call descend,power/$@) | ||
39 | |||
36 | cpupower: FORCE | 40 | cpupower: FORCE |
37 | $(call descend,power/$@) | 41 | $(call descend,power/$@) |
38 | 42 | ||
@@ -54,6 +58,9 @@ turbostat x86_energy_perf_policy: FORCE | |||
54 | tmon: FORCE | 58 | tmon: FORCE |
55 | $(call descend,thermal/$@) | 59 | $(call descend,thermal/$@) |
56 | 60 | ||
61 | acpi_install: | ||
62 | $(call descend,power/$(@:_install=),install) | ||
63 | |||
57 | cpupower_install: | 64 | cpupower_install: |
58 | $(call descend,power/$(@:_install=),install) | 65 | $(call descend,power/$(@:_install=),install) |
59 | 66 | ||
@@ -69,11 +76,14 @@ turbostat_install x86_energy_perf_policy_install: | |||
69 | tmon_install: | 76 | tmon_install: |
70 | $(call descend,thermal/$(@:_install=),install) | 77 | $(call descend,thermal/$(@:_install=),install) |
71 | 78 | ||
72 | install: cgroup_install cpupower_install firewire_install lguest_install \ | 79 | install: acpi_install cgroup_install cpupower_install firewire_install lguest_install \ |
73 | perf_install selftests_install turbostat_install usb_install \ | 80 | perf_install selftests_install turbostat_install usb_install \ |
74 | virtio_install vm_install net_install x86_energy_perf_policy_install \ | 81 | virtio_install vm_install net_install x86_energy_perf_policy_install \ |
75 | tmon | 82 | tmon |
76 | 83 | ||
84 | acpi_clean: | ||
85 | $(call descend,power/acpi,clean) | ||
86 | |||
77 | cpupower_clean: | 87 | cpupower_clean: |
78 | $(call descend,power/cpupower,clean) | 88 | $(call descend,power/cpupower,clean) |
79 | 89 | ||
@@ -95,8 +105,8 @@ turbostat_clean x86_energy_perf_policy_clean: | |||
95 | tmon_clean: | 105 | tmon_clean: |
96 | $(call descend,thermal/tmon,clean) | 106 | $(call descend,thermal/tmon,clean) |
97 | 107 | ||
98 | clean: cgroup_clean cpupower_clean firewire_clean lguest_clean perf_clean \ | 108 | clean: acpi_clean cgroup_clean cpupower_clean firewire_clean lguest_clean \ |
99 | selftests_clean turbostat_clean usb_clean virtio_clean \ | 109 | perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ |
100 | vm_clean net_clean x86_energy_perf_policy_clean tmon_clean | 110 | vm_clean net_clean x86_energy_perf_policy_clean tmon_clean |
101 | 111 | ||
102 | .PHONY: FORCE | 112 | .PHONY: FORCE |
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index bafeb8d662a3..d9186a2fdf06 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile | |||
@@ -1,18 +1,143 @@ | |||
1 | PROG= acpidump | 1 | # tools/power/acpi/Makefile - ACPI tool Makefile |
2 | SRCS= acpidump.c | 2 | # |
3 | # Copyright (c) 2013, Intel Corporation | ||
4 | # Author: Lv Zheng <lv.zheng@intel.com> | ||
5 | # | ||
6 | # This program is free software; you can redistribute it and/or | ||
7 | # modify it under the terms of the GNU General Public License | ||
8 | # as published by the Free Software Foundation; version 2 | ||
9 | # of the License. | ||
10 | |||
11 | OUTPUT=./ | ||
12 | ifeq ("$(origin O)", "command line") | ||
13 | OUTPUT := $(O)/ | ||
14 | endif | ||
15 | |||
16 | ifneq ($(OUTPUT),) | ||
17 | # check that the output directory actually exists | ||
18 | OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd) | ||
19 | $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) | ||
20 | endif | ||
21 | |||
22 | # --- CONFIGURATION BEGIN --- | ||
23 | |||
24 | # Set the following to `true' to make a unstripped, unoptimized | ||
25 | # binary. Leave this set to `false' for production use. | ||
26 | DEBUG ?= true | ||
27 | |||
28 | # make the build silent. Set this to something else to make it noisy again. | ||
29 | V ?= false | ||
30 | |||
31 | # Prefix to the directories we're installing to | ||
32 | DESTDIR ?= | ||
33 | |||
34 | # --- CONFIGURATION END --- | ||
35 | |||
36 | # Directory definitions. These are default and most probably | ||
37 | # do not need to be changed. Please note that DESTDIR is | ||
38 | # added in front of any of them | ||
39 | |||
40 | bindir ?= /usr/bin | ||
41 | sbindir ?= /usr/sbin | ||
42 | mandir ?= /usr/man | ||
43 | |||
44 | # Toolchain: what tools do we use, and what options do they need: | ||
45 | |||
46 | INSTALL = /usr/bin/install -c | ||
47 | INSTALL_PROGRAM = ${INSTALL} | ||
48 | INSTALL_DATA = ${INSTALL} -m 644 | ||
49 | INSTALL_SCRIPT = ${INSTALL_PROGRAM} | ||
50 | |||
51 | # If you are running a cross compiler, you may want to set this | ||
52 | # to something more interesting, like "arm-linux-". If you want | ||
53 | # to compile vs uClibc, that can be done here as well. | ||
54 | CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- | ||
55 | CC = $(CROSS)gcc | ||
56 | LD = $(CROSS)gcc | ||
57 | STRIP = $(CROSS)strip | ||
58 | HOSTCC = gcc | ||
59 | |||
60 | # check if compiler option is supported | ||
61 | cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -x c /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;} | ||
62 | |||
63 | # use '-Os' optimization if available, else use -O2 | ||
64 | OPTIMIZATION := $(call cc-supports,-Os,-O2) | ||
65 | |||
66 | WARNINGS := -Wall | ||
67 | WARNINGS += $(call cc-supports,-Wstrict-prototypes) | ||
68 | WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) | ||
69 | |||
3 | KERNEL_INCLUDE := ../../../include | 70 | KERNEL_INCLUDE := ../../../include |
4 | CFLAGS += -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Os -s -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) | 71 | CFLAGS += -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) |
72 | CFLAGS += $(WARNINGS) | ||
73 | |||
74 | ifeq ($(strip $(V)),false) | ||
75 | QUIET=@ | ||
76 | ECHO=@echo | ||
77 | else | ||
78 | QUIET= | ||
79 | ECHO=@\# | ||
80 | endif | ||
81 | export QUIET ECHO | ||
82 | |||
83 | # if DEBUG is enabled, then we do not strip or optimize | ||
84 | ifeq ($(strip $(DEBUG)),true) | ||
85 | CFLAGS += -O1 -g -DDEBUG | ||
86 | STRIPCMD = /bin/true -Since_we_are_debugging | ||
87 | else | ||
88 | CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer | ||
89 | STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment | ||
90 | endif | ||
91 | |||
92 | # if DEBUG is enabled, then we do not strip or optimize | ||
93 | ifeq ($(strip $(DEBUG)),true) | ||
94 | CFLAGS += -O1 -g -DDEBUG | ||
95 | STRIPCMD = /bin/true -Since_we_are_debugging | ||
96 | else | ||
97 | CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer | ||
98 | STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment | ||
99 | endif | ||
100 | |||
101 | # --- ACPIDUMP BEGIN --- | ||
102 | |||
103 | vpath %.c \ | ||
104 | tools/acpidump | ||
105 | |||
106 | DUMP_OBJS = \ | ||
107 | acpidump.o | ||
108 | |||
109 | DUMP_OBJS := $(addprefix $(OUTPUT)tools/acpidump/,$(DUMP_OBJS)) | ||
110 | |||
111 | $(OUTPUT)acpidump: $(DUMP_OBJS) | ||
112 | $(ECHO) " LD " $@ | ||
113 | $(QUIET) $(LD) $(CFLAGS) $(LDFLAGS) $(DUMP_OBJS) -L$(OUTPUT) -o $@ | ||
114 | $(QUIET) $(STRIPCMD) $@ | ||
115 | |||
116 | $(OUTPUT)tools/acpidump/%.o: %.c | ||
117 | $(ECHO) " CC " $@ | ||
118 | $(QUIET) $(CC) -c $(CFLAGS) -o $@ $< | ||
119 | |||
120 | # --- ACPIDUMP END --- | ||
121 | |||
122 | all: $(OUTPUT)acpidump | ||
123 | echo $(OUTPUT) | ||
124 | |||
125 | clean: | ||
126 | -find $(OUTPUT) \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | ||
127 | | xargs rm -f | ||
128 | -rm -f $(OUTPUT)acpidump | ||
5 | 129 | ||
6 | all: acpidump | 130 | install-tools: |
7 | $(PROG) : $(SRCS) | 131 | $(INSTALL) -d $(DESTDIR)${bindir} |
8 | $(CC) $(CFLAGS) $(SRCS) -o $(PROG) | 132 | $(INSTALL_PROGRAM) $(OUTPUT)acpidump $(DESTDIR)${sbindir} |
9 | 133 | ||
10 | CLEANFILES= $(PROG) | 134 | install-man: |
135 | $(INSTALL_DATA) -D man/acpidump.8 $(DESTDIR)${mandir}/man8/acpidump.8 | ||
11 | 136 | ||
12 | clean : | 137 | install: all install-tools install-man |
13 | rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~ | ||
14 | 138 | ||
15 | install : | 139 | uninstall: |
16 | install acpidump /usr/sbin/acpidump | 140 | - rm -f $(DESTDIR)${sbindir}/acpidump |
17 | install acpidump.8 /usr/share/man/man8 | 141 | - rm -f $(DESTDIR)${mandir}/man8/acpidump.8 |
18 | 142 | ||
143 | .PHONY: all utils install-tools install-man install uninstall clean | ||
diff --git a/tools/power/acpi/acpidump.8 b/tools/power/acpi/man/acpidump.8 index adfa99166e5e..adfa99166e5e 100644 --- a/tools/power/acpi/acpidump.8 +++ b/tools/power/acpi/man/acpidump.8 | |||
diff --git a/tools/power/acpi/acpidump.c b/tools/power/acpi/tools/acpidump/acpidump.c index a84553a0e0df..a84553a0e0df 100644 --- a/tools/power/acpi/acpidump.c +++ b/tools/power/acpi/tools/acpidump/acpidump.c | |||
diff --git a/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c index 66cace601e57..0f10b81e3322 100644 --- a/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c +++ b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c | |||
@@ -25,12 +25,9 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | 28 | #include <linux/acpi.h> | |
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | 30 | ||
31 | #include <acpi/acpi_bus.h> | ||
32 | #include <acpi/acpi_drivers.h> | ||
33 | |||
34 | static int pm_tmr_ioport = 0; | 31 | static int pm_tmr_ioport = 0; |
35 | 32 | ||
36 | /*helper function to safely read acpi pm timesource*/ | 33 | /*helper function to safely read acpi pm timesource*/ |
diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c index dd1539eb8c63..a416de80c55e 100644 --- a/tools/power/cpupower/utils/cpufreq-set.c +++ b/tools/power/cpupower/utils/cpufreq-set.c | |||
@@ -257,7 +257,7 @@ int cmd_freq_set(int argc, char **argv) | |||
257 | print_unknown_arg(); | 257 | print_unknown_arg(); |
258 | return -EINVAL; | 258 | return -EINVAL; |
259 | } | 259 | } |
260 | if ((sscanf(optarg, "%s", gov)) != 1) { | 260 | if ((sscanf(optarg, "%19s", gov)) != 1) { |
261 | print_unknown_arg(); | 261 | print_unknown_arg(); |
262 | return -EINVAL; | 262 | return -EINVAL; |
263 | } | 263 | } |