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 | } |
