diff options
299 files changed, 5316 insertions, 1828 deletions
diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt index b60d2ab69497..9b121a569ab4 100644 --- a/Documentation/acpi/enumeration.txt +++ b/Documentation/acpi/enumeration.txt | |||
@@ -243,7 +243,7 @@ input driver: | |||
243 | .owner = THIS_MODULE, | 243 | .owner = THIS_MODULE, |
244 | .pm = &mpu3050_pm, | 244 | .pm = &mpu3050_pm, |
245 | .of_match_table = mpu3050_of_match, | 245 | .of_match_table = mpu3050_of_match, |
246 | .acpi_match_table ACPI_PTR(mpu3050_acpi_match), | 246 | .acpi_match_table = ACPI_PTR(mpu3050_acpi_match), |
247 | }, | 247 | }, |
248 | .probe = mpu3050_probe, | 248 | .probe = mpu3050_probe, |
249 | .remove = mpu3050_remove, | 249 | .remove = mpu3050_remove, |
diff --git a/Documentation/cpu-freq/intel-pstate.txt b/Documentation/cpu-freq/intel-pstate.txt index 765d7fc0e692..655750743fb0 100644 --- a/Documentation/cpu-freq/intel-pstate.txt +++ b/Documentation/cpu-freq/intel-pstate.txt | |||
@@ -37,6 +37,14 @@ controlling P state selection. These files have been added to | |||
37 | no_turbo: limits the driver to selecting P states below the turbo | 37 | no_turbo: limits the driver to selecting P states below the turbo |
38 | frequency range. | 38 | frequency range. |
39 | 39 | ||
40 | turbo_pct: displays the percentage of the total performance that | ||
41 | is supported by hardware that is in the turbo range. This number | ||
42 | is independent of whether turbo has been disabled or not. | ||
43 | |||
44 | num_pstates: displays the number of pstates that are supported | ||
45 | by hardware. This number is independent of whether turbo has | ||
46 | been disabled or not. | ||
47 | |||
40 | For contemporary Intel processors, the frequency is controlled by the | 48 | For contemporary Intel processors, the frequency is controlled by the |
41 | processor itself and the P-states exposed to software are related to | 49 | processor itself and the P-states exposed to software are related to |
42 | performance levels. The idea that frequency can be set to a single | 50 | performance levels. The idea that frequency can be set to a single |
diff --git a/Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt b/Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt new file mode 100644 index 000000000000..b54bf3a2ff57 --- /dev/null +++ b/Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt | |||
@@ -0,0 +1,110 @@ | |||
1 | |||
2 | * Samsung Exynos PPMU (Platform Performance Monitoring Unit) device | ||
3 | |||
4 | The Samsung Exynos SoC has PPMU (Platform Performance Monitoring Unit) for | ||
5 | each IP. PPMU provides the primitive values to get performance data. These | ||
6 | PPMU events provide information of the SoC's behaviors so that you may | ||
7 | use to analyze system performance, to make behaviors visible and to count | ||
8 | usages of each IP (DMC, CPU, RIGHTBUS, LEFTBUS, CAM interface, LCD, G3D, MFC). | ||
9 | The Exynos PPMU driver uses the devfreq-event class to provide event data | ||
10 | to various devfreq devices. The devfreq devices would use the event data when | ||
11 | derterming the current state of each IP. | ||
12 | |||
13 | Required properties: | ||
14 | - compatible: Should be "samsung,exynos-ppmu". | ||
15 | - reg: physical base address of each PPMU and length of memory mapped region. | ||
16 | |||
17 | Optional properties: | ||
18 | - clock-names : the name of clock used by the PPMU, "ppmu" | ||
19 | - clocks : phandles for clock specified in "clock-names" property | ||
20 | - #clock-cells: should be 1. | ||
21 | |||
22 | Example1 : PPMU nodes in exynos3250.dtsi are listed below. | ||
23 | |||
24 | ppmu_dmc0: ppmu_dmc0@106a0000 { | ||
25 | compatible = "samsung,exynos-ppmu"; | ||
26 | reg = <0x106a0000 0x2000>; | ||
27 | status = "disabled"; | ||
28 | }; | ||
29 | |||
30 | ppmu_dmc1: ppmu_dmc1@106b0000 { | ||
31 | compatible = "samsung,exynos-ppmu"; | ||
32 | reg = <0x106b0000 0x2000>; | ||
33 | status = "disabled"; | ||
34 | }; | ||
35 | |||
36 | ppmu_cpu: ppmu_cpu@106c0000 { | ||
37 | compatible = "samsung,exynos-ppmu"; | ||
38 | reg = <0x106c0000 0x2000>; | ||
39 | status = "disabled"; | ||
40 | }; | ||
41 | |||
42 | ppmu_rightbus: ppmu_rightbus@112a0000 { | ||
43 | compatible = "samsung,exynos-ppmu"; | ||
44 | reg = <0x112a0000 0x2000>; | ||
45 | clocks = <&cmu CLK_PPMURIGHT>; | ||
46 | clock-names = "ppmu"; | ||
47 | status = "disabled"; | ||
48 | }; | ||
49 | |||
50 | ppmu_leftbus: ppmu_leftbus0@116a0000 { | ||
51 | compatible = "samsung,exynos-ppmu"; | ||
52 | reg = <0x116a0000 0x2000>; | ||
53 | clocks = <&cmu CLK_PPMULEFT>; | ||
54 | clock-names = "ppmu"; | ||
55 | status = "disabled"; | ||
56 | }; | ||
57 | |||
58 | Example2 : Events of each PPMU node in exynos3250-rinato.dts are listed below. | ||
59 | |||
60 | &ppmu_dmc0 { | ||
61 | status = "okay"; | ||
62 | |||
63 | events { | ||
64 | ppmu_dmc0_3: ppmu-event3-dmc0 { | ||
65 | event-name = "ppmu-event3-dmc0"; | ||
66 | }; | ||
67 | |||
68 | ppmu_dmc0_2: ppmu-event2-dmc0 { | ||
69 | event-name = "ppmu-event2-dmc0"; | ||
70 | }; | ||
71 | |||
72 | ppmu_dmc0_1: ppmu-event1-dmc0 { | ||
73 | event-name = "ppmu-event1-dmc0"; | ||
74 | }; | ||
75 | |||
76 | ppmu_dmc0_0: ppmu-event0-dmc0 { | ||
77 | event-name = "ppmu-event0-dmc0"; | ||
78 | }; | ||
79 | }; | ||
80 | }; | ||
81 | |||
82 | &ppmu_dmc1 { | ||
83 | status = "okay"; | ||
84 | |||
85 | events { | ||
86 | ppmu_dmc1_3: ppmu-event3-dmc1 { | ||
87 | event-name = "ppmu-event3-dmc1"; | ||
88 | }; | ||
89 | }; | ||
90 | }; | ||
91 | |||
92 | &ppmu_leftbus { | ||
93 | status = "okay"; | ||
94 | |||
95 | events { | ||
96 | ppmu_leftbus_3: ppmu-event3-leftbus { | ||
97 | event-name = "ppmu-event3-leftbus"; | ||
98 | }; | ||
99 | }; | ||
100 | }; | ||
101 | |||
102 | &ppmu_rightbus { | ||
103 | status = "okay"; | ||
104 | |||
105 | events { | ||
106 | ppmu_rightbus_3: ppmu-event3-rightbus { | ||
107 | event-name = "ppmu-event3-rightbus"; | ||
108 | }; | ||
109 | }; | ||
110 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 176d4fe4f076..f06f1f609cb7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1470,6 +1470,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1470 | no_hwp | 1470 | no_hwp |
1471 | Do not enable hardware P state control (HWP) | 1471 | Do not enable hardware P state control (HWP) |
1472 | if available. | 1472 | if available. |
1473 | hwp_only | ||
1474 | Only load intel_pstate on systems which support | ||
1475 | hardware P state control (HWP) if available. | ||
1473 | 1476 | ||
1474 | intremap= [X86-64, Intel-IOMMU] | 1477 | intremap= [X86-64, Intel-IOMMU] |
1475 | on enable Interrupt Remapping (default) | 1478 | on enable Interrupt Remapping (default) |
diff --git a/Documentation/power/s2ram.txt b/Documentation/power/s2ram.txt index 1bdfa0443773..4685aee197fd 100644 --- a/Documentation/power/s2ram.txt +++ b/Documentation/power/s2ram.txt | |||
@@ -69,6 +69,10 @@ Reason for this is that the RTC is the only reliably available piece of | |||
69 | hardware during resume operations where a value can be set that will | 69 | hardware during resume operations where a value can be set that will |
70 | survive a reboot. | 70 | survive a reboot. |
71 | 71 | ||
72 | pm_trace is not compatible with asynchronous suspend, so it turns | ||
73 | asynchronous suspend off (which may work around timing or | ||
74 | ordering-sensitive bugs). | ||
75 | |||
72 | Consequence is that after a resume (even if it is successful) your system | 76 | Consequence is that after a resume (even if it is successful) your system |
73 | clock will have a value corresponding to the magic number instead of the | 77 | clock will have a value corresponding to the magic number instead of the |
74 | correct date/time! It is therefore advisable to use a program like ntp-date | 78 | correct date/time! It is therefore advisable to use a program like ntp-date |
diff --git a/MAINTAINERS b/MAINTAINERS index b1ddeb69cd9f..54c7ce00d85f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -270,12 +270,12 @@ F: drivers/acpi/ | |||
270 | F: drivers/pnp/pnpacpi/ | 270 | F: drivers/pnp/pnpacpi/ |
271 | F: include/linux/acpi.h | 271 | F: include/linux/acpi.h |
272 | F: include/acpi/ | 272 | F: include/acpi/ |
273 | F: Documentation/acpi | 273 | F: Documentation/acpi/ |
274 | F: Documentation/ABI/testing/sysfs-bus-acpi | 274 | F: Documentation/ABI/testing/sysfs-bus-acpi |
275 | F: drivers/pci/*acpi* | 275 | F: drivers/pci/*acpi* |
276 | F: drivers/pci/*/*acpi* | 276 | F: drivers/pci/*/*acpi* |
277 | F: drivers/pci/*/*/*acpi* | 277 | F: drivers/pci/*/*/*acpi* |
278 | F: tools/power/acpi | 278 | F: tools/power/acpi/ |
279 | 279 | ||
280 | ACPI COMPONENT ARCHITECTURE (ACPICA) | 280 | ACPI COMPONENT ARCHITECTURE (ACPICA) |
281 | M: Robert Moore <robert.moore@intel.com> | 281 | M: Robert Moore <robert.moore@intel.com> |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index ddd75c58b1e8..ab19b7c03423 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -422,17 +422,16 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
422 | static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) | 422 | static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) |
423 | { | 423 | { |
424 | int ret; | 424 | int ret; |
425 | struct pci_host_bridge_window *window; | 425 | struct resource_entry *window; |
426 | 426 | ||
427 | if (list_empty(&sys->resources)) { | 427 | if (list_empty(&sys->resources)) { |
428 | pci_add_resource_offset(&sys->resources, | 428 | pci_add_resource_offset(&sys->resources, |
429 | &iomem_resource, sys->mem_offset); | 429 | &iomem_resource, sys->mem_offset); |
430 | } | 430 | } |
431 | 431 | ||
432 | list_for_each_entry(window, &sys->resources, list) { | 432 | resource_list_for_each_entry(window, &sys->resources) |
433 | if (resource_type(window->res) == IORESOURCE_IO) | 433 | if (resource_type(window->res) == IORESOURCE_IO) |
434 | return 0; | 434 | return 0; |
435 | } | ||
436 | 435 | ||
437 | sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io; | 436 | sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io; |
438 | sys->io_res.end = (busnr + 1) * SZ_64K - 1; | 437 | sys->io_res.end = (busnr + 1) * SZ_64K - 1; |
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index 8b9318d311a0..bd09bf74f187 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c | |||
@@ -69,10 +69,10 @@ static acpi_status find_csr_space(struct acpi_resource *resource, void *data) | |||
69 | status = acpi_resource_to_address64(resource, &addr); | 69 | status = acpi_resource_to_address64(resource, &addr); |
70 | if (ACPI_SUCCESS(status) && | 70 | if (ACPI_SUCCESS(status) && |
71 | addr.resource_type == ACPI_MEMORY_RANGE && | 71 | addr.resource_type == ACPI_MEMORY_RANGE && |
72 | addr.address_length && | 72 | addr.address.address_length && |
73 | addr.producer_consumer == ACPI_CONSUMER) { | 73 | addr.producer_consumer == ACPI_CONSUMER) { |
74 | space->base = addr.minimum; | 74 | space->base = addr.address.minimum; |
75 | space->length = addr.address_length; | 75 | space->length = addr.address.address_length; |
76 | return AE_CTRL_TERMINATE; | 76 | return AE_CTRL_TERMINATE; |
77 | } | 77 | } |
78 | return AE_OK; /* keep looking */ | 78 | return AE_OK; /* keep looking */ |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index e795cb848154..2c4498919d3c 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -380,9 +380,6 @@ static void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
380 | 380 | ||
381 | static int __init acpi_parse_madt(struct acpi_table_header *table) | 381 | static int __init acpi_parse_madt(struct acpi_table_header *table) |
382 | { | 382 | { |
383 | if (!table) | ||
384 | return -EINVAL; | ||
385 | |||
386 | acpi_madt = (struct acpi_table_madt *)table; | 383 | acpi_madt = (struct acpi_table_madt *)table; |
387 | 384 | ||
388 | acpi_madt_rev = acpi_madt->header.revision; | 385 | acpi_madt_rev = acpi_madt->header.revision; |
@@ -645,9 +642,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table) | |||
645 | struct acpi_table_header *fadt_header; | 642 | struct acpi_table_header *fadt_header; |
646 | struct acpi_table_fadt *fadt; | 643 | struct acpi_table_fadt *fadt; |
647 | 644 | ||
648 | if (!table) | ||
649 | return -EINVAL; | ||
650 | |||
651 | fadt_header = (struct acpi_table_header *)table; | 645 | fadt_header = (struct acpi_table_header *)table; |
652 | if (fadt_header->revision != 3) | 646 | if (fadt_header->revision != 3) |
653 | return -ENODEV; /* Only deal with ACPI 2.0 FADT */ | 647 | return -ENODEV; /* Only deal with ACPI 2.0 FADT */ |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 900cc93e5409..48cc65705db4 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -188,12 +188,12 @@ static u64 add_io_space(struct pci_root_info *info, | |||
188 | 188 | ||
189 | name = (char *)(iospace + 1); | 189 | name = (char *)(iospace + 1); |
190 | 190 | ||
191 | min = addr->minimum; | 191 | min = addr->address.minimum; |
192 | max = min + addr->address_length - 1; | 192 | max = min + addr->address.address_length - 1; |
193 | if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION) | 193 | if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION) |
194 | sparse = 1; | 194 | sparse = 1; |
195 | 195 | ||
196 | space_nr = new_space(addr->translation_offset, sparse); | 196 | space_nr = new_space(addr->address.translation_offset, sparse); |
197 | if (space_nr == ~0) | 197 | if (space_nr == ~0) |
198 | goto free_resource; | 198 | goto free_resource; |
199 | 199 | ||
@@ -247,7 +247,7 @@ static acpi_status resource_to_window(struct acpi_resource *resource, | |||
247 | if (ACPI_SUCCESS(status) && | 247 | if (ACPI_SUCCESS(status) && |
248 | (addr->resource_type == ACPI_MEMORY_RANGE || | 248 | (addr->resource_type == ACPI_MEMORY_RANGE || |
249 | addr->resource_type == ACPI_IO_RANGE) && | 249 | addr->resource_type == ACPI_IO_RANGE) && |
250 | addr->address_length && | 250 | addr->address.address_length && |
251 | addr->producer_consumer == ACPI_PRODUCER) | 251 | addr->producer_consumer == ACPI_PRODUCER) |
252 | return AE_OK; | 252 | return AE_OK; |
253 | 253 | ||
@@ -284,7 +284,7 @@ static acpi_status add_window(struct acpi_resource *res, void *data) | |||
284 | if (addr.resource_type == ACPI_MEMORY_RANGE) { | 284 | if (addr.resource_type == ACPI_MEMORY_RANGE) { |
285 | flags = IORESOURCE_MEM; | 285 | flags = IORESOURCE_MEM; |
286 | root = &iomem_resource; | 286 | root = &iomem_resource; |
287 | offset = addr.translation_offset; | 287 | offset = addr.address.translation_offset; |
288 | } else if (addr.resource_type == ACPI_IO_RANGE) { | 288 | } else if (addr.resource_type == ACPI_IO_RANGE) { |
289 | flags = IORESOURCE_IO; | 289 | flags = IORESOURCE_IO; |
290 | root = &ioport_resource; | 290 | root = &ioport_resource; |
@@ -297,8 +297,8 @@ static acpi_status add_window(struct acpi_resource *res, void *data) | |||
297 | resource = &info->res[info->res_num]; | 297 | resource = &info->res[info->res_num]; |
298 | resource->name = info->name; | 298 | resource->name = info->name; |
299 | resource->flags = flags; | 299 | resource->flags = flags; |
300 | resource->start = addr.minimum + offset; | 300 | resource->start = addr.address.minimum + offset; |
301 | resource->end = resource->start + addr.address_length - 1; | 301 | resource->end = resource->start + addr.address.address_length - 1; |
302 | info->res_offset[info->res_num] = offset; | 302 | info->res_offset[info->res_num] = offset; |
303 | 303 | ||
304 | if (insert_resource(root, resource)) { | 304 | if (insert_resource(root, resource)) { |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5e28e2be3a41..019f4e5c2b75 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -497,6 +497,17 @@ config X86_INTEL_LPSS | |||
497 | things like clock tree (common clock framework) and pincontrol | 497 | things like clock tree (common clock framework) and pincontrol |
498 | which are needed by the LPSS peripheral drivers. | 498 | which are needed by the LPSS peripheral drivers. |
499 | 499 | ||
500 | config X86_AMD_PLATFORM_DEVICE | ||
501 | bool "AMD ACPI2Platform devices support" | ||
502 | depends on ACPI | ||
503 | select COMMON_CLK | ||
504 | select PINCTRL | ||
505 | ---help--- | ||
506 | Select to interpret AMD specific ACPI device to platform device | ||
507 | such as I2C, UART, GPIO found on AMD Carrizo and later chipsets. | ||
508 | I2C and UART depend on COMMON_CLK to set clock. GPIO driver is | ||
509 | implemented under PINCTRL subsystem. | ||
510 | |||
500 | config IOSF_MBI | 511 | config IOSF_MBI |
501 | tristate "Intel SoC IOSF Sideband support for SoC platforms" | 512 | tristate "Intel SoC IOSF Sideband support for SoC platforms" |
502 | depends on PCI | 513 | depends on PCI |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 164e3f8d3c3d..fa1195dae425 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -93,8 +93,6 @@ extern raw_spinlock_t pci_config_lock; | |||
93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); | 93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); |
94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); | 94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); |
95 | 95 | ||
96 | extern bool mp_should_keep_irq(struct device *dev); | ||
97 | |||
98 | struct pci_raw_ops { | 96 | struct pci_raw_ops { |
99 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, | 97 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, |
100 | int reg, int len, u32 *val); | 98 | int reg, int len, u32 *val); |
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index d979e5abae55..536240fa9a95 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -152,6 +152,10 @@ | |||
152 | #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 | 152 | #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 |
153 | #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 | 153 | #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 |
154 | 154 | ||
155 | #define MSR_CORE_PERF_LIMIT_REASONS 0x00000690 | ||
156 | #define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0 | ||
157 | #define MSR_RING_PERF_LIMIT_REASONS 0x000006B1 | ||
158 | |||
155 | /* Hardware P state interface */ | 159 | /* Hardware P state interface */ |
156 | #define MSR_PPERF 0x0000064e | 160 | #define MSR_PPERF 0x0000064e |
157 | #define MSR_PERF_LIMIT_REASONS 0x0000064f | 161 | #define MSR_PERF_LIMIT_REASONS 0x0000064f |
@@ -362,6 +366,7 @@ | |||
362 | 366 | ||
363 | #define MSR_IA32_PERF_STATUS 0x00000198 | 367 | #define MSR_IA32_PERF_STATUS 0x00000198 |
364 | #define MSR_IA32_PERF_CTL 0x00000199 | 368 | #define MSR_IA32_PERF_CTL 0x00000199 |
369 | #define INTEL_PERF_CTL_MASK 0xffff | ||
365 | #define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 | 370 | #define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 |
366 | #define MSR_AMD_PERF_STATUS 0xc0010063 | 371 | #define MSR_AMD_PERF_STATUS 0xc0010063 |
367 | #define MSR_AMD_PERF_CTL 0xc0010062 | 372 | #define MSR_AMD_PERF_CTL 0xc0010062 |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a18fff361c7f..ae97ed0873c6 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -845,13 +845,7 @@ int acpi_ioapic_registered(acpi_handle handle, u32 gsi_base) | |||
845 | 845 | ||
846 | static int __init acpi_parse_sbf(struct acpi_table_header *table) | 846 | static int __init acpi_parse_sbf(struct acpi_table_header *table) |
847 | { | 847 | { |
848 | struct acpi_table_boot *sb; | 848 | struct acpi_table_boot *sb = (struct acpi_table_boot *)table; |
849 | |||
850 | sb = (struct acpi_table_boot *)table; | ||
851 | if (!sb) { | ||
852 | printk(KERN_WARNING PREFIX "Unable to map SBF\n"); | ||
853 | return -ENODEV; | ||
854 | } | ||
855 | 849 | ||
856 | sbf_port = sb->cmos_index; /* Save CMOS port */ | 850 | sbf_port = sb->cmos_index; /* Save CMOS port */ |
857 | 851 | ||
@@ -865,13 +859,7 @@ static struct resource *hpet_res __initdata; | |||
865 | 859 | ||
866 | static int __init acpi_parse_hpet(struct acpi_table_header *table) | 860 | static int __init acpi_parse_hpet(struct acpi_table_header *table) |
867 | { | 861 | { |
868 | struct acpi_table_hpet *hpet_tbl; | 862 | struct acpi_table_hpet *hpet_tbl = (struct acpi_table_hpet *)table; |
869 | |||
870 | hpet_tbl = (struct acpi_table_hpet *)table; | ||
871 | if (!hpet_tbl) { | ||
872 | printk(KERN_WARNING PREFIX "Unable to map HPET\n"); | ||
873 | return -ENODEV; | ||
874 | } | ||
875 | 863 | ||
876 | if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { | 864 | if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { |
877 | printk(KERN_WARNING PREFIX "HPET timers must be located in " | 865 | printk(KERN_WARNING PREFIX "HPET timers must be located in " |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index cfd1b132b8e3..6ac273832f28 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -10,9 +10,6 @@ | |||
10 | struct pci_root_info { | 10 | struct pci_root_info { |
11 | struct acpi_device *bridge; | 11 | struct acpi_device *bridge; |
12 | char name[16]; | 12 | char name[16]; |
13 | unsigned int res_num; | ||
14 | struct resource *res; | ||
15 | resource_size_t *res_offset; | ||
16 | struct pci_sysdata sd; | 13 | struct pci_sysdata sd; |
17 | #ifdef CONFIG_PCI_MMCONFIG | 14 | #ifdef CONFIG_PCI_MMCONFIG |
18 | bool mcfg_added; | 15 | bool mcfg_added; |
@@ -218,130 +215,41 @@ static void teardown_mcfg_map(struct pci_root_info *info) | |||
218 | } | 215 | } |
219 | #endif | 216 | #endif |
220 | 217 | ||
221 | static acpi_status resource_to_addr(struct acpi_resource *resource, | 218 | static void validate_resources(struct device *dev, struct list_head *crs_res, |
222 | struct acpi_resource_address64 *addr) | 219 | unsigned long type) |
223 | { | ||
224 | acpi_status status; | ||
225 | struct acpi_resource_memory24 *memory24; | ||
226 | struct acpi_resource_memory32 *memory32; | ||
227 | struct acpi_resource_fixed_memory32 *fixed_memory32; | ||
228 | |||
229 | memset(addr, 0, sizeof(*addr)); | ||
230 | switch (resource->type) { | ||
231 | case ACPI_RESOURCE_TYPE_MEMORY24: | ||
232 | memory24 = &resource->data.memory24; | ||
233 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
234 | addr->minimum = memory24->minimum; | ||
235 | addr->address_length = memory24->address_length; | ||
236 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
237 | return AE_OK; | ||
238 | case ACPI_RESOURCE_TYPE_MEMORY32: | ||
239 | memory32 = &resource->data.memory32; | ||
240 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
241 | addr->minimum = memory32->minimum; | ||
242 | addr->address_length = memory32->address_length; | ||
243 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
244 | return AE_OK; | ||
245 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | ||
246 | fixed_memory32 = &resource->data.fixed_memory32; | ||
247 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
248 | addr->minimum = fixed_memory32->address; | ||
249 | addr->address_length = fixed_memory32->address_length; | ||
250 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
251 | return AE_OK; | ||
252 | case ACPI_RESOURCE_TYPE_ADDRESS16: | ||
253 | case ACPI_RESOURCE_TYPE_ADDRESS32: | ||
254 | case ACPI_RESOURCE_TYPE_ADDRESS64: | ||
255 | status = acpi_resource_to_address64(resource, addr); | ||
256 | if (ACPI_SUCCESS(status) && | ||
257 | (addr->resource_type == ACPI_MEMORY_RANGE || | ||
258 | addr->resource_type == ACPI_IO_RANGE) && | ||
259 | addr->address_length > 0) { | ||
260 | return AE_OK; | ||
261 | } | ||
262 | break; | ||
263 | } | ||
264 | return AE_ERROR; | ||
265 | } | ||
266 | |||
267 | static acpi_status count_resource(struct acpi_resource *acpi_res, void *data) | ||
268 | { | 220 | { |
269 | struct pci_root_info *info = data; | 221 | LIST_HEAD(list); |
270 | struct acpi_resource_address64 addr; | 222 | struct resource *res1, *res2, *root = NULL; |
271 | acpi_status status; | 223 | struct resource_entry *tmp, *entry, *entry2; |
272 | |||
273 | status = resource_to_addr(acpi_res, &addr); | ||
274 | if (ACPI_SUCCESS(status)) | ||
275 | info->res_num++; | ||
276 | return AE_OK; | ||
277 | } | ||
278 | |||
279 | static acpi_status setup_resource(struct acpi_resource *acpi_res, void *data) | ||
280 | { | ||
281 | struct pci_root_info *info = data; | ||
282 | struct resource *res; | ||
283 | struct acpi_resource_address64 addr; | ||
284 | acpi_status status; | ||
285 | unsigned long flags; | ||
286 | u64 start, orig_end, end; | ||
287 | |||
288 | status = resource_to_addr(acpi_res, &addr); | ||
289 | if (!ACPI_SUCCESS(status)) | ||
290 | return AE_OK; | ||
291 | |||
292 | if (addr.resource_type == ACPI_MEMORY_RANGE) { | ||
293 | flags = IORESOURCE_MEM; | ||
294 | if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY) | ||
295 | flags |= IORESOURCE_PREFETCH; | ||
296 | } else if (addr.resource_type == ACPI_IO_RANGE) { | ||
297 | flags = IORESOURCE_IO; | ||
298 | } else | ||
299 | return AE_OK; | ||
300 | |||
301 | start = addr.minimum + addr.translation_offset; | ||
302 | orig_end = end = addr.maximum + addr.translation_offset; | ||
303 | |||
304 | /* Exclude non-addressable range or non-addressable portion of range */ | ||
305 | end = min(end, (u64)iomem_resource.end); | ||
306 | if (end <= start) { | ||
307 | dev_info(&info->bridge->dev, | ||
308 | "host bridge window [%#llx-%#llx] " | ||
309 | "(ignored, not CPU addressable)\n", start, orig_end); | ||
310 | return AE_OK; | ||
311 | } else if (orig_end != end) { | ||
312 | dev_info(&info->bridge->dev, | ||
313 | "host bridge window [%#llx-%#llx] " | ||
314 | "([%#llx-%#llx] ignored, not CPU addressable)\n", | ||
315 | start, orig_end, end + 1, orig_end); | ||
316 | } | ||
317 | 224 | ||
318 | res = &info->res[info->res_num]; | 225 | BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0); |
319 | res->name = info->name; | 226 | root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource; |
320 | res->flags = flags; | ||
321 | res->start = start; | ||
322 | res->end = end; | ||
323 | info->res_offset[info->res_num] = addr.translation_offset; | ||
324 | info->res_num++; | ||
325 | 227 | ||
326 | if (!pci_use_crs) | 228 | list_splice_init(crs_res, &list); |
327 | dev_printk(KERN_DEBUG, &info->bridge->dev, | 229 | resource_list_for_each_entry_safe(entry, tmp, &list) { |
328 | "host bridge window %pR (ignored)\n", res); | 230 | bool free = false; |
231 | resource_size_t end; | ||
329 | 232 | ||
330 | return AE_OK; | 233 | res1 = entry->res; |
331 | } | ||
332 | |||
333 | static void coalesce_windows(struct pci_root_info *info, unsigned long type) | ||
334 | { | ||
335 | int i, j; | ||
336 | struct resource *res1, *res2; | ||
337 | |||
338 | for (i = 0; i < info->res_num; i++) { | ||
339 | res1 = &info->res[i]; | ||
340 | if (!(res1->flags & type)) | 234 | if (!(res1->flags & type)) |
341 | continue; | 235 | goto next; |
236 | |||
237 | /* Exclude non-addressable range or non-addressable portion */ | ||
238 | end = min(res1->end, root->end); | ||
239 | if (end <= res1->start) { | ||
240 | dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n", | ||
241 | res1); | ||
242 | free = true; | ||
243 | goto next; | ||
244 | } else if (res1->end != end) { | ||
245 | dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n", | ||
246 | res1, (unsigned long long)end + 1, | ||
247 | (unsigned long long)res1->end); | ||
248 | res1->end = end; | ||
249 | } | ||
342 | 250 | ||
343 | for (j = i + 1; j < info->res_num; j++) { | 251 | resource_list_for_each_entry(entry2, crs_res) { |
344 | res2 = &info->res[j]; | 252 | res2 = entry2->res; |
345 | if (!(res2->flags & type)) | 253 | if (!(res2->flags & type)) |
346 | continue; | 254 | continue; |
347 | 255 | ||
@@ -353,118 +261,92 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type) | |||
353 | if (resource_overlaps(res1, res2)) { | 261 | if (resource_overlaps(res1, res2)) { |
354 | res2->start = min(res1->start, res2->start); | 262 | res2->start = min(res1->start, res2->start); |
355 | res2->end = max(res1->end, res2->end); | 263 | res2->end = max(res1->end, res2->end); |
356 | dev_info(&info->bridge->dev, | 264 | dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n", |
357 | "host bridge window expanded to %pR; %pR ignored\n", | ||
358 | res2, res1); | 265 | res2, res1); |
359 | res1->flags = 0; | 266 | free = true; |
267 | goto next; | ||
360 | } | 268 | } |
361 | } | 269 | } |
270 | |||
271 | next: | ||
272 | resource_list_del(entry); | ||
273 | if (free) | ||
274 | resource_list_free_entry(entry); | ||
275 | else | ||
276 | resource_list_add_tail(entry, crs_res); | ||
362 | } | 277 | } |
363 | } | 278 | } |
364 | 279 | ||
365 | static void add_resources(struct pci_root_info *info, | 280 | static void add_resources(struct pci_root_info *info, |
366 | struct list_head *resources) | 281 | struct list_head *resources, |
282 | struct list_head *crs_res) | ||
367 | { | 283 | { |
368 | int i; | 284 | struct resource_entry *entry, *tmp; |
369 | struct resource *res, *root, *conflict; | 285 | struct resource *res, *conflict, *root = NULL; |
370 | |||
371 | coalesce_windows(info, IORESOURCE_MEM); | ||
372 | coalesce_windows(info, IORESOURCE_IO); | ||
373 | 286 | ||
374 | for (i = 0; i < info->res_num; i++) { | 287 | validate_resources(&info->bridge->dev, crs_res, IORESOURCE_MEM); |
375 | res = &info->res[i]; | 288 | validate_resources(&info->bridge->dev, crs_res, IORESOURCE_IO); |
376 | 289 | ||
290 | resource_list_for_each_entry_safe(entry, tmp, crs_res) { | ||
291 | res = entry->res; | ||
377 | if (res->flags & IORESOURCE_MEM) | 292 | if (res->flags & IORESOURCE_MEM) |
378 | root = &iomem_resource; | 293 | root = &iomem_resource; |
379 | else if (res->flags & IORESOURCE_IO) | 294 | else if (res->flags & IORESOURCE_IO) |
380 | root = &ioport_resource; | 295 | root = &ioport_resource; |
381 | else | 296 | else |
382 | continue; | 297 | BUG_ON(res); |
383 | 298 | ||
384 | conflict = insert_resource_conflict(root, res); | 299 | conflict = insert_resource_conflict(root, res); |
385 | if (conflict) | 300 | if (conflict) { |
386 | dev_info(&info->bridge->dev, | 301 | dev_info(&info->bridge->dev, |
387 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", | 302 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", |
388 | res, conflict->name, conflict); | 303 | res, conflict->name, conflict); |
389 | else | 304 | resource_list_destroy_entry(entry); |
390 | pci_add_resource_offset(resources, res, | 305 | } |
391 | info->res_offset[i]); | ||
392 | } | 306 | } |
393 | } | ||
394 | 307 | ||
395 | static void free_pci_root_info_res(struct pci_root_info *info) | 308 | list_splice_tail(crs_res, resources); |
396 | { | ||
397 | kfree(info->res); | ||
398 | info->res = NULL; | ||
399 | kfree(info->res_offset); | ||
400 | info->res_offset = NULL; | ||
401 | info->res_num = 0; | ||
402 | } | 309 | } |
403 | 310 | ||
404 | static void __release_pci_root_info(struct pci_root_info *info) | 311 | static void release_pci_root_info(struct pci_host_bridge *bridge) |
405 | { | 312 | { |
406 | int i; | ||
407 | struct resource *res; | 313 | struct resource *res; |
314 | struct resource_entry *entry; | ||
315 | struct pci_root_info *info = bridge->release_data; | ||
408 | 316 | ||
409 | for (i = 0; i < info->res_num; i++) { | 317 | resource_list_for_each_entry(entry, &bridge->windows) { |
410 | res = &info->res[i]; | 318 | res = entry->res; |
411 | 319 | if (res->parent && | |
412 | if (!res->parent) | 320 | (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) |
413 | continue; | 321 | release_resource(res); |
414 | |||
415 | if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) | ||
416 | continue; | ||
417 | |||
418 | release_resource(res); | ||
419 | } | 322 | } |
420 | 323 | ||
421 | free_pci_root_info_res(info); | ||
422 | |||
423 | teardown_mcfg_map(info); | 324 | teardown_mcfg_map(info); |
424 | |||
425 | kfree(info); | 325 | kfree(info); |
426 | } | 326 | } |
427 | 327 | ||
428 | static void release_pci_root_info(struct pci_host_bridge *bridge) | ||
429 | { | ||
430 | struct pci_root_info *info = bridge->release_data; | ||
431 | |||
432 | __release_pci_root_info(info); | ||
433 | } | ||
434 | |||
435 | static void probe_pci_root_info(struct pci_root_info *info, | 328 | static void probe_pci_root_info(struct pci_root_info *info, |
436 | struct acpi_device *device, | 329 | struct acpi_device *device, |
437 | int busnum, int domain) | 330 | int busnum, int domain, |
331 | struct list_head *list) | ||
438 | { | 332 | { |
439 | size_t size; | 333 | int ret; |
334 | struct resource_entry *entry; | ||
440 | 335 | ||
441 | sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); | 336 | sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); |
442 | info->bridge = device; | 337 | info->bridge = device; |
443 | 338 | ret = acpi_dev_get_resources(device, list, | |
444 | info->res_num = 0; | 339 | acpi_dev_filter_resource_type_cb, |
445 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, | 340 | (void *)(IORESOURCE_IO | IORESOURCE_MEM)); |
446 | info); | 341 | if (ret < 0) |
447 | if (!info->res_num) | 342 | dev_warn(&device->dev, |
448 | return; | 343 | "failed to parse _CRS method, error code %d\n", ret); |
449 | 344 | else if (ret == 0) | |
450 | size = sizeof(*info->res) * info->res_num; | 345 | dev_dbg(&device->dev, |
451 | info->res = kzalloc_node(size, GFP_KERNEL, info->sd.node); | 346 | "no IO and memory resources present in _CRS\n"); |
452 | if (!info->res) { | 347 | else |
453 | info->res_num = 0; | 348 | resource_list_for_each_entry(entry, list) |
454 | return; | 349 | entry->res->name = info->name; |
455 | } | ||
456 | |||
457 | size = sizeof(*info->res_offset) * info->res_num; | ||
458 | info->res_num = 0; | ||
459 | info->res_offset = kzalloc_node(size, GFP_KERNEL, info->sd.node); | ||
460 | if (!info->res_offset) { | ||
461 | kfree(info->res); | ||
462 | info->res = NULL; | ||
463 | return; | ||
464 | } | ||
465 | |||
466 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, | ||
467 | info); | ||
468 | } | 350 | } |
469 | 351 | ||
470 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | 352 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) |
@@ -473,6 +355,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
473 | struct pci_root_info *info; | 355 | struct pci_root_info *info; |
474 | int domain = root->segment; | 356 | int domain = root->segment; |
475 | int busnum = root->secondary.start; | 357 | int busnum = root->secondary.start; |
358 | struct resource_entry *res_entry; | ||
359 | LIST_HEAD(crs_res); | ||
476 | LIST_HEAD(resources); | 360 | LIST_HEAD(resources); |
477 | struct pci_bus *bus; | 361 | struct pci_bus *bus; |
478 | struct pci_sysdata *sd; | 362 | struct pci_sysdata *sd; |
@@ -520,18 +404,22 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
520 | memcpy(bus->sysdata, sd, sizeof(*sd)); | 404 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
521 | kfree(info); | 405 | kfree(info); |
522 | } else { | 406 | } else { |
523 | probe_pci_root_info(info, device, busnum, domain); | ||
524 | |||
525 | /* insert busn res at first */ | 407 | /* insert busn res at first */ |
526 | pci_add_resource(&resources, &root->secondary); | 408 | pci_add_resource(&resources, &root->secondary); |
409 | |||
527 | /* | 410 | /* |
528 | * _CRS with no apertures is normal, so only fall back to | 411 | * _CRS with no apertures is normal, so only fall back to |
529 | * defaults or native bridge info if we're ignoring _CRS. | 412 | * defaults or native bridge info if we're ignoring _CRS. |
530 | */ | 413 | */ |
531 | if (pci_use_crs) | 414 | probe_pci_root_info(info, device, busnum, domain, &crs_res); |
532 | add_resources(info, &resources); | 415 | if (pci_use_crs) { |
533 | else { | 416 | add_resources(info, &resources, &crs_res); |
534 | free_pci_root_info_res(info); | 417 | } else { |
418 | resource_list_for_each_entry(res_entry, &crs_res) | ||
419 | dev_printk(KERN_DEBUG, &device->dev, | ||
420 | "host bridge window %pR (ignored)\n", | ||
421 | res_entry->res); | ||
422 | resource_list_free(&crs_res); | ||
535 | x86_pci_root_bus_resources(busnum, &resources); | 423 | x86_pci_root_bus_resources(busnum, &resources); |
536 | } | 424 | } |
537 | 425 | ||
@@ -546,8 +434,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
546 | to_pci_host_bridge(bus->bridge), | 434 | to_pci_host_bridge(bus->bridge), |
547 | release_pci_root_info, info); | 435 | release_pci_root_info, info); |
548 | } else { | 436 | } else { |
549 | pci_free_resource_list(&resources); | 437 | resource_list_free(&resources); |
550 | __release_pci_root_info(info); | 438 | teardown_mcfg_map(info); |
439 | kfree(info); | ||
551 | } | 440 | } |
552 | } | 441 | } |
553 | 442 | ||
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c index f3a2cfc14125..7bcf06a7cd12 100644 --- a/arch/x86/pci/bus_numa.c +++ b/arch/x86/pci/bus_numa.c | |||
@@ -31,7 +31,7 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) | |||
31 | { | 31 | { |
32 | struct pci_root_info *info = x86_find_pci_root_info(bus); | 32 | struct pci_root_info *info = x86_find_pci_root_info(bus); |
33 | struct pci_root_res *root_res; | 33 | struct pci_root_res *root_res; |
34 | struct pci_host_bridge_window *window; | 34 | struct resource_entry *window; |
35 | bool found = false; | 35 | bool found = false; |
36 | 36 | ||
37 | if (!info) | 37 | if (!info) |
@@ -41,7 +41,7 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) | |||
41 | bus); | 41 | bus); |
42 | 42 | ||
43 | /* already added by acpi ? */ | 43 | /* already added by acpi ? */ |
44 | list_for_each_entry(window, resources, list) | 44 | resource_list_for_each_entry(window, resources) |
45 | if (window->res->flags & IORESOURCE_BUS) { | 45 | if (window->res->flags & IORESOURCE_BUS) { |
46 | found = true; | 46 | found = true; |
47 | break; | 47 | break; |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 2fb384724ebb..3d2612b68694 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -513,6 +513,31 @@ void __init pcibios_set_cache_line_size(void) | |||
513 | } | 513 | } |
514 | } | 514 | } |
515 | 515 | ||
516 | /* | ||
517 | * Some device drivers assume dev->irq won't change after calling | ||
518 | * pci_disable_device(). So delay releasing of IRQ resource to driver | ||
519 | * unbinding time. Otherwise it will break PM subsystem and drivers | ||
520 | * like xen-pciback etc. | ||
521 | */ | ||
522 | static int pci_irq_notifier(struct notifier_block *nb, unsigned long action, | ||
523 | void *data) | ||
524 | { | ||
525 | struct pci_dev *dev = to_pci_dev(data); | ||
526 | |||
527 | if (action != BUS_NOTIFY_UNBOUND_DRIVER) | ||
528 | return NOTIFY_DONE; | ||
529 | |||
530 | if (pcibios_disable_irq) | ||
531 | pcibios_disable_irq(dev); | ||
532 | |||
533 | return NOTIFY_OK; | ||
534 | } | ||
535 | |||
536 | static struct notifier_block pci_irq_nb = { | ||
537 | .notifier_call = pci_irq_notifier, | ||
538 | .priority = INT_MIN, | ||
539 | }; | ||
540 | |||
516 | int __init pcibios_init(void) | 541 | int __init pcibios_init(void) |
517 | { | 542 | { |
518 | if (!raw_pci_ops) { | 543 | if (!raw_pci_ops) { |
@@ -525,6 +550,9 @@ int __init pcibios_init(void) | |||
525 | 550 | ||
526 | if (pci_bf_sort >= pci_force_bf) | 551 | if (pci_bf_sort >= pci_force_bf) |
527 | pci_sort_breadthfirst(); | 552 | pci_sort_breadthfirst(); |
553 | |||
554 | bus_register_notifier(&pci_bus_type, &pci_irq_nb); | ||
555 | |||
528 | return 0; | 556 | return 0; |
529 | } | 557 | } |
530 | 558 | ||
@@ -683,12 +711,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
683 | return 0; | 711 | return 0; |
684 | } | 712 | } |
685 | 713 | ||
686 | void pcibios_disable_device (struct pci_dev *dev) | ||
687 | { | ||
688 | if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) | ||
689 | pcibios_disable_irq(dev); | ||
690 | } | ||
691 | |||
692 | int pci_ext_cfg_avail(void) | 714 | int pci_ext_cfg_avail(void) |
693 | { | 715 | { |
694 | if (raw_pci_ext_ops) | 716 | if (raw_pci_ext_ops) |
diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c index 852aa4c92da0..efb849323c74 100644 --- a/arch/x86/pci/intel_mid_pci.c +++ b/arch/x86/pci/intel_mid_pci.c | |||
@@ -234,10 +234,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) | |||
234 | 234 | ||
235 | static void intel_mid_pci_irq_disable(struct pci_dev *dev) | 235 | static void intel_mid_pci_irq_disable(struct pci_dev *dev) |
236 | { | 236 | { |
237 | if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed && | 237 | if (dev->irq_managed && dev->irq > 0) { |
238 | dev->irq > 0) { | ||
239 | mp_unmap_irq(dev->irq); | 238 | mp_unmap_irq(dev->irq); |
240 | dev->irq_managed = 0; | 239 | dev->irq_managed = 0; |
240 | dev->irq = 0; | ||
241 | } | 241 | } |
242 | } | 242 | } |
243 | 243 | ||
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 5dc6ca5e1741..e71b3dbd87b8 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -1256,22 +1256,9 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1256 | return 0; | 1256 | return 0; |
1257 | } | 1257 | } |
1258 | 1258 | ||
1259 | bool mp_should_keep_irq(struct device *dev) | ||
1260 | { | ||
1261 | if (dev->power.is_prepared) | ||
1262 | return true; | ||
1263 | #ifdef CONFIG_PM | ||
1264 | if (dev->power.runtime_status == RPM_SUSPENDING) | ||
1265 | return true; | ||
1266 | #endif | ||
1267 | |||
1268 | return false; | ||
1269 | } | ||
1270 | |||
1271 | static void pirq_disable_irq(struct pci_dev *dev) | 1259 | static void pirq_disable_irq(struct pci_dev *dev) |
1272 | { | 1260 | { |
1273 | if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && | 1261 | if (io_apic_assign_pci_irqs && dev->irq_managed && dev->irq) { |
1274 | dev->irq_managed && dev->irq) { | ||
1275 | mp_unmap_irq(dev->irq); | 1262 | mp_unmap_irq(dev->irq); |
1276 | dev->irq = 0; | 1263 | dev->irq = 0; |
1277 | dev->irq_managed = 0; | 1264 | dev->irq_managed = 0; |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 676e5e04e4d4..dd30b7e08bc2 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -397,12 +397,12 @@ static acpi_status check_mcfg_resource(struct acpi_resource *res, void *data) | |||
397 | 397 | ||
398 | status = acpi_resource_to_address64(res, &address); | 398 | status = acpi_resource_to_address64(res, &address); |
399 | if (ACPI_FAILURE(status) || | 399 | if (ACPI_FAILURE(status) || |
400 | (address.address_length <= 0) || | 400 | (address.address.address_length <= 0) || |
401 | (address.resource_type != ACPI_MEMORY_RANGE)) | 401 | (address.resource_type != ACPI_MEMORY_RANGE)) |
402 | return AE_OK; | 402 | return AE_OK; |
403 | 403 | ||
404 | if ((mcfg_res->start >= address.minimum) && | 404 | if ((mcfg_res->start >= address.address.minimum) && |
405 | (mcfg_res->end < (address.minimum + address.address_length))) { | 405 | (mcfg_res->end < (address.address.minimum + address.address.address_length))) { |
406 | mcfg_res->flags = 1; | 406 | mcfg_res->flags = 1; |
407 | return AE_CTRL_TERMINATE; | 407 | return AE_CTRL_TERMINATE; |
408 | } | 408 | } |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 8951cefb0a96..e6c3ddd92665 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -315,6 +315,12 @@ config ACPI_HOTPLUG_MEMORY | |||
315 | To compile this driver as a module, choose M here: | 315 | To compile this driver as a module, choose M here: |
316 | the module will be called acpi_memhotplug. | 316 | the module will be called acpi_memhotplug. |
317 | 317 | ||
318 | config ACPI_HOTPLUG_IOAPIC | ||
319 | bool | ||
320 | depends on PCI | ||
321 | depends on X86_IO_APIC | ||
322 | default y | ||
323 | |||
318 | config ACPI_SBS | 324 | config ACPI_SBS |
319 | tristate "Smart Battery System" | 325 | tristate "Smart Battery System" |
320 | depends on X86 | 326 | depends on X86 |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index f74317cc1ca9..b18cd2151ddb 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -40,7 +40,7 @@ acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o | |||
40 | acpi-y += ec.o | 40 | acpi-y += ec.o |
41 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 41 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
42 | acpi-y += pci_root.o pci_link.o pci_irq.o | 42 | acpi-y += pci_root.o pci_link.o pci_irq.o |
43 | acpi-y += acpi_lpss.o | 43 | acpi-y += acpi_lpss.o acpi_apd.o |
44 | acpi-y += acpi_platform.o | 44 | acpi-y += acpi_platform.o |
45 | acpi-y += acpi_pnp.o | 45 | acpi-y += acpi_pnp.o |
46 | acpi-y += int340x_thermal.o | 46 | acpi-y += int340x_thermal.o |
@@ -70,6 +70,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o | |||
70 | obj-y += container.o | 70 | obj-y += container.o |
71 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o | 71 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o |
72 | obj-y += acpi_memhotplug.o | 72 | obj-y += acpi_memhotplug.o |
73 | obj-$(CONFIG_ACPI_HOTPLUG_IOAPIC) += ioapic.o | ||
73 | obj-$(CONFIG_ACPI_BATTERY) += battery.o | 74 | obj-$(CONFIG_ACPI_BATTERY) += battery.o |
74 | obj-$(CONFIG_ACPI_SBS) += sbshc.o | 75 | obj-$(CONFIG_ACPI_SBS) += sbshc.o |
75 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 76 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c new file mode 100644 index 000000000000..3984ea96e5f7 --- /dev/null +++ b/drivers/acpi/acpi_apd.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * AMD ACPI support for ACPI2platform device. | ||
3 | * | ||
4 | * Copyright (c) 2014,2015 AMD Corporation. | ||
5 | * Authors: Ken Xue <Ken.Xue@amd.com> | ||
6 | * Wu, Jeff <Jeff.Wu@amd.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk-provider.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/pm_domain.h> | ||
16 | #include <linux/clkdev.h> | ||
17 | #include <linux/acpi.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/pm.h> | ||
21 | |||
22 | #include "internal.h" | ||
23 | |||
24 | ACPI_MODULE_NAME("acpi_apd"); | ||
25 | struct apd_private_data; | ||
26 | |||
27 | /** | ||
28 | * ACPI_APD_SYSFS : add device attributes in sysfs | ||
29 | * ACPI_APD_PM : attach power domain to device | ||
30 | */ | ||
31 | #define ACPI_APD_SYSFS BIT(0) | ||
32 | #define ACPI_APD_PM BIT(1) | ||
33 | |||
34 | /** | ||
35 | * struct apd_device_desc - a descriptor for apd device | ||
36 | * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM | ||
37 | * @fixed_clk_rate: fixed rate input clock source for acpi device; | ||
38 | * 0 means no fixed rate input clock source | ||
39 | * @setup: a hook routine to set device resource during create platform device | ||
40 | * | ||
41 | * Device description defined as acpi_device_id.driver_data | ||
42 | */ | ||
43 | struct apd_device_desc { | ||
44 | unsigned int flags; | ||
45 | unsigned int fixed_clk_rate; | ||
46 | int (*setup)(struct apd_private_data *pdata); | ||
47 | }; | ||
48 | |||
49 | struct apd_private_data { | ||
50 | struct clk *clk; | ||
51 | struct acpi_device *adev; | ||
52 | const struct apd_device_desc *dev_desc; | ||
53 | }; | ||
54 | |||
55 | #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE | ||
56 | #define APD_ADDR(desc) ((unsigned long)&desc) | ||
57 | |||
58 | static int acpi_apd_setup(struct apd_private_data *pdata) | ||
59 | { | ||
60 | const struct apd_device_desc *dev_desc = pdata->dev_desc; | ||
61 | struct clk *clk = ERR_PTR(-ENODEV); | ||
62 | |||
63 | if (dev_desc->fixed_clk_rate) { | ||
64 | clk = clk_register_fixed_rate(&pdata->adev->dev, | ||
65 | dev_name(&pdata->adev->dev), | ||
66 | NULL, CLK_IS_ROOT, | ||
67 | dev_desc->fixed_clk_rate); | ||
68 | clk_register_clkdev(clk, NULL, dev_name(&pdata->adev->dev)); | ||
69 | pdata->clk = clk; | ||
70 | } | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static struct apd_device_desc cz_i2c_desc = { | ||
76 | .setup = acpi_apd_setup, | ||
77 | .fixed_clk_rate = 133000000, | ||
78 | }; | ||
79 | |||
80 | static struct apd_device_desc cz_uart_desc = { | ||
81 | .setup = acpi_apd_setup, | ||
82 | .fixed_clk_rate = 48000000, | ||
83 | }; | ||
84 | |||
85 | #else | ||
86 | |||
87 | #define APD_ADDR(desc) (0UL) | ||
88 | |||
89 | #endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */ | ||
90 | |||
91 | /** | ||
92 | * Create platform device during acpi scan attach handle. | ||
93 | * Return value > 0 on success of creating device. | ||
94 | */ | ||
95 | static int acpi_apd_create_device(struct acpi_device *adev, | ||
96 | const struct acpi_device_id *id) | ||
97 | { | ||
98 | const struct apd_device_desc *dev_desc = (void *)id->driver_data; | ||
99 | struct apd_private_data *pdata; | ||
100 | struct platform_device *pdev; | ||
101 | int ret; | ||
102 | |||
103 | if (!dev_desc) { | ||
104 | pdev = acpi_create_platform_device(adev); | ||
105 | return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1; | ||
106 | } | ||
107 | |||
108 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | ||
109 | if (!pdata) | ||
110 | return -ENOMEM; | ||
111 | |||
112 | pdata->adev = adev; | ||
113 | pdata->dev_desc = dev_desc; | ||
114 | |||
115 | if (dev_desc->setup) { | ||
116 | ret = dev_desc->setup(pdata); | ||
117 | if (ret) | ||
118 | goto err_out; | ||
119 | } | ||
120 | |||
121 | adev->driver_data = pdata; | ||
122 | pdev = acpi_create_platform_device(adev); | ||
123 | if (!IS_ERR_OR_NULL(pdev)) | ||
124 | return 1; | ||
125 | |||
126 | ret = PTR_ERR(pdev); | ||
127 | adev->driver_data = NULL; | ||
128 | |||
129 | err_out: | ||
130 | kfree(pdata); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static const struct acpi_device_id acpi_apd_device_ids[] = { | ||
135 | /* Generic apd devices */ | ||
136 | { "AMD0010", APD_ADDR(cz_i2c_desc) }, | ||
137 | { "AMD0020", APD_ADDR(cz_uart_desc) }, | ||
138 | { "AMD0030", }, | ||
139 | { } | ||
140 | }; | ||
141 | |||
142 | static struct acpi_scan_handler apd_handler = { | ||
143 | .ids = acpi_apd_device_ids, | ||
144 | .attach = acpi_apd_create_device, | ||
145 | }; | ||
146 | |||
147 | void __init acpi_apd_init(void) | ||
148 | { | ||
149 | acpi_scan_add_handler(&apd_handler); | ||
150 | } | ||
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index e75737fd7eef..02e835f3cf8a 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -125,7 +125,7 @@ static struct lpss_device_desc lpt_dev_desc = { | |||
125 | }; | 125 | }; |
126 | 126 | ||
127 | static struct lpss_device_desc lpt_i2c_dev_desc = { | 127 | static struct lpss_device_desc lpt_i2c_dev_desc = { |
128 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_LTR, | 128 | .flags = LPSS_CLK | LPSS_LTR, |
129 | .prv_offset = 0x800, | 129 | .prv_offset = 0x800, |
130 | }; | 130 | }; |
131 | 131 | ||
@@ -307,7 +307,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
307 | { | 307 | { |
308 | struct lpss_device_desc *dev_desc; | 308 | struct lpss_device_desc *dev_desc; |
309 | struct lpss_private_data *pdata; | 309 | struct lpss_private_data *pdata; |
310 | struct resource_list_entry *rentry; | 310 | struct resource_entry *rentry; |
311 | struct list_head resource_list; | 311 | struct list_head resource_list; |
312 | struct platform_device *pdev; | 312 | struct platform_device *pdev; |
313 | int ret; | 313 | int ret; |
@@ -327,13 +327,15 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
327 | goto err_out; | 327 | goto err_out; |
328 | 328 | ||
329 | list_for_each_entry(rentry, &resource_list, node) | 329 | list_for_each_entry(rentry, &resource_list, node) |
330 | if (resource_type(&rentry->res) == IORESOURCE_MEM) { | 330 | if (resource_type(rentry->res) == IORESOURCE_MEM) { |
331 | if (dev_desc->prv_size_override) | 331 | if (dev_desc->prv_size_override) |
332 | pdata->mmio_size = dev_desc->prv_size_override; | 332 | pdata->mmio_size = dev_desc->prv_size_override; |
333 | else | 333 | else |
334 | pdata->mmio_size = resource_size(&rentry->res); | 334 | pdata->mmio_size = resource_size(rentry->res); |
335 | pdata->mmio_base = ioremap(rentry->res.start, | 335 | pdata->mmio_base = ioremap(rentry->res->start, |
336 | pdata->mmio_size); | 336 | pdata->mmio_size); |
337 | if (!pdata->mmio_base) | ||
338 | goto err_out; | ||
337 | break; | 339 | break; |
338 | } | 340 | } |
339 | 341 | ||
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 23e2319ead41..ee28f4d15625 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -101,8 +101,8 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context) | |||
101 | /* Can we combine the resource range information? */ | 101 | /* Can we combine the resource range information? */ |
102 | if ((info->caching == address64.info.mem.caching) && | 102 | if ((info->caching == address64.info.mem.caching) && |
103 | (info->write_protect == address64.info.mem.write_protect) && | 103 | (info->write_protect == address64.info.mem.write_protect) && |
104 | (info->start_addr + info->length == address64.minimum)) { | 104 | (info->start_addr + info->length == address64.address.minimum)) { |
105 | info->length += address64.address_length; | 105 | info->length += address64.address.address_length; |
106 | return AE_OK; | 106 | return AE_OK; |
107 | } | 107 | } |
108 | } | 108 | } |
@@ -114,8 +114,8 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context) | |||
114 | INIT_LIST_HEAD(&new->list); | 114 | INIT_LIST_HEAD(&new->list); |
115 | new->caching = address64.info.mem.caching; | 115 | new->caching = address64.info.mem.caching; |
116 | new->write_protect = address64.info.mem.write_protect; | 116 | new->write_protect = address64.info.mem.write_protect; |
117 | new->start_addr = address64.minimum; | 117 | new->start_addr = address64.address.minimum; |
118 | new->length = address64.address_length; | 118 | new->length = address64.address.address_length; |
119 | list_add_tail(&new->list, &mem_device->res_list); | 119 | list_add_tail(&new->list, &mem_device->res_list); |
120 | 120 | ||
121 | return AE_OK; | 121 | return AE_OK; |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 6ba8beb6b9d2..1284138e42ab 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -45,7 +45,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) | |||
45 | struct platform_device *pdev = NULL; | 45 | struct platform_device *pdev = NULL; |
46 | struct acpi_device *acpi_parent; | 46 | struct acpi_device *acpi_parent; |
47 | struct platform_device_info pdevinfo; | 47 | struct platform_device_info pdevinfo; |
48 | struct resource_list_entry *rentry; | 48 | struct resource_entry *rentry; |
49 | struct list_head resource_list; | 49 | struct list_head resource_list; |
50 | struct resource *resources = NULL; | 50 | struct resource *resources = NULL; |
51 | int count; | 51 | int count; |
@@ -71,7 +71,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) | |||
71 | } | 71 | } |
72 | count = 0; | 72 | count = 0; |
73 | list_for_each_entry(rentry, &resource_list, node) | 73 | list_for_each_entry(rentry, &resource_list, node) |
74 | resources[count++] = rentry->res; | 74 | resources[count++] = *rentry->res; |
75 | 75 | ||
76 | acpi_dev_free_resource_list(&resource_list); | 76 | acpi_dev_free_resource_list(&resource_list); |
77 | } | 77 | } |
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index 3d2c88289da9..d863016565b5 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -47,7 +47,7 @@ | |||
47 | /* Common info for tool signons */ | 47 | /* Common info for tool signons */ |
48 | 48 | ||
49 | #define ACPICA_NAME "Intel ACPI Component Architecture" | 49 | #define ACPICA_NAME "Intel ACPI Component Architecture" |
50 | #define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2014 Intel Corporation" | 50 | #define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2015 Intel Corporation" |
51 | 51 | ||
52 | #if ACPI_MACHINE_WIDTH == 64 | 52 | #if ACPI_MACHINE_WIDTH == 64 |
53 | #define ACPI_WIDTH "-64" | 53 | #define ACPI_WIDTH "-64" |
diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 6f1c616910ac..853aa2dbdb61 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 1d026ff1683f..4169bb87a996 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index d3e2cc395d7f..408f04bcaab4 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 7a7811a9fc26..228704b78657 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -143,8 +143,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
143 | acpi_status | 143 | acpi_status |
144 | acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context); | 144 | acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context); |
145 | 145 | ||
146 | u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info); | ||
147 | |||
148 | acpi_status | 146 | acpi_status |
149 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 147 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
150 | struct acpi_gpe_block_info *gpe_block, void *context); | 148 | struct acpi_gpe_block_info *gpe_block, void *context); |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 7f60582d0c8c..a165d25343e8 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index c318d3e27893..196a55244559 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index b01f71ce0523..1886bde54b5d 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 680d23bbae7c..7add32e5d8c5 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 4bceb11c7380..cf607fe69dbd 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index ee1c040f321c..952fbe0b7231 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 8abb393dafab..3e9720e1f34f 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index dda0e6affcf1..a5f17de45ac6 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 6168b85463ed..74a390c6db16 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index bd3908d26c4f..a972d11c97c9 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index 4b008e8884a1..efc4c7124ccc 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index cf7346110bd8..d14b547b7cd5 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 1afe46e44dac..1c127a43017b 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 486d342e74b6..c2f03e8774ad 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 5908ccec6aea..3a95068fc119 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
@@ -7,7 +7,7 @@ | |||
7 | *****************************************************************************/ | 7 | *****************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2014, Intel Corp. | 10 | * Copyright (C) 2000 - 2015, Intel Corp. |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index 3a0beeb86ba5..ee0cdd60b93d 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c index 720b1cdda711..3e6989738e85 100644 --- a/drivers/acpi/acpica/dsargs.c +++ b/drivers/acpi/acpica/dsargs.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c index 8daf9de82b73..39da9da62bbf 100644 --- a/drivers/acpi/acpica/dscontrol.c +++ b/drivers/acpi/acpica/dscontrol.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index c57666196672..43b40de90484 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index aee5e45f6d35..bbe74bcebbae 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 3c7f7378b94d..d72565a3c646 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index b67522df01ac..2e4c42b377ec 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index a1e7e6b6fcf7..8a7b07b6adc8 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 6c0759c0db47..77244182ff02 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 9f74795e2268..e5ff89bcb3f5 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index f7f5107e754d..df54d46225cd 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 15623da26200..843942fb4be5 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index 2ac28d297305..fcaa30c611fb 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index 9d6e2c1de1f8..43b3ea40c0b6 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 24f7d5ea678a..89ac2022465e 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index c7bffff9ed32..bf6873f95e72 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c index 3393a73ca0d6..b78dc7c6d5d7 100644 --- a/drivers/acpi/acpica/evglock.c +++ b/drivers/acpi/acpica/evglock.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index aa70154cf4fa..5ed064e8673c 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -114,17 +114,6 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
114 | 114 | ||
115 | ACPI_FUNCTION_TRACE(ev_enable_gpe); | 115 | ACPI_FUNCTION_TRACE(ev_enable_gpe); |
116 | 116 | ||
117 | /* | ||
118 | * We will only allow a GPE to be enabled if it has either an associated | ||
119 | * method (_Lxx/_Exx) or a handler, or is using the implicit notify | ||
120 | * feature. Otherwise, the GPE will be immediately disabled by | ||
121 | * acpi_ev_gpe_dispatch the first time it fires. | ||
122 | */ | ||
123 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | ||
124 | ACPI_GPE_DISPATCH_NONE) { | ||
125 | return_ACPI_STATUS(AE_NO_HANDLER); | ||
126 | } | ||
127 | |||
128 | /* Clear the GPE (of stale events) */ | 117 | /* Clear the GPE (of stale events) */ |
129 | 118 | ||
130 | status = acpi_hw_clear_gpe(gpe_event_info); | 119 | status = acpi_hw_clear_gpe(gpe_event_info); |
@@ -339,7 +328,11 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) | |||
339 | { | 328 | { |
340 | acpi_status status; | 329 | acpi_status status; |
341 | struct acpi_gpe_block_info *gpe_block; | 330 | struct acpi_gpe_block_info *gpe_block; |
331 | struct acpi_namespace_node *gpe_device; | ||
342 | struct acpi_gpe_register_info *gpe_register_info; | 332 | struct acpi_gpe_register_info *gpe_register_info; |
333 | struct acpi_gpe_event_info *gpe_event_info; | ||
334 | u32 gpe_number; | ||
335 | struct acpi_gpe_handler_info *gpe_handler_info; | ||
343 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; | 336 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; |
344 | u8 enabled_status_byte; | 337 | u8 enabled_status_byte; |
345 | u32 status_reg; | 338 | u32 status_reg; |
@@ -367,6 +360,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) | |||
367 | 360 | ||
368 | gpe_block = gpe_xrupt_list->gpe_block_list_head; | 361 | gpe_block = gpe_xrupt_list->gpe_block_list_head; |
369 | while (gpe_block) { | 362 | while (gpe_block) { |
363 | gpe_device = gpe_block->node; | ||
364 | |||
370 | /* | 365 | /* |
371 | * Read all of the 8-bit GPE status and enable registers in this GPE | 366 | * Read all of the 8-bit GPE status and enable registers in this GPE |
372 | * block, saving all of them. Find all currently active GP events. | 367 | * block, saving all of them. Find all currently active GP events. |
@@ -442,16 +437,68 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) | |||
442 | 437 | ||
443 | /* Examine one GPE bit */ | 438 | /* Examine one GPE bit */ |
444 | 439 | ||
440 | gpe_event_info = | ||
441 | &gpe_block-> | ||
442 | event_info[((acpi_size) i * | ||
443 | ACPI_GPE_REGISTER_WIDTH) + j]; | ||
444 | gpe_number = | ||
445 | j + gpe_register_info->base_gpe_number; | ||
446 | |||
445 | if (enabled_status_byte & (1 << j)) { | 447 | if (enabled_status_byte & (1 << j)) { |
446 | /* | 448 | |
447 | * Found an active GPE. Dispatch the event to a handler | 449 | /* Invoke global event handler if present */ |
448 | * or method. | 450 | |
449 | */ | 451 | acpi_gpe_count++; |
450 | int_status |= | 452 | if (acpi_gbl_global_event_handler) { |
451 | acpi_ev_gpe_dispatch(gpe_block-> | 453 | acpi_gbl_global_event_handler |
452 | node, | 454 | (ACPI_EVENT_TYPE_GPE, |
453 | &gpe_block-> | 455 | gpe_device, gpe_number, |
454 | event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); | 456 | acpi_gbl_global_event_handler_context); |
457 | } | ||
458 | |||
459 | /* Found an active GPE */ | ||
460 | |||
461 | if (ACPI_GPE_DISPATCH_TYPE | ||
462 | (gpe_event_info->flags) == | ||
463 | ACPI_GPE_DISPATCH_RAW_HANDLER) { | ||
464 | |||
465 | /* Dispatch the event to a raw handler */ | ||
466 | |||
467 | gpe_handler_info = | ||
468 | gpe_event_info->dispatch. | ||
469 | handler; | ||
470 | |||
471 | /* | ||
472 | * There is no protection around the namespace node | ||
473 | * and the GPE handler to ensure a safe destruction | ||
474 | * because: | ||
475 | * 1. The namespace node is expected to always | ||
476 | * exist after loading a table. | ||
477 | * 2. The GPE handler is expected to be flushed by | ||
478 | * acpi_os_wait_events_complete() before the | ||
479 | * destruction. | ||
480 | */ | ||
481 | acpi_os_release_lock | ||
482 | (acpi_gbl_gpe_lock, flags); | ||
483 | int_status |= | ||
484 | gpe_handler_info-> | ||
485 | address(gpe_device, | ||
486 | gpe_number, | ||
487 | gpe_handler_info-> | ||
488 | context); | ||
489 | flags = | ||
490 | acpi_os_acquire_lock | ||
491 | (acpi_gbl_gpe_lock); | ||
492 | } else { | ||
493 | /* | ||
494 | * Dispatch the event to a standard handler or | ||
495 | * method. | ||
496 | */ | ||
497 | int_status |= | ||
498 | acpi_ev_gpe_dispatch | ||
499 | (gpe_device, gpe_event_info, | ||
500 | gpe_number); | ||
501 | } | ||
455 | } | 502 | } |
456 | } | 503 | } |
457 | } | 504 | } |
@@ -484,52 +531,15 @@ unlock_and_exit: | |||
484 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | 531 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) |
485 | { | 532 | { |
486 | struct acpi_gpe_event_info *gpe_event_info = context; | 533 | struct acpi_gpe_event_info *gpe_event_info = context; |
487 | acpi_status status; | 534 | acpi_status status = AE_OK; |
488 | struct acpi_gpe_event_info *local_gpe_event_info; | ||
489 | struct acpi_evaluate_info *info; | 535 | struct acpi_evaluate_info *info; |
490 | struct acpi_gpe_notify_info *notify; | 536 | struct acpi_gpe_notify_info *notify; |
491 | 537 | ||
492 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); | 538 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); |
493 | 539 | ||
494 | /* Allocate a local GPE block */ | ||
495 | |||
496 | local_gpe_event_info = | ||
497 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info)); | ||
498 | if (!local_gpe_event_info) { | ||
499 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE")); | ||
500 | return_VOID; | ||
501 | } | ||
502 | |||
503 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
504 | if (ACPI_FAILURE(status)) { | ||
505 | ACPI_FREE(local_gpe_event_info); | ||
506 | return_VOID; | ||
507 | } | ||
508 | |||
509 | /* Must revalidate the gpe_number/gpe_block */ | ||
510 | |||
511 | if (!acpi_ev_valid_gpe_event(gpe_event_info)) { | ||
512 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
513 | ACPI_FREE(local_gpe_event_info); | ||
514 | return_VOID; | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * Take a snapshot of the GPE info for this level - we copy the info to | ||
519 | * prevent a race condition with remove_handler/remove_block. | ||
520 | */ | ||
521 | ACPI_MEMCPY(local_gpe_event_info, gpe_event_info, | ||
522 | sizeof(struct acpi_gpe_event_info)); | ||
523 | |||
524 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
525 | if (ACPI_FAILURE(status)) { | ||
526 | ACPI_FREE(local_gpe_event_info); | ||
527 | return_VOID; | ||
528 | } | ||
529 | |||
530 | /* Do the correct dispatch - normal method or implicit notify */ | 540 | /* Do the correct dispatch - normal method or implicit notify */ |
531 | 541 | ||
532 | switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { | 542 | switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) { |
533 | case ACPI_GPE_DISPATCH_NOTIFY: | 543 | case ACPI_GPE_DISPATCH_NOTIFY: |
534 | /* | 544 | /* |
535 | * Implicit notify. | 545 | * Implicit notify. |
@@ -542,7 +552,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
542 | * June 2012: Expand implicit notify mechanism to support | 552 | * June 2012: Expand implicit notify mechanism to support |
543 | * notifies on multiple device objects. | 553 | * notifies on multiple device objects. |
544 | */ | 554 | */ |
545 | notify = local_gpe_event_info->dispatch.notify_list; | 555 | notify = gpe_event_info->dispatch.notify_list; |
546 | while (ACPI_SUCCESS(status) && notify) { | 556 | while (ACPI_SUCCESS(status) && notify) { |
547 | status = | 557 | status = |
548 | acpi_ev_queue_notify_request(notify->device_node, | 558 | acpi_ev_queue_notify_request(notify->device_node, |
@@ -566,7 +576,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
566 | * _Lxx/_Exx control method that corresponds to this GPE | 576 | * _Lxx/_Exx control method that corresponds to this GPE |
567 | */ | 577 | */ |
568 | info->prefix_node = | 578 | info->prefix_node = |
569 | local_gpe_event_info->dispatch.method_node; | 579 | gpe_event_info->dispatch.method_node; |
570 | info->flags = ACPI_IGNORE_RETURN_VALUE; | 580 | info->flags = ACPI_IGNORE_RETURN_VALUE; |
571 | 581 | ||
572 | status = acpi_ns_evaluate(info); | 582 | status = acpi_ns_evaluate(info); |
@@ -576,25 +586,27 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
576 | if (ACPI_FAILURE(status)) { | 586 | if (ACPI_FAILURE(status)) { |
577 | ACPI_EXCEPTION((AE_INFO, status, | 587 | ACPI_EXCEPTION((AE_INFO, status, |
578 | "while evaluating GPE method [%4.4s]", | 588 | "while evaluating GPE method [%4.4s]", |
579 | acpi_ut_get_node_name | 589 | acpi_ut_get_node_name(gpe_event_info-> |
580 | (local_gpe_event_info->dispatch. | 590 | dispatch. |
581 | method_node))); | 591 | method_node))); |
582 | } | 592 | } |
583 | break; | 593 | break; |
584 | 594 | ||
585 | default: | 595 | default: |
586 | 596 | ||
587 | return_VOID; /* Should never happen */ | 597 | goto error_exit; /* Should never happen */ |
588 | } | 598 | } |
589 | 599 | ||
590 | /* Defer enabling of GPE until all notify handlers are done */ | 600 | /* Defer enabling of GPE until all notify handlers are done */ |
591 | 601 | ||
592 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, | 602 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, |
593 | acpi_ev_asynch_enable_gpe, | 603 | acpi_ev_asynch_enable_gpe, gpe_event_info); |
594 | local_gpe_event_info); | 604 | if (ACPI_SUCCESS(status)) { |
595 | if (ACPI_FAILURE(status)) { | 605 | return_VOID; |
596 | ACPI_FREE(local_gpe_event_info); | ||
597 | } | 606 | } |
607 | |||
608 | error_exit: | ||
609 | acpi_ev_asynch_enable_gpe(gpe_event_info); | ||
598 | return_VOID; | 610 | return_VOID; |
599 | } | 611 | } |
600 | 612 | ||
@@ -622,7 +634,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context) | |||
622 | (void)acpi_ev_finish_gpe(gpe_event_info); | 634 | (void)acpi_ev_finish_gpe(gpe_event_info); |
623 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 635 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
624 | 636 | ||
625 | ACPI_FREE(gpe_event_info); | ||
626 | return; | 637 | return; |
627 | } | 638 | } |
628 | 639 | ||
@@ -692,15 +703,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
692 | 703 | ||
693 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); | 704 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); |
694 | 705 | ||
695 | /* Invoke global event handler if present */ | ||
696 | |||
697 | acpi_gpe_count++; | ||
698 | if (acpi_gbl_global_event_handler) { | ||
699 | acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device, | ||
700 | gpe_number, | ||
701 | acpi_gbl_global_event_handler_context); | ||
702 | } | ||
703 | |||
704 | /* | 706 | /* |
705 | * Always disable the GPE so that it does not keep firing before | 707 | * Always disable the GPE so that it does not keep firing before |
706 | * any asynchronous activity completes (either from the execution | 708 | * any asynchronous activity completes (either from the execution |
@@ -741,7 +743,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
741 | * If there is neither a handler nor a method, leave the GPE | 743 | * If there is neither a handler nor a method, leave the GPE |
742 | * disabled. | 744 | * disabled. |
743 | */ | 745 | */ |
744 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { | 746 | switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) { |
745 | case ACPI_GPE_DISPATCH_HANDLER: | 747 | case ACPI_GPE_DISPATCH_HANDLER: |
746 | 748 | ||
747 | /* Invoke the installed handler (at interrupt level) */ | 749 | /* Invoke the installed handler (at interrupt level) */ |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index d86699eea33c..e0f24c504513 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -474,10 +474,12 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
474 | * Ignore GPEs that have no corresponding _Lxx/_Exx method | 474 | * Ignore GPEs that have no corresponding _Lxx/_Exx method |
475 | * and GPEs that are used to wake the system | 475 | * and GPEs that are used to wake the system |
476 | */ | 476 | */ |
477 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 477 | if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == |
478 | ACPI_GPE_DISPATCH_NONE) | 478 | ACPI_GPE_DISPATCH_NONE) |
479 | || ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | 479 | || (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == |
480 | == ACPI_GPE_DISPATCH_HANDLER) | 480 | ACPI_GPE_DISPATCH_HANDLER) |
481 | || (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == | ||
482 | ACPI_GPE_DISPATCH_RAW_HANDLER) | ||
481 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | 483 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { |
482 | continue; | 484 | continue; |
483 | } | 485 | } |
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 7be928379879..8840296d5b20 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -401,15 +401,17 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
401 | return_ACPI_STATUS(AE_OK); | 401 | return_ACPI_STATUS(AE_OK); |
402 | } | 402 | } |
403 | 403 | ||
404 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 404 | if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == |
405 | ACPI_GPE_DISPATCH_HANDLER) { | 405 | ACPI_GPE_DISPATCH_HANDLER) || |
406 | (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == | ||
407 | ACPI_GPE_DISPATCH_RAW_HANDLER)) { | ||
406 | 408 | ||
407 | /* If there is already a handler, ignore this GPE method */ | 409 | /* If there is already a handler, ignore this GPE method */ |
408 | 410 | ||
409 | return_ACPI_STATUS(AE_OK); | 411 | return_ACPI_STATUS(AE_OK); |
410 | } | 412 | } |
411 | 413 | ||
412 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 414 | if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == |
413 | ACPI_GPE_DISPATCH_METHOD) { | 415 | ACPI_GPE_DISPATCH_METHOD) { |
414 | /* | 416 | /* |
415 | * If there is already a method, ignore this method. But check | 417 | * If there is already a method, ignore this method. But check |
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index 17e4bbfdb096..3a958f3612fe 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -108,53 +108,6 @@ unlock_and_exit: | |||
108 | 108 | ||
109 | /******************************************************************************* | 109 | /******************************************************************************* |
110 | * | 110 | * |
111 | * FUNCTION: acpi_ev_valid_gpe_event | ||
112 | * | ||
113 | * PARAMETERS: gpe_event_info - Info for this GPE | ||
114 | * | ||
115 | * RETURN: TRUE if the gpe_event is valid | ||
116 | * | ||
117 | * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. | ||
118 | * Should be called only when the GPE lists are semaphore locked | ||
119 | * and not subject to change. | ||
120 | * | ||
121 | ******************************************************************************/ | ||
122 | |||
123 | u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) | ||
124 | { | ||
125 | struct acpi_gpe_xrupt_info *gpe_xrupt_block; | ||
126 | struct acpi_gpe_block_info *gpe_block; | ||
127 | |||
128 | ACPI_FUNCTION_ENTRY(); | ||
129 | |||
130 | /* No need for spin lock since we are not changing any list elements */ | ||
131 | |||
132 | /* Walk the GPE interrupt levels */ | ||
133 | |||
134 | gpe_xrupt_block = acpi_gbl_gpe_xrupt_list_head; | ||
135 | while (gpe_xrupt_block) { | ||
136 | gpe_block = gpe_xrupt_block->gpe_block_list_head; | ||
137 | |||
138 | /* Walk the GPE blocks on this interrupt level */ | ||
139 | |||
140 | while (gpe_block) { | ||
141 | if ((&gpe_block->event_info[0] <= gpe_event_info) && | ||
142 | (&gpe_block->event_info[gpe_block->gpe_count] > | ||
143 | gpe_event_info)) { | ||
144 | return (TRUE); | ||
145 | } | ||
146 | |||
147 | gpe_block = gpe_block->next; | ||
148 | } | ||
149 | |||
150 | gpe_xrupt_block = gpe_xrupt_block->next; | ||
151 | } | ||
152 | |||
153 | return (FALSE); | ||
154 | } | ||
155 | |||
156 | /******************************************************************************* | ||
157 | * | ||
158 | * FUNCTION: acpi_ev_get_gpe_device | 111 | * FUNCTION: acpi_ev_get_gpe_device |
159 | * | 112 | * |
160 | * PARAMETERS: GPE_WALK_CALLBACK | 113 | * PARAMETERS: GPE_WALK_CALLBACK |
@@ -371,8 +324,10 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
371 | ACPI_GPE_REGISTER_WIDTH) | 324 | ACPI_GPE_REGISTER_WIDTH) |
372 | + j]; | 325 | + j]; |
373 | 326 | ||
374 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 327 | if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == |
375 | ACPI_GPE_DISPATCH_HANDLER) { | 328 | ACPI_GPE_DISPATCH_HANDLER) || |
329 | (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == | ||
330 | ACPI_GPE_DISPATCH_RAW_HANDLER)) { | ||
376 | 331 | ||
377 | /* Delete an installed handler block */ | 332 | /* Delete an installed handler block */ |
378 | 333 | ||
@@ -380,10 +335,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
380 | gpe_event_info->dispatch.handler = NULL; | 335 | gpe_event_info->dispatch.handler = NULL; |
381 | gpe_event_info->flags &= | 336 | gpe_event_info->flags &= |
382 | ~ACPI_GPE_DISPATCH_MASK; | 337 | ~ACPI_GPE_DISPATCH_MASK; |
383 | } else | 338 | } else if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) |
384 | if ((gpe_event_info-> | 339 | == ACPI_GPE_DISPATCH_NOTIFY) { |
385 | flags & ACPI_GPE_DISPATCH_MASK) == | ||
386 | ACPI_GPE_DISPATCH_NOTIFY) { | ||
387 | 340 | ||
388 | /* Delete the implicit notification device list */ | 341 | /* Delete the implicit notification device list */ |
389 | 342 | ||
diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c index 78ac29351c9e..74e8595f5a2b 100644 --- a/drivers/acpi/acpica/evhandler.c +++ b/drivers/acpi/acpica/evhandler.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 24ea3424981b..f7c9dfe7b990 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 8eb8575e8c16..9abace3401f9 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 1b148a440d67..da323390bb70 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 29630e303829..0366703d2970 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 55a58f3ec8df..81f2d9e87fad 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -51,6 +51,16 @@ | |||
51 | 51 | ||
52 | #define _COMPONENT ACPI_EVENTS | 52 | #define _COMPONENT ACPI_EVENTS |
53 | ACPI_MODULE_NAME("evxface") | 53 | ACPI_MODULE_NAME("evxface") |
54 | #if (!ACPI_REDUCED_HARDWARE) | ||
55 | /* Local prototypes */ | ||
56 | static acpi_status | ||
57 | acpi_ev_install_gpe_handler(acpi_handle gpe_device, | ||
58 | u32 gpe_number, | ||
59 | u32 type, | ||
60 | u8 is_raw_handler, | ||
61 | acpi_gpe_handler address, void *context); | ||
62 | |||
63 | #endif | ||
54 | 64 | ||
55 | 65 | ||
56 | /******************************************************************************* | 66 | /******************************************************************************* |
@@ -76,6 +86,7 @@ ACPI_MODULE_NAME("evxface") | |||
76 | * handlers. | 86 | * handlers. |
77 | * | 87 | * |
78 | ******************************************************************************/ | 88 | ******************************************************************************/ |
89 | |||
79 | acpi_status | 90 | acpi_status |
80 | acpi_install_notify_handler(acpi_handle device, | 91 | acpi_install_notify_handler(acpi_handle device, |
81 | u32 handler_type, | 92 | u32 handler_type, |
@@ -717,32 +728,37 @@ ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler) | |||
717 | 728 | ||
718 | /******************************************************************************* | 729 | /******************************************************************************* |
719 | * | 730 | * |
720 | * FUNCTION: acpi_install_gpe_handler | 731 | * FUNCTION: acpi_ev_install_gpe_handler |
721 | * | 732 | * |
722 | * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT | 733 | * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT |
723 | * defined GPEs) | 734 | * defined GPEs) |
724 | * gpe_number - The GPE number within the GPE block | 735 | * gpe_number - The GPE number within the GPE block |
725 | * type - Whether this GPE should be treated as an | 736 | * type - Whether this GPE should be treated as an |
726 | * edge- or level-triggered interrupt. | 737 | * edge- or level-triggered interrupt. |
738 | * is_raw_handler - Whether this GPE should be handled using | ||
739 | * the special GPE handler mode. | ||
727 | * address - Address of the handler | 740 | * address - Address of the handler |
728 | * context - Value passed to the handler on each GPE | 741 | * context - Value passed to the handler on each GPE |
729 | * | 742 | * |
730 | * RETURN: Status | 743 | * RETURN: Status |
731 | * | 744 | * |
732 | * DESCRIPTION: Install a handler for a General Purpose Event. | 745 | * DESCRIPTION: Internal function to install a handler for a General Purpose |
746 | * Event. | ||
733 | * | 747 | * |
734 | ******************************************************************************/ | 748 | ******************************************************************************/ |
735 | acpi_status | 749 | static acpi_status |
736 | acpi_install_gpe_handler(acpi_handle gpe_device, | 750 | acpi_ev_install_gpe_handler(acpi_handle gpe_device, |
737 | u32 gpe_number, | 751 | u32 gpe_number, |
738 | u32 type, acpi_gpe_handler address, void *context) | 752 | u32 type, |
753 | u8 is_raw_handler, | ||
754 | acpi_gpe_handler address, void *context) | ||
739 | { | 755 | { |
740 | struct acpi_gpe_event_info *gpe_event_info; | 756 | struct acpi_gpe_event_info *gpe_event_info; |
741 | struct acpi_gpe_handler_info *handler; | 757 | struct acpi_gpe_handler_info *handler; |
742 | acpi_status status; | 758 | acpi_status status; |
743 | acpi_cpu_flags flags; | 759 | acpi_cpu_flags flags; |
744 | 760 | ||
745 | ACPI_FUNCTION_TRACE(acpi_install_gpe_handler); | 761 | ACPI_FUNCTION_TRACE(ev_install_gpe_handler); |
746 | 762 | ||
747 | /* Parameter validation */ | 763 | /* Parameter validation */ |
748 | 764 | ||
@@ -775,8 +791,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
775 | 791 | ||
776 | /* Make sure that there isn't a handler there already */ | 792 | /* Make sure that there isn't a handler there already */ |
777 | 793 | ||
778 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 794 | if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == |
779 | ACPI_GPE_DISPATCH_HANDLER) { | 795 | ACPI_GPE_DISPATCH_HANDLER) || |
796 | (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == | ||
797 | ACPI_GPE_DISPATCH_RAW_HANDLER)) { | ||
780 | status = AE_ALREADY_EXISTS; | 798 | status = AE_ALREADY_EXISTS; |
781 | goto free_and_exit; | 799 | goto free_and_exit; |
782 | } | 800 | } |
@@ -793,9 +811,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
793 | * automatically during initialization, in which case it has to be | 811 | * automatically during initialization, in which case it has to be |
794 | * disabled now to avoid spurious execution of the handler. | 812 | * disabled now to avoid spurious execution of the handler. |
795 | */ | 813 | */ |
796 | if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) || | 814 | if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) == |
797 | (handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) && | 815 | ACPI_GPE_DISPATCH_METHOD) || |
798 | gpe_event_info->runtime_count) { | 816 | (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) == |
817 | ACPI_GPE_DISPATCH_NOTIFY)) && gpe_event_info->runtime_count) { | ||
799 | handler->originally_enabled = TRUE; | 818 | handler->originally_enabled = TRUE; |
800 | (void)acpi_ev_remove_gpe_reference(gpe_event_info); | 819 | (void)acpi_ev_remove_gpe_reference(gpe_event_info); |
801 | 820 | ||
@@ -816,7 +835,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
816 | 835 | ||
817 | gpe_event_info->flags &= | 836 | gpe_event_info->flags &= |
818 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | 837 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
819 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_HANDLER); | 838 | gpe_event_info->flags |= |
839 | (u8)(type | | ||
840 | (is_raw_handler ? ACPI_GPE_DISPATCH_RAW_HANDLER : | ||
841 | ACPI_GPE_DISPATCH_HANDLER)); | ||
820 | 842 | ||
821 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 843 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
822 | 844 | ||
@@ -830,10 +852,78 @@ free_and_exit: | |||
830 | goto unlock_and_exit; | 852 | goto unlock_and_exit; |
831 | } | 853 | } |
832 | 854 | ||
855 | /******************************************************************************* | ||
856 | * | ||
857 | * FUNCTION: acpi_install_gpe_handler | ||
858 | * | ||
859 | * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT | ||
860 | * defined GPEs) | ||
861 | * gpe_number - The GPE number within the GPE block | ||
862 | * type - Whether this GPE should be treated as an | ||
863 | * edge- or level-triggered interrupt. | ||
864 | * address - Address of the handler | ||
865 | * context - Value passed to the handler on each GPE | ||
866 | * | ||
867 | * RETURN: Status | ||
868 | * | ||
869 | * DESCRIPTION: Install a handler for a General Purpose Event. | ||
870 | * | ||
871 | ******************************************************************************/ | ||
872 | |||
873 | acpi_status | ||
874 | acpi_install_gpe_handler(acpi_handle gpe_device, | ||
875 | u32 gpe_number, | ||
876 | u32 type, acpi_gpe_handler address, void *context) | ||
877 | { | ||
878 | acpi_status status; | ||
879 | |||
880 | ACPI_FUNCTION_TRACE(acpi_install_gpe_handler); | ||
881 | |||
882 | status = | ||
883 | acpi_ev_install_gpe_handler(gpe_device, gpe_number, type, FALSE, | ||
884 | address, context); | ||
885 | |||
886 | return_ACPI_STATUS(status); | ||
887 | } | ||
888 | |||
833 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) | 889 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) |
834 | 890 | ||
835 | /******************************************************************************* | 891 | /******************************************************************************* |
836 | * | 892 | * |
893 | * FUNCTION: acpi_install_gpe_raw_handler | ||
894 | * | ||
895 | * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT | ||
896 | * defined GPEs) | ||
897 | * gpe_number - The GPE number within the GPE block | ||
898 | * type - Whether this GPE should be treated as an | ||
899 | * edge- or level-triggered interrupt. | ||
900 | * address - Address of the handler | ||
901 | * context - Value passed to the handler on each GPE | ||
902 | * | ||
903 | * RETURN: Status | ||
904 | * | ||
905 | * DESCRIPTION: Install a handler for a General Purpose Event. | ||
906 | * | ||
907 | ******************************************************************************/ | ||
908 | acpi_status | ||
909 | acpi_install_gpe_raw_handler(acpi_handle gpe_device, | ||
910 | u32 gpe_number, | ||
911 | u32 type, acpi_gpe_handler address, void *context) | ||
912 | { | ||
913 | acpi_status status; | ||
914 | |||
915 | ACPI_FUNCTION_TRACE(acpi_install_gpe_raw_handler); | ||
916 | |||
917 | status = acpi_ev_install_gpe_handler(gpe_device, gpe_number, type, TRUE, | ||
918 | address, context); | ||
919 | |||
920 | return_ACPI_STATUS(status); | ||
921 | } | ||
922 | |||
923 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_raw_handler) | ||
924 | |||
925 | /******************************************************************************* | ||
926 | * | ||
837 | * FUNCTION: acpi_remove_gpe_handler | 927 | * FUNCTION: acpi_remove_gpe_handler |
838 | * | 928 | * |
839 | * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT | 929 | * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT |
@@ -880,8 +970,10 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
880 | 970 | ||
881 | /* Make sure that a handler is indeed installed */ | 971 | /* Make sure that a handler is indeed installed */ |
882 | 972 | ||
883 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != | 973 | if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != |
884 | ACPI_GPE_DISPATCH_HANDLER) { | 974 | ACPI_GPE_DISPATCH_HANDLER) && |
975 | (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != | ||
976 | ACPI_GPE_DISPATCH_RAW_HANDLER)) { | ||
885 | status = AE_NOT_EXIST; | 977 | status = AE_NOT_EXIST; |
886 | goto unlock_and_exit; | 978 | goto unlock_and_exit; |
887 | } | 979 | } |
@@ -896,6 +988,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
896 | /* Remove the handler */ | 988 | /* Remove the handler */ |
897 | 989 | ||
898 | handler = gpe_event_info->dispatch.handler; | 990 | handler = gpe_event_info->dispatch.handler; |
991 | gpe_event_info->dispatch.handler = NULL; | ||
899 | 992 | ||
900 | /* Restore Method node (if any), set dispatch flags */ | 993 | /* Restore Method node (if any), set dispatch flags */ |
901 | 994 | ||
@@ -909,9 +1002,10 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
909 | * enabled, it should be enabled at this point to restore the | 1002 | * enabled, it should be enabled at this point to restore the |
910 | * post-initialization configuration. | 1003 | * post-initialization configuration. |
911 | */ | 1004 | */ |
912 | if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) || | 1005 | if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) == |
913 | (handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) && | 1006 | ACPI_GPE_DISPATCH_METHOD) || |
914 | handler->originally_enabled) { | 1007 | (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) == |
1008 | ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) { | ||
915 | (void)acpi_ev_add_gpe_reference(gpe_event_info); | 1009 | (void)acpi_ev_add_gpe_reference(gpe_event_info); |
916 | } | 1010 | } |
917 | 1011 | ||
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index bb8cbf5961bf..df06a23c4197 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index e889a5304abd..70eb47e3d724 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -132,7 +132,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
132 | */ | 132 | */ |
133 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 133 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
134 | if (gpe_event_info) { | 134 | if (gpe_event_info) { |
135 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != | 135 | if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != |
136 | ACPI_GPE_DISPATCH_NONE) { | 136 | ACPI_GPE_DISPATCH_NONE) { |
137 | status = acpi_ev_add_gpe_reference(gpe_event_info); | 137 | status = acpi_ev_add_gpe_reference(gpe_event_info); |
138 | } else { | 138 | } else { |
@@ -183,6 +183,77 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
183 | 183 | ||
184 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | 184 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) |
185 | 185 | ||
186 | /******************************************************************************* | ||
187 | * | ||
188 | * FUNCTION: acpi_set_gpe | ||
189 | * | ||
190 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
191 | * gpe_number - GPE level within the GPE block | ||
192 | * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE | ||
193 | * | ||
194 | * RETURN: Status | ||
195 | * | ||
196 | * DESCRIPTION: Enable or disable an individual GPE. This function bypasses | ||
197 | * the reference count mechanism used in the acpi_enable_gpe(), | ||
198 | * acpi_disable_gpe() interfaces. | ||
199 | * This API is typically used by the GPE raw handler mode driver | ||
200 | * to switch between the polling mode and the interrupt mode after | ||
201 | * the driver has enabled the GPE. | ||
202 | * The APIs should be invoked in this order: | ||
203 | * acpi_enable_gpe() <- Ensure the reference count > 0 | ||
204 | * acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode | ||
205 | * acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode | ||
206 | * acpi_disable_gpe() <- Decrease the reference count | ||
207 | * | ||
208 | * Note: If a GPE is shared by 2 silicon components, then both the drivers | ||
209 | * should support GPE polling mode or disabling the GPE for long period | ||
210 | * for one driver may break the other. So use it with care since all | ||
211 | * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode. | ||
212 | * | ||
213 | ******************************************************************************/ | ||
214 | acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) | ||
215 | { | ||
216 | struct acpi_gpe_event_info *gpe_event_info; | ||
217 | acpi_status status; | ||
218 | acpi_cpu_flags flags; | ||
219 | |||
220 | ACPI_FUNCTION_TRACE(acpi_set_gpe); | ||
221 | |||
222 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
223 | |||
224 | /* Ensure that we have a valid GPE number */ | ||
225 | |||
226 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
227 | if (!gpe_event_info) { | ||
228 | status = AE_BAD_PARAMETER; | ||
229 | goto unlock_and_exit; | ||
230 | } | ||
231 | |||
232 | /* Perform the action */ | ||
233 | |||
234 | switch (action) { | ||
235 | case ACPI_GPE_ENABLE: | ||
236 | |||
237 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); | ||
238 | break; | ||
239 | |||
240 | case ACPI_GPE_DISABLE: | ||
241 | |||
242 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
243 | break; | ||
244 | |||
245 | default: | ||
246 | |||
247 | status = AE_BAD_PARAMETER; | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | unlock_and_exit: | ||
252 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
253 | return_ACPI_STATUS(status); | ||
254 | } | ||
255 | |||
256 | ACPI_EXPORT_SYMBOL(acpi_set_gpe) | ||
186 | 257 | ||
187 | /******************************************************************************* | 258 | /******************************************************************************* |
188 | * | 259 | * |
@@ -313,7 +384,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, | |||
313 | * known as an "implicit notify". Note: The GPE is assumed to be | 384 | * known as an "implicit notify". Note: The GPE is assumed to be |
314 | * level-triggered (for windows compatibility). | 385 | * level-triggered (for windows compatibility). |
315 | */ | 386 | */ |
316 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 387 | if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == |
317 | ACPI_GPE_DISPATCH_NONE) { | 388 | ACPI_GPE_DISPATCH_NONE) { |
318 | /* | 389 | /* |
319 | * This is the first device for implicit notify on this GPE. | 390 | * This is the first device for implicit notify on this GPE. |
@@ -327,7 +398,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, | |||
327 | * If we already have an implicit notify on this GPE, add | 398 | * If we already have an implicit notify on this GPE, add |
328 | * this device to the notify list. | 399 | * this device to the notify list. |
329 | */ | 400 | */ |
330 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 401 | if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == |
331 | ACPI_GPE_DISPATCH_NOTIFY) { | 402 | ACPI_GPE_DISPATCH_NOTIFY) { |
332 | 403 | ||
333 | /* Ensure that the device is not already in the list */ | 404 | /* Ensure that the device is not already in the list */ |
@@ -530,6 +601,49 @@ unlock_and_exit: | |||
530 | 601 | ||
531 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) | 602 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) |
532 | 603 | ||
604 | /******************************************************************************* | ||
605 | * | ||
606 | * FUNCTION: acpi_finish_gpe | ||
607 | * | ||
608 | * PARAMETERS: gpe_device - Namespace node for the GPE Block | ||
609 | * (NULL for FADT defined GPEs) | ||
610 | * gpe_number - GPE level within the GPE block | ||
611 | * | ||
612 | * RETURN: Status | ||
613 | * | ||
614 | * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE | ||
615 | * processing. Intended for use by asynchronous host-installed | ||
616 | * GPE handlers. The GPE is only reenabled if the enable_for_run bit | ||
617 | * is set in the GPE info. | ||
618 | * | ||
619 | ******************************************************************************/ | ||
620 | acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
621 | { | ||
622 | struct acpi_gpe_event_info *gpe_event_info; | ||
623 | acpi_status status; | ||
624 | acpi_cpu_flags flags; | ||
625 | |||
626 | ACPI_FUNCTION_TRACE(acpi_finish_gpe); | ||
627 | |||
628 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
629 | |||
630 | /* Ensure that we have a valid GPE number */ | ||
631 | |||
632 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
633 | if (!gpe_event_info) { | ||
634 | status = AE_BAD_PARAMETER; | ||
635 | goto unlock_and_exit; | ||
636 | } | ||
637 | |||
638 | status = acpi_ev_finish_gpe(gpe_event_info); | ||
639 | |||
640 | unlock_and_exit: | ||
641 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
642 | return_ACPI_STATUS(status); | ||
643 | } | ||
644 | |||
645 | ACPI_EXPORT_SYMBOL(acpi_finish_gpe) | ||
646 | |||
533 | /****************************************************************************** | 647 | /****************************************************************************** |
534 | * | 648 | * |
535 | * FUNCTION: acpi_disable_all_gpes | 649 | * FUNCTION: acpi_disable_all_gpes |
@@ -604,7 +718,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes) | |||
604 | * all GPE blocks. | 718 | * all GPE blocks. |
605 | * | 719 | * |
606 | ******************************************************************************/ | 720 | ******************************************************************************/ |
607 | |||
608 | acpi_status acpi_enable_all_wakeup_gpes(void) | 721 | acpi_status acpi_enable_all_wakeup_gpes(void) |
609 | { | 722 | { |
610 | acpi_status status; | 723 | acpi_status status; |
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index 2d6f187939c7..f21afbab03f7 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 7d2949420db7..6e0df2b9d5a4 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index c545386fee96..89a976b4ccf2 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 95d23dabcfbb..aaeea4840aaa 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index 6fbfad47518c..e67d0aca3fe6 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 0f23c3f2678e..7c213b6b6472 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index b994845ed359..c161dd974f74 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 1d1b27a96c5b..49479927e7f7 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 2207e624f538..b56fc9d6f48e 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index b49ea2a95f4f..472030f2b5bb 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index dbb03b544e8c..453b00c30177 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 1b8e94104407..77930683ab7d 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index 2ede656ee26a..fcc618aa2061 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 363767cf01e5..b813fed95e56 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 29e9e99f7fe3..c930edda3f65 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 118e942005e5..4c2836dc825b 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index cd5288a257a9..0fe188e238ef 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index ab060261b43e..c7e3b929aa85 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index 3cde553bcbe1..b6b7f3af29e4 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 3af8de3fcea4..d2964af9ad4d 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index daf49f7ea311..a7eee2400ce0 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index 04bd16c08f9e..3101607b4efe 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index fd11018b0168..6fa3c8d8fc5f 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index f7da64123ed5..05450656fe3d 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index d9d72dff2a76..3f4225e95d93 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index 1e66d960fc11..e5c5949f9081 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index 858fdd6be598..e5599f610808 100644 --- a/drivers/acpi/acpica/hwesleep.c +++ b/drivers/acpi/acpica/hwesleep.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 494027f5c067..84bc550f4f1d 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -54,6 +54,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
54 | struct acpi_gpe_block_info *gpe_block, | 54 | struct acpi_gpe_block_info *gpe_block, |
55 | void *context); | 55 | void *context); |
56 | 56 | ||
57 | static acpi_status | ||
58 | acpi_hw_gpe_enable_write(u8 enable_mask, | ||
59 | struct acpi_gpe_register_info *gpe_register_info); | ||
60 | |||
57 | /****************************************************************************** | 61 | /****************************************************************************** |
58 | * | 62 | * |
59 | * FUNCTION: acpi_hw_get_gpe_register_bit | 63 | * FUNCTION: acpi_hw_get_gpe_register_bit |
@@ -146,7 +150,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) | |||
146 | 150 | ||
147 | status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); | 151 | status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); |
148 | if (ACPI_SUCCESS(status) && (action & ACPI_GPE_SAVE_MASK)) { | 152 | if (ACPI_SUCCESS(status) && (action & ACPI_GPE_SAVE_MASK)) { |
149 | gpe_register_info->enable_mask = enable_mask; | 153 | gpe_register_info->enable_mask = (u8)enable_mask; |
150 | } | 154 | } |
151 | return (status); | 155 | return (status); |
152 | } | 156 | } |
@@ -221,7 +225,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
221 | 225 | ||
222 | /* GPE currently handled? */ | 226 | /* GPE currently handled? */ |
223 | 227 | ||
224 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != | 228 | if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != |
225 | ACPI_GPE_DISPATCH_NONE) { | 229 | ACPI_GPE_DISPATCH_NONE) { |
226 | local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; | 230 | local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; |
227 | } | 231 | } |
diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c index 6aade8e1d2a1..c5214dec4988 100644 --- a/drivers/acpi/acpica/hwpci.c +++ b/drivers/acpi/acpica/hwpci.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index a4c34d2c556b..3cf77afd142c 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index d590693eb54e..7d21cae6d602 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 76ab5c1a814e..675c709a300b 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index 6b919127cd9d..2bd33fe56cb3 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 96d007df65ec..5f97468df8ff 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index 6921c7f3d208..3b3767698827 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index f1249e3463be..24fa19a76d70 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 607eb9e5150d..e107f929d9cf 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsarguments.c b/drivers/acpi/acpica/nsarguments.c index 80fcfc8c9c1b..5d347a71bd0b 100644 --- a/drivers/acpi/acpica/nsarguments.c +++ b/drivers/acpi/acpica/nsarguments.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c index b55642c4ee58..1a8b39c8d969 100644 --- a/drivers/acpi/acpica/nsconvert.c +++ b/drivers/acpi/acpica/nsconvert.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 3d88ef4a3e0d..80f097eb7381 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 42d37109aa5d..7dc367e6fe09 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index e634a05974db..7bcc68f57afa 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index a3fb7e4c0809..4a85c4517988 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index 7c9d0181f341..bd6cd4a81316 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 7eee0a6f02f6..d293d9748036 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index a42ee9d6970d..677bc9330e64 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index e83cff31754b..c95a119767b5 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 392910ffbed9..0eb54315b4be 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c index 1b13b921dda9..8b79958b7aca 100644 --- a/drivers/acpi/acpica/nsprepkg.c +++ b/drivers/acpi/acpica/nsprepkg.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 7e417aa5c91e..151fcd95ba84 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index b09e6bef72b8..c30672d23878 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index af1cc42a8aa1..4a9d4a66016e 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 4a5e3f5c0ff7..6ad02008c0c2 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 4758a1f2ce22..c68609a2bc1b 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index 4bd558bf10d2..b6030a2deee1 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 8c6c11ce9760..d66c326485d8 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index dae9401be7a2..793383501f81 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2014, Intel Corp. | 9 | * Copyright (C) 2000 - 2015, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -53,50 +53,6 @@ ACPI_MODULE_NAME("nsxfobj") | |||
53 | 53 | ||
54 | /******************************************************************************* | 54 | /******************************************************************************* |
55 | * | 55 | * |
56 | * FUNCTION: acpi_get_id | ||
57 | * | ||
58 | * PARAMETERS: Handle - Handle of object whose id is desired | ||
59 | * ret_id - Where the id will be placed | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: This routine returns the owner id associated with a handle | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | acpi_status acpi_get_id(acpi_handle handle, acpi_owner_id * ret_id) | ||
67 | { | ||
68 | struct acpi_namespace_node *node; | ||
69 | acpi_status status; | ||
70 | |||
71 | /* Parameter Validation */ | ||
72 | |||
73 | if (!ret_id) { | ||
74 | return (AE_BAD_PARAMETER); | ||
75 | } | ||
76 | |||
77 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
78 | if (ACPI_FAILURE(status)) { | ||
79 | return (status); | ||
80 | } | ||
81 | |||
82 | /* Convert and validate the handle */ | ||
83 | |||
84 | node = acpi_ns_validate_handle(handle); | ||
85 | if (!node) { | ||
86 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
87 | return (AE_BAD_PARAMETER); | ||
88 | } | ||
89 | |||
90 | *ret_id = node->owner_id; | ||
91 | |||
92 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
93 | return (status); | ||
94 | } | ||
95 | |||
96 | ACPI_EXPORT_SYMBOL(acpi_get_id) | ||
97 | |||
98 | /******************************************************************************* | ||
99 | * | ||
100 | * FUNCTION: acpi_get_type | 56 | * FUNCTION: acpi_get_type |
101 | * | 57 | * |
102 | * PARAMETERS: handle - Handle of object whose type is desired | 58 | * PARAMETERS: handle - Handle of object whose type is desired |
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 314d314340ae..6d038770577b 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index b058e2390fdd..90437227d790 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c index a6885077d59e..2f5ddd806c58 100644 --- a/drivers/acpi/acpica/psobject.c +++ b/drivers/acpi/acpica/psobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index 1755d2ac5656..1af4a405e351 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psopinfo.c b/drivers/acpi/acpica/psopinfo.c index 0d8d37ffd04d..e18e7c47f482 100644 --- a/drivers/acpi/acpica/psopinfo.c +++ b/drivers/acpi/acpica/psopinfo.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 6d27b597394e..a555f7f7b9a2 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c index 32d250feea21..9d669cc6cb62 100644 --- a/drivers/acpi/acpica/psscope.c +++ b/drivers/acpi/acpica/psscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c index 0b64181e7720..89984f30addc 100644 --- a/drivers/acpi/acpica/pstree.c +++ b/drivers/acpi/acpica/pstree.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index 3cd48802eede..960505ab409a 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c index 9cb07e1e76d9..ba5f69171288 100644 --- a/drivers/acpi/acpica/pswalk.c +++ b/drivers/acpi/acpica/pswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index e135acaa5e1c..841a5ea06094 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c index 916fd095ff34..66d406e8fe36 100644 --- a/drivers/acpi/acpica/rsaddr.c +++ b/drivers/acpi/acpica/rsaddr.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -74,7 +74,7 @@ struct acpi_rsconvert_info acpi_rs_convert_address16[5] = { | |||
74 | * Address Translation Offset | 74 | * Address Translation Offset |
75 | * Address Length | 75 | * Address Length |
76 | */ | 76 | */ |
77 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity), | 77 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.address.granularity), |
78 | AML_OFFSET(address16.granularity), | 78 | AML_OFFSET(address16.granularity), |
79 | 5}, | 79 | 5}, |
80 | 80 | ||
@@ -112,7 +112,7 @@ struct acpi_rsconvert_info acpi_rs_convert_address32[5] = { | |||
112 | * Address Translation Offset | 112 | * Address Translation Offset |
113 | * Address Length | 113 | * Address Length |
114 | */ | 114 | */ |
115 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity), | 115 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.address.granularity), |
116 | AML_OFFSET(address32.granularity), | 116 | AML_OFFSET(address32.granularity), |
117 | 5}, | 117 | 5}, |
118 | 118 | ||
@@ -150,7 +150,7 @@ struct acpi_rsconvert_info acpi_rs_convert_address64[5] = { | |||
150 | * Address Translation Offset | 150 | * Address Translation Offset |
151 | * Address Length | 151 | * Address Length |
152 | */ | 152 | */ |
153 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity), | 153 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.address.granularity), |
154 | AML_OFFSET(address64.granularity), | 154 | AML_OFFSET(address64.granularity), |
155 | 5}, | 155 | 5}, |
156 | 156 | ||
@@ -194,7 +194,8 @@ struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = { | |||
194 | * Address Length | 194 | * Address Length |
195 | * Type-Specific Attribute | 195 | * Type-Specific Attribute |
196 | */ | 196 | */ |
197 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity), | 197 | {ACPI_RSC_MOVE64, |
198 | ACPI_RS_OFFSET(data.ext_address64.address.granularity), | ||
198 | AML_OFFSET(ext_address64.granularity), | 199 | AML_OFFSET(ext_address64.granularity), |
199 | 6} | 200 | 6} |
200 | }; | 201 | }; |
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 689556744b03..cb739a694931 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 049d9c22a0f9..15434e4c9b34 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index c3c56b5a9788..1539394c8c52 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsdumpinfo.c b/drivers/acpi/acpica/rsdumpinfo.c index 2f9332d5c973..b29d9ec63d1b 100644 --- a/drivers/acpi/acpica/rsdumpinfo.c +++ b/drivers/acpi/acpica/rsdumpinfo.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -183,15 +183,15 @@ struct acpi_rsdump_info acpi_rs_dump_address16[8] = { | |||
183 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16), | 183 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16), |
184 | "16-Bit WORD Address Space", NULL}, | 184 | "16-Bit WORD Address Space", NULL}, |
185 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, | 185 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, |
186 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity", | 186 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address.granularity), |
187 | NULL}, | 187 | "Granularity", NULL}, |
188 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum", | 188 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address.minimum), |
189 | NULL}, | 189 | "Address Minimum", NULL}, |
190 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum", | 190 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address.maximum), |
191 | NULL}, | 191 | "Address Maximum", NULL}, |
192 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset), | 192 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address.translation_offset), |
193 | "Translation Offset", NULL}, | 193 | "Translation Offset", NULL}, |
194 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length), | 194 | {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address.address_length), |
195 | "Address Length", NULL}, | 195 | "Address Length", NULL}, |
196 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL} | 196 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL} |
197 | }; | 197 | }; |
@@ -200,15 +200,15 @@ struct acpi_rsdump_info acpi_rs_dump_address32[8] = { | |||
200 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32), | 200 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32), |
201 | "32-Bit DWORD Address Space", NULL}, | 201 | "32-Bit DWORD Address Space", NULL}, |
202 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, | 202 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, |
203 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity", | 203 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address.granularity), |
204 | NULL}, | 204 | "Granularity", NULL}, |
205 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum", | 205 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address.minimum), |
206 | NULL}, | 206 | "Address Minimum", NULL}, |
207 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum", | 207 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address.maximum), |
208 | NULL}, | 208 | "Address Maximum", NULL}, |
209 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset), | 209 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address.translation_offset), |
210 | "Translation Offset", NULL}, | 210 | "Translation Offset", NULL}, |
211 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length), | 211 | {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address.address_length), |
212 | "Address Length", NULL}, | 212 | "Address Length", NULL}, |
213 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL} | 213 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL} |
214 | }; | 214 | }; |
@@ -217,15 +217,15 @@ struct acpi_rsdump_info acpi_rs_dump_address64[8] = { | |||
217 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64), | 217 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64), |
218 | "64-Bit QWORD Address Space", NULL}, | 218 | "64-Bit QWORD Address Space", NULL}, |
219 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, | 219 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, |
220 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity", | 220 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address.granularity), |
221 | NULL}, | 221 | "Granularity", NULL}, |
222 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum", | 222 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address.minimum), |
223 | NULL}, | 223 | "Address Minimum", NULL}, |
224 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum", | 224 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address.maximum), |
225 | NULL}, | 225 | "Address Maximum", NULL}, |
226 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset), | 226 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address.translation_offset), |
227 | "Translation Offset", NULL}, | 227 | "Translation Offset", NULL}, |
228 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length), | 228 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address.address_length), |
229 | "Address Length", NULL}, | 229 | "Address Length", NULL}, |
230 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL} | 230 | {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL} |
231 | }; | 231 | }; |
@@ -234,15 +234,16 @@ struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = { | |||
234 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64), | 234 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64), |
235 | "64-Bit Extended Address Space", NULL}, | 235 | "64-Bit Extended Address Space", NULL}, |
236 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, | 236 | {ACPI_RSD_ADDRESS, 0, NULL, NULL}, |
237 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity), | 237 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address.granularity), |
238 | "Granularity", NULL}, | 238 | "Granularity", NULL}, |
239 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum), | 239 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address.minimum), |
240 | "Address Minimum", NULL}, | 240 | "Address Minimum", NULL}, |
241 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum), | 241 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address.maximum), |
242 | "Address Maximum", NULL}, | 242 | "Address Maximum", NULL}, |
243 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset), | 243 | {ACPI_RSD_UINT64, |
244 | ACPI_RSD_OFFSET(ext_address64.address.translation_offset), | ||
244 | "Translation Offset", NULL}, | 245 | "Translation Offset", NULL}, |
245 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length), | 246 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address.address_length), |
246 | "Address Length", NULL}, | 247 | "Address Length", NULL}, |
247 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific), | 248 | {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific), |
248 | "Type-Specific Attribute", NULL} | 249 | "Type-Specific Attribute", NULL} |
diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c index 9d3f8a9a24bd..edecfc675979 100644 --- a/drivers/acpi/acpica/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c index 19d64873290a..5adba018bab0 100644 --- a/drivers/acpi/acpica/rsio.c +++ b/drivers/acpi/acpica/rsio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c index 3461f7db26df..07cfa70a475b 100644 --- a/drivers/acpi/acpica/rsirq.c +++ b/drivers/acpi/acpica/rsirq.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index 77291293af64..50d5be2ee062 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c index eab4483ff5f8..c6b80862030e 100644 --- a/drivers/acpi/acpica/rsmemory.c +++ b/drivers/acpi/acpica/rsmemory.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index 41eea4bc089c..1fe49d223663 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsserial.c b/drivers/acpi/acpica/rsserial.c index 9e8407223d95..4c8c6fe6ea74 100644 --- a/drivers/acpi/acpica/rsserial.c +++ b/drivers/acpi/acpica/rsserial.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 897a5ceb0420..ece3cd60cc6a 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 877ab9202133..8e6276df0226 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -60,11 +60,11 @@ ACPI_MODULE_NAME("rsxface") | |||
60 | ACPI_COPY_FIELD(out, in, min_address_fixed); \ | 60 | ACPI_COPY_FIELD(out, in, min_address_fixed); \ |
61 | ACPI_COPY_FIELD(out, in, max_address_fixed); \ | 61 | ACPI_COPY_FIELD(out, in, max_address_fixed); \ |
62 | ACPI_COPY_FIELD(out, in, info); \ | 62 | ACPI_COPY_FIELD(out, in, info); \ |
63 | ACPI_COPY_FIELD(out, in, granularity); \ | 63 | ACPI_COPY_FIELD(out, in, address.granularity); \ |
64 | ACPI_COPY_FIELD(out, in, minimum); \ | 64 | ACPI_COPY_FIELD(out, in, address.minimum); \ |
65 | ACPI_COPY_FIELD(out, in, maximum); \ | 65 | ACPI_COPY_FIELD(out, in, address.maximum); \ |
66 | ACPI_COPY_FIELD(out, in, translation_offset); \ | 66 | ACPI_COPY_FIELD(out, in, address.translation_offset); \ |
67 | ACPI_COPY_FIELD(out, in, address_length); \ | 67 | ACPI_COPY_FIELD(out, in, address.address_length); \ |
68 | ACPI_COPY_FIELD(out, in, resource_source); | 68 | ACPI_COPY_FIELD(out, in, resource_source); |
69 | /* Local prototypes */ | 69 | /* Local prototypes */ |
70 | static acpi_status | 70 | static acpi_status |
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c index f499c10ceb4a..6a144957aadd 100644 --- a/drivers/acpi/acpica/tbdata.c +++ b/drivers/acpi/acpica/tbdata.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 41519a958083..7d2486005e3f 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index cb947700206c..0b879fcfef67 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 755b90c40ddf..9bad45e63a45 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbprint.c b/drivers/acpi/acpica/tbprint.c index df3bb20ea325..ef16c06e5091 100644 --- a/drivers/acpi/acpica/tbprint.c +++ b/drivers/acpi/acpica/tbprint.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 6b1ca9991b90..6559a58439c5 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 6482b0ded652..60e94f87f27a 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -265,45 +265,6 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_header) | |||
265 | 265 | ||
266 | /******************************************************************************* | 266 | /******************************************************************************* |
267 | * | 267 | * |
268 | * FUNCTION: acpi_unload_table_id | ||
269 | * | ||
270 | * PARAMETERS: id - Owner ID of the table to be removed. | ||
271 | * | ||
272 | * RETURN: Status | ||
273 | * | ||
274 | * DESCRIPTION: This routine is used to force the unload of a table (by id) | ||
275 | * | ||
276 | ******************************************************************************/ | ||
277 | acpi_status acpi_unload_table_id(acpi_owner_id id) | ||
278 | { | ||
279 | int i; | ||
280 | acpi_status status = AE_NOT_EXIST; | ||
281 | |||
282 | ACPI_FUNCTION_TRACE(acpi_unload_table_id); | ||
283 | |||
284 | /* Find table in the global table list */ | ||
285 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | ||
286 | if (id != acpi_gbl_root_table_list.tables[i].owner_id) { | ||
287 | continue; | ||
288 | } | ||
289 | /* | ||
290 | * Delete all namespace objects owned by this table. Note that these | ||
291 | * objects can appear anywhere in the namespace by virtue of the AML | ||
292 | * "Scope" operator. Thus, we need to track ownership by an ID, not | ||
293 | * simply a position within the hierarchy | ||
294 | */ | ||
295 | acpi_tb_delete_namespace_by_owner(i); | ||
296 | status = acpi_tb_release_owner_id(i); | ||
297 | acpi_tb_set_table_loaded_flag(i, FALSE); | ||
298 | break; | ||
299 | } | ||
300 | return_ACPI_STATUS(status); | ||
301 | } | ||
302 | |||
303 | ACPI_EXPORT_SYMBOL(acpi_unload_table_id) | ||
304 | |||
305 | /******************************************************************************* | ||
306 | * | ||
307 | * FUNCTION: acpi_get_table_with_size | 268 | * FUNCTION: acpi_get_table_with_size |
308 | * | 269 | * |
309 | * PARAMETERS: signature - ACPI signature of needed table | 270 | * PARAMETERS: signature - ACPI signature of needed table |
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index ab5308b81aa8..aadb3002a2dd 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index 43a54af2b548..eac52cf14f1a 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utaddress.c b/drivers/acpi/acpica/utaddress.c index a1acec9d2ef3..1279f50da757 100644 --- a/drivers/acpi/acpica/utaddress.c +++ b/drivers/acpi/acpica/utaddress.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index efac83c606dc..61d8f6d186d1 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c index 038ea887f562..242bd071f007 100644 --- a/drivers/acpi/acpica/utbuffer.c +++ b/drivers/acpi/acpica/utbuffer.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c index 78fde0aac487..eacc5eee362e 100644 --- a/drivers/acpi/acpica/utcache.c +++ b/drivers/acpi/acpica/utcache.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index ff601c0f7c7a..c37ec5035f4c 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index e516254c63b2..57078e3ea9b7 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 40e923e675fc..988e23b7795c 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index a3516de213fa..71fce389fd48 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c index 8e544d4688cd..9ef80f2828e3 100644 --- a/drivers/acpi/acpica/uterror.c +++ b/drivers/acpi/acpica/uterror.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 8fed1482d228..6c738fa0cd42 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utexcep.c b/drivers/acpi/acpica/utexcep.c index 0403dcaabaf2..743a0ae9fb17 100644 --- a/drivers/acpi/acpica/utexcep.c +++ b/drivers/acpi/acpica/utexcep.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c index 4e263a8cc6f0..7e1168be39fa 100644 --- a/drivers/acpi/acpica/utfileio.c +++ b/drivers/acpi/acpica/utfileio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 77ceac715f28..5e8df9177da4 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/uthex.c b/drivers/acpi/acpica/uthex.c index 9afa9441b183..aa448278ba28 100644 --- a/drivers/acpi/acpica/uthex.c +++ b/drivers/acpi/acpica/uthex.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index 4b12880e5b11..27431cfc1c44 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 77120ec9ea86..e402e07b4846 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c index dc6e96547f18..089f78bbd59b 100644 --- a/drivers/acpi/acpica/utlock.c +++ b/drivers/acpi/acpica/utlock.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index d44dee6ee10a..f9ff100f0159 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 2e2bb14e1099..56bbacd576f2 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 82717fff9ffc..37b8b58fcd56 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index dfa9009bfc87..7d83efe1ea29 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 685766fc6ca8..574cd3118313 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utownerid.c b/drivers/acpi/acpica/utownerid.c index 36bec57ebd23..2959217067cb 100644 --- a/drivers/acpi/acpica/utownerid.c +++ b/drivers/acpi/acpica/utownerid.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utpredef.c b/drivers/acpi/acpica/utpredef.c index db30caff130a..29e449935a82 100644 --- a/drivers/acpi/acpica/utpredef.c +++ b/drivers/acpi/acpica/utpredef.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index 0ce3f5a0dd67..82ca9142e10d 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index bc1ff820c7dd..b3505dbc715e 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index 1cc97a752c15..8274cc16edc3 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index 6dc54b3c28b0..83b6c52490dc 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c index 7d0ee969d781..130dd9f96f0f 100644 --- a/drivers/acpi/acpica/uttrack.c +++ b/drivers/acpi/acpica/uttrack.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utuuid.c b/drivers/acpi/acpica/utuuid.c index 4dc33130f134..c6149a212149 100644 --- a/drivers/acpi/acpica/utuuid.c +++ b/drivers/acpi/acpica/utuuid.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 49c873c68756..0929187bdce0 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index 88ef77f3cf88..306e785f9418 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index b1fd6886e439..083a76891889 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utxfmutex.c b/drivers/acpi/acpica/utxfmutex.c index 2a0f9e04d3a4..f2606af3364c 100644 --- a/drivers/acpi/acpica/utxfmutex.c +++ b/drivers/acpi/acpica/utxfmutex.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index c0d44d394ca3..735db11a9b00 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -1027,7 +1027,6 @@ EXPORT_SYMBOL_GPL(acpi_subsys_freeze); | |||
1027 | 1027 | ||
1028 | static struct dev_pm_domain acpi_general_pm_domain = { | 1028 | static struct dev_pm_domain acpi_general_pm_domain = { |
1029 | .ops = { | 1029 | .ops = { |
1030 | #ifdef CONFIG_PM | ||
1031 | .runtime_suspend = acpi_subsys_runtime_suspend, | 1030 | .runtime_suspend = acpi_subsys_runtime_suspend, |
1032 | .runtime_resume = acpi_subsys_runtime_resume, | 1031 | .runtime_resume = acpi_subsys_runtime_resume, |
1033 | #ifdef CONFIG_PM_SLEEP | 1032 | #ifdef CONFIG_PM_SLEEP |
@@ -1041,7 +1040,6 @@ static struct dev_pm_domain acpi_general_pm_domain = { | |||
1041 | .poweroff_late = acpi_subsys_suspend_late, | 1040 | .poweroff_late = acpi_subsys_suspend_late, |
1042 | .restore_early = acpi_subsys_resume_early, | 1041 | .restore_early = acpi_subsys_resume_early, |
1043 | #endif | 1042 | #endif |
1044 | #endif | ||
1045 | }, | 1043 | }, |
1046 | }; | 1044 | }; |
1047 | 1045 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1b5853f384e2..14d0c89ada2a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * ec.c - ACPI Embedded Controller Driver (v2.2) | 2 | * ec.c - ACPI Embedded Controller Driver (v3) |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2014 Intel Corporation | 4 | * Copyright (C) 2001-2015 Intel Corporation |
5 | * Author: 2014 Lv Zheng <lv.zheng@intel.com> | 5 | * Author: 2014, 2015 Lv Zheng <lv.zheng@intel.com> |
6 | * 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 6 | * 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> |
7 | * 2006 Denis Sadykov <denis.m.sadykov@intel.com> | 7 | * 2006 Denis Sadykov <denis.m.sadykov@intel.com> |
8 | * 2004 Luming Yu <luming.yu@intel.com> | 8 | * 2004 Luming Yu <luming.yu@intel.com> |
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | /* Uncomment next line to get verbose printout */ | 32 | /* Uncomment next line to get verbose printout */ |
33 | /* #define DEBUG */ | 33 | /* #define DEBUG */ |
34 | #define DEBUG_REF 0 | ||
34 | #define pr_fmt(fmt) "ACPI : EC: " fmt | 35 | #define pr_fmt(fmt) "ACPI : EC: " fmt |
35 | 36 | ||
36 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
@@ -71,20 +72,32 @@ enum ec_command { | |||
71 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 72 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
72 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 73 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
73 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | 74 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ |
75 | #define ACPI_EC_UDELAY_POLL 1000 /* Wait 1ms for EC transaction polling */ | ||
74 | #define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query | 76 | #define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query |
75 | * when trying to clear the EC */ | 77 | * when trying to clear the EC */ |
76 | 78 | ||
77 | enum { | 79 | enum { |
78 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 80 | EC_FLAGS_EVENT_ENABLED, /* Event is enabled */ |
79 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 81 | EC_FLAGS_EVENT_PENDING, /* Event is pending */ |
82 | EC_FLAGS_EVENT_DETECTED, /* Event is detected */ | ||
80 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and | 83 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
81 | * OpReg are installed */ | 84 | * OpReg are installed */ |
82 | EC_FLAGS_BLOCKED, /* Transactions are blocked */ | 85 | EC_FLAGS_STARTED, /* Driver is started */ |
86 | EC_FLAGS_STOPPED, /* Driver is stopped */ | ||
87 | EC_FLAGS_COMMAND_STORM, /* GPE storms occurred to the | ||
88 | * current command processing */ | ||
83 | }; | 89 | }; |
84 | 90 | ||
85 | #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ | 91 | #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ |
86 | #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ | 92 | #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ |
87 | 93 | ||
94 | #define ec_debug_ref(ec, fmt, ...) \ | ||
95 | do { \ | ||
96 | if (DEBUG_REF) \ | ||
97 | pr_debug("%lu: " fmt, ec->reference_count, \ | ||
98 | ## __VA_ARGS__); \ | ||
99 | } while (0) | ||
100 | |||
88 | /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ | 101 | /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ |
89 | static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; | 102 | static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; |
90 | module_param(ec_delay, uint, 0644); | 103 | module_param(ec_delay, uint, 0644); |
@@ -105,6 +118,7 @@ struct acpi_ec_query_handler { | |||
105 | acpi_handle handle; | 118 | acpi_handle handle; |
106 | void *data; | 119 | void *data; |
107 | u8 query_bit; | 120 | u8 query_bit; |
121 | struct kref kref; | ||
108 | }; | 122 | }; |
109 | 123 | ||
110 | struct transaction { | 124 | struct transaction { |
@@ -117,8 +131,12 @@ struct transaction { | |||
117 | u8 wlen; | 131 | u8 wlen; |
118 | u8 rlen; | 132 | u8 rlen; |
119 | u8 flags; | 133 | u8 flags; |
134 | unsigned long timestamp; | ||
120 | }; | 135 | }; |
121 | 136 | ||
137 | static int acpi_ec_query(struct acpi_ec *ec, u8 *data); | ||
138 | static void advance_transaction(struct acpi_ec *ec); | ||
139 | |||
122 | struct acpi_ec *boot_ec, *first_ec; | 140 | struct acpi_ec *boot_ec, *first_ec; |
123 | EXPORT_SYMBOL(first_ec); | 141 | EXPORT_SYMBOL(first_ec); |
124 | 142 | ||
@@ -129,7 +147,28 @@ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ | |||
129 | static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ | 147 | static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ |
130 | 148 | ||
131 | /* -------------------------------------------------------------------------- | 149 | /* -------------------------------------------------------------------------- |
132 | * Transaction Management | 150 | * Device Flags |
151 | * -------------------------------------------------------------------------- */ | ||
152 | |||
153 | static bool acpi_ec_started(struct acpi_ec *ec) | ||
154 | { | ||
155 | return test_bit(EC_FLAGS_STARTED, &ec->flags) && | ||
156 | !test_bit(EC_FLAGS_STOPPED, &ec->flags); | ||
157 | } | ||
158 | |||
159 | static bool acpi_ec_flushed(struct acpi_ec *ec) | ||
160 | { | ||
161 | return ec->reference_count == 1; | ||
162 | } | ||
163 | |||
164 | static bool acpi_ec_has_pending_event(struct acpi_ec *ec) | ||
165 | { | ||
166 | return test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) || | ||
167 | test_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); | ||
168 | } | ||
169 | |||
170 | /* -------------------------------------------------------------------------- | ||
171 | * EC Registers | ||
133 | * -------------------------------------------------------------------------- */ | 172 | * -------------------------------------------------------------------------- */ |
134 | 173 | ||
135 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) | 174 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
@@ -151,6 +190,7 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | |||
151 | { | 190 | { |
152 | u8 x = inb(ec->data_addr); | 191 | u8 x = inb(ec->data_addr); |
153 | 192 | ||
193 | ec->curr->timestamp = jiffies; | ||
154 | pr_debug("EC_DATA(R) = 0x%2.2x\n", x); | 194 | pr_debug("EC_DATA(R) = 0x%2.2x\n", x); |
155 | return x; | 195 | return x; |
156 | } | 196 | } |
@@ -159,12 +199,14 @@ static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | |||
159 | { | 199 | { |
160 | pr_debug("EC_SC(W) = 0x%2.2x\n", command); | 200 | pr_debug("EC_SC(W) = 0x%2.2x\n", command); |
161 | outb(command, ec->command_addr); | 201 | outb(command, ec->command_addr); |
202 | ec->curr->timestamp = jiffies; | ||
162 | } | 203 | } |
163 | 204 | ||
164 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | 205 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
165 | { | 206 | { |
166 | pr_debug("EC_DATA(W) = 0x%2.2x\n", data); | 207 | pr_debug("EC_DATA(W) = 0x%2.2x\n", data); |
167 | outb(data, ec->data_addr); | 208 | outb(data, ec->data_addr); |
209 | ec->curr->timestamp = jiffies; | ||
168 | } | 210 | } |
169 | 211 | ||
170 | #ifdef DEBUG | 212 | #ifdef DEBUG |
@@ -188,6 +230,203 @@ static const char *acpi_ec_cmd_string(u8 cmd) | |||
188 | #define acpi_ec_cmd_string(cmd) "UNDEF" | 230 | #define acpi_ec_cmd_string(cmd) "UNDEF" |
189 | #endif | 231 | #endif |
190 | 232 | ||
233 | /* -------------------------------------------------------------------------- | ||
234 | * GPE Registers | ||
235 | * -------------------------------------------------------------------------- */ | ||
236 | |||
237 | static inline bool acpi_ec_is_gpe_raised(struct acpi_ec *ec) | ||
238 | { | ||
239 | acpi_event_status gpe_status = 0; | ||
240 | |||
241 | (void)acpi_get_gpe_status(NULL, ec->gpe, &gpe_status); | ||
242 | return (gpe_status & ACPI_EVENT_FLAG_SET) ? true : false; | ||
243 | } | ||
244 | |||
245 | static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) | ||
246 | { | ||
247 | if (open) | ||
248 | acpi_enable_gpe(NULL, ec->gpe); | ||
249 | else { | ||
250 | BUG_ON(ec->reference_count < 1); | ||
251 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); | ||
252 | } | ||
253 | if (acpi_ec_is_gpe_raised(ec)) { | ||
254 | /* | ||
255 | * On some platforms, EN=1 writes cannot trigger GPE. So | ||
256 | * software need to manually trigger a pseudo GPE event on | ||
257 | * EN=1 writes. | ||
258 | */ | ||
259 | pr_debug("***** Polling quirk *****\n"); | ||
260 | advance_transaction(ec); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | static inline void acpi_ec_disable_gpe(struct acpi_ec *ec, bool close) | ||
265 | { | ||
266 | if (close) | ||
267 | acpi_disable_gpe(NULL, ec->gpe); | ||
268 | else { | ||
269 | BUG_ON(ec->reference_count < 1); | ||
270 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static inline void acpi_ec_clear_gpe(struct acpi_ec *ec) | ||
275 | { | ||
276 | /* | ||
277 | * GPE STS is a W1C register, which means: | ||
278 | * 1. Software can clear it without worrying about clearing other | ||
279 | * GPEs' STS bits when the hardware sets them in parallel. | ||
280 | * 2. As long as software can ensure only clearing it when it is | ||
281 | * set, hardware won't set it in parallel. | ||
282 | * So software can clear GPE in any contexts. | ||
283 | * Warning: do not move the check into advance_transaction() as the | ||
284 | * EC commands will be sent without GPE raised. | ||
285 | */ | ||
286 | if (!acpi_ec_is_gpe_raised(ec)) | ||
287 | return; | ||
288 | acpi_clear_gpe(NULL, ec->gpe); | ||
289 | } | ||
290 | |||
291 | /* -------------------------------------------------------------------------- | ||
292 | * Transaction Management | ||
293 | * -------------------------------------------------------------------------- */ | ||
294 | |||
295 | static void acpi_ec_submit_request(struct acpi_ec *ec) | ||
296 | { | ||
297 | ec->reference_count++; | ||
298 | if (ec->reference_count == 1) | ||
299 | acpi_ec_enable_gpe(ec, true); | ||
300 | } | ||
301 | |||
302 | static void acpi_ec_complete_request(struct acpi_ec *ec) | ||
303 | { | ||
304 | bool flushed = false; | ||
305 | |||
306 | ec->reference_count--; | ||
307 | if (ec->reference_count == 0) | ||
308 | acpi_ec_disable_gpe(ec, true); | ||
309 | flushed = acpi_ec_flushed(ec); | ||
310 | if (flushed) | ||
311 | wake_up(&ec->wait); | ||
312 | } | ||
313 | |||
314 | static void acpi_ec_set_storm(struct acpi_ec *ec, u8 flag) | ||
315 | { | ||
316 | if (!test_bit(flag, &ec->flags)) { | ||
317 | acpi_ec_disable_gpe(ec, false); | ||
318 | pr_debug("+++++ Polling enabled +++++\n"); | ||
319 | set_bit(flag, &ec->flags); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag) | ||
324 | { | ||
325 | if (test_bit(flag, &ec->flags)) { | ||
326 | clear_bit(flag, &ec->flags); | ||
327 | acpi_ec_enable_gpe(ec, false); | ||
328 | pr_debug("+++++ Polling disabled +++++\n"); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * acpi_ec_submit_flushable_request() - Increase the reference count unless | ||
334 | * the flush operation is not in | ||
335 | * progress | ||
336 | * @ec: the EC device | ||
337 | * @allow_event: whether event should be handled | ||
338 | * | ||
339 | * This function must be used before taking a new action that should hold | ||
340 | * the reference count. If this function returns false, then the action | ||
341 | * must be discarded or it will prevent the flush operation from being | ||
342 | * completed. | ||
343 | * | ||
344 | * During flushing, QR_EC command need to pass this check when there is a | ||
345 | * pending event, so that the reference count held for the pending event | ||
346 | * can be decreased by the completion of the QR_EC command. | ||
347 | */ | ||
348 | static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec, | ||
349 | bool allow_event) | ||
350 | { | ||
351 | if (!acpi_ec_started(ec)) { | ||
352 | if (!allow_event || !acpi_ec_has_pending_event(ec)) | ||
353 | return false; | ||
354 | } | ||
355 | acpi_ec_submit_request(ec); | ||
356 | return true; | ||
357 | } | ||
358 | |||
359 | static void acpi_ec_submit_event(struct acpi_ec *ec) | ||
360 | { | ||
361 | if (!test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) || | ||
362 | !test_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags)) | ||
363 | return; | ||
364 | /* Hold reference for pending event */ | ||
365 | if (!acpi_ec_submit_flushable_request(ec, true)) | ||
366 | return; | ||
367 | ec_debug_ref(ec, "Increase event\n"); | ||
368 | if (!test_and_set_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) { | ||
369 | pr_debug("***** Event query started *****\n"); | ||
370 | schedule_work(&ec->work); | ||
371 | return; | ||
372 | } | ||
373 | acpi_ec_complete_request(ec); | ||
374 | ec_debug_ref(ec, "Decrease event\n"); | ||
375 | } | ||
376 | |||
377 | static void acpi_ec_complete_event(struct acpi_ec *ec) | ||
378 | { | ||
379 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | ||
380 | clear_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); | ||
381 | pr_debug("***** Event query stopped *****\n"); | ||
382 | /* Unhold reference for pending event */ | ||
383 | acpi_ec_complete_request(ec); | ||
384 | ec_debug_ref(ec, "Decrease event\n"); | ||
385 | /* Check if there is another SCI_EVT detected */ | ||
386 | acpi_ec_submit_event(ec); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | static void acpi_ec_submit_detection(struct acpi_ec *ec) | ||
391 | { | ||
392 | /* Hold reference for query submission */ | ||
393 | if (!acpi_ec_submit_flushable_request(ec, false)) | ||
394 | return; | ||
395 | ec_debug_ref(ec, "Increase query\n"); | ||
396 | if (!test_and_set_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags)) { | ||
397 | pr_debug("***** Event detection blocked *****\n"); | ||
398 | acpi_ec_submit_event(ec); | ||
399 | return; | ||
400 | } | ||
401 | acpi_ec_complete_request(ec); | ||
402 | ec_debug_ref(ec, "Decrease query\n"); | ||
403 | } | ||
404 | |||
405 | static void acpi_ec_complete_detection(struct acpi_ec *ec) | ||
406 | { | ||
407 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | ||
408 | clear_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags); | ||
409 | pr_debug("***** Event detetion unblocked *****\n"); | ||
410 | /* Unhold reference for query submission */ | ||
411 | acpi_ec_complete_request(ec); | ||
412 | ec_debug_ref(ec, "Decrease query\n"); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | static void acpi_ec_enable_event(struct acpi_ec *ec) | ||
417 | { | ||
418 | unsigned long flags; | ||
419 | |||
420 | spin_lock_irqsave(&ec->lock, flags); | ||
421 | set_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags); | ||
422 | /* | ||
423 | * An event may be pending even with SCI_EVT=0, so QR_EC should | ||
424 | * always be issued right after started. | ||
425 | */ | ||
426 | acpi_ec_submit_detection(ec); | ||
427 | spin_unlock_irqrestore(&ec->lock, flags); | ||
428 | } | ||
429 | |||
191 | static int ec_transaction_completed(struct acpi_ec *ec) | 430 | static int ec_transaction_completed(struct acpi_ec *ec) |
192 | { | 431 | { |
193 | unsigned long flags; | 432 | unsigned long flags; |
@@ -200,7 +439,7 @@ static int ec_transaction_completed(struct acpi_ec *ec) | |||
200 | return ret; | 439 | return ret; |
201 | } | 440 | } |
202 | 441 | ||
203 | static bool advance_transaction(struct acpi_ec *ec) | 442 | static void advance_transaction(struct acpi_ec *ec) |
204 | { | 443 | { |
205 | struct transaction *t; | 444 | struct transaction *t; |
206 | u8 status; | 445 | u8 status; |
@@ -208,6 +447,12 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
208 | 447 | ||
209 | pr_debug("===== %s (%d) =====\n", | 448 | pr_debug("===== %s (%d) =====\n", |
210 | in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); | 449 | in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); |
450 | /* | ||
451 | * By always clearing STS before handling all indications, we can | ||
452 | * ensure a hardware STS 0->1 change after this clearing can always | ||
453 | * trigger a GPE interrupt. | ||
454 | */ | ||
455 | acpi_ec_clear_gpe(ec); | ||
211 | status = acpi_ec_read_status(ec); | 456 | status = acpi_ec_read_status(ec); |
212 | t = ec->curr; | 457 | t = ec->curr; |
213 | if (!t) | 458 | if (!t) |
@@ -223,6 +468,7 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
223 | t->rdata[t->ri++] = acpi_ec_read_data(ec); | 468 | t->rdata[t->ri++] = acpi_ec_read_data(ec); |
224 | if (t->rlen == t->ri) { | 469 | if (t->rlen == t->ri) { |
225 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 470 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
471 | acpi_ec_complete_event(ec); | ||
226 | if (t->command == ACPI_EC_COMMAND_QUERY) | 472 | if (t->command == ACPI_EC_COMMAND_QUERY) |
227 | pr_debug("***** Command(%s) hardware completion *****\n", | 473 | pr_debug("***** Command(%s) hardware completion *****\n", |
228 | acpi_ec_cmd_string(t->command)); | 474 | acpi_ec_cmd_string(t->command)); |
@@ -233,25 +479,29 @@ static bool advance_transaction(struct acpi_ec *ec) | |||
233 | } else if (t->wlen == t->wi && | 479 | } else if (t->wlen == t->wi && |
234 | (status & ACPI_EC_FLAG_IBF) == 0) { | 480 | (status & ACPI_EC_FLAG_IBF) == 0) { |
235 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 481 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
482 | acpi_ec_complete_event(ec); | ||
236 | wakeup = true; | 483 | wakeup = true; |
237 | } | 484 | } |
238 | return wakeup; | 485 | goto out; |
239 | } else { | 486 | } else { |
240 | if (EC_FLAGS_QUERY_HANDSHAKE && | 487 | if (EC_FLAGS_QUERY_HANDSHAKE && |
241 | !(status & ACPI_EC_FLAG_SCI) && | 488 | !(status & ACPI_EC_FLAG_SCI) && |
242 | (t->command == ACPI_EC_COMMAND_QUERY)) { | 489 | (t->command == ACPI_EC_COMMAND_QUERY)) { |
243 | t->flags |= ACPI_EC_COMMAND_POLL; | 490 | t->flags |= ACPI_EC_COMMAND_POLL; |
491 | acpi_ec_complete_detection(ec); | ||
244 | t->rdata[t->ri++] = 0x00; | 492 | t->rdata[t->ri++] = 0x00; |
245 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 493 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
494 | acpi_ec_complete_event(ec); | ||
246 | pr_debug("***** Command(%s) software completion *****\n", | 495 | pr_debug("***** Command(%s) software completion *****\n", |
247 | acpi_ec_cmd_string(t->command)); | 496 | acpi_ec_cmd_string(t->command)); |
248 | wakeup = true; | 497 | wakeup = true; |
249 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { | 498 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { |
250 | acpi_ec_write_cmd(ec, t->command); | 499 | acpi_ec_write_cmd(ec, t->command); |
251 | t->flags |= ACPI_EC_COMMAND_POLL; | 500 | t->flags |= ACPI_EC_COMMAND_POLL; |
501 | acpi_ec_complete_detection(ec); | ||
252 | } else | 502 | } else |
253 | goto err; | 503 | goto err; |
254 | return wakeup; | 504 | goto out; |
255 | } | 505 | } |
256 | err: | 506 | err: |
257 | /* | 507 | /* |
@@ -259,28 +509,27 @@ err: | |||
259 | * otherwise will take a not handled IRQ as a false one. | 509 | * otherwise will take a not handled IRQ as a false one. |
260 | */ | 510 | */ |
261 | if (!(status & ACPI_EC_FLAG_SCI)) { | 511 | if (!(status & ACPI_EC_FLAG_SCI)) { |
262 | if (in_interrupt() && t) | 512 | if (in_interrupt() && t) { |
263 | ++t->irq_count; | 513 | if (t->irq_count < ec_storm_threshold) |
514 | ++t->irq_count; | ||
515 | /* Allow triggering on 0 threshold */ | ||
516 | if (t->irq_count == ec_storm_threshold) | ||
517 | acpi_ec_set_storm(ec, EC_FLAGS_COMMAND_STORM); | ||
518 | } | ||
264 | } | 519 | } |
265 | return wakeup; | 520 | out: |
521 | if (status & ACPI_EC_FLAG_SCI) | ||
522 | acpi_ec_submit_detection(ec); | ||
523 | if (wakeup && in_interrupt()) | ||
524 | wake_up(&ec->wait); | ||
266 | } | 525 | } |
267 | 526 | ||
268 | static void start_transaction(struct acpi_ec *ec) | 527 | static void start_transaction(struct acpi_ec *ec) |
269 | { | 528 | { |
270 | ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; | 529 | ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; |
271 | ec->curr->flags = 0; | 530 | ec->curr->flags = 0; |
272 | (void)advance_transaction(ec); | 531 | ec->curr->timestamp = jiffies; |
273 | } | 532 | advance_transaction(ec); |
274 | |||
275 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); | ||
276 | |||
277 | static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) | ||
278 | { | ||
279 | if (state & ACPI_EC_FLAG_SCI) { | ||
280 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) | ||
281 | return acpi_ec_sync_query(ec, NULL); | ||
282 | } | ||
283 | return 0; | ||
284 | } | 533 | } |
285 | 534 | ||
286 | static int ec_poll(struct acpi_ec *ec) | 535 | static int ec_poll(struct acpi_ec *ec) |
@@ -291,20 +540,25 @@ static int ec_poll(struct acpi_ec *ec) | |||
291 | while (repeat--) { | 540 | while (repeat--) { |
292 | unsigned long delay = jiffies + | 541 | unsigned long delay = jiffies + |
293 | msecs_to_jiffies(ec_delay); | 542 | msecs_to_jiffies(ec_delay); |
543 | unsigned long usecs = ACPI_EC_UDELAY_POLL; | ||
294 | do { | 544 | do { |
295 | /* don't sleep with disabled interrupts */ | 545 | /* don't sleep with disabled interrupts */ |
296 | if (EC_FLAGS_MSI || irqs_disabled()) { | 546 | if (EC_FLAGS_MSI || irqs_disabled()) { |
297 | udelay(ACPI_EC_MSI_UDELAY); | 547 | usecs = ACPI_EC_MSI_UDELAY; |
548 | udelay(usecs); | ||
298 | if (ec_transaction_completed(ec)) | 549 | if (ec_transaction_completed(ec)) |
299 | return 0; | 550 | return 0; |
300 | } else { | 551 | } else { |
301 | if (wait_event_timeout(ec->wait, | 552 | if (wait_event_timeout(ec->wait, |
302 | ec_transaction_completed(ec), | 553 | ec_transaction_completed(ec), |
303 | msecs_to_jiffies(1))) | 554 | usecs_to_jiffies(usecs))) |
304 | return 0; | 555 | return 0; |
305 | } | 556 | } |
306 | spin_lock_irqsave(&ec->lock, flags); | 557 | spin_lock_irqsave(&ec->lock, flags); |
307 | (void)advance_transaction(ec); | 558 | if (time_after(jiffies, |
559 | ec->curr->timestamp + | ||
560 | usecs_to_jiffies(usecs))) | ||
561 | advance_transaction(ec); | ||
308 | spin_unlock_irqrestore(&ec->lock, flags); | 562 | spin_unlock_irqrestore(&ec->lock, flags); |
309 | } while (time_before(jiffies, delay)); | 563 | } while (time_before(jiffies, delay)); |
310 | pr_debug("controller reset, restart transaction\n"); | 564 | pr_debug("controller reset, restart transaction\n"); |
@@ -325,21 +579,29 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
325 | udelay(ACPI_EC_MSI_UDELAY); | 579 | udelay(ACPI_EC_MSI_UDELAY); |
326 | /* start transaction */ | 580 | /* start transaction */ |
327 | spin_lock_irqsave(&ec->lock, tmp); | 581 | spin_lock_irqsave(&ec->lock, tmp); |
582 | /* Enable GPE for command processing (IBF=0/OBF=1) */ | ||
583 | if (!acpi_ec_submit_flushable_request(ec, true)) { | ||
584 | ret = -EINVAL; | ||
585 | goto unlock; | ||
586 | } | ||
587 | ec_debug_ref(ec, "Increase command\n"); | ||
328 | /* following two actions should be kept atomic */ | 588 | /* following two actions should be kept atomic */ |
329 | ec->curr = t; | 589 | ec->curr = t; |
330 | pr_debug("***** Command(%s) started *****\n", | 590 | pr_debug("***** Command(%s) started *****\n", |
331 | acpi_ec_cmd_string(t->command)); | 591 | acpi_ec_cmd_string(t->command)); |
332 | start_transaction(ec); | 592 | start_transaction(ec); |
333 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | ||
334 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
335 | pr_debug("***** Event stopped *****\n"); | ||
336 | } | ||
337 | spin_unlock_irqrestore(&ec->lock, tmp); | 593 | spin_unlock_irqrestore(&ec->lock, tmp); |
338 | ret = ec_poll(ec); | 594 | ret = ec_poll(ec); |
339 | spin_lock_irqsave(&ec->lock, tmp); | 595 | spin_lock_irqsave(&ec->lock, tmp); |
596 | if (t->irq_count == ec_storm_threshold) | ||
597 | acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM); | ||
340 | pr_debug("***** Command(%s) stopped *****\n", | 598 | pr_debug("***** Command(%s) stopped *****\n", |
341 | acpi_ec_cmd_string(t->command)); | 599 | acpi_ec_cmd_string(t->command)); |
342 | ec->curr = NULL; | 600 | ec->curr = NULL; |
601 | /* Disable GPE for command processing (IBF=0/OBF=1) */ | ||
602 | acpi_ec_complete_request(ec); | ||
603 | ec_debug_ref(ec, "Decrease command\n"); | ||
604 | unlock: | ||
343 | spin_unlock_irqrestore(&ec->lock, tmp); | 605 | spin_unlock_irqrestore(&ec->lock, tmp); |
344 | return ret; | 606 | return ret; |
345 | } | 607 | } |
@@ -354,10 +616,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
354 | if (t->rdata) | 616 | if (t->rdata) |
355 | memset(t->rdata, 0, t->rlen); | 617 | memset(t->rdata, 0, t->rlen); |
356 | mutex_lock(&ec->mutex); | 618 | mutex_lock(&ec->mutex); |
357 | if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { | ||
358 | status = -EINVAL; | ||
359 | goto unlock; | ||
360 | } | ||
361 | if (ec->global_lock) { | 619 | if (ec->global_lock) { |
362 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 620 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
363 | if (ACPI_FAILURE(status)) { | 621 | if (ACPI_FAILURE(status)) { |
@@ -365,26 +623,11 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
365 | goto unlock; | 623 | goto unlock; |
366 | } | 624 | } |
367 | } | 625 | } |
368 | /* disable GPE during transaction if storm is detected */ | ||
369 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
370 | /* It has to be disabled, so that it doesn't trigger. */ | ||
371 | acpi_disable_gpe(NULL, ec->gpe); | ||
372 | } | ||
373 | 626 | ||
374 | status = acpi_ec_transaction_unlocked(ec, t); | 627 | status = acpi_ec_transaction_unlocked(ec, t); |
375 | 628 | ||
376 | /* check if we received SCI during transaction */ | 629 | if (test_bit(EC_FLAGS_COMMAND_STORM, &ec->flags)) |
377 | ec_check_sci_sync(ec, acpi_ec_read_status(ec)); | ||
378 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
379 | msleep(1); | 630 | msleep(1); |
380 | /* It is safe to enable the GPE outside of the transaction. */ | ||
381 | acpi_enable_gpe(NULL, ec->gpe); | ||
382 | } else if (t->irq_count > ec_storm_threshold) { | ||
383 | pr_info("GPE storm detected(%d GPEs), " | ||
384 | "transactions will use polling mode\n", | ||
385 | t->irq_count); | ||
386 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | ||
387 | } | ||
388 | if (ec->global_lock) | 631 | if (ec->global_lock) |
389 | acpi_release_global_lock(glk); | 632 | acpi_release_global_lock(glk); |
390 | unlock: | 633 | unlock: |
@@ -500,7 +743,7 @@ static void acpi_ec_clear(struct acpi_ec *ec) | |||
500 | u8 value = 0; | 743 | u8 value = 0; |
501 | 744 | ||
502 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { | 745 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { |
503 | status = acpi_ec_sync_query(ec, &value); | 746 | status = acpi_ec_query(ec, &value); |
504 | if (status || !value) | 747 | if (status || !value) |
505 | break; | 748 | break; |
506 | } | 749 | } |
@@ -511,6 +754,57 @@ static void acpi_ec_clear(struct acpi_ec *ec) | |||
511 | pr_info("%d stale EC events cleared\n", i); | 754 | pr_info("%d stale EC events cleared\n", i); |
512 | } | 755 | } |
513 | 756 | ||
757 | static void acpi_ec_start(struct acpi_ec *ec, bool resuming) | ||
758 | { | ||
759 | unsigned long flags; | ||
760 | |||
761 | spin_lock_irqsave(&ec->lock, flags); | ||
762 | if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { | ||
763 | pr_debug("+++++ Starting EC +++++\n"); | ||
764 | /* Enable GPE for event processing (SCI_EVT=1) */ | ||
765 | if (!resuming) { | ||
766 | acpi_ec_submit_request(ec); | ||
767 | ec_debug_ref(ec, "Increase driver\n"); | ||
768 | } | ||
769 | pr_info("+++++ EC started +++++\n"); | ||
770 | } | ||
771 | spin_unlock_irqrestore(&ec->lock, flags); | ||
772 | } | ||
773 | |||
774 | static bool acpi_ec_stopped(struct acpi_ec *ec) | ||
775 | { | ||
776 | unsigned long flags; | ||
777 | bool flushed; | ||
778 | |||
779 | spin_lock_irqsave(&ec->lock, flags); | ||
780 | flushed = acpi_ec_flushed(ec); | ||
781 | spin_unlock_irqrestore(&ec->lock, flags); | ||
782 | return flushed; | ||
783 | } | ||
784 | |||
785 | static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) | ||
786 | { | ||
787 | unsigned long flags; | ||
788 | |||
789 | spin_lock_irqsave(&ec->lock, flags); | ||
790 | if (acpi_ec_started(ec)) { | ||
791 | pr_debug("+++++ Stopping EC +++++\n"); | ||
792 | set_bit(EC_FLAGS_STOPPED, &ec->flags); | ||
793 | spin_unlock_irqrestore(&ec->lock, flags); | ||
794 | wait_event(ec->wait, acpi_ec_stopped(ec)); | ||
795 | spin_lock_irqsave(&ec->lock, flags); | ||
796 | /* Disable GPE for event processing (SCI_EVT=1) */ | ||
797 | if (!suspending) { | ||
798 | acpi_ec_complete_request(ec); | ||
799 | ec_debug_ref(ec, "Decrease driver\n"); | ||
800 | } | ||
801 | clear_bit(EC_FLAGS_STARTED, &ec->flags); | ||
802 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); | ||
803 | pr_info("+++++ EC stopped +++++\n"); | ||
804 | } | ||
805 | spin_unlock_irqrestore(&ec->lock, flags); | ||
806 | } | ||
807 | |||
514 | void acpi_ec_block_transactions(void) | 808 | void acpi_ec_block_transactions(void) |
515 | { | 809 | { |
516 | struct acpi_ec *ec = first_ec; | 810 | struct acpi_ec *ec = first_ec; |
@@ -520,7 +814,7 @@ void acpi_ec_block_transactions(void) | |||
520 | 814 | ||
521 | mutex_lock(&ec->mutex); | 815 | mutex_lock(&ec->mutex); |
522 | /* Prevent transactions from being carried out */ | 816 | /* Prevent transactions from being carried out */ |
523 | set_bit(EC_FLAGS_BLOCKED, &ec->flags); | 817 | acpi_ec_stop(ec, true); |
524 | mutex_unlock(&ec->mutex); | 818 | mutex_unlock(&ec->mutex); |
525 | } | 819 | } |
526 | 820 | ||
@@ -531,14 +825,11 @@ void acpi_ec_unblock_transactions(void) | |||
531 | if (!ec) | 825 | if (!ec) |
532 | return; | 826 | return; |
533 | 827 | ||
534 | mutex_lock(&ec->mutex); | ||
535 | /* Allow transactions to be carried out again */ | 828 | /* Allow transactions to be carried out again */ |
536 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); | 829 | acpi_ec_start(ec, true); |
537 | 830 | ||
538 | if (EC_FLAGS_CLEAR_ON_RESUME) | 831 | if (EC_FLAGS_CLEAR_ON_RESUME) |
539 | acpi_ec_clear(ec); | 832 | acpi_ec_clear(ec); |
540 | |||
541 | mutex_unlock(&ec->mutex); | ||
542 | } | 833 | } |
543 | 834 | ||
544 | void acpi_ec_unblock_transactions_early(void) | 835 | void acpi_ec_unblock_transactions_early(void) |
@@ -548,36 +839,33 @@ void acpi_ec_unblock_transactions_early(void) | |||
548 | * atomic context during wakeup, so we don't need to acquire the mutex). | 839 | * atomic context during wakeup, so we don't need to acquire the mutex). |
549 | */ | 840 | */ |
550 | if (first_ec) | 841 | if (first_ec) |
551 | clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); | 842 | acpi_ec_start(first_ec, true); |
552 | } | 843 | } |
553 | 844 | ||
554 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data) | 845 | /* -------------------------------------------------------------------------- |
846 | Event Management | ||
847 | -------------------------------------------------------------------------- */ | ||
848 | static struct acpi_ec_query_handler * | ||
849 | acpi_ec_get_query_handler(struct acpi_ec_query_handler *handler) | ||
555 | { | 850 | { |
556 | int result; | 851 | if (handler) |
557 | u8 d; | 852 | kref_get(&handler->kref); |
558 | struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, | 853 | return handler; |
559 | .wdata = NULL, .rdata = &d, | 854 | } |
560 | .wlen = 0, .rlen = 1}; | ||
561 | 855 | ||
562 | if (!ec || !data) | 856 | static void acpi_ec_query_handler_release(struct kref *kref) |
563 | return -EINVAL; | 857 | { |
564 | /* | 858 | struct acpi_ec_query_handler *handler = |
565 | * Query the EC to find out which _Qxx method we need to evaluate. | 859 | container_of(kref, struct acpi_ec_query_handler, kref); |
566 | * Note that successful completion of the query causes the ACPI_EC_SCI | 860 | |
567 | * bit to be cleared (and thus clearing the interrupt source). | 861 | kfree(handler); |
568 | */ | 862 | } |
569 | result = acpi_ec_transaction_unlocked(ec, &t); | 863 | |
570 | if (result) | 864 | static void acpi_ec_put_query_handler(struct acpi_ec_query_handler *handler) |
571 | return result; | 865 | { |
572 | if (!d) | 866 | kref_put(&handler->kref, acpi_ec_query_handler_release); |
573 | return -ENODATA; | ||
574 | *data = d; | ||
575 | return 0; | ||
576 | } | 867 | } |
577 | 868 | ||
578 | /* -------------------------------------------------------------------------- | ||
579 | Event Management | ||
580 | -------------------------------------------------------------------------- */ | ||
581 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | 869 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, |
582 | acpi_handle handle, acpi_ec_query_func func, | 870 | acpi_handle handle, acpi_ec_query_func func, |
583 | void *data) | 871 | void *data) |
@@ -593,6 +881,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | |||
593 | handler->func = func; | 881 | handler->func = func; |
594 | handler->data = data; | 882 | handler->data = data; |
595 | mutex_lock(&ec->mutex); | 883 | mutex_lock(&ec->mutex); |
884 | kref_init(&handler->kref); | ||
596 | list_add(&handler->node, &ec->list); | 885 | list_add(&handler->node, &ec->list); |
597 | mutex_unlock(&ec->mutex); | 886 | mutex_unlock(&ec->mutex); |
598 | return 0; | 887 | return 0; |
@@ -602,15 +891,18 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); | |||
602 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) | 891 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) |
603 | { | 892 | { |
604 | struct acpi_ec_query_handler *handler, *tmp; | 893 | struct acpi_ec_query_handler *handler, *tmp; |
894 | LIST_HEAD(free_list); | ||
605 | 895 | ||
606 | mutex_lock(&ec->mutex); | 896 | mutex_lock(&ec->mutex); |
607 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 897 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
608 | if (query_bit == handler->query_bit) { | 898 | if (query_bit == handler->query_bit) { |
609 | list_del(&handler->node); | 899 | list_del_init(&handler->node); |
610 | kfree(handler); | 900 | list_add(&handler->node, &free_list); |
611 | } | 901 | } |
612 | } | 902 | } |
613 | mutex_unlock(&ec->mutex); | 903 | mutex_unlock(&ec->mutex); |
904 | list_for_each_entry(handler, &free_list, node) | ||
905 | acpi_ec_put_query_handler(handler); | ||
614 | } | 906 | } |
615 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); | 907 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); |
616 | 908 | ||
@@ -626,59 +918,58 @@ static void acpi_ec_run(void *cxt) | |||
626 | else if (handler->handle) | 918 | else if (handler->handle) |
627 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); | 919 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
628 | pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); | 920 | pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); |
629 | kfree(handler); | 921 | acpi_ec_put_query_handler(handler); |
630 | } | 922 | } |
631 | 923 | ||
632 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) | 924 | static int acpi_ec_query(struct acpi_ec *ec, u8 *data) |
633 | { | 925 | { |
634 | u8 value = 0; | 926 | u8 value = 0; |
635 | int status; | 927 | int result; |
636 | struct acpi_ec_query_handler *handler, *copy; | 928 | acpi_status status; |
929 | struct acpi_ec_query_handler *handler; | ||
930 | struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, | ||
931 | .wdata = NULL, .rdata = &value, | ||
932 | .wlen = 0, .rlen = 1}; | ||
637 | 933 | ||
638 | status = acpi_ec_query_unlocked(ec, &value); | 934 | /* |
935 | * Query the EC to find out which _Qxx method we need to evaluate. | ||
936 | * Note that successful completion of the query causes the ACPI_EC_SCI | ||
937 | * bit to be cleared (and thus clearing the interrupt source). | ||
938 | */ | ||
939 | result = acpi_ec_transaction(ec, &t); | ||
940 | if (result) | ||
941 | return result; | ||
639 | if (data) | 942 | if (data) |
640 | *data = value; | 943 | *data = value; |
641 | if (status) | 944 | if (!value) |
642 | return status; | 945 | return -ENODATA; |
643 | 946 | ||
947 | mutex_lock(&ec->mutex); | ||
644 | list_for_each_entry(handler, &ec->list, node) { | 948 | list_for_each_entry(handler, &ec->list, node) { |
645 | if (value == handler->query_bit) { | 949 | if (value == handler->query_bit) { |
646 | /* have custom handler for this bit */ | 950 | /* have custom handler for this bit */ |
647 | copy = kmalloc(sizeof(*handler), GFP_KERNEL); | 951 | handler = acpi_ec_get_query_handler(handler); |
648 | if (!copy) | ||
649 | return -ENOMEM; | ||
650 | memcpy(copy, handler, sizeof(*copy)); | ||
651 | pr_debug("##### Query(0x%02x) scheduled #####\n", | 952 | pr_debug("##### Query(0x%02x) scheduled #####\n", |
652 | handler->query_bit); | 953 | handler->query_bit); |
653 | return acpi_os_execute((copy->func) ? | 954 | status = acpi_os_execute((handler->func) ? |
654 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, | 955 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, |
655 | acpi_ec_run, copy); | 956 | acpi_ec_run, handler); |
957 | if (ACPI_FAILURE(status)) | ||
958 | result = -EBUSY; | ||
959 | break; | ||
656 | } | 960 | } |
657 | } | 961 | } |
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static void acpi_ec_gpe_query(void *ec_cxt) | ||
662 | { | ||
663 | struct acpi_ec *ec = ec_cxt; | ||
664 | |||
665 | if (!ec) | ||
666 | return; | ||
667 | mutex_lock(&ec->mutex); | ||
668 | acpi_ec_sync_query(ec, NULL); | ||
669 | mutex_unlock(&ec->mutex); | 962 | mutex_unlock(&ec->mutex); |
963 | return result; | ||
670 | } | 964 | } |
671 | 965 | ||
672 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 966 | static void acpi_ec_gpe_poller(struct work_struct *work) |
673 | { | 967 | { |
674 | if (state & ACPI_EC_FLAG_SCI) { | 968 | struct acpi_ec *ec = container_of(work, struct acpi_ec, work); |
675 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { | 969 | |
676 | pr_debug("***** Event started *****\n"); | 970 | pr_debug("***** Event poller started *****\n"); |
677 | return acpi_os_execute(OSL_NOTIFY_HANDLER, | 971 | acpi_ec_query(ec, NULL); |
678 | acpi_ec_gpe_query, ec); | 972 | pr_debug("***** Event poller stopped *****\n"); |
679 | } | ||
680 | } | ||
681 | return 0; | ||
682 | } | 973 | } |
683 | 974 | ||
684 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | 975 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, |
@@ -688,11 +979,9 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | |||
688 | struct acpi_ec *ec = data; | 979 | struct acpi_ec *ec = data; |
689 | 980 | ||
690 | spin_lock_irqsave(&ec->lock, flags); | 981 | spin_lock_irqsave(&ec->lock, flags); |
691 | if (advance_transaction(ec)) | 982 | advance_transaction(ec); |
692 | wake_up(&ec->wait); | ||
693 | spin_unlock_irqrestore(&ec->lock, flags); | 983 | spin_unlock_irqrestore(&ec->lock, flags); |
694 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 984 | return ACPI_INTERRUPT_HANDLED; |
695 | return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; | ||
696 | } | 985 | } |
697 | 986 | ||
698 | /* -------------------------------------------------------------------------- | 987 | /* -------------------------------------------------------------------------- |
@@ -750,11 +1039,11 @@ static struct acpi_ec *make_acpi_ec(void) | |||
750 | 1039 | ||
751 | if (!ec) | 1040 | if (!ec) |
752 | return NULL; | 1041 | return NULL; |
753 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; | ||
754 | mutex_init(&ec->mutex); | 1042 | mutex_init(&ec->mutex); |
755 | init_waitqueue_head(&ec->wait); | 1043 | init_waitqueue_head(&ec->wait); |
756 | INIT_LIST_HEAD(&ec->list); | 1044 | INIT_LIST_HEAD(&ec->list); |
757 | spin_lock_init(&ec->lock); | 1045 | spin_lock_init(&ec->lock); |
1046 | INIT_WORK(&ec->work, acpi_ec_gpe_poller); | ||
758 | return ec; | 1047 | return ec; |
759 | } | 1048 | } |
760 | 1049 | ||
@@ -810,13 +1099,13 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
810 | 1099 | ||
811 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | 1100 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) |
812 | return 0; | 1101 | return 0; |
813 | status = acpi_install_gpe_handler(NULL, ec->gpe, | 1102 | status = acpi_install_gpe_raw_handler(NULL, ec->gpe, |
814 | ACPI_GPE_EDGE_TRIGGERED, | 1103 | ACPI_GPE_EDGE_TRIGGERED, |
815 | &acpi_ec_gpe_handler, ec); | 1104 | &acpi_ec_gpe_handler, ec); |
816 | if (ACPI_FAILURE(status)) | 1105 | if (ACPI_FAILURE(status)) |
817 | return -ENODEV; | 1106 | return -ENODEV; |
818 | 1107 | ||
819 | acpi_enable_gpe(NULL, ec->gpe); | 1108 | acpi_ec_start(ec, false); |
820 | status = acpi_install_address_space_handler(ec->handle, | 1109 | status = acpi_install_address_space_handler(ec->handle, |
821 | ACPI_ADR_SPACE_EC, | 1110 | ACPI_ADR_SPACE_EC, |
822 | &acpi_ec_space_handler, | 1111 | &acpi_ec_space_handler, |
@@ -831,7 +1120,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
831 | pr_err("Fail in evaluating the _REG object" | 1120 | pr_err("Fail in evaluating the _REG object" |
832 | " of EC device. Broken bios is suspected.\n"); | 1121 | " of EC device. Broken bios is suspected.\n"); |
833 | } else { | 1122 | } else { |
834 | acpi_disable_gpe(NULL, ec->gpe); | 1123 | acpi_ec_stop(ec, false); |
835 | acpi_remove_gpe_handler(NULL, ec->gpe, | 1124 | acpi_remove_gpe_handler(NULL, ec->gpe, |
836 | &acpi_ec_gpe_handler); | 1125 | &acpi_ec_gpe_handler); |
837 | return -ENODEV; | 1126 | return -ENODEV; |
@@ -846,7 +1135,7 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
846 | { | 1135 | { |
847 | if (!test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | 1136 | if (!test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) |
848 | return; | 1137 | return; |
849 | acpi_disable_gpe(NULL, ec->gpe); | 1138 | acpi_ec_stop(ec, false); |
850 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 1139 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
851 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 1140 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
852 | pr_err("failed to remove space handler\n"); | 1141 | pr_err("failed to remove space handler\n"); |
@@ -900,14 +1189,11 @@ static int acpi_ec_add(struct acpi_device *device) | |||
900 | ret = ec_install_handlers(ec); | 1189 | ret = ec_install_handlers(ec); |
901 | 1190 | ||
902 | /* EC is fully operational, allow queries */ | 1191 | /* EC is fully operational, allow queries */ |
903 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 1192 | acpi_ec_enable_event(ec); |
904 | 1193 | ||
905 | /* Clear stale _Q events if hardware might require that */ | 1194 | /* Clear stale _Q events if hardware might require that */ |
906 | if (EC_FLAGS_CLEAR_ON_RESUME) { | 1195 | if (EC_FLAGS_CLEAR_ON_RESUME) |
907 | mutex_lock(&ec->mutex); | ||
908 | acpi_ec_clear(ec); | 1196 | acpi_ec_clear(ec); |
909 | mutex_unlock(&ec->mutex); | ||
910 | } | ||
911 | return ret; | 1197 | return ret; |
912 | } | 1198 | } |
913 | 1199 | ||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 163e82f536fa..56b321aa2b1c 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -35,6 +35,13 @@ void acpi_int340x_thermal_init(void); | |||
35 | int acpi_sysfs_init(void); | 35 | int acpi_sysfs_init(void); |
36 | void acpi_container_init(void); | 36 | void acpi_container_init(void); |
37 | void acpi_memory_hotplug_init(void); | 37 | void acpi_memory_hotplug_init(void); |
38 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC | ||
39 | int acpi_ioapic_add(struct acpi_pci_root *root); | ||
40 | int acpi_ioapic_remove(struct acpi_pci_root *root); | ||
41 | #else | ||
42 | static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; } | ||
43 | static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; } | ||
44 | #endif | ||
38 | #ifdef CONFIG_ACPI_DOCK | 45 | #ifdef CONFIG_ACPI_DOCK |
39 | void register_dock_dependent_device(struct acpi_device *adev, | 46 | void register_dock_dependent_device(struct acpi_device *adev, |
40 | acpi_handle dshandle); | 47 | acpi_handle dshandle); |
@@ -68,6 +75,8 @@ static inline void acpi_debugfs_init(void) { return; } | |||
68 | #endif | 75 | #endif |
69 | void acpi_lpss_init(void); | 76 | void acpi_lpss_init(void); |
70 | 77 | ||
78 | void acpi_apd_init(void); | ||
79 | |||
71 | acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src); | 80 | acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src); |
72 | bool acpi_queue_hotplug_work(struct work_struct *work); | 81 | bool acpi_queue_hotplug_work(struct work_struct *work); |
73 | void acpi_device_hotplug(struct acpi_device *adev, u32 src); | 82 | void acpi_device_hotplug(struct acpi_device *adev, u32 src); |
@@ -122,11 +131,13 @@ struct acpi_ec { | |||
122 | unsigned long data_addr; | 131 | unsigned long data_addr; |
123 | unsigned long global_lock; | 132 | unsigned long global_lock; |
124 | unsigned long flags; | 133 | unsigned long flags; |
134 | unsigned long reference_count; | ||
125 | struct mutex mutex; | 135 | struct mutex mutex; |
126 | wait_queue_head_t wait; | 136 | wait_queue_head_t wait; |
127 | struct list_head list; | 137 | struct list_head list; |
128 | struct transaction *curr; | 138 | struct transaction *curr; |
129 | spinlock_t lock; | 139 | spinlock_t lock; |
140 | struct work_struct work; | ||
130 | }; | 141 | }; |
131 | 142 | ||
132 | extern struct acpi_ec *first_ec; | 143 | extern struct acpi_ec *first_ec; |
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c new file mode 100644 index 000000000000..ccdc8db16bb8 --- /dev/null +++ b/drivers/acpi/ioapic.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * IOAPIC/IOxAPIC/IOSAPIC driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Fujitsu Limited. | ||
5 | * (c) Copyright 2009 Hewlett-Packard Development Company, L.P. | ||
6 | * | ||
7 | * Copyright (C) 2014 Intel Corporation | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * Based on original drivers/pci/ioapic.c | ||
14 | * Yinghai Lu <yinghai@kernel.org> | ||
15 | * Jiang Liu <jiang.liu@intel.com> | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * This driver manages I/O APICs added by hotplug after boot. | ||
20 | * We try to claim all I/O APIC devices, but those present at boot were | ||
21 | * registered when we parsed the ACPI MADT. | ||
22 | */ | ||
23 | |||
24 | #define pr_fmt(fmt) "ACPI : IOAPIC: " fmt | ||
25 | |||
26 | #include <linux/slab.h> | ||
27 | #include <linux/acpi.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <acpi/acpi.h> | ||
30 | |||
31 | struct acpi_pci_ioapic { | ||
32 | acpi_handle root_handle; | ||
33 | acpi_handle handle; | ||
34 | u32 gsi_base; | ||
35 | struct resource res; | ||
36 | struct pci_dev *pdev; | ||
37 | struct list_head list; | ||
38 | }; | ||
39 | |||
40 | static LIST_HEAD(ioapic_list); | ||
41 | static DEFINE_MUTEX(ioapic_list_lock); | ||
42 | |||
43 | static acpi_status setup_res(struct acpi_resource *acpi_res, void *data) | ||
44 | { | ||
45 | struct resource *res = data; | ||
46 | struct resource_win win; | ||
47 | |||
48 | res->flags = 0; | ||
49 | if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0) | ||
50 | return AE_OK; | ||
51 | |||
52 | if (!acpi_dev_resource_memory(acpi_res, res)) { | ||
53 | if (acpi_dev_resource_address_space(acpi_res, &win) || | ||
54 | acpi_dev_resource_ext_address_space(acpi_res, &win)) | ||
55 | *res = win.res; | ||
56 | } | ||
57 | if ((res->flags & IORESOURCE_PREFETCH) || | ||
58 | (res->flags & IORESOURCE_DISABLED)) | ||
59 | res->flags = 0; | ||
60 | |||
61 | return AE_CTRL_TERMINATE; | ||
62 | } | ||
63 | |||
64 | static bool acpi_is_ioapic(acpi_handle handle, char **type) | ||
65 | { | ||
66 | acpi_status status; | ||
67 | struct acpi_device_info *info; | ||
68 | char *hid = NULL; | ||
69 | bool match = false; | ||
70 | |||
71 | if (!acpi_has_method(handle, "_GSB")) | ||
72 | return false; | ||
73 | |||
74 | status = acpi_get_object_info(handle, &info); | ||
75 | if (ACPI_SUCCESS(status)) { | ||
76 | if (info->valid & ACPI_VALID_HID) | ||
77 | hid = info->hardware_id.string; | ||
78 | if (hid) { | ||
79 | if (strcmp(hid, "ACPI0009") == 0) { | ||
80 | *type = "IOxAPIC"; | ||
81 | match = true; | ||
82 | } else if (strcmp(hid, "ACPI000A") == 0) { | ||
83 | *type = "IOAPIC"; | ||
84 | match = true; | ||
85 | } | ||
86 | } | ||
87 | kfree(info); | ||
88 | } | ||
89 | |||
90 | return match; | ||
91 | } | ||
92 | |||
93 | static acpi_status handle_ioapic_add(acpi_handle handle, u32 lvl, | ||
94 | void *context, void **rv) | ||
95 | { | ||
96 | acpi_status status; | ||
97 | unsigned long long gsi_base; | ||
98 | struct acpi_pci_ioapic *ioapic; | ||
99 | struct pci_dev *dev = NULL; | ||
100 | struct resource *res = NULL; | ||
101 | char *type = NULL; | ||
102 | |||
103 | if (!acpi_is_ioapic(handle, &type)) | ||
104 | return AE_OK; | ||
105 | |||
106 | mutex_lock(&ioapic_list_lock); | ||
107 | list_for_each_entry(ioapic, &ioapic_list, list) | ||
108 | if (ioapic->handle == handle) { | ||
109 | mutex_unlock(&ioapic_list_lock); | ||
110 | return AE_OK; | ||
111 | } | ||
112 | |||
113 | status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsi_base); | ||
114 | if (ACPI_FAILURE(status)) { | ||
115 | acpi_handle_warn(handle, "failed to evaluate _GSB method\n"); | ||
116 | goto exit; | ||
117 | } | ||
118 | |||
119 | ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL); | ||
120 | if (!ioapic) { | ||
121 | pr_err("cannot allocate memory for new IOAPIC\n"); | ||
122 | goto exit; | ||
123 | } else { | ||
124 | ioapic->root_handle = (acpi_handle)context; | ||
125 | ioapic->handle = handle; | ||
126 | ioapic->gsi_base = (u32)gsi_base; | ||
127 | INIT_LIST_HEAD(&ioapic->list); | ||
128 | } | ||
129 | |||
130 | if (acpi_ioapic_registered(handle, (u32)gsi_base)) | ||
131 | goto done; | ||
132 | |||
133 | dev = acpi_get_pci_dev(handle); | ||
134 | if (dev && pci_resource_len(dev, 0)) { | ||
135 | if (pci_enable_device(dev) < 0) | ||
136 | goto exit_put; | ||
137 | pci_set_master(dev); | ||
138 | if (pci_request_region(dev, 0, type)) | ||
139 | goto exit_disable; | ||
140 | res = &dev->resource[0]; | ||
141 | ioapic->pdev = dev; | ||
142 | } else { | ||
143 | pci_dev_put(dev); | ||
144 | dev = NULL; | ||
145 | |||
146 | res = &ioapic->res; | ||
147 | acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res); | ||
148 | if (res->flags == 0) { | ||
149 | acpi_handle_warn(handle, "failed to get resource\n"); | ||
150 | goto exit_free; | ||
151 | } else if (request_resource(&iomem_resource, res)) { | ||
152 | acpi_handle_warn(handle, "failed to insert resource\n"); | ||
153 | goto exit_free; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) { | ||
158 | acpi_handle_warn(handle, "failed to register IOAPIC\n"); | ||
159 | goto exit_release; | ||
160 | } | ||
161 | done: | ||
162 | list_add(&ioapic->list, &ioapic_list); | ||
163 | mutex_unlock(&ioapic_list_lock); | ||
164 | |||
165 | if (dev) | ||
166 | dev_info(&dev->dev, "%s at %pR, GSI %u\n", | ||
167 | type, res, (u32)gsi_base); | ||
168 | else | ||
169 | acpi_handle_info(handle, "%s at %pR, GSI %u\n", | ||
170 | type, res, (u32)gsi_base); | ||
171 | |||
172 | return AE_OK; | ||
173 | |||
174 | exit_release: | ||
175 | if (dev) | ||
176 | pci_release_region(dev, 0); | ||
177 | else | ||
178 | release_resource(res); | ||
179 | exit_disable: | ||
180 | if (dev) | ||
181 | pci_disable_device(dev); | ||
182 | exit_put: | ||
183 | pci_dev_put(dev); | ||
184 | exit_free: | ||
185 | kfree(ioapic); | ||
186 | exit: | ||
187 | mutex_unlock(&ioapic_list_lock); | ||
188 | *(acpi_status *)rv = AE_ERROR; | ||
189 | return AE_OK; | ||
190 | } | ||
191 | |||
192 | int acpi_ioapic_add(struct acpi_pci_root *root) | ||
193 | { | ||
194 | acpi_status status, retval = AE_OK; | ||
195 | |||
196 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle, | ||
197 | UINT_MAX, handle_ioapic_add, NULL, | ||
198 | root->device->handle, (void **)&retval); | ||
199 | |||
200 | return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV; | ||
201 | } | ||
202 | |||
203 | int acpi_ioapic_remove(struct acpi_pci_root *root) | ||
204 | { | ||
205 | int retval = 0; | ||
206 | struct acpi_pci_ioapic *ioapic, *tmp; | ||
207 | |||
208 | mutex_lock(&ioapic_list_lock); | ||
209 | list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) { | ||
210 | if (root->device->handle != ioapic->root_handle) | ||
211 | continue; | ||
212 | |||
213 | if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base)) | ||
214 | retval = -EBUSY; | ||
215 | |||
216 | if (ioapic->pdev) { | ||
217 | pci_release_region(ioapic->pdev, 0); | ||
218 | pci_disable_device(ioapic->pdev); | ||
219 | pci_dev_put(ioapic->pdev); | ||
220 | } else if (ioapic->res.flags && ioapic->res.parent) { | ||
221 | release_resource(&ioapic->res); | ||
222 | } | ||
223 | list_del(&ioapic->list); | ||
224 | kfree(ioapic); | ||
225 | } | ||
226 | mutex_unlock(&ioapic_list_lock); | ||
227 | |||
228 | return retval; | ||
229 | } | ||
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 24b5476449a1..1333cbdc3ea2 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -177,12 +177,7 @@ static int __init slit_valid(struct acpi_table_slit *slit) | |||
177 | 177 | ||
178 | static int __init acpi_parse_slit(struct acpi_table_header *table) | 178 | static int __init acpi_parse_slit(struct acpi_table_header *table) |
179 | { | 179 | { |
180 | struct acpi_table_slit *slit; | 180 | struct acpi_table_slit *slit = (struct acpi_table_slit *)table; |
181 | |||
182 | if (!table) | ||
183 | return -EINVAL; | ||
184 | |||
185 | slit = (struct acpi_table_slit *)table; | ||
186 | 181 | ||
187 | if (!slit_valid(slit)) { | 182 | if (!slit_valid(slit)) { |
188 | printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); | 183 | printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); |
@@ -260,11 +255,8 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, | |||
260 | 255 | ||
261 | static int __init acpi_parse_srat(struct acpi_table_header *table) | 256 | static int __init acpi_parse_srat(struct acpi_table_header *table) |
262 | { | 257 | { |
263 | struct acpi_table_srat *srat; | 258 | struct acpi_table_srat *srat = (struct acpi_table_srat *)table; |
264 | if (!table) | ||
265 | return -EINVAL; | ||
266 | 259 | ||
267 | srat = (struct acpi_table_srat *)table; | ||
268 | acpi_srat_revision = srat->header.revision; | 260 | acpi_srat_revision = srat->header.revision; |
269 | 261 | ||
270 | /* Real work done in acpi_table_parse_srat below. */ | 262 | /* Real work done in acpi_table_parse_srat below. */ |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index b1def411c0b8..e7f718d6918a 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -485,14 +485,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
485 | if (!pin || !dev->irq_managed || dev->irq <= 0) | 485 | if (!pin || !dev->irq_managed || dev->irq <= 0) |
486 | return; | 486 | return; |
487 | 487 | ||
488 | /* Keep IOAPIC pin configuration when suspending */ | ||
489 | if (dev->dev.power.is_prepared) | ||
490 | return; | ||
491 | #ifdef CONFIG_PM | ||
492 | if (dev->dev.power.runtime_status == RPM_SUSPENDING) | ||
493 | return; | ||
494 | #endif | ||
495 | |||
496 | entry = acpi_pci_irq_lookup(dev, pin); | 488 | entry = acpi_pci_irq_lookup(dev, pin); |
497 | if (!entry) | 489 | if (!entry) |
498 | return; | 490 | return; |
@@ -513,5 +505,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
513 | if (gsi >= 0) { | 505 | if (gsi >= 0) { |
514 | acpi_unregister_gsi(gsi); | 506 | acpi_unregister_gsi(gsi); |
515 | dev->irq_managed = 0; | 507 | dev->irq_managed = 0; |
508 | dev->irq = 0; | ||
516 | } | 509 | } |
517 | } | 510 | } |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index c6bcb8c719d8..68a5f712cd19 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -112,10 +112,10 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | |||
112 | if (ACPI_FAILURE(status)) | 112 | if (ACPI_FAILURE(status)) |
113 | return AE_OK; | 113 | return AE_OK; |
114 | 114 | ||
115 | if ((address.address_length > 0) && | 115 | if ((address.address.address_length > 0) && |
116 | (address.resource_type == ACPI_BUS_NUMBER_RANGE)) { | 116 | (address.resource_type == ACPI_BUS_NUMBER_RANGE)) { |
117 | res->start = address.minimum; | 117 | res->start = address.address.minimum; |
118 | res->end = address.minimum + address.address_length - 1; | 118 | res->end = address.address.minimum + address.address.address_length - 1; |
119 | } | 119 | } |
120 | 120 | ||
121 | return AE_OK; | 121 | return AE_OK; |
@@ -621,6 +621,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
621 | if (hotadd) { | 621 | if (hotadd) { |
622 | pcibios_resource_survey_bus(root->bus); | 622 | pcibios_resource_survey_bus(root->bus); |
623 | pci_assign_unassigned_root_bus_resources(root->bus); | 623 | pci_assign_unassigned_root_bus_resources(root->bus); |
624 | acpi_ioapic_add(root); | ||
624 | } | 625 | } |
625 | 626 | ||
626 | pci_lock_rescan_remove(); | 627 | pci_lock_rescan_remove(); |
@@ -644,6 +645,8 @@ static void acpi_pci_root_remove(struct acpi_device *device) | |||
644 | 645 | ||
645 | pci_stop_root_bus(root->bus); | 646 | pci_stop_root_bus(root->bus); |
646 | 647 | ||
648 | WARN_ON(acpi_ioapic_remove(root)); | ||
649 | |||
647 | device_set_run_wake(root->bus->bridge, false); | 650 | device_set_run_wake(root->bus->bridge, false); |
648 | pci_acpi_remove_bus_pm_notifier(device); | 651 | pci_acpi_remove_bus_pm_notifier(device); |
649 | 652 | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 02e48394276c..7962651cdbd4 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -4,6 +4,10 @@ | |||
4 | * | 4 | * |
5 | * Alex Chiang <achiang@hp.com> | 5 | * Alex Chiang <achiang@hp.com> |
6 | * - Unified x86/ia64 implementations | 6 | * - Unified x86/ia64 implementations |
7 | * | ||
8 | * I/O APIC hotplug support | ||
9 | * Yinghai Lu <yinghai@kernel.org> | ||
10 | * Jiang Liu <jiang.liu@intel.com> | ||
7 | */ | 11 | */ |
8 | #include <linux/export.h> | 12 | #include <linux/export.h> |
9 | #include <linux/acpi.h> | 13 | #include <linux/acpi.h> |
@@ -12,6 +16,21 @@ | |||
12 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 16 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
13 | ACPI_MODULE_NAME("processor_core"); | 17 | ACPI_MODULE_NAME("processor_core"); |
14 | 18 | ||
19 | static struct acpi_table_madt *get_madt_table(void) | ||
20 | { | ||
21 | static struct acpi_table_madt *madt; | ||
22 | static int read_madt; | ||
23 | |||
24 | if (!read_madt) { | ||
25 | if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, | ||
26 | (struct acpi_table_header **)&madt))) | ||
27 | madt = NULL; | ||
28 | read_madt++; | ||
29 | } | ||
30 | |||
31 | return madt; | ||
32 | } | ||
33 | |||
15 | static int map_lapic_id(struct acpi_subtable_header *entry, | 34 | static int map_lapic_id(struct acpi_subtable_header *entry, |
16 | u32 acpi_id, int *apic_id) | 35 | u32 acpi_id, int *apic_id) |
17 | { | 36 | { |
@@ -67,17 +86,10 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, | |||
67 | static int map_madt_entry(int type, u32 acpi_id) | 86 | static int map_madt_entry(int type, u32 acpi_id) |
68 | { | 87 | { |
69 | unsigned long madt_end, entry; | 88 | unsigned long madt_end, entry; |
70 | static struct acpi_table_madt *madt; | ||
71 | static int read_madt; | ||
72 | int phys_id = -1; /* CPU hardware ID */ | 89 | int phys_id = -1; /* CPU hardware ID */ |
90 | struct acpi_table_madt *madt; | ||
73 | 91 | ||
74 | if (!read_madt) { | 92 | madt = get_madt_table(); |
75 | if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, | ||
76 | (struct acpi_table_header **)&madt))) | ||
77 | madt = NULL; | ||
78 | read_madt++; | ||
79 | } | ||
80 | |||
81 | if (!madt) | 93 | if (!madt) |
82 | return phys_id; | 94 | return phys_id; |
83 | 95 | ||
@@ -203,3 +215,96 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | |||
203 | return acpi_map_cpuid(phys_id, acpi_id); | 215 | return acpi_map_cpuid(phys_id, acpi_id); |
204 | } | 216 | } |
205 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 217 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
218 | |||
219 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC | ||
220 | static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base, | ||
221 | u64 *phys_addr, int *ioapic_id) | ||
222 | { | ||
223 | struct acpi_madt_io_apic *ioapic = (struct acpi_madt_io_apic *)entry; | ||
224 | |||
225 | if (ioapic->global_irq_base != gsi_base) | ||
226 | return 0; | ||
227 | |||
228 | *phys_addr = ioapic->address; | ||
229 | *ioapic_id = ioapic->id; | ||
230 | return 1; | ||
231 | } | ||
232 | |||
233 | static int parse_madt_ioapic_entry(u32 gsi_base, u64 *phys_addr) | ||
234 | { | ||
235 | struct acpi_subtable_header *hdr; | ||
236 | unsigned long madt_end, entry; | ||
237 | struct acpi_table_madt *madt; | ||
238 | int apic_id = -1; | ||
239 | |||
240 | madt = get_madt_table(); | ||
241 | if (!madt) | ||
242 | return apic_id; | ||
243 | |||
244 | entry = (unsigned long)madt; | ||
245 | madt_end = entry + madt->header.length; | ||
246 | |||
247 | /* Parse all entries looking for a match. */ | ||
248 | entry += sizeof(struct acpi_table_madt); | ||
249 | while (entry + sizeof(struct acpi_subtable_header) < madt_end) { | ||
250 | hdr = (struct acpi_subtable_header *)entry; | ||
251 | if (hdr->type == ACPI_MADT_TYPE_IO_APIC && | ||
252 | get_ioapic_id(hdr, gsi_base, phys_addr, &apic_id)) | ||
253 | break; | ||
254 | else | ||
255 | entry += hdr->length; | ||
256 | } | ||
257 | |||
258 | return apic_id; | ||
259 | } | ||
260 | |||
261 | static int parse_mat_ioapic_entry(acpi_handle handle, u32 gsi_base, | ||
262 | u64 *phys_addr) | ||
263 | { | ||
264 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
265 | struct acpi_subtable_header *header; | ||
266 | union acpi_object *obj; | ||
267 | int apic_id = -1; | ||
268 | |||
269 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | ||
270 | goto exit; | ||
271 | |||
272 | if (!buffer.length || !buffer.pointer) | ||
273 | goto exit; | ||
274 | |||
275 | obj = buffer.pointer; | ||
276 | if (obj->type != ACPI_TYPE_BUFFER || | ||
277 | obj->buffer.length < sizeof(struct acpi_subtable_header)) | ||
278 | goto exit; | ||
279 | |||
280 | header = (struct acpi_subtable_header *)obj->buffer.pointer; | ||
281 | if (header->type == ACPI_MADT_TYPE_IO_APIC) | ||
282 | get_ioapic_id(header, gsi_base, phys_addr, &apic_id); | ||
283 | |||
284 | exit: | ||
285 | kfree(buffer.pointer); | ||
286 | return apic_id; | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * acpi_get_ioapic_id - Get IOAPIC ID and physical address matching @gsi_base | ||
291 | * @handle: ACPI object for IOAPIC device | ||
292 | * @gsi_base: GSI base to match with | ||
293 | * @phys_addr: Pointer to store physical address of matching IOAPIC record | ||
294 | * | ||
295 | * Walk resources returned by ACPI_MAT method, then ACPI MADT table, to search | ||
296 | * for an ACPI IOAPIC record matching @gsi_base. | ||
297 | * Return IOAPIC id and store physical address in @phys_addr if found a match, | ||
298 | * otherwise return <0. | ||
299 | */ | ||
300 | int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr) | ||
301 | { | ||
302 | int apic_id; | ||
303 | |||
304 | apic_id = parse_mat_ioapic_entry(handle, gsi_base, phys_addr); | ||
305 | if (apic_id == -1) | ||
306 | apic_id = parse_madt_ioapic_entry(gsi_base, phys_addr); | ||
307 | |||
308 | return apic_id; | ||
309 | } | ||
310 | #endif /* CONFIG_ACPI_HOTPLUG_IOAPIC */ | ||
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 87b704e41877..c256bd7fbd78 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -681,15 +681,13 @@ static int acpi_idle_bm_check(void) | |||
681 | } | 681 | } |
682 | 682 | ||
683 | /** | 683 | /** |
684 | * acpi_idle_do_entry - a helper function that does C2 and C3 type entry | 684 | * acpi_idle_do_entry - enter idle state using the appropriate method |
685 | * @cx: cstate data | 685 | * @cx: cstate data |
686 | * | 686 | * |
687 | * Caller disables interrupt before call and enables interrupt after return. | 687 | * Caller disables interrupt before call and enables interrupt after return. |
688 | */ | 688 | */ |
689 | static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) | 689 | static void acpi_idle_do_entry(struct acpi_processor_cx *cx) |
690 | { | 690 | { |
691 | /* Don't trace irqs off for idle */ | ||
692 | stop_critical_timings(); | ||
693 | if (cx->entry_method == ACPI_CSTATE_FFH) { | 691 | if (cx->entry_method == ACPI_CSTATE_FFH) { |
694 | /* Call into architectural FFH based C-state */ | 692 | /* Call into architectural FFH based C-state */ |
695 | acpi_processor_ffh_cstate_enter(cx); | 693 | acpi_processor_ffh_cstate_enter(cx); |
@@ -703,38 +701,9 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) | |||
703 | gets asserted in time to freeze execution properly. */ | 701 | gets asserted in time to freeze execution properly. */ |
704 | inl(acpi_gbl_FADT.xpm_timer_block.address); | 702 | inl(acpi_gbl_FADT.xpm_timer_block.address); |
705 | } | 703 | } |
706 | start_critical_timings(); | ||
707 | } | 704 | } |
708 | 705 | ||
709 | /** | 706 | /** |
710 | * acpi_idle_enter_c1 - enters an ACPI C1 state-type | ||
711 | * @dev: the target CPU | ||
712 | * @drv: cpuidle driver containing cpuidle state info | ||
713 | * @index: index of target state | ||
714 | * | ||
715 | * This is equivalent to the HALT instruction. | ||
716 | */ | ||
717 | static int acpi_idle_enter_c1(struct cpuidle_device *dev, | ||
718 | struct cpuidle_driver *drv, int index) | ||
719 | { | ||
720 | struct acpi_processor *pr; | ||
721 | struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); | ||
722 | |||
723 | pr = __this_cpu_read(processors); | ||
724 | |||
725 | if (unlikely(!pr)) | ||
726 | return -EINVAL; | ||
727 | |||
728 | lapic_timer_state_broadcast(pr, cx, 1); | ||
729 | acpi_idle_do_entry(cx); | ||
730 | |||
731 | lapic_timer_state_broadcast(pr, cx, 0); | ||
732 | |||
733 | return index; | ||
734 | } | ||
735 | |||
736 | |||
737 | /** | ||
738 | * acpi_idle_play_dead - enters an ACPI state for long-term idle (i.e. off-lining) | 707 | * acpi_idle_play_dead - enters an ACPI state for long-term idle (i.e. off-lining) |
739 | * @dev: the target CPU | 708 | * @dev: the target CPU |
740 | * @index: the index of suggested state | 709 | * @index: the index of suggested state |
@@ -761,47 +730,11 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) | |||
761 | return 0; | 730 | return 0; |
762 | } | 731 | } |
763 | 732 | ||
764 | /** | 733 | static bool acpi_idle_fallback_to_c1(struct acpi_processor *pr) |
765 | * acpi_idle_enter_simple - enters an ACPI state without BM handling | ||
766 | * @dev: the target CPU | ||
767 | * @drv: cpuidle driver with cpuidle state information | ||
768 | * @index: the index of suggested state | ||
769 | */ | ||
770 | static int acpi_idle_enter_simple(struct cpuidle_device *dev, | ||
771 | struct cpuidle_driver *drv, int index) | ||
772 | { | 734 | { |
773 | struct acpi_processor *pr; | 735 | return IS_ENABLED(CONFIG_HOTPLUG_CPU) && num_online_cpus() > 1 && |
774 | struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); | 736 | !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED) && |
775 | 737 | !pr->flags.has_cst; | |
776 | pr = __this_cpu_read(processors); | ||
777 | |||
778 | if (unlikely(!pr)) | ||
779 | return -EINVAL; | ||
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 | |||
788 | /* | ||
789 | * Must be done before busmaster disable as we might need to | ||
790 | * access HPET ! | ||
791 | */ | ||
792 | lapic_timer_state_broadcast(pr, cx, 1); | ||
793 | |||
794 | if (cx->type == ACPI_STATE_C3) | ||
795 | ACPI_FLUSH_CPU_CACHE(); | ||
796 | |||
797 | /* Tell the scheduler that we are going deep-idle: */ | ||
798 | sched_clock_idle_sleep_event(); | ||
799 | acpi_idle_do_entry(cx); | ||
800 | |||
801 | sched_clock_idle_wakeup_event(0); | ||
802 | |||
803 | lapic_timer_state_broadcast(pr, cx, 0); | ||
804 | return index; | ||
805 | } | 738 | } |
806 | 739 | ||
807 | static int c3_cpu_count; | 740 | static int c3_cpu_count; |
@@ -809,44 +742,14 @@ static DEFINE_RAW_SPINLOCK(c3_lock); | |||
809 | 742 | ||
810 | /** | 743 | /** |
811 | * acpi_idle_enter_bm - enters C3 with proper BM handling | 744 | * acpi_idle_enter_bm - enters C3 with proper BM handling |
812 | * @dev: the target CPU | 745 | * @pr: Target processor |
813 | * @drv: cpuidle driver containing state data | 746 | * @cx: Target state context |
814 | * @index: the index of suggested state | ||
815 | * | ||
816 | * If BM is detected, the deepest non-C3 idle state is entered instead. | ||
817 | */ | 747 | */ |
818 | static int acpi_idle_enter_bm(struct cpuidle_device *dev, | 748 | static void acpi_idle_enter_bm(struct acpi_processor *pr, |
819 | struct cpuidle_driver *drv, int index) | 749 | struct acpi_processor_cx *cx) |
820 | { | 750 | { |
821 | struct acpi_processor *pr; | ||
822 | struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); | ||
823 | |||
824 | pr = __this_cpu_read(processors); | ||
825 | |||
826 | if (unlikely(!pr)) | ||
827 | return -EINVAL; | ||
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 | |||
836 | if (!cx->bm_sts_skip && acpi_idle_bm_check()) { | ||
837 | if (drv->safe_state_index >= 0) { | ||
838 | return drv->states[drv->safe_state_index].enter(dev, | ||
839 | drv, drv->safe_state_index); | ||
840 | } else { | ||
841 | acpi_safe_halt(); | ||
842 | return -EBUSY; | ||
843 | } | ||
844 | } | ||
845 | |||
846 | acpi_unlazy_tlb(smp_processor_id()); | 751 | acpi_unlazy_tlb(smp_processor_id()); |
847 | 752 | ||
848 | /* Tell the scheduler that we are going deep-idle: */ | ||
849 | sched_clock_idle_sleep_event(); | ||
850 | /* | 753 | /* |
851 | * Must be done before busmaster disable as we might need to | 754 | * Must be done before busmaster disable as we might need to |
852 | * access HPET ! | 755 | * access HPET ! |
@@ -856,37 +759,71 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
856 | /* | 759 | /* |
857 | * disable bus master | 760 | * disable bus master |
858 | * bm_check implies we need ARB_DIS | 761 | * bm_check implies we need ARB_DIS |
859 | * !bm_check implies we need cache flush | ||
860 | * bm_control implies whether we can do ARB_DIS | 762 | * bm_control implies whether we can do ARB_DIS |
861 | * | 763 | * |
862 | * That leaves a case where bm_check is set and bm_control is | 764 | * That leaves a case where bm_check is set and bm_control is |
863 | * not set. In that case we cannot do much, we enter C3 | 765 | * not set. In that case we cannot do much, we enter C3 |
864 | * without doing anything. | 766 | * without doing anything. |
865 | */ | 767 | */ |
866 | if (pr->flags.bm_check && pr->flags.bm_control) { | 768 | if (pr->flags.bm_control) { |
867 | raw_spin_lock(&c3_lock); | 769 | raw_spin_lock(&c3_lock); |
868 | c3_cpu_count++; | 770 | c3_cpu_count++; |
869 | /* Disable bus master arbitration when all CPUs are in C3 */ | 771 | /* Disable bus master arbitration when all CPUs are in C3 */ |
870 | if (c3_cpu_count == num_online_cpus()) | 772 | if (c3_cpu_count == num_online_cpus()) |
871 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); | 773 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); |
872 | raw_spin_unlock(&c3_lock); | 774 | raw_spin_unlock(&c3_lock); |
873 | } else if (!pr->flags.bm_check) { | ||
874 | ACPI_FLUSH_CPU_CACHE(); | ||
875 | } | 775 | } |
876 | 776 | ||
877 | acpi_idle_do_entry(cx); | 777 | acpi_idle_do_entry(cx); |
878 | 778 | ||
879 | /* Re-enable bus master arbitration */ | 779 | /* Re-enable bus master arbitration */ |
880 | if (pr->flags.bm_check && pr->flags.bm_control) { | 780 | if (pr->flags.bm_control) { |
881 | raw_spin_lock(&c3_lock); | 781 | raw_spin_lock(&c3_lock); |
882 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); | 782 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); |
883 | c3_cpu_count--; | 783 | c3_cpu_count--; |
884 | raw_spin_unlock(&c3_lock); | 784 | raw_spin_unlock(&c3_lock); |
885 | } | 785 | } |
886 | 786 | ||
887 | sched_clock_idle_wakeup_event(0); | 787 | lapic_timer_state_broadcast(pr, cx, 0); |
788 | } | ||
789 | |||
790 | static int acpi_idle_enter(struct cpuidle_device *dev, | ||
791 | struct cpuidle_driver *drv, int index) | ||
792 | { | ||
793 | struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); | ||
794 | struct acpi_processor *pr; | ||
795 | |||
796 | pr = __this_cpu_read(processors); | ||
797 | if (unlikely(!pr)) | ||
798 | return -EINVAL; | ||
799 | |||
800 | if (cx->type != ACPI_STATE_C1) { | ||
801 | if (acpi_idle_fallback_to_c1(pr)) { | ||
802 | index = CPUIDLE_DRIVER_STATE_START; | ||
803 | cx = per_cpu(acpi_cstate[index], dev->cpu); | ||
804 | } else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) { | ||
805 | if (cx->bm_sts_skip || !acpi_idle_bm_check()) { | ||
806 | acpi_idle_enter_bm(pr, cx); | ||
807 | return index; | ||
808 | } else if (drv->safe_state_index >= 0) { | ||
809 | index = drv->safe_state_index; | ||
810 | cx = per_cpu(acpi_cstate[index], dev->cpu); | ||
811 | } else { | ||
812 | acpi_safe_halt(); | ||
813 | return -EBUSY; | ||
814 | } | ||
815 | } | ||
816 | } | ||
817 | |||
818 | lapic_timer_state_broadcast(pr, cx, 1); | ||
819 | |||
820 | if (cx->type == ACPI_STATE_C3) | ||
821 | ACPI_FLUSH_CPU_CACHE(); | ||
822 | |||
823 | acpi_idle_do_entry(cx); | ||
888 | 824 | ||
889 | lapic_timer_state_broadcast(pr, cx, 0); | 825 | lapic_timer_state_broadcast(pr, cx, 0); |
826 | |||
890 | return index; | 827 | return index; |
891 | } | 828 | } |
892 | 829 | ||
@@ -981,27 +918,12 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) | |||
981 | strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); | 918 | strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); |
982 | state->exit_latency = cx->latency; | 919 | state->exit_latency = cx->latency; |
983 | state->target_residency = cx->latency * latency_factor; | 920 | state->target_residency = cx->latency * latency_factor; |
921 | state->enter = acpi_idle_enter; | ||
984 | 922 | ||
985 | state->flags = 0; | 923 | state->flags = 0; |
986 | switch (cx->type) { | 924 | if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2) { |
987 | case ACPI_STATE_C1: | ||
988 | |||
989 | state->enter = acpi_idle_enter_c1; | ||
990 | state->enter_dead = acpi_idle_play_dead; | ||
991 | drv->safe_state_index = count; | ||
992 | break; | ||
993 | |||
994 | case ACPI_STATE_C2: | ||
995 | state->enter = acpi_idle_enter_simple; | ||
996 | state->enter_dead = acpi_idle_play_dead; | 925 | state->enter_dead = acpi_idle_play_dead; |
997 | drv->safe_state_index = count; | 926 | drv->safe_state_index = count; |
998 | break; | ||
999 | |||
1000 | case ACPI_STATE_C3: | ||
1001 | state->enter = pr->flags.bm_check ? | ||
1002 | acpi_idle_enter_bm : | ||
1003 | acpi_idle_enter_simple; | ||
1004 | break; | ||
1005 | } | 927 | } |
1006 | 928 | ||
1007 | count++; | 929 | count++; |
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 782a0d15c25f..4752b9939987 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
@@ -34,21 +34,34 @@ | |||
34 | #define valid_IRQ(i) (true) | 34 | #define valid_IRQ(i) (true) |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect, | 37 | static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io) |
38 | bool window) | ||
39 | { | 38 | { |
40 | unsigned long flags = IORESOURCE_MEM; | 39 | u64 reslen = end - start + 1; |
41 | 40 | ||
42 | if (len == 0) | 41 | /* |
43 | flags |= IORESOURCE_DISABLED; | 42 | * CHECKME: len might be required to check versus a minimum |
43 | * length as well. 1 for io is fine, but for memory it does | ||
44 | * not make any sense at all. | ||
45 | */ | ||
46 | if (len && reslen && reslen == len && start <= end) | ||
47 | return true; | ||
44 | 48 | ||
45 | if (write_protect == ACPI_READ_WRITE_MEMORY) | 49 | pr_info("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n", |
46 | flags |= IORESOURCE_MEM_WRITEABLE; | 50 | io ? "io" : "mem", start, end, len); |
51 | |||
52 | return false; | ||
53 | } | ||
54 | |||
55 | static void acpi_dev_memresource_flags(struct resource *res, u64 len, | ||
56 | u8 write_protect) | ||
57 | { | ||
58 | res->flags = IORESOURCE_MEM; | ||
47 | 59 | ||
48 | if (window) | 60 | if (!acpi_dev_resource_len_valid(res->start, res->end, len, false)) |
49 | flags |= IORESOURCE_WINDOW; | 61 | res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET; |
50 | 62 | ||
51 | return flags; | 63 | if (write_protect == ACPI_READ_WRITE_MEMORY) |
64 | res->flags |= IORESOURCE_MEM_WRITEABLE; | ||
52 | } | 65 | } |
53 | 66 | ||
54 | static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, | 67 | static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, |
@@ -56,7 +69,7 @@ static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, | |||
56 | { | 69 | { |
57 | res->start = start; | 70 | res->start = start; |
58 | res->end = start + len - 1; | 71 | res->end = start + len - 1; |
59 | res->flags = acpi_dev_memresource_flags(len, write_protect, false); | 72 | acpi_dev_memresource_flags(res, len, write_protect); |
60 | } | 73 | } |
61 | 74 | ||
62 | /** | 75 | /** |
@@ -67,6 +80,11 @@ static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, | |||
67 | * Check if the given ACPI resource object represents a memory resource and | 80 | * Check if the given ACPI resource object represents a memory resource and |
68 | * if that's the case, use the information in it to populate the generic | 81 | * if that's the case, use the information in it to populate the generic |
69 | * resource object pointed to by @res. | 82 | * resource object pointed to by @res. |
83 | * | ||
84 | * Return: | ||
85 | * 1) false with res->flags setting to zero: not the expected resource type | ||
86 | * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource | ||
87 | * 3) true: valid assigned resource | ||
70 | */ | 88 | */ |
71 | bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) | 89 | bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) |
72 | { | 90 | { |
@@ -77,60 +95,52 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) | |||
77 | switch (ares->type) { | 95 | switch (ares->type) { |
78 | case ACPI_RESOURCE_TYPE_MEMORY24: | 96 | case ACPI_RESOURCE_TYPE_MEMORY24: |
79 | memory24 = &ares->data.memory24; | 97 | memory24 = &ares->data.memory24; |
80 | if (!memory24->minimum && !memory24->address_length) | 98 | acpi_dev_get_memresource(res, memory24->minimum << 8, |
81 | return false; | 99 | memory24->address_length << 8, |
82 | acpi_dev_get_memresource(res, memory24->minimum, | ||
83 | memory24->address_length, | ||
84 | memory24->write_protect); | 100 | memory24->write_protect); |
85 | break; | 101 | break; |
86 | case ACPI_RESOURCE_TYPE_MEMORY32: | 102 | case ACPI_RESOURCE_TYPE_MEMORY32: |
87 | memory32 = &ares->data.memory32; | 103 | memory32 = &ares->data.memory32; |
88 | if (!memory32->minimum && !memory32->address_length) | ||
89 | return false; | ||
90 | acpi_dev_get_memresource(res, memory32->minimum, | 104 | acpi_dev_get_memresource(res, memory32->minimum, |
91 | memory32->address_length, | 105 | memory32->address_length, |
92 | memory32->write_protect); | 106 | memory32->write_protect); |
93 | break; | 107 | break; |
94 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 108 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
95 | fixed_memory32 = &ares->data.fixed_memory32; | 109 | fixed_memory32 = &ares->data.fixed_memory32; |
96 | if (!fixed_memory32->address && !fixed_memory32->address_length) | ||
97 | return false; | ||
98 | acpi_dev_get_memresource(res, fixed_memory32->address, | 110 | acpi_dev_get_memresource(res, fixed_memory32->address, |
99 | fixed_memory32->address_length, | 111 | fixed_memory32->address_length, |
100 | fixed_memory32->write_protect); | 112 | fixed_memory32->write_protect); |
101 | break; | 113 | break; |
102 | default: | 114 | default: |
115 | res->flags = 0; | ||
103 | return false; | 116 | return false; |
104 | } | 117 | } |
105 | return true; | 118 | |
119 | return !(res->flags & IORESOURCE_DISABLED); | ||
106 | } | 120 | } |
107 | EXPORT_SYMBOL_GPL(acpi_dev_resource_memory); | 121 | EXPORT_SYMBOL_GPL(acpi_dev_resource_memory); |
108 | 122 | ||
109 | static unsigned int acpi_dev_ioresource_flags(u64 start, u64 end, u8 io_decode, | 123 | static void acpi_dev_ioresource_flags(struct resource *res, u64 len, |
110 | bool window) | 124 | u8 io_decode) |
111 | { | 125 | { |
112 | int flags = IORESOURCE_IO; | 126 | res->flags = IORESOURCE_IO; |
113 | 127 | ||
114 | if (io_decode == ACPI_DECODE_16) | 128 | if (!acpi_dev_resource_len_valid(res->start, res->end, len, true)) |
115 | flags |= IORESOURCE_IO_16BIT_ADDR; | 129 | res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET; |
116 | 130 | ||
117 | if (start > end || end >= 0x10003) | 131 | if (res->end >= 0x10003) |
118 | flags |= IORESOURCE_DISABLED; | 132 | res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET; |
119 | 133 | ||
120 | if (window) | 134 | if (io_decode == ACPI_DECODE_16) |
121 | flags |= IORESOURCE_WINDOW; | 135 | res->flags |= IORESOURCE_IO_16BIT_ADDR; |
122 | |||
123 | return flags; | ||
124 | } | 136 | } |
125 | 137 | ||
126 | static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len, | 138 | static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len, |
127 | u8 io_decode) | 139 | u8 io_decode) |
128 | { | 140 | { |
129 | u64 end = start + len - 1; | ||
130 | |||
131 | res->start = start; | 141 | res->start = start; |
132 | res->end = end; | 142 | res->end = start + len - 1; |
133 | res->flags = acpi_dev_ioresource_flags(start, end, io_decode, false); | 143 | acpi_dev_ioresource_flags(res, len, io_decode); |
134 | } | 144 | } |
135 | 145 | ||
136 | /** | 146 | /** |
@@ -141,6 +151,11 @@ static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len, | |||
141 | * Check if the given ACPI resource object represents an I/O resource and | 151 | * Check if the given ACPI resource object represents an I/O resource and |
142 | * if that's the case, use the information in it to populate the generic | 152 | * if that's the case, use the information in it to populate the generic |
143 | * resource object pointed to by @res. | 153 | * resource object pointed to by @res. |
154 | * | ||
155 | * Return: | ||
156 | * 1) false with res->flags setting to zero: not the expected resource type | ||
157 | * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource | ||
158 | * 3) true: valid assigned resource | ||
144 | */ | 159 | */ |
145 | bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) | 160 | bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) |
146 | { | 161 | { |
@@ -150,135 +165,143 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) | |||
150 | switch (ares->type) { | 165 | switch (ares->type) { |
151 | case ACPI_RESOURCE_TYPE_IO: | 166 | case ACPI_RESOURCE_TYPE_IO: |
152 | io = &ares->data.io; | 167 | io = &ares->data.io; |
153 | if (!io->minimum && !io->address_length) | ||
154 | return false; | ||
155 | acpi_dev_get_ioresource(res, io->minimum, | 168 | acpi_dev_get_ioresource(res, io->minimum, |
156 | io->address_length, | 169 | io->address_length, |
157 | io->io_decode); | 170 | io->io_decode); |
158 | break; | 171 | break; |
159 | case ACPI_RESOURCE_TYPE_FIXED_IO: | 172 | case ACPI_RESOURCE_TYPE_FIXED_IO: |
160 | fixed_io = &ares->data.fixed_io; | 173 | fixed_io = &ares->data.fixed_io; |
161 | if (!fixed_io->address && !fixed_io->address_length) | ||
162 | return false; | ||
163 | acpi_dev_get_ioresource(res, fixed_io->address, | 174 | acpi_dev_get_ioresource(res, fixed_io->address, |
164 | fixed_io->address_length, | 175 | fixed_io->address_length, |
165 | ACPI_DECODE_10); | 176 | ACPI_DECODE_10); |
166 | break; | 177 | break; |
167 | default: | 178 | default: |
179 | res->flags = 0; | ||
168 | return false; | 180 | return false; |
169 | } | 181 | } |
170 | return true; | 182 | |
183 | return !(res->flags & IORESOURCE_DISABLED); | ||
171 | } | 184 | } |
172 | EXPORT_SYMBOL_GPL(acpi_dev_resource_io); | 185 | EXPORT_SYMBOL_GPL(acpi_dev_resource_io); |
173 | 186 | ||
174 | /** | 187 | static bool acpi_decode_space(struct resource_win *win, |
175 | * acpi_dev_resource_address_space - Extract ACPI address space information. | 188 | struct acpi_resource_address *addr, |
176 | * @ares: Input ACPI resource object. | 189 | struct acpi_address64_attribute *attr) |
177 | * @res: Output generic resource object. | ||
178 | * | ||
179 | * Check if the given ACPI resource object represents an address space resource | ||
180 | * and if that's the case, use the information in it to populate the generic | ||
181 | * resource object pointed to by @res. | ||
182 | */ | ||
183 | bool acpi_dev_resource_address_space(struct acpi_resource *ares, | ||
184 | struct resource *res) | ||
185 | { | 190 | { |
186 | acpi_status status; | 191 | u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16; |
187 | struct acpi_resource_address64 addr; | 192 | bool wp = addr->info.mem.write_protect; |
188 | bool window; | 193 | u64 len = attr->address_length; |
189 | u64 len; | 194 | struct resource *res = &win->res; |
190 | u8 io_decode; | ||
191 | 195 | ||
192 | switch (ares->type) { | 196 | /* |
193 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 197 | * Filter out invalid descriptor according to ACPI Spec 5.0, section |
194 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 198 | * 6.4.3.5 Address Space Resource Descriptors. |
195 | case ACPI_RESOURCE_TYPE_ADDRESS64: | 199 | */ |
196 | break; | 200 | if ((addr->min_address_fixed != addr->max_address_fixed && len) || |
197 | default: | 201 | (addr->min_address_fixed && addr->max_address_fixed && !len)) |
198 | return false; | 202 | pr_debug("ACPI: Invalid address space min_addr_fix %d, max_addr_fix %d, len %llx\n", |
199 | } | 203 | addr->min_address_fixed, addr->max_address_fixed, len); |
200 | 204 | ||
201 | status = acpi_resource_to_address64(ares, &addr); | 205 | res->start = attr->minimum; |
202 | if (ACPI_FAILURE(status)) | 206 | res->end = attr->maximum; |
203 | return false; | ||
204 | 207 | ||
205 | res->start = addr.minimum; | 208 | /* |
206 | res->end = addr.maximum; | 209 | * For bridges that translate addresses across the bridge, |
207 | window = addr.producer_consumer == ACPI_PRODUCER; | 210 | * translation_offset is the offset that must be added to the |
211 | * address on the secondary side to obtain the address on the | ||
212 | * primary side. Non-bridge devices must list 0 for all Address | ||
213 | * Translation offset bits. | ||
214 | */ | ||
215 | if (addr->producer_consumer == ACPI_PRODUCER) { | ||
216 | res->start += attr->translation_offset; | ||
217 | res->end += attr->translation_offset; | ||
218 | } else if (attr->translation_offset) { | ||
219 | pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n", | ||
220 | attr->translation_offset); | ||
221 | } | ||
208 | 222 | ||
209 | switch(addr.resource_type) { | 223 | switch (addr->resource_type) { |
210 | case ACPI_MEMORY_RANGE: | 224 | case ACPI_MEMORY_RANGE: |
211 | len = addr.maximum - addr.minimum + 1; | 225 | acpi_dev_memresource_flags(res, len, wp); |
212 | res->flags = acpi_dev_memresource_flags(len, | ||
213 | addr.info.mem.write_protect, | ||
214 | window); | ||
215 | break; | 226 | break; |
216 | case ACPI_IO_RANGE: | 227 | case ACPI_IO_RANGE: |
217 | io_decode = addr.granularity == 0xfff ? | 228 | acpi_dev_ioresource_flags(res, len, iodec); |
218 | ACPI_DECODE_10 : ACPI_DECODE_16; | ||
219 | res->flags = acpi_dev_ioresource_flags(addr.minimum, | ||
220 | addr.maximum, | ||
221 | io_decode, window); | ||
222 | break; | 229 | break; |
223 | case ACPI_BUS_NUMBER_RANGE: | 230 | case ACPI_BUS_NUMBER_RANGE: |
224 | res->flags = IORESOURCE_BUS; | 231 | res->flags = IORESOURCE_BUS; |
225 | break; | 232 | break; |
226 | default: | 233 | default: |
227 | res->flags = 0; | 234 | return false; |
228 | } | 235 | } |
229 | 236 | ||
230 | return true; | 237 | win->offset = attr->translation_offset; |
238 | |||
239 | if (addr->producer_consumer == ACPI_PRODUCER) | ||
240 | res->flags |= IORESOURCE_WINDOW; | ||
241 | |||
242 | if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY) | ||
243 | res->flags |= IORESOURCE_PREFETCH; | ||
244 | |||
245 | return !(res->flags & IORESOURCE_DISABLED); | ||
246 | } | ||
247 | |||
248 | /** | ||
249 | * acpi_dev_resource_address_space - Extract ACPI address space information. | ||
250 | * @ares: Input ACPI resource object. | ||
251 | * @win: Output generic resource object. | ||
252 | * | ||
253 | * Check if the given ACPI resource object represents an address space resource | ||
254 | * and if that's the case, use the information in it to populate the generic | ||
255 | * resource object pointed to by @win. | ||
256 | * | ||
257 | * Return: | ||
258 | * 1) false with win->res.flags setting to zero: not the expected resource type | ||
259 | * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned | ||
260 | * resource | ||
261 | * 3) true: valid assigned resource | ||
262 | */ | ||
263 | bool acpi_dev_resource_address_space(struct acpi_resource *ares, | ||
264 | struct resource_win *win) | ||
265 | { | ||
266 | struct acpi_resource_address64 addr; | ||
267 | |||
268 | win->res.flags = 0; | ||
269 | if (ACPI_FAILURE(acpi_resource_to_address64(ares, &addr))) | ||
270 | return false; | ||
271 | |||
272 | return acpi_decode_space(win, (struct acpi_resource_address *)&addr, | ||
273 | &addr.address); | ||
231 | } | 274 | } |
232 | EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space); | 275 | EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space); |
233 | 276 | ||
234 | /** | 277 | /** |
235 | * acpi_dev_resource_ext_address_space - Extract ACPI address space information. | 278 | * acpi_dev_resource_ext_address_space - Extract ACPI address space information. |
236 | * @ares: Input ACPI resource object. | 279 | * @ares: Input ACPI resource object. |
237 | * @res: Output generic resource object. | 280 | * @win: Output generic resource object. |
238 | * | 281 | * |
239 | * Check if the given ACPI resource object represents an extended address space | 282 | * Check if the given ACPI resource object represents an extended address space |
240 | * resource and if that's the case, use the information in it to populate the | 283 | * resource and if that's the case, use the information in it to populate the |
241 | * generic resource object pointed to by @res. | 284 | * generic resource object pointed to by @win. |
285 | * | ||
286 | * Return: | ||
287 | * 1) false with win->res.flags setting to zero: not the expected resource type | ||
288 | * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned | ||
289 | * resource | ||
290 | * 3) true: valid assigned resource | ||
242 | */ | 291 | */ |
243 | bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, | 292 | bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, |
244 | struct resource *res) | 293 | struct resource_win *win) |
245 | { | 294 | { |
246 | struct acpi_resource_extended_address64 *ext_addr; | 295 | struct acpi_resource_extended_address64 *ext_addr; |
247 | bool window; | ||
248 | u64 len; | ||
249 | u8 io_decode; | ||
250 | 296 | ||
297 | win->res.flags = 0; | ||
251 | if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) | 298 | if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) |
252 | return false; | 299 | return false; |
253 | 300 | ||
254 | ext_addr = &ares->data.ext_address64; | 301 | ext_addr = &ares->data.ext_address64; |
255 | 302 | ||
256 | res->start = ext_addr->minimum; | 303 | return acpi_decode_space(win, (struct acpi_resource_address *)ext_addr, |
257 | res->end = ext_addr->maximum; | 304 | &ext_addr->address); |
258 | window = ext_addr->producer_consumer == ACPI_PRODUCER; | ||
259 | |||
260 | switch(ext_addr->resource_type) { | ||
261 | case ACPI_MEMORY_RANGE: | ||
262 | len = ext_addr->maximum - ext_addr->minimum + 1; | ||
263 | res->flags = acpi_dev_memresource_flags(len, | ||
264 | ext_addr->info.mem.write_protect, | ||
265 | window); | ||
266 | break; | ||
267 | case ACPI_IO_RANGE: | ||
268 | io_decode = ext_addr->granularity == 0xfff ? | ||
269 | ACPI_DECODE_10 : ACPI_DECODE_16; | ||
270 | res->flags = acpi_dev_ioresource_flags(ext_addr->minimum, | ||
271 | ext_addr->maximum, | ||
272 | io_decode, window); | ||
273 | break; | ||
274 | case ACPI_BUS_NUMBER_RANGE: | ||
275 | res->flags = IORESOURCE_BUS; | ||
276 | break; | ||
277 | default: | ||
278 | res->flags = 0; | ||
279 | } | ||
280 | |||
281 | return true; | ||
282 | } | 305 | } |
283 | EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space); | 306 | EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space); |
284 | 307 | ||
@@ -310,7 +333,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) | |||
310 | { | 333 | { |
311 | res->start = gsi; | 334 | res->start = gsi; |
312 | res->end = gsi; | 335 | res->end = gsi; |
313 | res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED; | 336 | res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; |
314 | } | 337 | } |
315 | 338 | ||
316 | static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, | 339 | static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, |
@@ -369,6 +392,11 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, | |||
369 | * represented by the resource and populate the generic resource object pointed | 392 | * represented by the resource and populate the generic resource object pointed |
370 | * to by @res accordingly. If the registration of the GSI is not successful, | 393 | * to by @res accordingly. If the registration of the GSI is not successful, |
371 | * IORESOURCE_DISABLED will be set it that object's flags. | 394 | * IORESOURCE_DISABLED will be set it that object's flags. |
395 | * | ||
396 | * Return: | ||
397 | * 1) false with res->flags setting to zero: not the expected resource type | ||
398 | * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource | ||
399 | * 3) true: valid assigned resource | ||
372 | */ | 400 | */ |
373 | bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, | 401 | bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, |
374 | struct resource *res) | 402 | struct resource *res) |
@@ -402,6 +430,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, | |||
402 | ext_irq->sharable, false); | 430 | ext_irq->sharable, false); |
403 | break; | 431 | break; |
404 | default: | 432 | default: |
433 | res->flags = 0; | ||
405 | return false; | 434 | return false; |
406 | } | 435 | } |
407 | 436 | ||
@@ -415,12 +444,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt); | |||
415 | */ | 444 | */ |
416 | void acpi_dev_free_resource_list(struct list_head *list) | 445 | void acpi_dev_free_resource_list(struct list_head *list) |
417 | { | 446 | { |
418 | struct resource_list_entry *rentry, *re; | 447 | resource_list_free(list); |
419 | |||
420 | list_for_each_entry_safe(rentry, re, list, node) { | ||
421 | list_del(&rentry->node); | ||
422 | kfree(rentry); | ||
423 | } | ||
424 | } | 448 | } |
425 | EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list); | 449 | EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list); |
426 | 450 | ||
@@ -432,18 +456,19 @@ struct res_proc_context { | |||
432 | int error; | 456 | int error; |
433 | }; | 457 | }; |
434 | 458 | ||
435 | static acpi_status acpi_dev_new_resource_entry(struct resource *r, | 459 | static acpi_status acpi_dev_new_resource_entry(struct resource_win *win, |
436 | struct res_proc_context *c) | 460 | struct res_proc_context *c) |
437 | { | 461 | { |
438 | struct resource_list_entry *rentry; | 462 | struct resource_entry *rentry; |
439 | 463 | ||
440 | rentry = kmalloc(sizeof(*rentry), GFP_KERNEL); | 464 | rentry = resource_list_create_entry(NULL, 0); |
441 | if (!rentry) { | 465 | if (!rentry) { |
442 | c->error = -ENOMEM; | 466 | c->error = -ENOMEM; |
443 | return AE_NO_MEMORY; | 467 | return AE_NO_MEMORY; |
444 | } | 468 | } |
445 | rentry->res = *r; | 469 | *rentry->res = win->res; |
446 | list_add_tail(&rentry->node, c->list); | 470 | rentry->offset = win->offset; |
471 | resource_list_add_tail(rentry, c->list); | ||
447 | c->count++; | 472 | c->count++; |
448 | return AE_OK; | 473 | return AE_OK; |
449 | } | 474 | } |
@@ -452,7 +477,8 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, | |||
452 | void *context) | 477 | void *context) |
453 | { | 478 | { |
454 | struct res_proc_context *c = context; | 479 | struct res_proc_context *c = context; |
455 | struct resource r; | 480 | struct resource_win win; |
481 | struct resource *res = &win.res; | ||
456 | int i; | 482 | int i; |
457 | 483 | ||
458 | if (c->preproc) { | 484 | if (c->preproc) { |
@@ -467,18 +493,18 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, | |||
467 | } | 493 | } |
468 | } | 494 | } |
469 | 495 | ||
470 | memset(&r, 0, sizeof(r)); | 496 | memset(&win, 0, sizeof(win)); |
471 | 497 | ||
472 | if (acpi_dev_resource_memory(ares, &r) | 498 | if (acpi_dev_resource_memory(ares, res) |
473 | || acpi_dev_resource_io(ares, &r) | 499 | || acpi_dev_resource_io(ares, res) |
474 | || acpi_dev_resource_address_space(ares, &r) | 500 | || acpi_dev_resource_address_space(ares, &win) |
475 | || acpi_dev_resource_ext_address_space(ares, &r)) | 501 | || acpi_dev_resource_ext_address_space(ares, &win)) |
476 | return acpi_dev_new_resource_entry(&r, c); | 502 | return acpi_dev_new_resource_entry(&win, c); |
477 | 503 | ||
478 | for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) { | 504 | for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) { |
479 | acpi_status status; | 505 | acpi_status status; |
480 | 506 | ||
481 | status = acpi_dev_new_resource_entry(&r, c); | 507 | status = acpi_dev_new_resource_entry(&win, c); |
482 | if (ACPI_FAILURE(status)) | 508 | if (ACPI_FAILURE(status)) |
483 | return status; | 509 | return status; |
484 | } | 510 | } |
@@ -503,7 +529,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, | |||
503 | * returned as the final error code. | 529 | * returned as the final error code. |
504 | * | 530 | * |
505 | * The resultant struct resource objects are put on the list pointed to by | 531 | * The resultant struct resource objects are put on the list pointed to by |
506 | * @list, that must be empty initially, as members of struct resource_list_entry | 532 | * @list, that must be empty initially, as members of struct resource_entry |
507 | * objects. Callers of this routine should use %acpi_dev_free_resource_list() to | 533 | * objects. Callers of this routine should use %acpi_dev_free_resource_list() to |
508 | * free that list. | 534 | * free that list. |
509 | * | 535 | * |
@@ -538,3 +564,58 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, | |||
538 | return c.count; | 564 | return c.count; |
539 | } | 565 | } |
540 | EXPORT_SYMBOL_GPL(acpi_dev_get_resources); | 566 | EXPORT_SYMBOL_GPL(acpi_dev_get_resources); |
567 | |||
568 | /** | ||
569 | * acpi_dev_filter_resource_type - Filter ACPI resource according to resource | ||
570 | * types | ||
571 | * @ares: Input ACPI resource object. | ||
572 | * @types: Valid resource types of IORESOURCE_XXX | ||
573 | * | ||
574 | * This is a hepler function to support acpi_dev_get_resources(), which filters | ||
575 | * ACPI resource objects according to resource types. | ||
576 | */ | ||
577 | int acpi_dev_filter_resource_type(struct acpi_resource *ares, | ||
578 | unsigned long types) | ||
579 | { | ||
580 | unsigned long type = 0; | ||
581 | |||
582 | switch (ares->type) { | ||
583 | case ACPI_RESOURCE_TYPE_MEMORY24: | ||
584 | case ACPI_RESOURCE_TYPE_MEMORY32: | ||
585 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | ||
586 | type = IORESOURCE_MEM; | ||
587 | break; | ||
588 | case ACPI_RESOURCE_TYPE_IO: | ||
589 | case ACPI_RESOURCE_TYPE_FIXED_IO: | ||
590 | type = IORESOURCE_IO; | ||
591 | break; | ||
592 | case ACPI_RESOURCE_TYPE_IRQ: | ||
593 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | ||
594 | type = IORESOURCE_IRQ; | ||
595 | break; | ||
596 | case ACPI_RESOURCE_TYPE_DMA: | ||
597 | case ACPI_RESOURCE_TYPE_FIXED_DMA: | ||
598 | type = IORESOURCE_DMA; | ||
599 | break; | ||
600 | case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: | ||
601 | type = IORESOURCE_REG; | ||
602 | break; | ||
603 | case ACPI_RESOURCE_TYPE_ADDRESS16: | ||
604 | case ACPI_RESOURCE_TYPE_ADDRESS32: | ||
605 | case ACPI_RESOURCE_TYPE_ADDRESS64: | ||
606 | case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: | ||
607 | if (ares->data.address.resource_type == ACPI_MEMORY_RANGE) | ||
608 | type = IORESOURCE_MEM; | ||
609 | else if (ares->data.address.resource_type == ACPI_IO_RANGE) | ||
610 | type = IORESOURCE_IO; | ||
611 | else if (ares->data.address.resource_type == | ||
612 | ACPI_BUS_NUMBER_RANGE) | ||
613 | type = IORESOURCE_BUS; | ||
614 | break; | ||
615 | default: | ||
616 | break; | ||
617 | } | ||
618 | |||
619 | return (type & types) ? 0 : 1; | ||
620 | } | ||
621 | EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type); | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index dc4d8960684a..bbca7830e18a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -2544,6 +2544,7 @@ int __init acpi_scan_init(void) | |||
2544 | acpi_pci_link_init(); | 2544 | acpi_pci_link_init(); |
2545 | acpi_processor_init(); | 2545 | acpi_processor_init(); |
2546 | acpi_lpss_init(); | 2546 | acpi_lpss_init(); |
2547 | acpi_apd_init(); | ||
2547 | acpi_cmos_rtc_init(); | 2548 | acpi_cmos_rtc_init(); |
2548 | acpi_container_init(); | 2549 | acpi_container_init(); |
2549 | acpi_memory_hotplug_init(); | 2550 | acpi_memory_hotplug_init(); |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 8aa9254a387f..7f251dd1a687 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -321,7 +321,7 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { | |||
321 | {}, | 321 | {}, |
322 | }; | 322 | }; |
323 | 323 | ||
324 | static void acpi_sleep_dmi_check(void) | 324 | static void __init acpi_sleep_dmi_check(void) |
325 | { | 325 | { |
326 | int year; | 326 | int year; |
327 | 327 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 032db459370f..88a4f99dd2a7 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -522,6 +522,24 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
522 | DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"), | 522 | DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"), |
523 | }, | 523 | }, |
524 | }, | 524 | }, |
525 | { | ||
526 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1186097 */ | ||
527 | .callback = video_disable_native_backlight, | ||
528 | .ident = "SAMSUNG 3570R/370R/470R/450R/510R/4450RV", | ||
529 | .matches = { | ||
530 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
531 | DMI_MATCH(DMI_PRODUCT_NAME, "3570R/370R/470R/450R/510R/4450RV"), | ||
532 | }, | ||
533 | }, | ||
534 | { | ||
535 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */ | ||
536 | .callback = video_disable_native_backlight, | ||
537 | .ident = "SAMSUNG 730U3E/740U3E", | ||
538 | .matches = { | ||
539 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
540 | DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"), | ||
541 | }, | ||
542 | }, | ||
525 | 543 | ||
526 | { | 544 | { |
527 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ | 545 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ |
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index b0f138806bbc..f32b802b98f4 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c | |||
@@ -19,8 +19,8 @@ | |||
19 | * @dev: Device to handle. | 19 | * @dev: Device to handle. |
20 | * | 20 | * |
21 | * If power.subsys_data is NULL, point it to a new object, otherwise increment | 21 | * If power.subsys_data is NULL, point it to a new object, otherwise increment |
22 | * its reference counter. Return 1 if a new object has been created, otherwise | 22 | * its reference counter. Return 0 if new object has been created or refcount |
23 | * return 0 or error code. | 23 | * increased, otherwise negative error code. |
24 | */ | 24 | */ |
25 | int dev_pm_get_subsys_data(struct device *dev) | 25 | int dev_pm_get_subsys_data(struct device *dev) |
26 | { | 26 | { |
@@ -56,13 +56,11 @@ EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data); | |||
56 | * @dev: Device to handle. | 56 | * @dev: Device to handle. |
57 | * | 57 | * |
58 | * If the reference counter of power.subsys_data is zero after dropping the | 58 | * If the reference counter of power.subsys_data is zero after dropping the |
59 | * reference, power.subsys_data is removed. Return 1 if that happens or 0 | 59 | * reference, power.subsys_data is removed. |
60 | * otherwise. | ||
61 | */ | 60 | */ |
62 | int dev_pm_put_subsys_data(struct device *dev) | 61 | void dev_pm_put_subsys_data(struct device *dev) |
63 | { | 62 | { |
64 | struct pm_subsys_data *psd; | 63 | struct pm_subsys_data *psd; |
65 | int ret = 1; | ||
66 | 64 | ||
67 | spin_lock_irq(&dev->power.lock); | 65 | spin_lock_irq(&dev->power.lock); |
68 | 66 | ||
@@ -70,18 +68,14 @@ int dev_pm_put_subsys_data(struct device *dev) | |||
70 | if (!psd) | 68 | if (!psd) |
71 | goto out; | 69 | goto out; |
72 | 70 | ||
73 | if (--psd->refcount == 0) { | 71 | if (--psd->refcount == 0) |
74 | dev->power.subsys_data = NULL; | 72 | dev->power.subsys_data = NULL; |
75 | } else { | 73 | else |
76 | psd = NULL; | 74 | psd = NULL; |
77 | ret = 0; | ||
78 | } | ||
79 | 75 | ||
80 | out: | 76 | out: |
81 | spin_unlock_irq(&dev->power.lock); | 77 | spin_unlock_irq(&dev->power.lock); |
82 | kfree(psd); | 78 | kfree(psd); |
83 | |||
84 | return ret; | ||
85 | } | 79 | } |
86 | EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data); | 80 | EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data); |
87 | 81 | ||
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 0d8780c04a5e..ba4abbe4693c 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -344,14 +344,7 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, | |||
344 | struct device *dev; | 344 | struct device *dev; |
345 | 345 | ||
346 | gpd_data = container_of(nb, struct generic_pm_domain_data, nb); | 346 | gpd_data = container_of(nb, struct generic_pm_domain_data, nb); |
347 | |||
348 | mutex_lock(&gpd_data->lock); | ||
349 | dev = gpd_data->base.dev; | 347 | dev = gpd_data->base.dev; |
350 | if (!dev) { | ||
351 | mutex_unlock(&gpd_data->lock); | ||
352 | return NOTIFY_DONE; | ||
353 | } | ||
354 | mutex_unlock(&gpd_data->lock); | ||
355 | 348 | ||
356 | for (;;) { | 349 | for (;;) { |
357 | struct generic_pm_domain *genpd; | 350 | struct generic_pm_domain *genpd; |
@@ -1384,25 +1377,66 @@ EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron); | |||
1384 | 1377 | ||
1385 | #endif /* CONFIG_PM_SLEEP */ | 1378 | #endif /* CONFIG_PM_SLEEP */ |
1386 | 1379 | ||
1387 | static struct generic_pm_domain_data *__pm_genpd_alloc_dev_data(struct device *dev) | 1380 | static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev, |
1381 | struct generic_pm_domain *genpd, | ||
1382 | struct gpd_timing_data *td) | ||
1388 | { | 1383 | { |
1389 | struct generic_pm_domain_data *gpd_data; | 1384 | struct generic_pm_domain_data *gpd_data; |
1385 | int ret; | ||
1386 | |||
1387 | ret = dev_pm_get_subsys_data(dev); | ||
1388 | if (ret) | ||
1389 | return ERR_PTR(ret); | ||
1390 | 1390 | ||
1391 | gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL); | 1391 | gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL); |
1392 | if (!gpd_data) | 1392 | if (!gpd_data) { |
1393 | return NULL; | 1393 | ret = -ENOMEM; |
1394 | goto err_put; | ||
1395 | } | ||
1396 | |||
1397 | if (td) | ||
1398 | gpd_data->td = *td; | ||
1394 | 1399 | ||
1395 | mutex_init(&gpd_data->lock); | 1400 | gpd_data->base.dev = dev; |
1401 | gpd_data->need_restore = -1; | ||
1402 | gpd_data->td.constraint_changed = true; | ||
1403 | gpd_data->td.effective_constraint_ns = -1; | ||
1396 | gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; | 1404 | gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; |
1397 | dev_pm_qos_add_notifier(dev, &gpd_data->nb); | 1405 | |
1406 | spin_lock_irq(&dev->power.lock); | ||
1407 | |||
1408 | if (dev->power.subsys_data->domain_data) { | ||
1409 | ret = -EINVAL; | ||
1410 | goto err_free; | ||
1411 | } | ||
1412 | |||
1413 | dev->power.subsys_data->domain_data = &gpd_data->base; | ||
1414 | dev->pm_domain = &genpd->domain; | ||
1415 | |||
1416 | spin_unlock_irq(&dev->power.lock); | ||
1417 | |||
1398 | return gpd_data; | 1418 | return gpd_data; |
1419 | |||
1420 | err_free: | ||
1421 | spin_unlock_irq(&dev->power.lock); | ||
1422 | kfree(gpd_data); | ||
1423 | err_put: | ||
1424 | dev_pm_put_subsys_data(dev); | ||
1425 | return ERR_PTR(ret); | ||
1399 | } | 1426 | } |
1400 | 1427 | ||
1401 | static void __pm_genpd_free_dev_data(struct device *dev, | 1428 | static void genpd_free_dev_data(struct device *dev, |
1402 | struct generic_pm_domain_data *gpd_data) | 1429 | struct generic_pm_domain_data *gpd_data) |
1403 | { | 1430 | { |
1404 | dev_pm_qos_remove_notifier(dev, &gpd_data->nb); | 1431 | spin_lock_irq(&dev->power.lock); |
1432 | |||
1433 | dev->pm_domain = NULL; | ||
1434 | dev->power.subsys_data->domain_data = NULL; | ||
1435 | |||
1436 | spin_unlock_irq(&dev->power.lock); | ||
1437 | |||
1405 | kfree(gpd_data); | 1438 | kfree(gpd_data); |
1439 | dev_pm_put_subsys_data(dev); | ||
1406 | } | 1440 | } |
1407 | 1441 | ||
1408 | /** | 1442 | /** |
@@ -1414,8 +1448,7 @@ static void __pm_genpd_free_dev_data(struct device *dev, | |||
1414 | int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, | 1448 | int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, |
1415 | struct gpd_timing_data *td) | 1449 | struct gpd_timing_data *td) |
1416 | { | 1450 | { |
1417 | struct generic_pm_domain_data *gpd_data_new, *gpd_data = NULL; | 1451 | struct generic_pm_domain_data *gpd_data; |
1418 | struct pm_domain_data *pdd; | ||
1419 | int ret = 0; | 1452 | int ret = 0; |
1420 | 1453 | ||
1421 | dev_dbg(dev, "%s()\n", __func__); | 1454 | dev_dbg(dev, "%s()\n", __func__); |
@@ -1423,9 +1456,9 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, | |||
1423 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) | 1456 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) |
1424 | return -EINVAL; | 1457 | return -EINVAL; |
1425 | 1458 | ||
1426 | gpd_data_new = __pm_genpd_alloc_dev_data(dev); | 1459 | gpd_data = genpd_alloc_dev_data(dev, genpd, td); |
1427 | if (!gpd_data_new) | 1460 | if (IS_ERR(gpd_data)) |
1428 | return -ENOMEM; | 1461 | return PTR_ERR(gpd_data); |
1429 | 1462 | ||
1430 | genpd_acquire_lock(genpd); | 1463 | genpd_acquire_lock(genpd); |
1431 | 1464 | ||
@@ -1434,50 +1467,22 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, | |||
1434 | goto out; | 1467 | goto out; |
1435 | } | 1468 | } |
1436 | 1469 | ||
1437 | list_for_each_entry(pdd, &genpd->dev_list, list_node) | 1470 | ret = genpd->attach_dev ? genpd->attach_dev(genpd, dev) : 0; |
1438 | if (pdd->dev == dev) { | ||
1439 | ret = -EINVAL; | ||
1440 | goto out; | ||
1441 | } | ||
1442 | |||
1443 | ret = dev_pm_get_subsys_data(dev); | ||
1444 | if (ret) | 1471 | if (ret) |
1445 | goto out; | 1472 | goto out; |
1446 | 1473 | ||
1447 | genpd->device_count++; | 1474 | genpd->device_count++; |
1448 | genpd->max_off_time_changed = true; | 1475 | genpd->max_off_time_changed = true; |
1449 | 1476 | ||
1450 | spin_lock_irq(&dev->power.lock); | ||
1451 | |||
1452 | dev->pm_domain = &genpd->domain; | ||
1453 | if (dev->power.subsys_data->domain_data) { | ||
1454 | gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); | ||
1455 | } else { | ||
1456 | gpd_data = gpd_data_new; | ||
1457 | dev->power.subsys_data->domain_data = &gpd_data->base; | ||
1458 | } | ||
1459 | gpd_data->refcount++; | ||
1460 | if (td) | ||
1461 | gpd_data->td = *td; | ||
1462 | |||
1463 | spin_unlock_irq(&dev->power.lock); | ||
1464 | |||
1465 | if (genpd->attach_dev) | ||
1466 | genpd->attach_dev(genpd, dev); | ||
1467 | |||
1468 | mutex_lock(&gpd_data->lock); | ||
1469 | gpd_data->base.dev = dev; | ||
1470 | list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); | 1477 | list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); |
1471 | gpd_data->need_restore = -1; | ||
1472 | gpd_data->td.constraint_changed = true; | ||
1473 | gpd_data->td.effective_constraint_ns = -1; | ||
1474 | mutex_unlock(&gpd_data->lock); | ||
1475 | 1478 | ||
1476 | out: | 1479 | out: |
1477 | genpd_release_lock(genpd); | 1480 | genpd_release_lock(genpd); |
1478 | 1481 | ||
1479 | if (gpd_data != gpd_data_new) | 1482 | if (ret) |
1480 | __pm_genpd_free_dev_data(dev, gpd_data_new); | 1483 | genpd_free_dev_data(dev, gpd_data); |
1484 | else | ||
1485 | dev_pm_qos_add_notifier(dev, &gpd_data->nb); | ||
1481 | 1486 | ||
1482 | return ret; | 1487 | return ret; |
1483 | } | 1488 | } |
@@ -1504,7 +1509,6 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, | |||
1504 | { | 1509 | { |
1505 | struct generic_pm_domain_data *gpd_data; | 1510 | struct generic_pm_domain_data *gpd_data; |
1506 | struct pm_domain_data *pdd; | 1511 | struct pm_domain_data *pdd; |
1507 | bool remove = false; | ||
1508 | int ret = 0; | 1512 | int ret = 0; |
1509 | 1513 | ||
1510 | dev_dbg(dev, "%s()\n", __func__); | 1514 | dev_dbg(dev, "%s()\n", __func__); |
@@ -1514,6 +1518,11 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, | |||
1514 | || pd_to_genpd(dev->pm_domain) != genpd) | 1518 | || pd_to_genpd(dev->pm_domain) != genpd) |
1515 | return -EINVAL; | 1519 | return -EINVAL; |
1516 | 1520 | ||
1521 | /* The above validation also means we have existing domain_data. */ | ||
1522 | pdd = dev->power.subsys_data->domain_data; | ||
1523 | gpd_data = to_gpd_data(pdd); | ||
1524 | dev_pm_qos_remove_notifier(dev, &gpd_data->nb); | ||
1525 | |||
1517 | genpd_acquire_lock(genpd); | 1526 | genpd_acquire_lock(genpd); |
1518 | 1527 | ||
1519 | if (genpd->prepared_count > 0) { | 1528 | if (genpd->prepared_count > 0) { |
@@ -1527,58 +1536,22 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd, | |||
1527 | if (genpd->detach_dev) | 1536 | if (genpd->detach_dev) |
1528 | genpd->detach_dev(genpd, dev); | 1537 | genpd->detach_dev(genpd, dev); |
1529 | 1538 | ||
1530 | spin_lock_irq(&dev->power.lock); | ||
1531 | |||
1532 | dev->pm_domain = NULL; | ||
1533 | pdd = dev->power.subsys_data->domain_data; | ||
1534 | list_del_init(&pdd->list_node); | 1539 | list_del_init(&pdd->list_node); |
1535 | gpd_data = to_gpd_data(pdd); | ||
1536 | if (--gpd_data->refcount == 0) { | ||
1537 | dev->power.subsys_data->domain_data = NULL; | ||
1538 | remove = true; | ||
1539 | } | ||
1540 | |||
1541 | spin_unlock_irq(&dev->power.lock); | ||
1542 | |||
1543 | mutex_lock(&gpd_data->lock); | ||
1544 | pdd->dev = NULL; | ||
1545 | mutex_unlock(&gpd_data->lock); | ||
1546 | 1540 | ||
1547 | genpd_release_lock(genpd); | 1541 | genpd_release_lock(genpd); |
1548 | 1542 | ||
1549 | dev_pm_put_subsys_data(dev); | 1543 | genpd_free_dev_data(dev, gpd_data); |
1550 | if (remove) | ||
1551 | __pm_genpd_free_dev_data(dev, gpd_data); | ||
1552 | 1544 | ||
1553 | return 0; | 1545 | return 0; |
1554 | 1546 | ||
1555 | out: | 1547 | out: |
1556 | genpd_release_lock(genpd); | 1548 | genpd_release_lock(genpd); |
1549 | dev_pm_qos_add_notifier(dev, &gpd_data->nb); | ||
1557 | 1550 | ||
1558 | return ret; | 1551 | return ret; |
1559 | } | 1552 | } |
1560 | 1553 | ||
1561 | /** | 1554 | /** |
1562 | * pm_genpd_dev_need_restore - Set/unset the device's "need restore" flag. | ||
1563 | * @dev: Device to set/unset the flag for. | ||
1564 | * @val: The new value of the device's "need restore" flag. | ||
1565 | */ | ||
1566 | void pm_genpd_dev_need_restore(struct device *dev, bool val) | ||
1567 | { | ||
1568 | struct pm_subsys_data *psd; | ||
1569 | unsigned long flags; | ||
1570 | |||
1571 | spin_lock_irqsave(&dev->power.lock, flags); | ||
1572 | |||
1573 | psd = dev_to_psd(dev); | ||
1574 | if (psd && psd->domain_data) | ||
1575 | to_gpd_data(psd->domain_data)->need_restore = val ? 1 : 0; | ||
1576 | |||
1577 | spin_unlock_irqrestore(&dev->power.lock, flags); | ||
1578 | } | ||
1579 | EXPORT_SYMBOL_GPL(pm_genpd_dev_need_restore); | ||
1580 | |||
1581 | /** | ||
1582 | * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain. | 1555 | * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain. |
1583 | * @genpd: Master PM domain to add the subdomain to. | 1556 | * @genpd: Master PM domain to add the subdomain to. |
1584 | * @subdomain: Subdomain to be added. | 1557 | * @subdomain: Subdomain to be added. |
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 106c69359306..15bf29974c31 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
@@ -117,20 +117,20 @@ do { \ | |||
117 | } while (0) | 117 | } while (0) |
118 | 118 | ||
119 | /** | 119 | /** |
120 | * find_device_opp() - find device_opp struct using device pointer | 120 | * _find_device_opp() - find device_opp struct using device pointer |
121 | * @dev: device pointer used to lookup device OPPs | 121 | * @dev: device pointer used to lookup device OPPs |
122 | * | 122 | * |
123 | * Search list of device OPPs for one containing matching device. Does a RCU | 123 | * Search list of device OPPs for one containing matching device. Does a RCU |
124 | * reader operation to grab the pointer needed. | 124 | * reader operation to grab the pointer needed. |
125 | * | 125 | * |
126 | * Returns pointer to 'struct device_opp' if found, otherwise -ENODEV or | 126 | * Return: pointer to 'struct device_opp' if found, otherwise -ENODEV or |
127 | * -EINVAL based on type of error. | 127 | * -EINVAL based on type of error. |
128 | * | 128 | * |
129 | * Locking: This function must be called under rcu_read_lock(). device_opp | 129 | * Locking: This function must be called under rcu_read_lock(). device_opp |
130 | * is a RCU protected pointer. This means that device_opp is valid as long | 130 | * is a RCU protected pointer. This means that device_opp is valid as long |
131 | * as we are under RCU lock. | 131 | * as we are under RCU lock. |
132 | */ | 132 | */ |
133 | static struct device_opp *find_device_opp(struct device *dev) | 133 | static struct device_opp *_find_device_opp(struct device *dev) |
134 | { | 134 | { |
135 | struct device_opp *tmp_dev_opp, *dev_opp = ERR_PTR(-ENODEV); | 135 | struct device_opp *tmp_dev_opp, *dev_opp = ERR_PTR(-ENODEV); |
136 | 136 | ||
@@ -153,7 +153,7 @@ static struct device_opp *find_device_opp(struct device *dev) | |||
153 | * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an available opp | 153 | * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an available opp |
154 | * @opp: opp for which voltage has to be returned for | 154 | * @opp: opp for which voltage has to be returned for |
155 | * | 155 | * |
156 | * Return voltage in micro volt corresponding to the opp, else | 156 | * Return: voltage in micro volt corresponding to the opp, else |
157 | * return 0 | 157 | * return 0 |
158 | * | 158 | * |
159 | * Locking: This function must be called under rcu_read_lock(). opp is a rcu | 159 | * Locking: This function must be called under rcu_read_lock(). opp is a rcu |
@@ -169,6 +169,8 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) | |||
169 | struct dev_pm_opp *tmp_opp; | 169 | struct dev_pm_opp *tmp_opp; |
170 | unsigned long v = 0; | 170 | unsigned long v = 0; |
171 | 171 | ||
172 | opp_rcu_lockdep_assert(); | ||
173 | |||
172 | tmp_opp = rcu_dereference(opp); | 174 | tmp_opp = rcu_dereference(opp); |
173 | if (unlikely(IS_ERR_OR_NULL(tmp_opp)) || !tmp_opp->available) | 175 | if (unlikely(IS_ERR_OR_NULL(tmp_opp)) || !tmp_opp->available) |
174 | pr_err("%s: Invalid parameters\n", __func__); | 176 | pr_err("%s: Invalid parameters\n", __func__); |
@@ -183,7 +185,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_voltage); | |||
183 | * dev_pm_opp_get_freq() - Gets the frequency corresponding to an available opp | 185 | * dev_pm_opp_get_freq() - Gets the frequency corresponding to an available opp |
184 | * @opp: opp for which frequency has to be returned for | 186 | * @opp: opp for which frequency has to be returned for |
185 | * | 187 | * |
186 | * Return frequency in hertz corresponding to the opp, else | 188 | * Return: frequency in hertz corresponding to the opp, else |
187 | * return 0 | 189 | * return 0 |
188 | * | 190 | * |
189 | * Locking: This function must be called under rcu_read_lock(). opp is a rcu | 191 | * Locking: This function must be called under rcu_read_lock(). opp is a rcu |
@@ -199,6 +201,8 @@ unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp) | |||
199 | struct dev_pm_opp *tmp_opp; | 201 | struct dev_pm_opp *tmp_opp; |
200 | unsigned long f = 0; | 202 | unsigned long f = 0; |
201 | 203 | ||
204 | opp_rcu_lockdep_assert(); | ||
205 | |||
202 | tmp_opp = rcu_dereference(opp); | 206 | tmp_opp = rcu_dereference(opp); |
203 | if (unlikely(IS_ERR_OR_NULL(tmp_opp)) || !tmp_opp->available) | 207 | if (unlikely(IS_ERR_OR_NULL(tmp_opp)) || !tmp_opp->available) |
204 | pr_err("%s: Invalid parameters\n", __func__); | 208 | pr_err("%s: Invalid parameters\n", __func__); |
@@ -213,7 +217,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); | |||
213 | * dev_pm_opp_get_opp_count() - Get number of opps available in the opp list | 217 | * dev_pm_opp_get_opp_count() - Get number of opps available in the opp list |
214 | * @dev: device for which we do this operation | 218 | * @dev: device for which we do this operation |
215 | * | 219 | * |
216 | * This function returns the number of available opps if there are any, | 220 | * Return: This function returns the number of available opps if there are any, |
217 | * else returns 0 if none or the corresponding error value. | 221 | * else returns 0 if none or the corresponding error value. |
218 | * | 222 | * |
219 | * Locking: This function takes rcu_read_lock(). | 223 | * Locking: This function takes rcu_read_lock(). |
@@ -226,7 +230,7 @@ int dev_pm_opp_get_opp_count(struct device *dev) | |||
226 | 230 | ||
227 | rcu_read_lock(); | 231 | rcu_read_lock(); |
228 | 232 | ||
229 | dev_opp = find_device_opp(dev); | 233 | dev_opp = _find_device_opp(dev); |
230 | if (IS_ERR(dev_opp)) { | 234 | if (IS_ERR(dev_opp)) { |
231 | count = PTR_ERR(dev_opp); | 235 | count = PTR_ERR(dev_opp); |
232 | dev_err(dev, "%s: device OPP not found (%d)\n", | 236 | dev_err(dev, "%s: device OPP not found (%d)\n", |
@@ -251,9 +255,9 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); | |||
251 | * @freq: frequency to search for | 255 | * @freq: frequency to search for |
252 | * @available: true/false - match for available opp | 256 | * @available: true/false - match for available opp |
253 | * | 257 | * |
254 | * Searches for exact match in the opp list and returns pointer to the matching | 258 | * Return: Searches for exact match in the opp list and returns pointer to the |
255 | * opp if found, else returns ERR_PTR in case of error and should be handled | 259 | * matching opp if found, else returns ERR_PTR in case of error and should |
256 | * using IS_ERR. Error return values can be: | 260 | * be handled using IS_ERR. Error return values can be: |
257 | * EINVAL: for bad pointer | 261 | * EINVAL: for bad pointer |
258 | * ERANGE: no match found for search | 262 | * ERANGE: no match found for search |
259 | * ENODEV: if device not found in list of registered devices | 263 | * ENODEV: if device not found in list of registered devices |
@@ -280,7 +284,7 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, | |||
280 | 284 | ||
281 | opp_rcu_lockdep_assert(); | 285 | opp_rcu_lockdep_assert(); |
282 | 286 | ||
283 | dev_opp = find_device_opp(dev); | 287 | dev_opp = _find_device_opp(dev); |
284 | if (IS_ERR(dev_opp)) { | 288 | if (IS_ERR(dev_opp)) { |
285 | int r = PTR_ERR(dev_opp); | 289 | int r = PTR_ERR(dev_opp); |
286 | dev_err(dev, "%s: device OPP not found (%d)\n", __func__, r); | 290 | dev_err(dev, "%s: device OPP not found (%d)\n", __func__, r); |
@@ -307,7 +311,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); | |||
307 | * Search for the matching ceil *available* OPP from a starting freq | 311 | * Search for the matching ceil *available* OPP from a starting freq |
308 | * for a device. | 312 | * for a device. |
309 | * | 313 | * |
310 | * Returns matching *opp and refreshes *freq accordingly, else returns | 314 | * Return: matching *opp and refreshes *freq accordingly, else returns |
311 | * ERR_PTR in case of error and should be handled using IS_ERR. Error return | 315 | * ERR_PTR in case of error and should be handled using IS_ERR. Error return |
312 | * values can be: | 316 | * values can be: |
313 | * EINVAL: for bad pointer | 317 | * EINVAL: for bad pointer |
@@ -333,7 +337,7 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, | |||
333 | return ERR_PTR(-EINVAL); | 337 | return ERR_PTR(-EINVAL); |
334 | } | 338 | } |
335 | 339 | ||
336 | dev_opp = find_device_opp(dev); | 340 | dev_opp = _find_device_opp(dev); |
337 | if (IS_ERR(dev_opp)) | 341 | if (IS_ERR(dev_opp)) |
338 | return ERR_CAST(dev_opp); | 342 | return ERR_CAST(dev_opp); |
339 | 343 | ||
@@ -357,7 +361,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); | |||
357 | * Search for the matching floor *available* OPP from a starting freq | 361 | * Search for the matching floor *available* OPP from a starting freq |
358 | * for a device. | 362 | * for a device. |
359 | * | 363 | * |
360 | * Returns matching *opp and refreshes *freq accordingly, else returns | 364 | * Return: matching *opp and refreshes *freq accordingly, else returns |
361 | * ERR_PTR in case of error and should be handled using IS_ERR. Error return | 365 | * ERR_PTR in case of error and should be handled using IS_ERR. Error return |
362 | * values can be: | 366 | * values can be: |
363 | * EINVAL: for bad pointer | 367 | * EINVAL: for bad pointer |
@@ -383,7 +387,7 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, | |||
383 | return ERR_PTR(-EINVAL); | 387 | return ERR_PTR(-EINVAL); |
384 | } | 388 | } |
385 | 389 | ||
386 | dev_opp = find_device_opp(dev); | 390 | dev_opp = _find_device_opp(dev); |
387 | if (IS_ERR(dev_opp)) | 391 | if (IS_ERR(dev_opp)) |
388 | return ERR_CAST(dev_opp); | 392 | return ERR_CAST(dev_opp); |
389 | 393 | ||
@@ -403,7 +407,16 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, | |||
403 | } | 407 | } |
404 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); | 408 | EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); |
405 | 409 | ||
406 | static struct device_opp *add_device_opp(struct device *dev) | 410 | /** |
411 | * _add_device_opp() - Allocate a new device OPP table | ||
412 | * @dev: device for which we do this operation | ||
413 | * | ||
414 | * New device node which uses OPPs - used when multiple devices with OPP tables | ||
415 | * are maintained. | ||
416 | * | ||
417 | * Return: valid device_opp pointer if success, else NULL. | ||
418 | */ | ||
419 | static struct device_opp *_add_device_opp(struct device *dev) | ||
407 | { | 420 | { |
408 | struct device_opp *dev_opp; | 421 | struct device_opp *dev_opp; |
409 | 422 | ||
@@ -424,8 +437,35 @@ static struct device_opp *add_device_opp(struct device *dev) | |||
424 | return dev_opp; | 437 | return dev_opp; |
425 | } | 438 | } |
426 | 439 | ||
427 | static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, | 440 | /** |
428 | unsigned long u_volt, bool dynamic) | 441 | * _opp_add_dynamic() - Allocate a dynamic OPP. |
442 | * @dev: device for which we do this operation | ||
443 | * @freq: Frequency in Hz for this OPP | ||
444 | * @u_volt: Voltage in uVolts for this OPP | ||
445 | * @dynamic: Dynamically added OPPs. | ||
446 | * | ||
447 | * This function adds an opp definition to the opp list and returns status. | ||
448 | * The opp is made available by default and it can be controlled using | ||
449 | * dev_pm_opp_enable/disable functions and may be removed by dev_pm_opp_remove. | ||
450 | * | ||
451 | * NOTE: "dynamic" parameter impacts OPPs added by the of_init_opp_table and | ||
452 | * freed by of_free_opp_table. | ||
453 | * | ||
454 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
455 | * Hence this function internally uses RCU updater strategy with mutex locks | ||
456 | * to keep the integrity of the internal data structures. Callers should ensure | ||
457 | * that this function is *NOT* called under RCU protection or in contexts where | ||
458 | * mutex cannot be locked. | ||
459 | * | ||
460 | * Return: | ||
461 | * 0 On success OR | ||
462 | * Duplicate OPPs (both freq and volt are same) and opp->available | ||
463 | * -EEXIST Freq are same and volt are different OR | ||
464 | * Duplicate OPPs (both freq and volt are same) and !opp->available | ||
465 | * -ENOMEM Memory allocation failure | ||
466 | */ | ||
467 | static int _opp_add_dynamic(struct device *dev, unsigned long freq, | ||
468 | long u_volt, bool dynamic) | ||
429 | { | 469 | { |
430 | struct device_opp *dev_opp = NULL; | 470 | struct device_opp *dev_opp = NULL; |
431 | struct dev_pm_opp *opp, *new_opp; | 471 | struct dev_pm_opp *opp, *new_opp; |
@@ -449,9 +489,9 @@ static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, | |||
449 | new_opp->dynamic = dynamic; | 489 | new_opp->dynamic = dynamic; |
450 | 490 | ||
451 | /* Check for existing list for 'dev' */ | 491 | /* Check for existing list for 'dev' */ |
452 | dev_opp = find_device_opp(dev); | 492 | dev_opp = _find_device_opp(dev); |
453 | if (IS_ERR(dev_opp)) { | 493 | if (IS_ERR(dev_opp)) { |
454 | dev_opp = add_device_opp(dev); | 494 | dev_opp = _add_device_opp(dev); |
455 | if (!dev_opp) { | 495 | if (!dev_opp) { |
456 | ret = -ENOMEM; | 496 | ret = -ENOMEM; |
457 | goto free_opp; | 497 | goto free_opp; |
@@ -519,34 +559,53 @@ free_opp: | |||
519 | * mutex cannot be locked. | 559 | * mutex cannot be locked. |
520 | * | 560 | * |
521 | * Return: | 561 | * Return: |
522 | * 0: On success OR | 562 | * 0 On success OR |
523 | * Duplicate OPPs (both freq and volt are same) and opp->available | 563 | * Duplicate OPPs (both freq and volt are same) and opp->available |
524 | * -EEXIST: Freq are same and volt are different OR | 564 | * -EEXIST Freq are same and volt are different OR |
525 | * Duplicate OPPs (both freq and volt are same) and !opp->available | 565 | * Duplicate OPPs (both freq and volt are same) and !opp->available |
526 | * -ENOMEM: Memory allocation failure | 566 | * -ENOMEM Memory allocation failure |
527 | */ | 567 | */ |
528 | int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) | 568 | int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) |
529 | { | 569 | { |
530 | return dev_pm_opp_add_dynamic(dev, freq, u_volt, true); | 570 | return _opp_add_dynamic(dev, freq, u_volt, true); |
531 | } | 571 | } |
532 | EXPORT_SYMBOL_GPL(dev_pm_opp_add); | 572 | EXPORT_SYMBOL_GPL(dev_pm_opp_add); |
533 | 573 | ||
534 | static void kfree_opp_rcu(struct rcu_head *head) | 574 | /** |
575 | * _kfree_opp_rcu() - Free OPP RCU handler | ||
576 | * @head: RCU head | ||
577 | */ | ||
578 | static void _kfree_opp_rcu(struct rcu_head *head) | ||
535 | { | 579 | { |
536 | struct dev_pm_opp *opp = container_of(head, struct dev_pm_opp, rcu_head); | 580 | struct dev_pm_opp *opp = container_of(head, struct dev_pm_opp, rcu_head); |
537 | 581 | ||
538 | kfree_rcu(opp, rcu_head); | 582 | kfree_rcu(opp, rcu_head); |
539 | } | 583 | } |
540 | 584 | ||
541 | static void kfree_device_rcu(struct rcu_head *head) | 585 | /** |
586 | * _kfree_device_rcu() - Free device_opp RCU handler | ||
587 | * @head: RCU head | ||
588 | */ | ||
589 | static void _kfree_device_rcu(struct rcu_head *head) | ||
542 | { | 590 | { |
543 | struct device_opp *device_opp = container_of(head, struct device_opp, rcu_head); | 591 | struct device_opp *device_opp = container_of(head, struct device_opp, rcu_head); |
544 | 592 | ||
545 | kfree_rcu(device_opp, rcu_head); | 593 | kfree_rcu(device_opp, rcu_head); |
546 | } | 594 | } |
547 | 595 | ||
548 | static void __dev_pm_opp_remove(struct device_opp *dev_opp, | 596 | /** |
549 | struct dev_pm_opp *opp) | 597 | * _opp_remove() - Remove an OPP from a table definition |
598 | * @dev_opp: points back to the device_opp struct this opp belongs to | ||
599 | * @opp: pointer to the OPP to remove | ||
600 | * | ||
601 | * This function removes an opp definition from the opp list. | ||
602 | * | ||
603 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
604 | * It is assumed that the caller holds required mutex for an RCU updater | ||
605 | * strategy. | ||
606 | */ | ||
607 | static void _opp_remove(struct device_opp *dev_opp, | ||
608 | struct dev_pm_opp *opp) | ||
550 | { | 609 | { |
551 | /* | 610 | /* |
552 | * Notify the changes in the availability of the operable | 611 | * Notify the changes in the availability of the operable |
@@ -554,12 +613,12 @@ static void __dev_pm_opp_remove(struct device_opp *dev_opp, | |||
554 | */ | 613 | */ |
555 | srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_REMOVE, opp); | 614 | srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_REMOVE, opp); |
556 | list_del_rcu(&opp->node); | 615 | list_del_rcu(&opp->node); |
557 | call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, kfree_opp_rcu); | 616 | call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, _kfree_opp_rcu); |
558 | 617 | ||
559 | if (list_empty(&dev_opp->opp_list)) { | 618 | if (list_empty(&dev_opp->opp_list)) { |
560 | list_del_rcu(&dev_opp->node); | 619 | list_del_rcu(&dev_opp->node); |
561 | call_srcu(&dev_opp->srcu_head.srcu, &dev_opp->rcu_head, | 620 | call_srcu(&dev_opp->srcu_head.srcu, &dev_opp->rcu_head, |
562 | kfree_device_rcu); | 621 | _kfree_device_rcu); |
563 | } | 622 | } |
564 | } | 623 | } |
565 | 624 | ||
@@ -569,6 +628,12 @@ static void __dev_pm_opp_remove(struct device_opp *dev_opp, | |||
569 | * @freq: OPP to remove with matching 'freq' | 628 | * @freq: OPP to remove with matching 'freq' |
570 | * | 629 | * |
571 | * This function removes an opp from the opp list. | 630 | * This function removes an opp from the opp list. |
631 | * | ||
632 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
633 | * Hence this function internally uses RCU updater strategy with mutex locks | ||
634 | * to keep the integrity of the internal data structures. Callers should ensure | ||
635 | * that this function is *NOT* called under RCU protection or in contexts where | ||
636 | * mutex cannot be locked. | ||
572 | */ | 637 | */ |
573 | void dev_pm_opp_remove(struct device *dev, unsigned long freq) | 638 | void dev_pm_opp_remove(struct device *dev, unsigned long freq) |
574 | { | 639 | { |
@@ -579,7 +644,7 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq) | |||
579 | /* Hold our list modification lock here */ | 644 | /* Hold our list modification lock here */ |
580 | mutex_lock(&dev_opp_list_lock); | 645 | mutex_lock(&dev_opp_list_lock); |
581 | 646 | ||
582 | dev_opp = find_device_opp(dev); | 647 | dev_opp = _find_device_opp(dev); |
583 | if (IS_ERR(dev_opp)) | 648 | if (IS_ERR(dev_opp)) |
584 | goto unlock; | 649 | goto unlock; |
585 | 650 | ||
@@ -596,14 +661,14 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq) | |||
596 | goto unlock; | 661 | goto unlock; |
597 | } | 662 | } |
598 | 663 | ||
599 | __dev_pm_opp_remove(dev_opp, opp); | 664 | _opp_remove(dev_opp, opp); |
600 | unlock: | 665 | unlock: |
601 | mutex_unlock(&dev_opp_list_lock); | 666 | mutex_unlock(&dev_opp_list_lock); |
602 | } | 667 | } |
603 | EXPORT_SYMBOL_GPL(dev_pm_opp_remove); | 668 | EXPORT_SYMBOL_GPL(dev_pm_opp_remove); |
604 | 669 | ||
605 | /** | 670 | /** |
606 | * opp_set_availability() - helper to set the availability of an opp | 671 | * _opp_set_availability() - helper to set the availability of an opp |
607 | * @dev: device for which we do this operation | 672 | * @dev: device for which we do this operation |
608 | * @freq: OPP frequency to modify availability | 673 | * @freq: OPP frequency to modify availability |
609 | * @availability_req: availability status requested for this opp | 674 | * @availability_req: availability status requested for this opp |
@@ -611,7 +676,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_remove); | |||
611 | * Set the availability of an OPP with an RCU operation, opp_{enable,disable} | 676 | * Set the availability of an OPP with an RCU operation, opp_{enable,disable} |
612 | * share a common logic which is isolated here. | 677 | * share a common logic which is isolated here. |
613 | * | 678 | * |
614 | * Returns -EINVAL for bad pointers, -ENOMEM if no memory available for the | 679 | * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the |
615 | * copy operation, returns 0 if no modifcation was done OR modification was | 680 | * copy operation, returns 0 if no modifcation was done OR modification was |
616 | * successful. | 681 | * successful. |
617 | * | 682 | * |
@@ -621,8 +686,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_remove); | |||
621 | * that this function is *NOT* called under RCU protection or in contexts where | 686 | * that this function is *NOT* called under RCU protection or in contexts where |
622 | * mutex locking or synchronize_rcu() blocking calls cannot be used. | 687 | * mutex locking or synchronize_rcu() blocking calls cannot be used. |
623 | */ | 688 | */ |
624 | static int opp_set_availability(struct device *dev, unsigned long freq, | 689 | static int _opp_set_availability(struct device *dev, unsigned long freq, |
625 | bool availability_req) | 690 | bool availability_req) |
626 | { | 691 | { |
627 | struct device_opp *dev_opp; | 692 | struct device_opp *dev_opp; |
628 | struct dev_pm_opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV); | 693 | struct dev_pm_opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV); |
@@ -638,7 +703,7 @@ static int opp_set_availability(struct device *dev, unsigned long freq, | |||
638 | mutex_lock(&dev_opp_list_lock); | 703 | mutex_lock(&dev_opp_list_lock); |
639 | 704 | ||
640 | /* Find the device_opp */ | 705 | /* Find the device_opp */ |
641 | dev_opp = find_device_opp(dev); | 706 | dev_opp = _find_device_opp(dev); |
642 | if (IS_ERR(dev_opp)) { | 707 | if (IS_ERR(dev_opp)) { |
643 | r = PTR_ERR(dev_opp); | 708 | r = PTR_ERR(dev_opp); |
644 | dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r); | 709 | dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r); |
@@ -668,7 +733,7 @@ static int opp_set_availability(struct device *dev, unsigned long freq, | |||
668 | 733 | ||
669 | list_replace_rcu(&opp->node, &new_opp->node); | 734 | list_replace_rcu(&opp->node, &new_opp->node); |
670 | mutex_unlock(&dev_opp_list_lock); | 735 | mutex_unlock(&dev_opp_list_lock); |
671 | call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, kfree_opp_rcu); | 736 | call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, _kfree_opp_rcu); |
672 | 737 | ||
673 | /* Notify the change of the OPP availability */ | 738 | /* Notify the change of the OPP availability */ |
674 | if (availability_req) | 739 | if (availability_req) |
@@ -700,10 +765,14 @@ unlock: | |||
700 | * integrity of the internal data structures. Callers should ensure that | 765 | * integrity of the internal data structures. Callers should ensure that |
701 | * this function is *NOT* called under RCU protection or in contexts where | 766 | * this function is *NOT* called under RCU protection or in contexts where |
702 | * mutex locking or synchronize_rcu() blocking calls cannot be used. | 767 | * mutex locking or synchronize_rcu() blocking calls cannot be used. |
768 | * | ||
769 | * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the | ||
770 | * copy operation, returns 0 if no modifcation was done OR modification was | ||
771 | * successful. | ||
703 | */ | 772 | */ |
704 | int dev_pm_opp_enable(struct device *dev, unsigned long freq) | 773 | int dev_pm_opp_enable(struct device *dev, unsigned long freq) |
705 | { | 774 | { |
706 | return opp_set_availability(dev, freq, true); | 775 | return _opp_set_availability(dev, freq, true); |
707 | } | 776 | } |
708 | EXPORT_SYMBOL_GPL(dev_pm_opp_enable); | 777 | EXPORT_SYMBOL_GPL(dev_pm_opp_enable); |
709 | 778 | ||
@@ -722,26 +791,41 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_enable); | |||
722 | * integrity of the internal data structures. Callers should ensure that | 791 | * integrity of the internal data structures. Callers should ensure that |
723 | * this function is *NOT* called under RCU protection or in contexts where | 792 | * this function is *NOT* called under RCU protection or in contexts where |
724 | * mutex locking or synchronize_rcu() blocking calls cannot be used. | 793 | * mutex locking or synchronize_rcu() blocking calls cannot be used. |
794 | * | ||
795 | * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the | ||
796 | * copy operation, returns 0 if no modifcation was done OR modification was | ||
797 | * successful. | ||
725 | */ | 798 | */ |
726 | int dev_pm_opp_disable(struct device *dev, unsigned long freq) | 799 | int dev_pm_opp_disable(struct device *dev, unsigned long freq) |
727 | { | 800 | { |
728 | return opp_set_availability(dev, freq, false); | 801 | return _opp_set_availability(dev, freq, false); |
729 | } | 802 | } |
730 | EXPORT_SYMBOL_GPL(dev_pm_opp_disable); | 803 | EXPORT_SYMBOL_GPL(dev_pm_opp_disable); |
731 | 804 | ||
732 | /** | 805 | /** |
733 | * dev_pm_opp_get_notifier() - find notifier_head of the device with opp | 806 | * dev_pm_opp_get_notifier() - find notifier_head of the device with opp |
734 | * @dev: device pointer used to lookup device OPPs. | 807 | * @dev: device pointer used to lookup device OPPs. |
808 | * | ||
809 | * Return: pointer to notifier head if found, otherwise -ENODEV or | ||
810 | * -EINVAL based on type of error casted as pointer. value must be checked | ||
811 | * with IS_ERR to determine valid pointer or error result. | ||
812 | * | ||
813 | * Locking: This function must be called under rcu_read_lock(). dev_opp is a RCU | ||
814 | * protected pointer. The reason for the same is that the opp pointer which is | ||
815 | * returned will remain valid for use with opp_get_{voltage, freq} only while | ||
816 | * under the locked area. The pointer returned must be used prior to unlocking | ||
817 | * with rcu_read_unlock() to maintain the integrity of the pointer. | ||
735 | */ | 818 | */ |
736 | struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev) | 819 | struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev) |
737 | { | 820 | { |
738 | struct device_opp *dev_opp = find_device_opp(dev); | 821 | struct device_opp *dev_opp = _find_device_opp(dev); |
739 | 822 | ||
740 | if (IS_ERR(dev_opp)) | 823 | if (IS_ERR(dev_opp)) |
741 | return ERR_CAST(dev_opp); /* matching type */ | 824 | return ERR_CAST(dev_opp); /* matching type */ |
742 | 825 | ||
743 | return &dev_opp->srcu_head; | 826 | return &dev_opp->srcu_head; |
744 | } | 827 | } |
828 | EXPORT_SYMBOL_GPL(dev_pm_opp_get_notifier); | ||
745 | 829 | ||
746 | #ifdef CONFIG_OF | 830 | #ifdef CONFIG_OF |
747 | /** | 831 | /** |
@@ -749,6 +833,22 @@ struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev) | |||
749 | * @dev: device pointer used to lookup device OPPs. | 833 | * @dev: device pointer used to lookup device OPPs. |
750 | * | 834 | * |
751 | * Register the initial OPP table with the OPP library for given device. | 835 | * Register the initial OPP table with the OPP library for given device. |
836 | * | ||
837 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
838 | * Hence this function indirectly uses RCU updater strategy with mutex locks | ||
839 | * to keep the integrity of the internal data structures. Callers should ensure | ||
840 | * that this function is *NOT* called under RCU protection or in contexts where | ||
841 | * mutex cannot be locked. | ||
842 | * | ||
843 | * Return: | ||
844 | * 0 On success OR | ||
845 | * Duplicate OPPs (both freq and volt are same) and opp->available | ||
846 | * -EEXIST Freq are same and volt are different OR | ||
847 | * Duplicate OPPs (both freq and volt are same) and !opp->available | ||
848 | * -ENOMEM Memory allocation failure | ||
849 | * -ENODEV when 'operating-points' property is not found or is invalid data | ||
850 | * in device node. | ||
851 | * -ENODATA when empty 'operating-points' property is found | ||
752 | */ | 852 | */ |
753 | int of_init_opp_table(struct device *dev) | 853 | int of_init_opp_table(struct device *dev) |
754 | { | 854 | { |
@@ -777,7 +877,7 @@ int of_init_opp_table(struct device *dev) | |||
777 | unsigned long freq = be32_to_cpup(val++) * 1000; | 877 | unsigned long freq = be32_to_cpup(val++) * 1000; |
778 | unsigned long volt = be32_to_cpup(val++); | 878 | unsigned long volt = be32_to_cpup(val++); |
779 | 879 | ||
780 | if (dev_pm_opp_add_dynamic(dev, freq, volt, false)) | 880 | if (_opp_add_dynamic(dev, freq, volt, false)) |
781 | dev_warn(dev, "%s: Failed to add OPP %ld\n", | 881 | dev_warn(dev, "%s: Failed to add OPP %ld\n", |
782 | __func__, freq); | 882 | __func__, freq); |
783 | nr -= 2; | 883 | nr -= 2; |
@@ -792,6 +892,12 @@ EXPORT_SYMBOL_GPL(of_init_opp_table); | |||
792 | * @dev: device pointer used to lookup device OPPs. | 892 | * @dev: device pointer used to lookup device OPPs. |
793 | * | 893 | * |
794 | * Free OPPs created using static entries present in DT. | 894 | * Free OPPs created using static entries present in DT. |
895 | * | ||
896 | * Locking: The internal device_opp and opp structures are RCU protected. | ||
897 | * Hence this function indirectly uses RCU updater strategy with mutex locks | ||
898 | * to keep the integrity of the internal data structures. Callers should ensure | ||
899 | * that this function is *NOT* called under RCU protection or in contexts where | ||
900 | * mutex cannot be locked. | ||
795 | */ | 901 | */ |
796 | void of_free_opp_table(struct device *dev) | 902 | void of_free_opp_table(struct device *dev) |
797 | { | 903 | { |
@@ -799,7 +905,7 @@ void of_free_opp_table(struct device *dev) | |||
799 | struct dev_pm_opp *opp, *tmp; | 905 | struct dev_pm_opp *opp, *tmp; |
800 | 906 | ||
801 | /* Check for existing list for 'dev' */ | 907 | /* Check for existing list for 'dev' */ |
802 | dev_opp = find_device_opp(dev); | 908 | dev_opp = _find_device_opp(dev); |
803 | if (IS_ERR(dev_opp)) { | 909 | if (IS_ERR(dev_opp)) { |
804 | int error = PTR_ERR(dev_opp); | 910 | int error = PTR_ERR(dev_opp); |
805 | if (error != -ENODEV) | 911 | if (error != -ENODEV) |
@@ -816,7 +922,7 @@ void of_free_opp_table(struct device *dev) | |||
816 | /* Free static OPPs */ | 922 | /* Free static OPPs */ |
817 | list_for_each_entry_safe(opp, tmp, &dev_opp->opp_list, node) { | 923 | list_for_each_entry_safe(opp, tmp, &dev_opp->opp_list, node) { |
818 | if (!opp->dynamic) | 924 | if (!opp->dynamic) |
819 | __dev_pm_opp_remove(dev_opp, opp); | 925 | _opp_remove(dev_opp, opp); |
820 | } | 926 | } |
821 | 927 | ||
822 | mutex_unlock(&dev_opp_list_lock); | 928 | mutex_unlock(&dev_opp_list_lock); |
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index a8fe4c1a8d07..e56d538d039e 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c | |||
@@ -64,6 +64,8 @@ enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask) | |||
64 | struct pm_qos_flags *pqf; | 64 | struct pm_qos_flags *pqf; |
65 | s32 val; | 65 | s32 val; |
66 | 66 | ||
67 | lockdep_assert_held(&dev->power.lock); | ||
68 | |||
67 | if (IS_ERR_OR_NULL(qos)) | 69 | if (IS_ERR_OR_NULL(qos)) |
68 | return PM_QOS_FLAGS_UNDEFINED; | 70 | return PM_QOS_FLAGS_UNDEFINED; |
69 | 71 | ||
@@ -104,6 +106,8 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_flags); | |||
104 | */ | 106 | */ |
105 | s32 __dev_pm_qos_read_value(struct device *dev) | 107 | s32 __dev_pm_qos_read_value(struct device *dev) |
106 | { | 108 | { |
109 | lockdep_assert_held(&dev->power.lock); | ||
110 | |||
107 | return IS_ERR_OR_NULL(dev->power.qos) ? | 111 | return IS_ERR_OR_NULL(dev->power.qos) ? |
108 | 0 : pm_qos_read_value(&dev->power.qos->resume_latency); | 112 | 0 : pm_qos_read_value(&dev->power.qos->resume_latency); |
109 | } | 113 | } |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index d5d4cd82b9f7..5c0baa9ffc64 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -976,8 +976,8 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
976 | status = acpi_resource_to_address64(res, &addr); | 976 | status = acpi_resource_to_address64(res, &addr); |
977 | 977 | ||
978 | if (ACPI_SUCCESS(status)) { | 978 | if (ACPI_SUCCESS(status)) { |
979 | hdp->hd_phys_address = addr.minimum; | 979 | hdp->hd_phys_address = addr.address.minimum; |
980 | hdp->hd_address = ioremap(addr.minimum, addr.address_length); | 980 | hdp->hd_address = ioremap(addr.address.minimum, addr.address.address_length); |
981 | 981 | ||
982 | if (hpet_is_known(hdp)) { | 982 | if (hpet_is_known(hdp)) { |
983 | iounmap(hdp->hd_address); | 983 | iounmap(hdp->hd_address); |
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index 89ae88f91895..c59bdcb83217 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 | |||
@@ -57,6 +57,16 @@ config X86_ACPI_CPUFREQ_CPB | |||
57 | By enabling this option the acpi_cpufreq driver provides the old | 57 | By enabling this option the acpi_cpufreq driver provides the old |
58 | entry in addition to the new boost ones, for compatibility reasons. | 58 | entry in addition to the new boost ones, for compatibility reasons. |
59 | 59 | ||
60 | config X86_SFI_CPUFREQ | ||
61 | tristate "SFI Performance-States driver" | ||
62 | depends on X86_INTEL_MID && SFI | ||
63 | help | ||
64 | This adds a CPUFreq driver for some Silvermont based Intel Atom | ||
65 | architectures like Z34xx and Z35xx which enumerate processor | ||
66 | performance states through SFI. | ||
67 | |||
68 | If in doubt, say N. | ||
69 | |||
60 | config ELAN_CPUFREQ | 70 | config ELAN_CPUFREQ |
61 | tristate "AMD Elan SC400 and SC410" | 71 | tristate "AMD Elan SC400 and SC410" |
62 | depends on MELAN | 72 | depends on MELAN |
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index b3ca7b0b2c33..8b4220ac888b 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -41,6 +41,7 @@ obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o | |||
41 | obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o | 41 | obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o |
42 | obj-$(CONFIG_X86_INTEL_PSTATE) += intel_pstate.o | 42 | obj-$(CONFIG_X86_INTEL_PSTATE) += intel_pstate.o |
43 | obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o | 43 | obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o |
44 | obj-$(CONFIG_X86_SFI_CPUFREQ) += sfi-cpufreq.o | ||
44 | 45 | ||
45 | ################################################################################## | 46 | ################################################################################## |
46 | # ARM SoC drivers | 47 | # ARM SoC drivers |
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index fde97d6e31d6..bab67db54b7e 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c | |||
@@ -320,8 +320,7 @@ static int cpufreq_exit(struct cpufreq_policy *policy) | |||
320 | { | 320 | { |
321 | struct private_data *priv = policy->driver_data; | 321 | struct private_data *priv = policy->driver_data; |
322 | 322 | ||
323 | if (priv->cdev) | 323 | cpufreq_cooling_unregister(priv->cdev); |
324 | cpufreq_cooling_unregister(priv->cdev); | ||
325 | dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); | 324 | dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); |
326 | of_free_opp_table(priv->cpu_dev); | 325 | of_free_opp_table(priv->cpu_dev); |
327 | clk_put(policy->clk); | 326 | clk_put(policy->clk); |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 46bed4f81cde..28e59a48b35f 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -27,9 +27,21 @@ | |||
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/suspend.h> | 29 | #include <linux/suspend.h> |
30 | #include <linux/syscore_ops.h> | ||
30 | #include <linux/tick.h> | 31 | #include <linux/tick.h> |
31 | #include <trace/events/power.h> | 32 | #include <trace/events/power.h> |
32 | 33 | ||
34 | /* Macros to iterate over lists */ | ||
35 | /* Iterate over online CPUs policies */ | ||
36 | static LIST_HEAD(cpufreq_policy_list); | ||
37 | #define for_each_policy(__policy) \ | ||
38 | list_for_each_entry(__policy, &cpufreq_policy_list, policy_list) | ||
39 | |||
40 | /* Iterate over governors */ | ||
41 | static LIST_HEAD(cpufreq_governor_list); | ||
42 | #define for_each_governor(__governor) \ | ||
43 | list_for_each_entry(__governor, &cpufreq_governor_list, governor_list) | ||
44 | |||
33 | /** | 45 | /** |
34 | * The "cpufreq driver" - the arch- or hardware-dependent low | 46 | * The "cpufreq driver" - the arch- or hardware-dependent low |
35 | * level driver of CPUFreq support, and its spinlock. This lock | 47 | * level driver of CPUFreq support, and its spinlock. This lock |
@@ -40,7 +52,6 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); | |||
40 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); | 52 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); |
41 | static DEFINE_RWLOCK(cpufreq_driver_lock); | 53 | static DEFINE_RWLOCK(cpufreq_driver_lock); |
42 | DEFINE_MUTEX(cpufreq_governor_lock); | 54 | DEFINE_MUTEX(cpufreq_governor_lock); |
43 | static LIST_HEAD(cpufreq_policy_list); | ||
44 | 55 | ||
45 | /* This one keeps track of the previously set governor of a removed CPU */ | 56 | /* This one keeps track of the previously set governor of a removed CPU */ |
46 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); | 57 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); |
@@ -62,7 +73,7 @@ static DECLARE_RWSEM(cpufreq_rwsem); | |||
62 | /* internal prototypes */ | 73 | /* internal prototypes */ |
63 | static int __cpufreq_governor(struct cpufreq_policy *policy, | 74 | static int __cpufreq_governor(struct cpufreq_policy *policy, |
64 | unsigned int event); | 75 | unsigned int event); |
65 | static unsigned int __cpufreq_get(unsigned int cpu); | 76 | static unsigned int __cpufreq_get(struct cpufreq_policy *policy); |
66 | static void handle_update(struct work_struct *work); | 77 | static void handle_update(struct work_struct *work); |
67 | 78 | ||
68 | /** | 79 | /** |
@@ -93,7 +104,6 @@ void disable_cpufreq(void) | |||
93 | { | 104 | { |
94 | off = 1; | 105 | off = 1; |
95 | } | 106 | } |
96 | static LIST_HEAD(cpufreq_governor_list); | ||
97 | static DEFINE_MUTEX(cpufreq_governor_mutex); | 107 | static DEFINE_MUTEX(cpufreq_governor_mutex); |
98 | 108 | ||
99 | bool have_governor_per_policy(void) | 109 | bool have_governor_per_policy(void) |
@@ -202,7 +212,7 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | |||
202 | struct cpufreq_policy *policy = NULL; | 212 | struct cpufreq_policy *policy = NULL; |
203 | unsigned long flags; | 213 | unsigned long flags; |
204 | 214 | ||
205 | if (cpufreq_disabled() || (cpu >= nr_cpu_ids)) | 215 | if (cpu >= nr_cpu_ids) |
206 | return NULL; | 216 | return NULL; |
207 | 217 | ||
208 | if (!down_read_trylock(&cpufreq_rwsem)) | 218 | if (!down_read_trylock(&cpufreq_rwsem)) |
@@ -229,9 +239,6 @@ EXPORT_SYMBOL_GPL(cpufreq_cpu_get); | |||
229 | 239 | ||
230 | void cpufreq_cpu_put(struct cpufreq_policy *policy) | 240 | void cpufreq_cpu_put(struct cpufreq_policy *policy) |
231 | { | 241 | { |
232 | if (cpufreq_disabled()) | ||
233 | return; | ||
234 | |||
235 | kobject_put(&policy->kobj); | 242 | kobject_put(&policy->kobj); |
236 | up_read(&cpufreq_rwsem); | 243 | up_read(&cpufreq_rwsem); |
237 | } | 244 | } |
@@ -249,12 +256,12 @@ EXPORT_SYMBOL_GPL(cpufreq_cpu_put); | |||
249 | * systems as each CPU might be scaled differently. So, use the arch | 256 | * systems as each CPU might be scaled differently. So, use the arch |
250 | * per-CPU loops_per_jiffy value wherever possible. | 257 | * per-CPU loops_per_jiffy value wherever possible. |
251 | */ | 258 | */ |
252 | #ifndef CONFIG_SMP | ||
253 | static unsigned long l_p_j_ref; | ||
254 | static unsigned int l_p_j_ref_freq; | ||
255 | |||
256 | static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) | 259 | static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) |
257 | { | 260 | { |
261 | #ifndef CONFIG_SMP | ||
262 | static unsigned long l_p_j_ref; | ||
263 | static unsigned int l_p_j_ref_freq; | ||
264 | |||
258 | if (ci->flags & CPUFREQ_CONST_LOOPS) | 265 | if (ci->flags & CPUFREQ_CONST_LOOPS) |
259 | return; | 266 | return; |
260 | 267 | ||
@@ -270,13 +277,8 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) | |||
270 | pr_debug("scaling loops_per_jiffy to %lu for frequency %u kHz\n", | 277 | pr_debug("scaling loops_per_jiffy to %lu for frequency %u kHz\n", |
271 | loops_per_jiffy, ci->new); | 278 | loops_per_jiffy, ci->new); |
272 | } | 279 | } |
273 | } | ||
274 | #else | ||
275 | static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) | ||
276 | { | ||
277 | return; | ||
278 | } | ||
279 | #endif | 280 | #endif |
281 | } | ||
280 | 282 | ||
281 | static void __cpufreq_notify_transition(struct cpufreq_policy *policy, | 283 | static void __cpufreq_notify_transition(struct cpufreq_policy *policy, |
282 | struct cpufreq_freqs *freqs, unsigned int state) | 284 | struct cpufreq_freqs *freqs, unsigned int state) |
@@ -432,11 +434,11 @@ static ssize_t store_boost(struct kobject *kobj, struct attribute *attr, | |||
432 | } | 434 | } |
433 | define_one_global_rw(boost); | 435 | define_one_global_rw(boost); |
434 | 436 | ||
435 | static struct cpufreq_governor *__find_governor(const char *str_governor) | 437 | static struct cpufreq_governor *find_governor(const char *str_governor) |
436 | { | 438 | { |
437 | struct cpufreq_governor *t; | 439 | struct cpufreq_governor *t; |
438 | 440 | ||
439 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) | 441 | for_each_governor(t) |
440 | if (!strncasecmp(str_governor, t->name, CPUFREQ_NAME_LEN)) | 442 | if (!strncasecmp(str_governor, t->name, CPUFREQ_NAME_LEN)) |
441 | return t; | 443 | return t; |
442 | 444 | ||
@@ -463,12 +465,12 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, | |||
463 | *policy = CPUFREQ_POLICY_POWERSAVE; | 465 | *policy = CPUFREQ_POLICY_POWERSAVE; |
464 | err = 0; | 466 | err = 0; |
465 | } | 467 | } |
466 | } else if (has_target()) { | 468 | } else { |
467 | struct cpufreq_governor *t; | 469 | struct cpufreq_governor *t; |
468 | 470 | ||
469 | mutex_lock(&cpufreq_governor_mutex); | 471 | mutex_lock(&cpufreq_governor_mutex); |
470 | 472 | ||
471 | t = __find_governor(str_governor); | 473 | t = find_governor(str_governor); |
472 | 474 | ||
473 | if (t == NULL) { | 475 | if (t == NULL) { |
474 | int ret; | 476 | int ret; |
@@ -478,7 +480,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, | |||
478 | mutex_lock(&cpufreq_governor_mutex); | 480 | mutex_lock(&cpufreq_governor_mutex); |
479 | 481 | ||
480 | if (ret == 0) | 482 | if (ret == 0) |
481 | t = __find_governor(str_governor); | 483 | t = find_governor(str_governor); |
482 | } | 484 | } |
483 | 485 | ||
484 | if (t != NULL) { | 486 | if (t != NULL) { |
@@ -513,8 +515,7 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency); | |||
513 | show_one(scaling_min_freq, min); | 515 | show_one(scaling_min_freq, min); |
514 | show_one(scaling_max_freq, max); | 516 | show_one(scaling_max_freq, max); |
515 | 517 | ||
516 | static ssize_t show_scaling_cur_freq( | 518 | static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf) |
517 | struct cpufreq_policy *policy, char *buf) | ||
518 | { | 519 | { |
519 | ssize_t ret; | 520 | ssize_t ret; |
520 | 521 | ||
@@ -563,7 +564,7 @@ store_one(scaling_max_freq, max); | |||
563 | static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, | 564 | static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, |
564 | char *buf) | 565 | char *buf) |
565 | { | 566 | { |
566 | unsigned int cur_freq = __cpufreq_get(policy->cpu); | 567 | unsigned int cur_freq = __cpufreq_get(policy); |
567 | if (!cur_freq) | 568 | if (!cur_freq) |
568 | return sprintf(buf, "<unknown>"); | 569 | return sprintf(buf, "<unknown>"); |
569 | return sprintf(buf, "%u\n", cur_freq); | 570 | return sprintf(buf, "%u\n", cur_freq); |
@@ -639,7 +640,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, | |||
639 | goto out; | 640 | goto out; |
640 | } | 641 | } |
641 | 642 | ||
642 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) { | 643 | for_each_governor(t) { |
643 | if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) | 644 | if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) |
644 | - (CPUFREQ_NAME_LEN + 2))) | 645 | - (CPUFREQ_NAME_LEN + 2))) |
645 | goto out; | 646 | goto out; |
@@ -902,7 +903,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, | |||
902 | 903 | ||
903 | /* set up files for this cpu device */ | 904 | /* set up files for this cpu device */ |
904 | drv_attr = cpufreq_driver->attr; | 905 | drv_attr = cpufreq_driver->attr; |
905 | while ((drv_attr) && (*drv_attr)) { | 906 | while (drv_attr && *drv_attr) { |
906 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); | 907 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); |
907 | if (ret) | 908 | if (ret) |
908 | return ret; | 909 | return ret; |
@@ -936,7 +937,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) | |||
936 | memcpy(&new_policy, policy, sizeof(*policy)); | 937 | memcpy(&new_policy, policy, sizeof(*policy)); |
937 | 938 | ||
938 | /* Update governor of new_policy to the governor used before hotplug */ | 939 | /* Update governor of new_policy to the governor used before hotplug */ |
939 | gov = __find_governor(per_cpu(cpufreq_cpu_governor, policy->cpu)); | 940 | gov = find_governor(per_cpu(cpufreq_cpu_governor, policy->cpu)); |
940 | if (gov) | 941 | if (gov) |
941 | pr_debug("Restoring governor %s for cpu %d\n", | 942 | pr_debug("Restoring governor %s for cpu %d\n", |
942 | policy->governor->name, policy->cpu); | 943 | policy->governor->name, policy->cpu); |
@@ -958,7 +959,6 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) | |||
958 | } | 959 | } |
959 | } | 960 | } |
960 | 961 | ||
961 | #ifdef CONFIG_HOTPLUG_CPU | ||
962 | static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, | 962 | static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, |
963 | unsigned int cpu, struct device *dev) | 963 | unsigned int cpu, struct device *dev) |
964 | { | 964 | { |
@@ -996,7 +996,6 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, | |||
996 | 996 | ||
997 | return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); | 997 | return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); |
998 | } | 998 | } |
999 | #endif | ||
1000 | 999 | ||
1001 | static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu) | 1000 | static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu) |
1002 | { | 1001 | { |
@@ -1033,6 +1032,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void) | |||
1033 | init_rwsem(&policy->rwsem); | 1032 | init_rwsem(&policy->rwsem); |
1034 | spin_lock_init(&policy->transition_lock); | 1033 | spin_lock_init(&policy->transition_lock); |
1035 | init_waitqueue_head(&policy->transition_wait); | 1034 | init_waitqueue_head(&policy->transition_wait); |
1035 | init_completion(&policy->kobj_unregister); | ||
1036 | INIT_WORK(&policy->update, handle_update); | ||
1036 | 1037 | ||
1037 | return policy; | 1038 | return policy; |
1038 | 1039 | ||
@@ -1091,15 +1092,9 @@ static int update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu, | |||
1091 | } | 1092 | } |
1092 | 1093 | ||
1093 | down_write(&policy->rwsem); | 1094 | down_write(&policy->rwsem); |
1094 | |||
1095 | policy->last_cpu = policy->cpu; | ||
1096 | policy->cpu = cpu; | 1095 | policy->cpu = cpu; |
1097 | |||
1098 | up_write(&policy->rwsem); | 1096 | up_write(&policy->rwsem); |
1099 | 1097 | ||
1100 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | ||
1101 | CPUFREQ_UPDATE_POLICY_CPU, policy); | ||
1102 | |||
1103 | return 0; | 1098 | return 0; |
1104 | } | 1099 | } |
1105 | 1100 | ||
@@ -1110,41 +1105,32 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1110 | struct cpufreq_policy *policy; | 1105 | struct cpufreq_policy *policy; |
1111 | unsigned long flags; | 1106 | unsigned long flags; |
1112 | bool recover_policy = cpufreq_suspended; | 1107 | bool recover_policy = cpufreq_suspended; |
1113 | #ifdef CONFIG_HOTPLUG_CPU | ||
1114 | struct cpufreq_policy *tpolicy; | ||
1115 | #endif | ||
1116 | 1108 | ||
1117 | if (cpu_is_offline(cpu)) | 1109 | if (cpu_is_offline(cpu)) |
1118 | return 0; | 1110 | return 0; |
1119 | 1111 | ||
1120 | pr_debug("adding CPU %u\n", cpu); | 1112 | pr_debug("adding CPU %u\n", cpu); |
1121 | 1113 | ||
1122 | #ifdef CONFIG_SMP | ||
1123 | /* check whether a different CPU already registered this | 1114 | /* check whether a different CPU already registered this |
1124 | * CPU because it is in the same boat. */ | 1115 | * CPU because it is in the same boat. */ |
1125 | policy = cpufreq_cpu_get(cpu); | 1116 | policy = cpufreq_cpu_get_raw(cpu); |
1126 | if (unlikely(policy)) { | 1117 | if (unlikely(policy)) |
1127 | cpufreq_cpu_put(policy); | ||
1128 | return 0; | 1118 | return 0; |
1129 | } | ||
1130 | #endif | ||
1131 | 1119 | ||
1132 | if (!down_read_trylock(&cpufreq_rwsem)) | 1120 | if (!down_read_trylock(&cpufreq_rwsem)) |
1133 | return 0; | 1121 | return 0; |
1134 | 1122 | ||
1135 | #ifdef CONFIG_HOTPLUG_CPU | ||
1136 | /* Check if this cpu was hot-unplugged earlier and has siblings */ | 1123 | /* Check if this cpu was hot-unplugged earlier and has siblings */ |
1137 | read_lock_irqsave(&cpufreq_driver_lock, flags); | 1124 | read_lock_irqsave(&cpufreq_driver_lock, flags); |
1138 | list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) { | 1125 | for_each_policy(policy) { |
1139 | if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { | 1126 | if (cpumask_test_cpu(cpu, policy->related_cpus)) { |
1140 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1127 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1141 | ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev); | 1128 | ret = cpufreq_add_policy_cpu(policy, cpu, dev); |
1142 | up_read(&cpufreq_rwsem); | 1129 | up_read(&cpufreq_rwsem); |
1143 | return ret; | 1130 | return ret; |
1144 | } | 1131 | } |
1145 | } | 1132 | } |
1146 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1133 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1147 | #endif | ||
1148 | 1134 | ||
1149 | /* | 1135 | /* |
1150 | * Restore the saved policy when doing light-weight init and fall back | 1136 | * Restore the saved policy when doing light-weight init and fall back |
@@ -1171,9 +1157,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1171 | 1157 | ||
1172 | cpumask_copy(policy->cpus, cpumask_of(cpu)); | 1158 | cpumask_copy(policy->cpus, cpumask_of(cpu)); |
1173 | 1159 | ||
1174 | init_completion(&policy->kobj_unregister); | ||
1175 | INIT_WORK(&policy->update, handle_update); | ||
1176 | |||
1177 | /* call driver. From then on the cpufreq must be able | 1160 | /* call driver. From then on the cpufreq must be able |
1178 | * to accept all calls to ->verify and ->setpolicy for this CPU | 1161 | * to accept all calls to ->verify and ->setpolicy for this CPU |
1179 | */ | 1162 | */ |
@@ -1371,11 +1354,10 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, | |||
1371 | pr_err("%s: Failed to stop governor\n", __func__); | 1354 | pr_err("%s: Failed to stop governor\n", __func__); |
1372 | return ret; | 1355 | return ret; |
1373 | } | 1356 | } |
1374 | } | ||
1375 | 1357 | ||
1376 | if (!cpufreq_driver->setpolicy) | ||
1377 | strncpy(per_cpu(cpufreq_cpu_governor, cpu), | 1358 | strncpy(per_cpu(cpufreq_cpu_governor, cpu), |
1378 | policy->governor->name, CPUFREQ_NAME_LEN); | 1359 | policy->governor->name, CPUFREQ_NAME_LEN); |
1360 | } | ||
1379 | 1361 | ||
1380 | down_read(&policy->rwsem); | 1362 | down_read(&policy->rwsem); |
1381 | cpus = cpumask_weight(policy->cpus); | 1363 | cpus = cpumask_weight(policy->cpus); |
@@ -1416,9 +1398,10 @@ static int __cpufreq_remove_dev_finish(struct device *dev, | |||
1416 | unsigned long flags; | 1398 | unsigned long flags; |
1417 | struct cpufreq_policy *policy; | 1399 | struct cpufreq_policy *policy; |
1418 | 1400 | ||
1419 | read_lock_irqsave(&cpufreq_driver_lock, flags); | 1401 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1420 | policy = per_cpu(cpufreq_cpu_data, cpu); | 1402 | policy = per_cpu(cpufreq_cpu_data, cpu); |
1421 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1403 | per_cpu(cpufreq_cpu_data, cpu) = NULL; |
1404 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1422 | 1405 | ||
1423 | if (!policy) { | 1406 | if (!policy) { |
1424 | pr_debug("%s: No cpu_data found\n", __func__); | 1407 | pr_debug("%s: No cpu_data found\n", __func__); |
@@ -1473,7 +1456,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev, | |||
1473 | } | 1456 | } |
1474 | } | 1457 | } |
1475 | 1458 | ||
1476 | per_cpu(cpufreq_cpu_data, cpu) = NULL; | ||
1477 | return 0; | 1459 | return 0; |
1478 | } | 1460 | } |
1479 | 1461 | ||
@@ -1510,30 +1492,23 @@ static void handle_update(struct work_struct *work) | |||
1510 | /** | 1492 | /** |
1511 | * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're | 1493 | * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're |
1512 | * in deep trouble. | 1494 | * in deep trouble. |
1513 | * @cpu: cpu number | 1495 | * @policy: policy managing CPUs |
1514 | * @old_freq: CPU frequency the kernel thinks the CPU runs at | ||
1515 | * @new_freq: CPU frequency the CPU actually runs at | 1496 | * @new_freq: CPU frequency the CPU actually runs at |
1516 | * | 1497 | * |
1517 | * We adjust to current frequency first, and need to clean up later. | 1498 | * We adjust to current frequency first, and need to clean up later. |
1518 | * So either call to cpufreq_update_policy() or schedule handle_update()). | 1499 | * So either call to cpufreq_update_policy() or schedule handle_update()). |
1519 | */ | 1500 | */ |
1520 | static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, | 1501 | static void cpufreq_out_of_sync(struct cpufreq_policy *policy, |
1521 | unsigned int new_freq) | 1502 | unsigned int new_freq) |
1522 | { | 1503 | { |
1523 | struct cpufreq_policy *policy; | ||
1524 | struct cpufreq_freqs freqs; | 1504 | struct cpufreq_freqs freqs; |
1525 | unsigned long flags; | ||
1526 | 1505 | ||
1527 | pr_debug("Warning: CPU frequency out of sync: cpufreq and timing core thinks of %u, is %u kHz\n", | 1506 | pr_debug("Warning: CPU frequency out of sync: cpufreq and timing core thinks of %u, is %u kHz\n", |
1528 | old_freq, new_freq); | 1507 | policy->cur, new_freq); |
1529 | 1508 | ||
1530 | freqs.old = old_freq; | 1509 | freqs.old = policy->cur; |
1531 | freqs.new = new_freq; | 1510 | freqs.new = new_freq; |
1532 | 1511 | ||
1533 | read_lock_irqsave(&cpufreq_driver_lock, flags); | ||
1534 | policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1535 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1536 | |||
1537 | cpufreq_freq_transition_begin(policy, &freqs); | 1512 | cpufreq_freq_transition_begin(policy, &freqs); |
1538 | cpufreq_freq_transition_end(policy, &freqs, 0); | 1513 | cpufreq_freq_transition_end(policy, &freqs, 0); |
1539 | } | 1514 | } |
@@ -1583,22 +1558,21 @@ unsigned int cpufreq_quick_get_max(unsigned int cpu) | |||
1583 | } | 1558 | } |
1584 | EXPORT_SYMBOL(cpufreq_quick_get_max); | 1559 | EXPORT_SYMBOL(cpufreq_quick_get_max); |
1585 | 1560 | ||
1586 | static unsigned int __cpufreq_get(unsigned int cpu) | 1561 | static unsigned int __cpufreq_get(struct cpufreq_policy *policy) |
1587 | { | 1562 | { |
1588 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1589 | unsigned int ret_freq = 0; | 1563 | unsigned int ret_freq = 0; |
1590 | 1564 | ||
1591 | if (!cpufreq_driver->get) | 1565 | if (!cpufreq_driver->get) |
1592 | return ret_freq; | 1566 | return ret_freq; |
1593 | 1567 | ||
1594 | ret_freq = cpufreq_driver->get(cpu); | 1568 | ret_freq = cpufreq_driver->get(policy->cpu); |
1595 | 1569 | ||
1596 | if (ret_freq && policy->cur && | 1570 | if (ret_freq && policy->cur && |
1597 | !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { | 1571 | !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { |
1598 | /* verify no discrepancy between actual and | 1572 | /* verify no discrepancy between actual and |
1599 | saved value exists */ | 1573 | saved value exists */ |
1600 | if (unlikely(ret_freq != policy->cur)) { | 1574 | if (unlikely(ret_freq != policy->cur)) { |
1601 | cpufreq_out_of_sync(cpu, policy->cur, ret_freq); | 1575 | cpufreq_out_of_sync(policy, ret_freq); |
1602 | schedule_work(&policy->update); | 1576 | schedule_work(&policy->update); |
1603 | } | 1577 | } |
1604 | } | 1578 | } |
@@ -1619,7 +1593,7 @@ unsigned int cpufreq_get(unsigned int cpu) | |||
1619 | 1593 | ||
1620 | if (policy) { | 1594 | if (policy) { |
1621 | down_read(&policy->rwsem); | 1595 | down_read(&policy->rwsem); |
1622 | ret_freq = __cpufreq_get(cpu); | 1596 | ret_freq = __cpufreq_get(policy); |
1623 | up_read(&policy->rwsem); | 1597 | up_read(&policy->rwsem); |
1624 | 1598 | ||
1625 | cpufreq_cpu_put(policy); | 1599 | cpufreq_cpu_put(policy); |
@@ -1682,7 +1656,7 @@ void cpufreq_suspend(void) | |||
1682 | 1656 | ||
1683 | pr_debug("%s: Suspending Governors\n", __func__); | 1657 | pr_debug("%s: Suspending Governors\n", __func__); |
1684 | 1658 | ||
1685 | list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { | 1659 | for_each_policy(policy) { |
1686 | if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) | 1660 | if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) |
1687 | pr_err("%s: Failed to stop governor for policy: %p\n", | 1661 | pr_err("%s: Failed to stop governor for policy: %p\n", |
1688 | __func__, policy); | 1662 | __func__, policy); |
@@ -1716,7 +1690,7 @@ void cpufreq_resume(void) | |||
1716 | 1690 | ||
1717 | pr_debug("%s: Resuming Governors\n", __func__); | 1691 | pr_debug("%s: Resuming Governors\n", __func__); |
1718 | 1692 | ||
1719 | list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { | 1693 | for_each_policy(policy) { |
1720 | if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) | 1694 | if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) |
1721 | pr_err("%s: Failed to resume driver: %p\n", __func__, | 1695 | pr_err("%s: Failed to resume driver: %p\n", __func__, |
1722 | policy); | 1696 | policy); |
@@ -2006,10 +1980,6 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, | |||
2006 | } | 1980 | } |
2007 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); | 1981 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); |
2008 | 1982 | ||
2009 | /* | ||
2010 | * when "event" is CPUFREQ_GOV_LIMITS | ||
2011 | */ | ||
2012 | |||
2013 | static int __cpufreq_governor(struct cpufreq_policy *policy, | 1983 | static int __cpufreq_governor(struct cpufreq_policy *policy, |
2014 | unsigned int event) | 1984 | unsigned int event) |
2015 | { | 1985 | { |
@@ -2107,7 +2077,7 @@ int cpufreq_register_governor(struct cpufreq_governor *governor) | |||
2107 | 2077 | ||
2108 | governor->initialized = 0; | 2078 | governor->initialized = 0; |
2109 | err = -EBUSY; | 2079 | err = -EBUSY; |
2110 | if (__find_governor(governor->name) == NULL) { | 2080 | if (!find_governor(governor->name)) { |
2111 | err = 0; | 2081 | err = 0; |
2112 | list_add(&governor->governor_list, &cpufreq_governor_list); | 2082 | list_add(&governor->governor_list, &cpufreq_governor_list); |
2113 | } | 2083 | } |
@@ -2307,8 +2277,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
2307 | policy->cur = new_policy.cur; | 2277 | policy->cur = new_policy.cur; |
2308 | } else { | 2278 | } else { |
2309 | if (policy->cur != new_policy.cur && has_target()) | 2279 | if (policy->cur != new_policy.cur && has_target()) |
2310 | cpufreq_out_of_sync(cpu, policy->cur, | 2280 | cpufreq_out_of_sync(policy, new_policy.cur); |
2311 | new_policy.cur); | ||
2312 | } | 2281 | } |
2313 | } | 2282 | } |
2314 | 2283 | ||
@@ -2364,7 +2333,7 @@ static int cpufreq_boost_set_sw(int state) | |||
2364 | struct cpufreq_policy *policy; | 2333 | struct cpufreq_policy *policy; |
2365 | int ret = -EINVAL; | 2334 | int ret = -EINVAL; |
2366 | 2335 | ||
2367 | list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { | 2336 | for_each_policy(policy) { |
2368 | freq_table = cpufreq_frequency_get_table(policy->cpu); | 2337 | freq_table = cpufreq_frequency_get_table(policy->cpu); |
2369 | if (freq_table) { | 2338 | if (freq_table) { |
2370 | ret = cpufreq_frequency_table_cpuinfo(policy, | 2339 | ret = cpufreq_frequency_table_cpuinfo(policy, |
@@ -2454,9 +2423,6 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2454 | 2423 | ||
2455 | pr_debug("trying to register driver %s\n", driver_data->name); | 2424 | pr_debug("trying to register driver %s\n", driver_data->name); |
2456 | 2425 | ||
2457 | if (driver_data->setpolicy) | ||
2458 | driver_data->flags |= CPUFREQ_CONST_LOOPS; | ||
2459 | |||
2460 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 2426 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
2461 | if (cpufreq_driver) { | 2427 | if (cpufreq_driver) { |
2462 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2428 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
@@ -2465,6 +2431,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2465 | cpufreq_driver = driver_data; | 2431 | cpufreq_driver = driver_data; |
2466 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2432 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
2467 | 2433 | ||
2434 | if (driver_data->setpolicy) | ||
2435 | driver_data->flags |= CPUFREQ_CONST_LOOPS; | ||
2436 | |||
2468 | if (cpufreq_boost_supported()) { | 2437 | if (cpufreq_boost_supported()) { |
2469 | /* | 2438 | /* |
2470 | * Check if driver provides function to enable boost - | 2439 | * Check if driver provides function to enable boost - |
@@ -2485,23 +2454,12 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2485 | if (ret) | 2454 | if (ret) |
2486 | goto err_boost_unreg; | 2455 | goto err_boost_unreg; |
2487 | 2456 | ||
2488 | if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { | 2457 | if (!(cpufreq_driver->flags & CPUFREQ_STICKY) && |
2489 | int i; | 2458 | list_empty(&cpufreq_policy_list)) { |
2490 | ret = -ENODEV; | ||
2491 | |||
2492 | /* check for at least one working CPU */ | ||
2493 | for (i = 0; i < nr_cpu_ids; i++) | ||
2494 | if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) { | ||
2495 | ret = 0; | ||
2496 | break; | ||
2497 | } | ||
2498 | |||
2499 | /* if all ->init() calls failed, unregister */ | 2459 | /* if all ->init() calls failed, unregister */ |
2500 | if (ret) { | 2460 | pr_debug("%s: No CPU initialized for driver %s\n", __func__, |
2501 | pr_debug("no CPU initialized for driver %s\n", | 2461 | driver_data->name); |
2502 | driver_data->name); | 2462 | goto err_if_unreg; |
2503 | goto err_if_unreg; | ||
2504 | } | ||
2505 | } | 2463 | } |
2506 | 2464 | ||
2507 | register_hotcpu_notifier(&cpufreq_cpu_notifier); | 2465 | register_hotcpu_notifier(&cpufreq_cpu_notifier); |
@@ -2556,6 +2514,14 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) | |||
2556 | } | 2514 | } |
2557 | EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); | 2515 | EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); |
2558 | 2516 | ||
2517 | /* | ||
2518 | * Stop cpufreq at shutdown to make sure it isn't holding any locks | ||
2519 | * or mutexes when secondary CPUs are halted. | ||
2520 | */ | ||
2521 | static struct syscore_ops cpufreq_syscore_ops = { | ||
2522 | .shutdown = cpufreq_suspend, | ||
2523 | }; | ||
2524 | |||
2559 | static int __init cpufreq_core_init(void) | 2525 | static int __init cpufreq_core_init(void) |
2560 | { | 2526 | { |
2561 | if (cpufreq_disabled()) | 2527 | if (cpufreq_disabled()) |
@@ -2564,6 +2530,8 @@ static int __init cpufreq_core_init(void) | |||
2564 | cpufreq_global_kobject = kobject_create(); | 2530 | cpufreq_global_kobject = kobject_create(); |
2565 | BUG_ON(!cpufreq_global_kobject); | 2531 | BUG_ON(!cpufreq_global_kobject); |
2566 | 2532 | ||
2533 | register_syscore_ops(&cpufreq_syscore_ops); | ||
2534 | |||
2567 | return 0; | 2535 | return 0; |
2568 | } | 2536 | } |
2569 | core_initcall(cpufreq_core_init); | 2537 | core_initcall(cpufreq_core_init); |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 0cd9b4dcef99..5e370a30a964 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -18,7 +18,6 @@ | |||
18 | static spinlock_t cpufreq_stats_lock; | 18 | static spinlock_t cpufreq_stats_lock; |
19 | 19 | ||
20 | struct cpufreq_stats { | 20 | struct cpufreq_stats { |
21 | unsigned int cpu; | ||
22 | unsigned int total_trans; | 21 | unsigned int total_trans; |
23 | unsigned long long last_time; | 22 | unsigned long long last_time; |
24 | unsigned int max_state; | 23 | unsigned int max_state; |
@@ -31,50 +30,33 @@ struct cpufreq_stats { | |||
31 | #endif | 30 | #endif |
32 | }; | 31 | }; |
33 | 32 | ||
34 | static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table); | 33 | static int cpufreq_stats_update(struct cpufreq_stats *stats) |
35 | |||
36 | struct cpufreq_stats_attribute { | ||
37 | struct attribute attr; | ||
38 | ssize_t(*show) (struct cpufreq_stats *, char *); | ||
39 | }; | ||
40 | |||
41 | static int cpufreq_stats_update(unsigned int cpu) | ||
42 | { | 34 | { |
43 | struct cpufreq_stats *stat; | 35 | unsigned long long cur_time = get_jiffies_64(); |
44 | unsigned long long cur_time; | ||
45 | 36 | ||
46 | cur_time = get_jiffies_64(); | ||
47 | spin_lock(&cpufreq_stats_lock); | 37 | spin_lock(&cpufreq_stats_lock); |
48 | stat = per_cpu(cpufreq_stats_table, cpu); | 38 | stats->time_in_state[stats->last_index] += cur_time - stats->last_time; |
49 | if (stat->time_in_state) | 39 | stats->last_time = cur_time; |
50 | stat->time_in_state[stat->last_index] += | ||
51 | cur_time - stat->last_time; | ||
52 | stat->last_time = cur_time; | ||
53 | spin_unlock(&cpufreq_stats_lock); | 40 | spin_unlock(&cpufreq_stats_lock); |
54 | return 0; | 41 | return 0; |
55 | } | 42 | } |
56 | 43 | ||
57 | static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) | 44 | static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) |
58 | { | 45 | { |
59 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | 46 | return sprintf(buf, "%d\n", policy->stats->total_trans); |
60 | if (!stat) | ||
61 | return 0; | ||
62 | return sprintf(buf, "%d\n", | ||
63 | per_cpu(cpufreq_stats_table, stat->cpu)->total_trans); | ||
64 | } | 47 | } |
65 | 48 | ||
66 | static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) | 49 | static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) |
67 | { | 50 | { |
51 | struct cpufreq_stats *stats = policy->stats; | ||
68 | ssize_t len = 0; | 52 | ssize_t len = 0; |
69 | int i; | 53 | int i; |
70 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | 54 | |
71 | if (!stat) | 55 | cpufreq_stats_update(stats); |
72 | return 0; | 56 | for (i = 0; i < stats->state_num; i++) { |
73 | cpufreq_stats_update(stat->cpu); | 57 | len += sprintf(buf + len, "%u %llu\n", stats->freq_table[i], |
74 | for (i = 0; i < stat->state_num; i++) { | ||
75 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], | ||
76 | (unsigned long long) | 58 | (unsigned long long) |
77 | jiffies_64_to_clock_t(stat->time_in_state[i])); | 59 | jiffies_64_to_clock_t(stats->time_in_state[i])); |
78 | } | 60 | } |
79 | return len; | 61 | return len; |
80 | } | 62 | } |
@@ -82,38 +64,35 @@ static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) | |||
82 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 64 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
83 | static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) | 65 | static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) |
84 | { | 66 | { |
67 | struct cpufreq_stats *stats = policy->stats; | ||
85 | ssize_t len = 0; | 68 | ssize_t len = 0; |
86 | int i, j; | 69 | int i, j; |
87 | 70 | ||
88 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | ||
89 | if (!stat) | ||
90 | return 0; | ||
91 | cpufreq_stats_update(stat->cpu); | ||
92 | len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); | 71 | len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); |
93 | len += snprintf(buf + len, PAGE_SIZE - len, " : "); | 72 | len += snprintf(buf + len, PAGE_SIZE - len, " : "); |
94 | for (i = 0; i < stat->state_num; i++) { | 73 | for (i = 0; i < stats->state_num; i++) { |
95 | if (len >= PAGE_SIZE) | 74 | if (len >= PAGE_SIZE) |
96 | break; | 75 | break; |
97 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", | 76 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", |
98 | stat->freq_table[i]); | 77 | stats->freq_table[i]); |
99 | } | 78 | } |
100 | if (len >= PAGE_SIZE) | 79 | if (len >= PAGE_SIZE) |
101 | return PAGE_SIZE; | 80 | return PAGE_SIZE; |
102 | 81 | ||
103 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | 82 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); |
104 | 83 | ||
105 | for (i = 0; i < stat->state_num; i++) { | 84 | for (i = 0; i < stats->state_num; i++) { |
106 | if (len >= PAGE_SIZE) | 85 | if (len >= PAGE_SIZE) |
107 | break; | 86 | break; |
108 | 87 | ||
109 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ", | 88 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ", |
110 | stat->freq_table[i]); | 89 | stats->freq_table[i]); |
111 | 90 | ||
112 | for (j = 0; j < stat->state_num; j++) { | 91 | for (j = 0; j < stats->state_num; j++) { |
113 | if (len >= PAGE_SIZE) | 92 | if (len >= PAGE_SIZE) |
114 | break; | 93 | break; |
115 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", | 94 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", |
116 | stat->trans_table[i*stat->max_state+j]); | 95 | stats->trans_table[i*stats->max_state+j]); |
117 | } | 96 | } |
118 | if (len >= PAGE_SIZE) | 97 | if (len >= PAGE_SIZE) |
119 | break; | 98 | break; |
@@ -142,28 +121,29 @@ static struct attribute_group stats_attr_group = { | |||
142 | .name = "stats" | 121 | .name = "stats" |
143 | }; | 122 | }; |
144 | 123 | ||
145 | static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) | 124 | static int freq_table_get_index(struct cpufreq_stats *stats, unsigned int freq) |
146 | { | 125 | { |
147 | int index; | 126 | int index; |
148 | for (index = 0; index < stat->max_state; index++) | 127 | for (index = 0; index < stats->max_state; index++) |
149 | if (stat->freq_table[index] == freq) | 128 | if (stats->freq_table[index] == freq) |
150 | return index; | 129 | return index; |
151 | return -1; | 130 | return -1; |
152 | } | 131 | } |
153 | 132 | ||
154 | static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) | 133 | static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) |
155 | { | 134 | { |
156 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | 135 | struct cpufreq_stats *stats = policy->stats; |
157 | 136 | ||
158 | if (!stat) | 137 | /* Already freed */ |
138 | if (!stats) | ||
159 | return; | 139 | return; |
160 | 140 | ||
161 | pr_debug("%s: Free stat table\n", __func__); | 141 | pr_debug("%s: Free stats table\n", __func__); |
162 | 142 | ||
163 | sysfs_remove_group(&policy->kobj, &stats_attr_group); | 143 | sysfs_remove_group(&policy->kobj, &stats_attr_group); |
164 | kfree(stat->time_in_state); | 144 | kfree(stats->time_in_state); |
165 | kfree(stat); | 145 | kfree(stats); |
166 | per_cpu(cpufreq_stats_table, policy->cpu) = NULL; | 146 | policy->stats = NULL; |
167 | } | 147 | } |
168 | 148 | ||
169 | static void cpufreq_stats_free_table(unsigned int cpu) | 149 | static void cpufreq_stats_free_table(unsigned int cpu) |
@@ -174,37 +154,33 @@ static void cpufreq_stats_free_table(unsigned int cpu) | |||
174 | if (!policy) | 154 | if (!policy) |
175 | return; | 155 | return; |
176 | 156 | ||
177 | if (cpufreq_frequency_get_table(policy->cpu)) | 157 | __cpufreq_stats_free_table(policy); |
178 | __cpufreq_stats_free_table(policy); | ||
179 | 158 | ||
180 | cpufreq_cpu_put(policy); | 159 | cpufreq_cpu_put(policy); |
181 | } | 160 | } |
182 | 161 | ||
183 | static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) | 162 | static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) |
184 | { | 163 | { |
185 | unsigned int i, count = 0, ret = 0; | 164 | unsigned int i = 0, count = 0, ret = -ENOMEM; |
186 | struct cpufreq_stats *stat; | 165 | struct cpufreq_stats *stats; |
187 | unsigned int alloc_size; | 166 | unsigned int alloc_size; |
188 | unsigned int cpu = policy->cpu; | 167 | unsigned int cpu = policy->cpu; |
189 | struct cpufreq_frequency_table *pos, *table; | 168 | struct cpufreq_frequency_table *pos, *table; |
190 | 169 | ||
170 | /* We need cpufreq table for creating stats table */ | ||
191 | table = cpufreq_frequency_get_table(cpu); | 171 | table = cpufreq_frequency_get_table(cpu); |
192 | if (unlikely(!table)) | 172 | if (unlikely(!table)) |
193 | return 0; | 173 | return 0; |
194 | 174 | ||
195 | if (per_cpu(cpufreq_stats_table, cpu)) | 175 | /* stats already initialized */ |
196 | return -EBUSY; | 176 | if (policy->stats) |
197 | stat = kzalloc(sizeof(*stat), GFP_KERNEL); | 177 | return -EEXIST; |
198 | if ((stat) == NULL) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | ret = sysfs_create_group(&policy->kobj, &stats_attr_group); | ||
202 | if (ret) | ||
203 | goto error_out; | ||
204 | 178 | ||
205 | stat->cpu = cpu; | 179 | stats = kzalloc(sizeof(*stats), GFP_KERNEL); |
206 | per_cpu(cpufreq_stats_table, cpu) = stat; | 180 | if (!stats) |
181 | return -ENOMEM; | ||
207 | 182 | ||
183 | /* Find total allocation size */ | ||
208 | cpufreq_for_each_valid_entry(pos, table) | 184 | cpufreq_for_each_valid_entry(pos, table) |
209 | count++; | 185 | count++; |
210 | 186 | ||
@@ -213,32 +189,40 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) | |||
213 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 189 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
214 | alloc_size += count * count * sizeof(int); | 190 | alloc_size += count * count * sizeof(int); |
215 | #endif | 191 | #endif |
216 | stat->max_state = count; | 192 | |
217 | stat->time_in_state = kzalloc(alloc_size, GFP_KERNEL); | 193 | /* Allocate memory for time_in_state/freq_table/trans_table in one go */ |
218 | if (!stat->time_in_state) { | 194 | stats->time_in_state = kzalloc(alloc_size, GFP_KERNEL); |
219 | ret = -ENOMEM; | 195 | if (!stats->time_in_state) |
220 | goto error_alloc; | 196 | goto free_stat; |
221 | } | 197 | |
222 | stat->freq_table = (unsigned int *)(stat->time_in_state + count); | 198 | stats->freq_table = (unsigned int *)(stats->time_in_state + count); |
223 | 199 | ||
224 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 200 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
225 | stat->trans_table = stat->freq_table + count; | 201 | stats->trans_table = stats->freq_table + count; |
226 | #endif | 202 | #endif |
227 | i = 0; | 203 | |
204 | stats->max_state = count; | ||
205 | |||
206 | /* Find valid-unique entries */ | ||
228 | cpufreq_for_each_valid_entry(pos, table) | 207 | cpufreq_for_each_valid_entry(pos, table) |
229 | if (freq_table_get_index(stat, pos->frequency) == -1) | 208 | if (freq_table_get_index(stats, pos->frequency) == -1) |
230 | stat->freq_table[i++] = pos->frequency; | 209 | stats->freq_table[i++] = pos->frequency; |
231 | stat->state_num = i; | 210 | |
232 | spin_lock(&cpufreq_stats_lock); | 211 | stats->state_num = i; |
233 | stat->last_time = get_jiffies_64(); | 212 | stats->last_time = get_jiffies_64(); |
234 | stat->last_index = freq_table_get_index(stat, policy->cur); | 213 | stats->last_index = freq_table_get_index(stats, policy->cur); |
235 | spin_unlock(&cpufreq_stats_lock); | 214 | |
236 | return 0; | 215 | policy->stats = stats; |
237 | error_alloc: | 216 | ret = sysfs_create_group(&policy->kobj, &stats_attr_group); |
238 | sysfs_remove_group(&policy->kobj, &stats_attr_group); | 217 | if (!ret) |
239 | error_out: | 218 | return 0; |
240 | kfree(stat); | 219 | |
241 | per_cpu(cpufreq_stats_table, cpu) = NULL; | 220 | /* We failed, release resources */ |
221 | policy->stats = NULL; | ||
222 | kfree(stats->time_in_state); | ||
223 | free_stat: | ||
224 | kfree(stats); | ||
225 | |||
242 | return ret; | 226 | return ret; |
243 | } | 227 | } |
244 | 228 | ||
@@ -259,30 +243,12 @@ static void cpufreq_stats_create_table(unsigned int cpu) | |||
259 | cpufreq_cpu_put(policy); | 243 | cpufreq_cpu_put(policy); |
260 | } | 244 | } |
261 | 245 | ||
262 | static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) | ||
263 | { | ||
264 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, | ||
265 | policy->last_cpu); | ||
266 | |||
267 | pr_debug("Updating stats_table for new_cpu %u from last_cpu %u\n", | ||
268 | policy->cpu, policy->last_cpu); | ||
269 | per_cpu(cpufreq_stats_table, policy->cpu) = per_cpu(cpufreq_stats_table, | ||
270 | policy->last_cpu); | ||
271 | per_cpu(cpufreq_stats_table, policy->last_cpu) = NULL; | ||
272 | stat->cpu = policy->cpu; | ||
273 | } | ||
274 | |||
275 | static int cpufreq_stat_notifier_policy(struct notifier_block *nb, | 246 | static int cpufreq_stat_notifier_policy(struct notifier_block *nb, |
276 | unsigned long val, void *data) | 247 | unsigned long val, void *data) |
277 | { | 248 | { |
278 | int ret = 0; | 249 | int ret = 0; |
279 | struct cpufreq_policy *policy = data; | 250 | struct cpufreq_policy *policy = data; |
280 | 251 | ||
281 | if (val == CPUFREQ_UPDATE_POLICY_CPU) { | ||
282 | cpufreq_stats_update_policy_cpu(policy); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | if (val == CPUFREQ_CREATE_POLICY) | 252 | if (val == CPUFREQ_CREATE_POLICY) |
287 | ret = __cpufreq_stats_create_table(policy); | 253 | ret = __cpufreq_stats_create_table(policy); |
288 | else if (val == CPUFREQ_REMOVE_POLICY) | 254 | else if (val == CPUFREQ_REMOVE_POLICY) |
@@ -295,35 +261,45 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, | |||
295 | unsigned long val, void *data) | 261 | unsigned long val, void *data) |
296 | { | 262 | { |
297 | struct cpufreq_freqs *freq = data; | 263 | struct cpufreq_freqs *freq = data; |
298 | struct cpufreq_stats *stat; | 264 | struct cpufreq_policy *policy = cpufreq_cpu_get(freq->cpu); |
265 | struct cpufreq_stats *stats; | ||
299 | int old_index, new_index; | 266 | int old_index, new_index; |
300 | 267 | ||
301 | if (val != CPUFREQ_POSTCHANGE) | 268 | if (!policy) { |
269 | pr_err("%s: No policy found\n", __func__); | ||
302 | return 0; | 270 | return 0; |
271 | } | ||
303 | 272 | ||
304 | stat = per_cpu(cpufreq_stats_table, freq->cpu); | 273 | if (val != CPUFREQ_POSTCHANGE) |
305 | if (!stat) | 274 | goto put_policy; |
306 | return 0; | ||
307 | 275 | ||
308 | old_index = stat->last_index; | 276 | if (!policy->stats) { |
309 | new_index = freq_table_get_index(stat, freq->new); | 277 | pr_debug("%s: No stats found\n", __func__); |
278 | goto put_policy; | ||
279 | } | ||
310 | 280 | ||
311 | /* We can't do stat->time_in_state[-1]= .. */ | 281 | stats = policy->stats; |
312 | if (old_index == -1 || new_index == -1) | 282 | |
313 | return 0; | 283 | old_index = stats->last_index; |
284 | new_index = freq_table_get_index(stats, freq->new); | ||
314 | 285 | ||
315 | cpufreq_stats_update(freq->cpu); | 286 | /* We can't do stats->time_in_state[-1]= .. */ |
287 | if (old_index == -1 || new_index == -1) | ||
288 | goto put_policy; | ||
316 | 289 | ||
317 | if (old_index == new_index) | 290 | if (old_index == new_index) |
318 | return 0; | 291 | goto put_policy; |
319 | 292 | ||
320 | spin_lock(&cpufreq_stats_lock); | 293 | cpufreq_stats_update(stats); |
321 | stat->last_index = new_index; | 294 | |
295 | stats->last_index = new_index; | ||
322 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 296 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
323 | stat->trans_table[old_index * stat->max_state + new_index]++; | 297 | stats->trans_table[old_index * stats->max_state + new_index]++; |
324 | #endif | 298 | #endif |
325 | stat->total_trans++; | 299 | stats->total_trans++; |
326 | spin_unlock(&cpufreq_stats_lock); | 300 | |
301 | put_policy: | ||
302 | cpufreq_cpu_put(policy); | ||
327 | return 0; | 303 | return 0; |
328 | } | 304 | } |
329 | 305 | ||
@@ -374,8 +350,7 @@ static void __exit cpufreq_stats_exit(void) | |||
374 | } | 350 | } |
375 | 351 | ||
376 | MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>"); | 352 | MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>"); |
377 | MODULE_DESCRIPTION("'cpufreq_stats' - A driver to export cpufreq stats " | 353 | MODULE_DESCRIPTION("Export cpufreq stats via sysfs"); |
378 | "through sysfs filesystem"); | ||
379 | MODULE_LICENSE("GPL"); | 354 | MODULE_LICENSE("GPL"); |
380 | 355 | ||
381 | module_init(cpufreq_stats_init); | 356 | module_init(cpufreq_stats_init); |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 742eefba12c2..872c5772c5d3 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -148,6 +148,8 @@ struct perf_limits { | |||
148 | int32_t min_perf; | 148 | int32_t min_perf; |
149 | int max_policy_pct; | 149 | int max_policy_pct; |
150 | int max_sysfs_pct; | 150 | int max_sysfs_pct; |
151 | int min_policy_pct; | ||
152 | int min_sysfs_pct; | ||
151 | }; | 153 | }; |
152 | 154 | ||
153 | static struct perf_limits limits = { | 155 | static struct perf_limits limits = { |
@@ -159,6 +161,8 @@ static struct perf_limits limits = { | |||
159 | .min_perf = 0, | 161 | .min_perf = 0, |
160 | .max_policy_pct = 100, | 162 | .max_policy_pct = 100, |
161 | .max_sysfs_pct = 100, | 163 | .max_sysfs_pct = 100, |
164 | .min_policy_pct = 0, | ||
165 | .min_sysfs_pct = 0, | ||
162 | }; | 166 | }; |
163 | 167 | ||
164 | static inline void pid_reset(struct _pid *pid, int setpoint, int busy, | 168 | static inline void pid_reset(struct _pid *pid, int setpoint, int busy, |
@@ -338,6 +342,33 @@ static void __init intel_pstate_debug_expose_params(void) | |||
338 | return sprintf(buf, "%u\n", limits.object); \ | 342 | return sprintf(buf, "%u\n", limits.object); \ |
339 | } | 343 | } |
340 | 344 | ||
345 | static ssize_t show_turbo_pct(struct kobject *kobj, | ||
346 | struct attribute *attr, char *buf) | ||
347 | { | ||
348 | struct cpudata *cpu; | ||
349 | int total, no_turbo, turbo_pct; | ||
350 | uint32_t turbo_fp; | ||
351 | |||
352 | cpu = all_cpu_data[0]; | ||
353 | |||
354 | total = cpu->pstate.turbo_pstate - cpu->pstate.min_pstate + 1; | ||
355 | no_turbo = cpu->pstate.max_pstate - cpu->pstate.min_pstate + 1; | ||
356 | turbo_fp = div_fp(int_tofp(no_turbo), int_tofp(total)); | ||
357 | turbo_pct = 100 - fp_toint(mul_fp(turbo_fp, int_tofp(100))); | ||
358 | return sprintf(buf, "%u\n", turbo_pct); | ||
359 | } | ||
360 | |||
361 | static ssize_t show_num_pstates(struct kobject *kobj, | ||
362 | struct attribute *attr, char *buf) | ||
363 | { | ||
364 | struct cpudata *cpu; | ||
365 | int total; | ||
366 | |||
367 | cpu = all_cpu_data[0]; | ||
368 | total = cpu->pstate.turbo_pstate - cpu->pstate.min_pstate + 1; | ||
369 | return sprintf(buf, "%u\n", total); | ||
370 | } | ||
371 | |||
341 | static ssize_t show_no_turbo(struct kobject *kobj, | 372 | static ssize_t show_no_turbo(struct kobject *kobj, |
342 | struct attribute *attr, char *buf) | 373 | struct attribute *attr, char *buf) |
343 | { | 374 | { |
@@ -404,7 +435,9 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, | |||
404 | ret = sscanf(buf, "%u", &input); | 435 | ret = sscanf(buf, "%u", &input); |
405 | if (ret != 1) | 436 | if (ret != 1) |
406 | return -EINVAL; | 437 | return -EINVAL; |
407 | limits.min_perf_pct = clamp_t(int, input, 0 , 100); | 438 | |
439 | limits.min_sysfs_pct = clamp_t(int, input, 0 , 100); | ||
440 | limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); | ||
408 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); | 441 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); |
409 | 442 | ||
410 | if (hwp_active) | 443 | if (hwp_active) |
@@ -418,11 +451,15 @@ show_one(min_perf_pct, min_perf_pct); | |||
418 | define_one_global_rw(no_turbo); | 451 | define_one_global_rw(no_turbo); |
419 | define_one_global_rw(max_perf_pct); | 452 | define_one_global_rw(max_perf_pct); |
420 | define_one_global_rw(min_perf_pct); | 453 | define_one_global_rw(min_perf_pct); |
454 | define_one_global_ro(turbo_pct); | ||
455 | define_one_global_ro(num_pstates); | ||
421 | 456 | ||
422 | static struct attribute *intel_pstate_attributes[] = { | 457 | static struct attribute *intel_pstate_attributes[] = { |
423 | &no_turbo.attr, | 458 | &no_turbo.attr, |
424 | &max_perf_pct.attr, | 459 | &max_perf_pct.attr, |
425 | &min_perf_pct.attr, | 460 | &min_perf_pct.attr, |
461 | &turbo_pct.attr, | ||
462 | &num_pstates.attr, | ||
426 | NULL | 463 | NULL |
427 | }; | 464 | }; |
428 | 465 | ||
@@ -825,6 +862,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | |||
825 | ICPU(0x46, core_params), | 862 | ICPU(0x46, core_params), |
826 | ICPU(0x47, core_params), | 863 | ICPU(0x47, core_params), |
827 | ICPU(0x4c, byt_params), | 864 | ICPU(0x4c, byt_params), |
865 | ICPU(0x4e, core_params), | ||
828 | ICPU(0x4f, core_params), | 866 | ICPU(0x4f, core_params), |
829 | ICPU(0x56, core_params), | 867 | ICPU(0x56, core_params), |
830 | {} | 868 | {} |
@@ -887,7 +925,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
887 | if (!policy->cpuinfo.max_freq) | 925 | if (!policy->cpuinfo.max_freq) |
888 | return -ENODEV; | 926 | return -ENODEV; |
889 | 927 | ||
890 | if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { | 928 | if (policy->policy == CPUFREQ_POLICY_PERFORMANCE && |
929 | policy->max >= policy->cpuinfo.max_freq) { | ||
930 | limits.min_policy_pct = 100; | ||
891 | limits.min_perf_pct = 100; | 931 | limits.min_perf_pct = 100; |
892 | limits.min_perf = int_tofp(1); | 932 | limits.min_perf = int_tofp(1); |
893 | limits.max_policy_pct = 100; | 933 | limits.max_policy_pct = 100; |
@@ -897,8 +937,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
897 | return 0; | 937 | return 0; |
898 | } | 938 | } |
899 | 939 | ||
900 | limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; | 940 | limits.min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq; |
901 | limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100); | 941 | limits.min_policy_pct = clamp_t(int, limits.min_policy_pct, 0 , 100); |
942 | limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); | ||
902 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); | 943 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); |
903 | 944 | ||
904 | limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq; | 945 | limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq; |
@@ -978,6 +1019,7 @@ static struct cpufreq_driver intel_pstate_driver = { | |||
978 | 1019 | ||
979 | static int __initdata no_load; | 1020 | static int __initdata no_load; |
980 | static int __initdata no_hwp; | 1021 | static int __initdata no_hwp; |
1022 | static int __initdata hwp_only; | ||
981 | static unsigned int force_load; | 1023 | static unsigned int force_load; |
982 | 1024 | ||
983 | static int intel_pstate_msrs_not_valid(void) | 1025 | static int intel_pstate_msrs_not_valid(void) |
@@ -1175,6 +1217,9 @@ static int __init intel_pstate_init(void) | |||
1175 | if (cpu_has(c,X86_FEATURE_HWP) && !no_hwp) | 1217 | if (cpu_has(c,X86_FEATURE_HWP) && !no_hwp) |
1176 | intel_pstate_hwp_enable(); | 1218 | intel_pstate_hwp_enable(); |
1177 | 1219 | ||
1220 | if (!hwp_active && hwp_only) | ||
1221 | goto out; | ||
1222 | |||
1178 | rc = cpufreq_register_driver(&intel_pstate_driver); | 1223 | rc = cpufreq_register_driver(&intel_pstate_driver); |
1179 | if (rc) | 1224 | if (rc) |
1180 | goto out; | 1225 | goto out; |
@@ -1209,6 +1254,8 @@ static int __init intel_pstate_setup(char *str) | |||
1209 | no_hwp = 1; | 1254 | no_hwp = 1; |
1210 | if (!strcmp(str, "force")) | 1255 | if (!strcmp(str, "force")) |
1211 | force_load = 1; | 1256 | force_load = 1; |
1257 | if (!strcmp(str, "hwp_only")) | ||
1258 | hwp_only = 1; | ||
1212 | return 0; | 1259 | return 0; |
1213 | } | 1260 | } |
1214 | early_param("intel_pstate", intel_pstate_setup); | 1261 | early_param("intel_pstate", intel_pstate_setup); |
diff --git a/drivers/cpufreq/ls1x-cpufreq.c b/drivers/cpufreq/ls1x-cpufreq.c index 25fbd6a1374f..f0913eee2f50 100644 --- a/drivers/cpufreq/ls1x-cpufreq.c +++ b/drivers/cpufreq/ls1x-cpufreq.c | |||
@@ -210,7 +210,6 @@ out: | |||
210 | static struct platform_driver ls1x_cpufreq_platdrv = { | 210 | static struct platform_driver ls1x_cpufreq_platdrv = { |
211 | .driver = { | 211 | .driver = { |
212 | .name = "ls1x-cpufreq", | 212 | .name = "ls1x-cpufreq", |
213 | .owner = THIS_MODULE, | ||
214 | }, | 213 | }, |
215 | .probe = ls1x_cpufreq_probe, | 214 | .probe = ls1x_cpufreq_probe, |
216 | .remove = ls1x_cpufreq_remove, | 215 | .remove = ls1x_cpufreq_remove, |
diff --git a/drivers/cpufreq/sfi-cpufreq.c b/drivers/cpufreq/sfi-cpufreq.c new file mode 100644 index 000000000000..ffa3389e535b --- /dev/null +++ b/drivers/cpufreq/sfi-cpufreq.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * SFI Performance States Driver | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * Author: Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com> | ||
14 | * Author: Srinidhi Kasagar <srinidhi.kasagar@intel.com> | ||
15 | */ | ||
16 | |||
17 | #include <linux/cpufreq.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/sfi.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/smp.h> | ||
24 | |||
25 | #include <asm/msr.h> | ||
26 | |||
27 | struct cpufreq_frequency_table *freq_table; | ||
28 | static struct sfi_freq_table_entry *sfi_cpufreq_array; | ||
29 | static int num_freq_table_entries; | ||
30 | |||
31 | static int sfi_parse_freq(struct sfi_table_header *table) | ||
32 | { | ||
33 | struct sfi_table_simple *sb; | ||
34 | struct sfi_freq_table_entry *pentry; | ||
35 | int totallen; | ||
36 | |||
37 | sb = (struct sfi_table_simple *)table; | ||
38 | num_freq_table_entries = SFI_GET_NUM_ENTRIES(sb, | ||
39 | struct sfi_freq_table_entry); | ||
40 | if (num_freq_table_entries <= 1) { | ||
41 | pr_err("No p-states discovered\n"); | ||
42 | return -ENODEV; | ||
43 | } | ||
44 | |||
45 | pentry = (struct sfi_freq_table_entry *)sb->pentry; | ||
46 | totallen = num_freq_table_entries * sizeof(*pentry); | ||
47 | |||
48 | sfi_cpufreq_array = kzalloc(totallen, GFP_KERNEL); | ||
49 | if (!sfi_cpufreq_array) | ||
50 | return -ENOMEM; | ||
51 | |||
52 | memcpy(sfi_cpufreq_array, pentry, totallen); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int sfi_cpufreq_target(struct cpufreq_policy *policy, unsigned int index) | ||
58 | { | ||
59 | unsigned int next_perf_state = 0; /* Index into perf table */ | ||
60 | u32 lo, hi; | ||
61 | |||
62 | next_perf_state = policy->freq_table[index].driver_data; | ||
63 | |||
64 | rdmsr_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, &lo, &hi); | ||
65 | lo = (lo & ~INTEL_PERF_CTL_MASK) | | ||
66 | ((u32) sfi_cpufreq_array[next_perf_state].ctrl_val & | ||
67 | INTEL_PERF_CTL_MASK); | ||
68 | wrmsr_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, lo, hi); | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int sfi_cpufreq_cpu_init(struct cpufreq_policy *policy) | ||
74 | { | ||
75 | policy->shared_type = CPUFREQ_SHARED_TYPE_HW; | ||
76 | policy->cpuinfo.transition_latency = 100000; /* 100us */ | ||
77 | |||
78 | return cpufreq_table_validate_and_show(policy, freq_table); | ||
79 | } | ||
80 | |||
81 | static struct cpufreq_driver sfi_cpufreq_driver = { | ||
82 | .flags = CPUFREQ_CONST_LOOPS, | ||
83 | .verify = cpufreq_generic_frequency_table_verify, | ||
84 | .target_index = sfi_cpufreq_target, | ||
85 | .init = sfi_cpufreq_cpu_init, | ||
86 | .name = "sfi-cpufreq", | ||
87 | .attr = cpufreq_generic_attr, | ||
88 | }; | ||
89 | |||
90 | static int __init sfi_cpufreq_init(void) | ||
91 | { | ||
92 | int ret, i; | ||
93 | |||
94 | /* parse the freq table from SFI */ | ||
95 | ret = sfi_table_parse(SFI_SIG_FREQ, NULL, NULL, sfi_parse_freq); | ||
96 | if (ret) | ||
97 | return ret; | ||
98 | |||
99 | freq_table = kzalloc(sizeof(*freq_table) * | ||
100 | (num_freq_table_entries + 1), GFP_KERNEL); | ||
101 | if (!freq_table) { | ||
102 | ret = -ENOMEM; | ||
103 | goto err_free_array; | ||
104 | } | ||
105 | |||
106 | for (i = 0; i < num_freq_table_entries; i++) { | ||
107 | freq_table[i].driver_data = i; | ||
108 | freq_table[i].frequency = sfi_cpufreq_array[i].freq_mhz * 1000; | ||
109 | } | ||
110 | freq_table[i].frequency = CPUFREQ_TABLE_END; | ||
111 | |||
112 | ret = cpufreq_register_driver(&sfi_cpufreq_driver); | ||
113 | if (ret) | ||
114 | goto err_free_tbl; | ||
115 | |||
116 | return ret; | ||
117 | |||
118 | err_free_tbl: | ||
119 | kfree(freq_table); | ||
120 | err_free_array: | ||
121 | kfree(sfi_cpufreq_array); | ||
122 | return ret; | ||
123 | } | ||
124 | late_initcall(sfi_cpufreq_init); | ||
125 | |||
126 | static void __exit sfi_cpufreq_exit(void) | ||
127 | { | ||
128 | cpufreq_unregister_driver(&sfi_cpufreq_driver); | ||
129 | kfree(freq_table); | ||
130 | kfree(sfi_cpufreq_array); | ||
131 | } | ||
132 | module_exit(sfi_cpufreq_exit); | ||
133 | |||
134 | MODULE_AUTHOR("Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>"); | ||
135 | MODULE_DESCRIPTION("SFI Performance-States Driver"); | ||
136 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c index e3e225fe6b45..40c34faffe59 100644 --- a/drivers/cpuidle/cpuidle-big_little.c +++ b/drivers/cpuidle/cpuidle-big_little.c | |||
@@ -182,6 +182,10 @@ static int __init bl_idle_init(void) | |||
182 | */ | 182 | */ |
183 | if (!of_match_node(compatible_machine_match, root)) | 183 | if (!of_match_node(compatible_machine_match, root)) |
184 | return -ENODEV; | 184 | return -ENODEV; |
185 | |||
186 | if (!mcpm_is_available()) | ||
187 | return -EUNATCH; | ||
188 | |||
185 | /* | 189 | /* |
186 | * For now the differentiation between little and big cores | 190 | * For now the differentiation between little and big cores |
187 | * is based on the part number. A7 cores are considered little | 191 | * is based on the part number. A7 cores are considered little |
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 3891f6781298..64281bb2f650 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig | |||
@@ -88,4 +88,16 @@ config ARM_EXYNOS5_BUS_DEVFREQ | |||
88 | It reads PPMU counters of memory controllers and adjusts the | 88 | It reads PPMU counters of memory controllers and adjusts the |
89 | operating frequencies and voltages with OPP support. | 89 | operating frequencies and voltages with OPP support. |
90 | 90 | ||
91 | config ARM_TEGRA_DEVFREQ | ||
92 | tristate "Tegra DEVFREQ Driver" | ||
93 | depends on ARCH_TEGRA_124_SOC | ||
94 | select DEVFREQ_GOV_SIMPLE_ONDEMAND | ||
95 | select PM_OPP | ||
96 | help | ||
97 | This adds the DEVFREQ driver for the Tegra family of SoCs. | ||
98 | It reads ACTMON counters of memory controllers and adjusts the | ||
99 | operating frequencies and voltages with OPP support. | ||
100 | |||
101 | source "drivers/devfreq/event/Kconfig" | ||
102 | |||
91 | endif # PM_DEVFREQ | 103 | endif # PM_DEVFREQ |
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 16138c9e0d58..5134f9ee983d 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | obj-$(CONFIG_PM_DEVFREQ) += devfreq.o | 1 | obj-$(CONFIG_PM_DEVFREQ) += devfreq.o |
2 | obj-$(CONFIG_PM_DEVFREQ_EVENT) += devfreq-event.o | ||
2 | obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) += governor_simpleondemand.o | 3 | obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) += governor_simpleondemand.o |
3 | obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o | 4 | obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o |
4 | obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o | 5 | obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o |
@@ -7,3 +8,7 @@ obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o | |||
7 | # DEVFREQ Drivers | 8 | # DEVFREQ Drivers |
8 | obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos/ | 9 | obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos/ |
9 | obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos/ | 10 | obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos/ |
11 | obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra-devfreq.o | ||
12 | |||
13 | # DEVFREQ Event Drivers | ||
14 | obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/ | ||
diff --git a/drivers/devfreq/devfreq-event.c b/drivers/devfreq/devfreq-event.c new file mode 100644 index 000000000000..f304a0289eda --- /dev/null +++ b/drivers/devfreq/devfreq-event.c | |||
@@ -0,0 +1,494 @@ | |||
1 | /* | ||
2 | * devfreq-event: a framework to provide raw data and events of devfreq devices | ||
3 | * | ||
4 | * Copyright (C) 2015 Samsung Electronics | ||
5 | * Author: Chanwoo Choi <cw00.choi@samsung.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 | * This driver is based on drivers/devfreq/devfreq.c. | ||
12 | */ | ||
13 | |||
14 | #include <linux/devfreq-event.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/list.h> | ||
21 | #include <linux/of.h> | ||
22 | |||
23 | static struct class *devfreq_event_class; | ||
24 | |||
25 | /* The list of all devfreq event list */ | ||
26 | static LIST_HEAD(devfreq_event_list); | ||
27 | static DEFINE_MUTEX(devfreq_event_list_lock); | ||
28 | |||
29 | #define to_devfreq_event(DEV) container_of(DEV, struct devfreq_event_dev, dev) | ||
30 | |||
31 | /** | ||
32 | * devfreq_event_enable_edev() - Enable the devfreq-event dev and increase | ||
33 | * the enable_count of devfreq-event dev. | ||
34 | * @edev : the devfreq-event device | ||
35 | * | ||
36 | * Note that this function increase the enable_count and enable the | ||
37 | * devfreq-event device. The devfreq-event device should be enabled before | ||
38 | * using it by devfreq device. | ||
39 | */ | ||
40 | int devfreq_event_enable_edev(struct devfreq_event_dev *edev) | ||
41 | { | ||
42 | int ret = 0; | ||
43 | |||
44 | if (!edev || !edev->desc) | ||
45 | return -EINVAL; | ||
46 | |||
47 | mutex_lock(&edev->lock); | ||
48 | if (edev->desc->ops && edev->desc->ops->enable | ||
49 | && edev->enable_count == 0) { | ||
50 | ret = edev->desc->ops->enable(edev); | ||
51 | if (ret < 0) | ||
52 | goto err; | ||
53 | } | ||
54 | edev->enable_count++; | ||
55 | err: | ||
56 | mutex_unlock(&edev->lock); | ||
57 | |||
58 | return ret; | ||
59 | } | ||
60 | EXPORT_SYMBOL_GPL(devfreq_event_enable_edev); | ||
61 | |||
62 | /** | ||
63 | * devfreq_event_disable_edev() - Disable the devfreq-event dev and decrease | ||
64 | * the enable_count of the devfreq-event dev. | ||
65 | * @edev : the devfreq-event device | ||
66 | * | ||
67 | * Note that this function decrease the enable_count and disable the | ||
68 | * devfreq-event device. After the devfreq-event device is disabled, | ||
69 | * devfreq device can't use the devfreq-event device for get/set/reset | ||
70 | * operations. | ||
71 | */ | ||
72 | int devfreq_event_disable_edev(struct devfreq_event_dev *edev) | ||
73 | { | ||
74 | int ret = 0; | ||
75 | |||
76 | if (!edev || !edev->desc) | ||
77 | return -EINVAL; | ||
78 | |||
79 | mutex_lock(&edev->lock); | ||
80 | if (edev->enable_count <= 0) { | ||
81 | dev_warn(&edev->dev, "unbalanced enable_count\n"); | ||
82 | ret = -EIO; | ||
83 | goto err; | ||
84 | } | ||
85 | |||
86 | if (edev->desc->ops && edev->desc->ops->disable | ||
87 | && edev->enable_count == 1) { | ||
88 | ret = edev->desc->ops->disable(edev); | ||
89 | if (ret < 0) | ||
90 | goto err; | ||
91 | } | ||
92 | edev->enable_count--; | ||
93 | err: | ||
94 | mutex_unlock(&edev->lock); | ||
95 | |||
96 | return ret; | ||
97 | } | ||
98 | EXPORT_SYMBOL_GPL(devfreq_event_disable_edev); | ||
99 | |||
100 | /** | ||
101 | * devfreq_event_is_enabled() - Check whether devfreq-event dev is enabled or | ||
102 | * not. | ||
103 | * @edev : the devfreq-event device | ||
104 | * | ||
105 | * Note that this function check whether devfreq-event dev is enabled or not. | ||
106 | * If return true, the devfreq-event dev is enabeld. If return false, the | ||
107 | * devfreq-event dev is disabled. | ||
108 | */ | ||
109 | bool devfreq_event_is_enabled(struct devfreq_event_dev *edev) | ||
110 | { | ||
111 | bool enabled = false; | ||
112 | |||
113 | if (!edev || !edev->desc) | ||
114 | return enabled; | ||
115 | |||
116 | mutex_lock(&edev->lock); | ||
117 | |||
118 | if (edev->enable_count > 0) | ||
119 | enabled = true; | ||
120 | |||
121 | mutex_unlock(&edev->lock); | ||
122 | |||
123 | return enabled; | ||
124 | } | ||
125 | EXPORT_SYMBOL_GPL(devfreq_event_is_enabled); | ||
126 | |||
127 | /** | ||
128 | * devfreq_event_set_event() - Set event to devfreq-event dev to start. | ||
129 | * @edev : the devfreq-event device | ||
130 | * | ||
131 | * Note that this function set the event to the devfreq-event device to start | ||
132 | * for getting the event data which could be various event type. | ||
133 | */ | ||
134 | int devfreq_event_set_event(struct devfreq_event_dev *edev) | ||
135 | { | ||
136 | int ret; | ||
137 | |||
138 | if (!edev || !edev->desc) | ||
139 | return -EINVAL; | ||
140 | |||
141 | if (!edev->desc->ops || !edev->desc->ops->set_event) | ||
142 | return -EINVAL; | ||
143 | |||
144 | if (!devfreq_event_is_enabled(edev)) | ||
145 | return -EPERM; | ||
146 | |||
147 | mutex_lock(&edev->lock); | ||
148 | ret = edev->desc->ops->set_event(edev); | ||
149 | mutex_unlock(&edev->lock); | ||
150 | |||
151 | return ret; | ||
152 | } | ||
153 | EXPORT_SYMBOL_GPL(devfreq_event_set_event); | ||
154 | |||
155 | /** | ||
156 | * devfreq_event_get_event() - Get {load|total}_count from devfreq-event dev. | ||
157 | * @edev : the devfreq-event device | ||
158 | * @edata : the calculated data of devfreq-event device | ||
159 | * | ||
160 | * Note that this function get the calculated event data from devfreq-event dev | ||
161 | * after stoping the progress of whole sequence of devfreq-event dev. | ||
162 | */ | ||
163 | int devfreq_event_get_event(struct devfreq_event_dev *edev, | ||
164 | struct devfreq_event_data *edata) | ||
165 | { | ||
166 | int ret; | ||
167 | |||
168 | if (!edev || !edev->desc) | ||
169 | return -EINVAL; | ||
170 | |||
171 | if (!edev->desc->ops || !edev->desc->ops->get_event) | ||
172 | return -EINVAL; | ||
173 | |||
174 | if (!devfreq_event_is_enabled(edev)) | ||
175 | return -EINVAL; | ||
176 | |||
177 | edata->total_count = edata->load_count = 0; | ||
178 | |||
179 | mutex_lock(&edev->lock); | ||
180 | ret = edev->desc->ops->get_event(edev, edata); | ||
181 | if (ret < 0) | ||
182 | edata->total_count = edata->load_count = 0; | ||
183 | mutex_unlock(&edev->lock); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | EXPORT_SYMBOL_GPL(devfreq_event_get_event); | ||
188 | |||
189 | /** | ||
190 | * devfreq_event_reset_event() - Reset all opeations of devfreq-event dev. | ||
191 | * @edev : the devfreq-event device | ||
192 | * | ||
193 | * Note that this function stop all operations of devfreq-event dev and reset | ||
194 | * the current event data to make the devfreq-event device into initial state. | ||
195 | */ | ||
196 | int devfreq_event_reset_event(struct devfreq_event_dev *edev) | ||
197 | { | ||
198 | int ret = 0; | ||
199 | |||
200 | if (!edev || !edev->desc) | ||
201 | return -EINVAL; | ||
202 | |||
203 | if (!devfreq_event_is_enabled(edev)) | ||
204 | return -EPERM; | ||
205 | |||
206 | mutex_lock(&edev->lock); | ||
207 | if (edev->desc->ops && edev->desc->ops->reset) | ||
208 | ret = edev->desc->ops->reset(edev); | ||
209 | mutex_unlock(&edev->lock); | ||
210 | |||
211 | return ret; | ||
212 | } | ||
213 | EXPORT_SYMBOL_GPL(devfreq_event_reset_event); | ||
214 | |||
215 | /** | ||
216 | * devfreq_event_get_edev_by_phandle() - Get the devfreq-event dev from | ||
217 | * devicetree. | ||
218 | * @dev : the pointer to the given device | ||
219 | * @index : the index into list of devfreq-event device | ||
220 | * | ||
221 | * Note that this function return the pointer of devfreq-event device. | ||
222 | */ | ||
223 | struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(struct device *dev, | ||
224 | int index) | ||
225 | { | ||
226 | struct device_node *node; | ||
227 | struct devfreq_event_dev *edev; | ||
228 | |||
229 | if (!dev->of_node) { | ||
230 | dev_err(dev, "device does not have a device node entry\n"); | ||
231 | return ERR_PTR(-EINVAL); | ||
232 | } | ||
233 | |||
234 | node = of_parse_phandle(dev->of_node, "devfreq-events", index); | ||
235 | if (!node) { | ||
236 | dev_err(dev, "failed to get phandle in %s node\n", | ||
237 | dev->of_node->full_name); | ||
238 | return ERR_PTR(-ENODEV); | ||
239 | } | ||
240 | |||
241 | mutex_lock(&devfreq_event_list_lock); | ||
242 | list_for_each_entry(edev, &devfreq_event_list, node) { | ||
243 | if (!strcmp(edev->desc->name, node->name)) | ||
244 | goto out; | ||
245 | } | ||
246 | edev = NULL; | ||
247 | out: | ||
248 | mutex_unlock(&devfreq_event_list_lock); | ||
249 | |||
250 | if (!edev) { | ||
251 | dev_err(dev, "unable to get devfreq-event device : %s\n", | ||
252 | node->name); | ||
253 | of_node_put(node); | ||
254 | return ERR_PTR(-ENODEV); | ||
255 | } | ||
256 | |||
257 | of_node_put(node); | ||
258 | |||
259 | return edev; | ||
260 | } | ||
261 | EXPORT_SYMBOL_GPL(devfreq_event_get_edev_by_phandle); | ||
262 | |||
263 | /** | ||
264 | * devfreq_event_get_edev_count() - Get the count of devfreq-event dev | ||
265 | * @dev : the pointer to the given device | ||
266 | * | ||
267 | * Note that this function return the count of devfreq-event devices. | ||
268 | */ | ||
269 | int devfreq_event_get_edev_count(struct device *dev) | ||
270 | { | ||
271 | int count; | ||
272 | |||
273 | if (!dev->of_node) { | ||
274 | dev_err(dev, "device does not have a device node entry\n"); | ||
275 | return -EINVAL; | ||
276 | } | ||
277 | |||
278 | count = of_property_count_elems_of_size(dev->of_node, "devfreq-events", | ||
279 | sizeof(u32)); | ||
280 | if (count < 0 ) { | ||
281 | dev_err(dev, | ||
282 | "failed to get the count of devfreq-event in %s node\n", | ||
283 | dev->of_node->full_name); | ||
284 | return count; | ||
285 | } | ||
286 | |||
287 | return count; | ||
288 | } | ||
289 | EXPORT_SYMBOL_GPL(devfreq_event_get_edev_count); | ||
290 | |||
291 | static void devfreq_event_release_edev(struct device *dev) | ||
292 | { | ||
293 | struct devfreq_event_dev *edev = to_devfreq_event(dev); | ||
294 | |||
295 | kfree(edev); | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * devfreq_event_add_edev() - Add new devfreq-event device. | ||
300 | * @dev : the device owning the devfreq-event device being created | ||
301 | * @desc : the devfreq-event device's decriptor which include essential | ||
302 | * data for devfreq-event device. | ||
303 | * | ||
304 | * Note that this function add new devfreq-event device to devfreq-event class | ||
305 | * list and register the device of the devfreq-event device. | ||
306 | */ | ||
307 | struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev, | ||
308 | struct devfreq_event_desc *desc) | ||
309 | { | ||
310 | struct devfreq_event_dev *edev; | ||
311 | static atomic_t event_no = ATOMIC_INIT(0); | ||
312 | int ret; | ||
313 | |||
314 | if (!dev || !desc) | ||
315 | return ERR_PTR(-EINVAL); | ||
316 | |||
317 | if (!desc->name || !desc->ops) | ||
318 | return ERR_PTR(-EINVAL); | ||
319 | |||
320 | if (!desc->ops->set_event || !desc->ops->get_event) | ||
321 | return ERR_PTR(-EINVAL); | ||
322 | |||
323 | edev = kzalloc(sizeof(struct devfreq_event_dev), GFP_KERNEL); | ||
324 | if (!edev) | ||
325 | return ERR_PTR(-ENOMEM); | ||
326 | |||
327 | mutex_init(&edev->lock); | ||
328 | edev->desc = desc; | ||
329 | edev->enable_count = 0; | ||
330 | edev->dev.parent = dev; | ||
331 | edev->dev.class = devfreq_event_class; | ||
332 | edev->dev.release = devfreq_event_release_edev; | ||
333 | |||
334 | dev_set_name(&edev->dev, "event.%d", atomic_inc_return(&event_no) - 1); | ||
335 | ret = device_register(&edev->dev); | ||
336 | if (ret < 0) { | ||
337 | put_device(&edev->dev); | ||
338 | return ERR_PTR(ret); | ||
339 | } | ||
340 | dev_set_drvdata(&edev->dev, edev); | ||
341 | |||
342 | INIT_LIST_HEAD(&edev->node); | ||
343 | |||
344 | mutex_lock(&devfreq_event_list_lock); | ||
345 | list_add(&edev->node, &devfreq_event_list); | ||
346 | mutex_unlock(&devfreq_event_list_lock); | ||
347 | |||
348 | return edev; | ||
349 | } | ||
350 | EXPORT_SYMBOL_GPL(devfreq_event_add_edev); | ||
351 | |||
352 | /** | ||
353 | * devfreq_event_remove_edev() - Remove the devfreq-event device registered. | ||
354 | * @dev : the devfreq-event device | ||
355 | * | ||
356 | * Note that this function remove the registered devfreq-event device. | ||
357 | */ | ||
358 | int devfreq_event_remove_edev(struct devfreq_event_dev *edev) | ||
359 | { | ||
360 | if (!edev) | ||
361 | return -EINVAL; | ||
362 | |||
363 | WARN_ON(edev->enable_count); | ||
364 | |||
365 | mutex_lock(&devfreq_event_list_lock); | ||
366 | list_del(&edev->node); | ||
367 | mutex_unlock(&devfreq_event_list_lock); | ||
368 | |||
369 | device_unregister(&edev->dev); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | EXPORT_SYMBOL_GPL(devfreq_event_remove_edev); | ||
374 | |||
375 | static int devm_devfreq_event_match(struct device *dev, void *res, void *data) | ||
376 | { | ||
377 | struct devfreq_event_dev **r = res; | ||
378 | |||
379 | if (WARN_ON(!r || !*r)) | ||
380 | return 0; | ||
381 | |||
382 | return *r == data; | ||
383 | } | ||
384 | |||
385 | static void devm_devfreq_event_release(struct device *dev, void *res) | ||
386 | { | ||
387 | devfreq_event_remove_edev(*(struct devfreq_event_dev **)res); | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * devm_devfreq_event_add_edev() - Resource-managed devfreq_event_add_edev() | ||
392 | * @dev : the device owning the devfreq-event device being created | ||
393 | * @desc : the devfreq-event device's decriptor which include essential | ||
394 | * data for devfreq-event device. | ||
395 | * | ||
396 | * Note that this function manages automatically the memory of devfreq-event | ||
397 | * device using device resource management and simplify the free operation | ||
398 | * for memory of devfreq-event device. | ||
399 | */ | ||
400 | struct devfreq_event_dev *devm_devfreq_event_add_edev(struct device *dev, | ||
401 | struct devfreq_event_desc *desc) | ||
402 | { | ||
403 | struct devfreq_event_dev **ptr, *edev; | ||
404 | |||
405 | ptr = devres_alloc(devm_devfreq_event_release, sizeof(*ptr), GFP_KERNEL); | ||
406 | if (!ptr) | ||
407 | return ERR_PTR(-ENOMEM); | ||
408 | |||
409 | edev = devfreq_event_add_edev(dev, desc); | ||
410 | if (IS_ERR(edev)) { | ||
411 | devres_free(ptr); | ||
412 | return ERR_PTR(-ENOMEM); | ||
413 | } | ||
414 | |||
415 | *ptr = edev; | ||
416 | devres_add(dev, ptr); | ||
417 | |||
418 | return edev; | ||
419 | } | ||
420 | EXPORT_SYMBOL_GPL(devm_devfreq_event_add_edev); | ||
421 | |||
422 | /** | ||
423 | * devm_devfreq_event_remove_edev()- Resource-managed devfreq_event_remove_edev() | ||
424 | * @dev : the device owning the devfreq-event device being created | ||
425 | * @edev : the devfreq-event device | ||
426 | * | ||
427 | * Note that this function manages automatically the memory of devfreq-event | ||
428 | * device using device resource management. | ||
429 | */ | ||
430 | void devm_devfreq_event_remove_edev(struct device *dev, | ||
431 | struct devfreq_event_dev *edev) | ||
432 | { | ||
433 | WARN_ON(devres_release(dev, devm_devfreq_event_release, | ||
434 | devm_devfreq_event_match, edev)); | ||
435 | } | ||
436 | EXPORT_SYMBOL_GPL(devm_devfreq_event_remove_edev); | ||
437 | |||
438 | /* | ||
439 | * Device attributes for devfreq-event class. | ||
440 | */ | ||
441 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, | ||
442 | char *buf) | ||
443 | { | ||
444 | struct devfreq_event_dev *edev = to_devfreq_event(dev); | ||
445 | |||
446 | if (!edev || !edev->desc) | ||
447 | return -EINVAL; | ||
448 | |||
449 | return sprintf(buf, "%s\n", edev->desc->name); | ||
450 | } | ||
451 | static DEVICE_ATTR_RO(name); | ||
452 | |||
453 | static ssize_t enable_count_show(struct device *dev, | ||
454 | struct device_attribute *attr, char *buf) | ||
455 | { | ||
456 | struct devfreq_event_dev *edev = to_devfreq_event(dev); | ||
457 | |||
458 | if (!edev || !edev->desc) | ||
459 | return -EINVAL; | ||
460 | |||
461 | return sprintf(buf, "%d\n", edev->enable_count); | ||
462 | } | ||
463 | static DEVICE_ATTR_RO(enable_count); | ||
464 | |||
465 | static struct attribute *devfreq_event_attrs[] = { | ||
466 | &dev_attr_name.attr, | ||
467 | &dev_attr_enable_count.attr, | ||
468 | NULL, | ||
469 | }; | ||
470 | ATTRIBUTE_GROUPS(devfreq_event); | ||
471 | |||
472 | static int __init devfreq_event_init(void) | ||
473 | { | ||
474 | devfreq_event_class = class_create(THIS_MODULE, "devfreq-event"); | ||
475 | if (IS_ERR(devfreq_event_class)) { | ||
476 | pr_err("%s: couldn't create class\n", __FILE__); | ||
477 | return PTR_ERR(devfreq_event_class); | ||
478 | } | ||
479 | |||
480 | devfreq_event_class->dev_groups = devfreq_event_groups; | ||
481 | |||
482 | return 0; | ||
483 | } | ||
484 | subsys_initcall(devfreq_event_init); | ||
485 | |||
486 | static void __exit devfreq_event_exit(void) | ||
487 | { | ||
488 | class_destroy(devfreq_event_class); | ||
489 | } | ||
490 | module_exit(devfreq_event_exit); | ||
491 | |||
492 | MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); | ||
493 | MODULE_DESCRIPTION("DEVFREQ-Event class support"); | ||
494 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig new file mode 100644 index 000000000000..a11720affc31 --- /dev/null +++ b/drivers/devfreq/event/Kconfig | |||
@@ -0,0 +1,25 @@ | |||
1 | menuconfig PM_DEVFREQ_EVENT | ||
2 | bool "DEVFREQ-Event device Support" | ||
3 | help | ||
4 | The devfreq-event device provide the raw data and events which | ||
5 | indicate the current state of devfreq-event device. The provided | ||
6 | data from devfreq-event device is used to monitor the state of | ||
7 | device and determine the suitable size of resource to reduce the | ||
8 | wasted resource. | ||
9 | |||
10 | The devfreq-event device can support the various type of events | ||
11 | (e.g., raw data, utilization, latency, bandwidth). The events | ||
12 | may be used by devfreq governor and other subsystem. | ||
13 | |||
14 | if PM_DEVFREQ_EVENT | ||
15 | |||
16 | config DEVFREQ_EVENT_EXYNOS_PPMU | ||
17 | bool "EXYNOS PPMU (Platform Performance Monitoring Unit) DEVFREQ event Driver" | ||
18 | depends on ARCH_EXYNOS | ||
19 | select PM_OPP | ||
20 | help | ||
21 | This add the devfreq-event driver for Exynos SoC. It provides PPMU | ||
22 | (Platform Performance Monitoring Unit) counters to estimate the | ||
23 | utilization of each module. | ||
24 | |||
25 | endif # PM_DEVFREQ_EVENT | ||
diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile new file mode 100644 index 000000000000..be146ead79cf --- /dev/null +++ b/drivers/devfreq/event/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | # Exynos DEVFREQ Event Drivers | ||
2 | obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU) += exynos-ppmu.o | ||
diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c new file mode 100644 index 000000000000..135be0aada9d --- /dev/null +++ b/drivers/devfreq/event/exynos-ppmu.c | |||
@@ -0,0 +1,374 @@ | |||
1 | /* | ||
2 | * exynos_ppmu.c - EXYNOS PPMU (Platform Performance Monitoring Unit) support | ||
3 | * | ||
4 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
5 | * Author : Chanwoo Choi <cw00.choi@samsung.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 | * This driver is based on drivers/devfreq/exynos/exynos_ppmu.c | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/suspend.h> | ||
22 | #include <linux/devfreq-event.h> | ||
23 | |||
24 | #include "exynos-ppmu.h" | ||
25 | |||
26 | struct exynos_ppmu_data { | ||
27 | void __iomem *base; | ||
28 | struct clk *clk; | ||
29 | }; | ||
30 | |||
31 | struct exynos_ppmu { | ||
32 | struct devfreq_event_dev **edev; | ||
33 | struct devfreq_event_desc *desc; | ||
34 | unsigned int num_events; | ||
35 | |||
36 | struct device *dev; | ||
37 | struct mutex lock; | ||
38 | |||
39 | struct exynos_ppmu_data ppmu; | ||
40 | }; | ||
41 | |||
42 | #define PPMU_EVENT(name) \ | ||
43 | { "ppmu-event0-"#name, PPMU_PMNCNT0 }, \ | ||
44 | { "ppmu-event1-"#name, PPMU_PMNCNT1 }, \ | ||
45 | { "ppmu-event2-"#name, PPMU_PMNCNT2 }, \ | ||
46 | { "ppmu-event3-"#name, PPMU_PMNCNT3 } | ||
47 | |||
48 | struct __exynos_ppmu_events { | ||
49 | char *name; | ||
50 | int id; | ||
51 | } ppmu_events[] = { | ||
52 | /* For Exynos3250, Exynos4 and Exynos5260 */ | ||
53 | PPMU_EVENT(g3d), | ||
54 | PPMU_EVENT(fsys), | ||
55 | |||
56 | /* For Exynos4 SoCs and Exynos3250 */ | ||
57 | PPMU_EVENT(dmc0), | ||
58 | PPMU_EVENT(dmc1), | ||
59 | PPMU_EVENT(cpu), | ||
60 | PPMU_EVENT(rightbus), | ||
61 | PPMU_EVENT(leftbus), | ||
62 | PPMU_EVENT(lcd0), | ||
63 | PPMU_EVENT(camif), | ||
64 | |||
65 | /* Only for Exynos3250 and Exynos5260 */ | ||
66 | PPMU_EVENT(mfc), | ||
67 | |||
68 | /* Only for Exynos4 SoCs */ | ||
69 | PPMU_EVENT(mfc-left), | ||
70 | PPMU_EVENT(mfc-right), | ||
71 | |||
72 | /* Only for Exynos5260 SoCs */ | ||
73 | PPMU_EVENT(drex0-s0), | ||
74 | PPMU_EVENT(drex0-s1), | ||
75 | PPMU_EVENT(drex1-s0), | ||
76 | PPMU_EVENT(drex1-s1), | ||
77 | PPMU_EVENT(eagle), | ||
78 | PPMU_EVENT(kfc), | ||
79 | PPMU_EVENT(isp), | ||
80 | PPMU_EVENT(fimc), | ||
81 | PPMU_EVENT(gscl), | ||
82 | PPMU_EVENT(mscl), | ||
83 | PPMU_EVENT(fimd0x), | ||
84 | PPMU_EVENT(fimd1x), | ||
85 | { /* sentinel */ }, | ||
86 | }; | ||
87 | |||
88 | static int exynos_ppmu_find_ppmu_id(struct devfreq_event_dev *edev) | ||
89 | { | ||
90 | int i; | ||
91 | |||
92 | for (i = 0; i < ARRAY_SIZE(ppmu_events); i++) | ||
93 | if (!strcmp(edev->desc->name, ppmu_events[i].name)) | ||
94 | return ppmu_events[i].id; | ||
95 | |||
96 | return -EINVAL; | ||
97 | } | ||
98 | |||
99 | static int exynos_ppmu_disable(struct devfreq_event_dev *edev) | ||
100 | { | ||
101 | struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); | ||
102 | u32 pmnc; | ||
103 | |||
104 | /* Disable all counters */ | ||
105 | __raw_writel(PPMU_CCNT_MASK | | ||
106 | PPMU_PMCNT0_MASK | | ||
107 | PPMU_PMCNT1_MASK | | ||
108 | PPMU_PMCNT2_MASK | | ||
109 | PPMU_PMCNT3_MASK, | ||
110 | info->ppmu.base + PPMU_CNTENC); | ||
111 | |||
112 | /* Disable PPMU */ | ||
113 | pmnc = __raw_readl(info->ppmu.base + PPMU_PMNC); | ||
114 | pmnc &= ~PPMU_PMNC_ENABLE_MASK; | ||
115 | __raw_writel(pmnc, info->ppmu.base + PPMU_PMNC); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int exynos_ppmu_set_event(struct devfreq_event_dev *edev) | ||
121 | { | ||
122 | struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); | ||
123 | int id = exynos_ppmu_find_ppmu_id(edev); | ||
124 | u32 pmnc, cntens; | ||
125 | |||
126 | if (id < 0) | ||
127 | return id; | ||
128 | |||
129 | /* Enable specific counter */ | ||
130 | cntens = __raw_readl(info->ppmu.base + PPMU_CNTENS); | ||
131 | cntens |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); | ||
132 | __raw_writel(cntens, info->ppmu.base + PPMU_CNTENS); | ||
133 | |||
134 | /* Set the event of Read/Write data count */ | ||
135 | __raw_writel(PPMU_RO_DATA_CNT | PPMU_WO_DATA_CNT, | ||
136 | info->ppmu.base + PPMU_BEVTxSEL(id)); | ||
137 | |||
138 | /* Reset cycle counter/performance counter and enable PPMU */ | ||
139 | pmnc = __raw_readl(info->ppmu.base + PPMU_PMNC); | ||
140 | pmnc &= ~(PPMU_PMNC_ENABLE_MASK | ||
141 | | PPMU_PMNC_COUNTER_RESET_MASK | ||
142 | | PPMU_PMNC_CC_RESET_MASK); | ||
143 | pmnc |= (PPMU_ENABLE << PPMU_PMNC_ENABLE_SHIFT); | ||
144 | pmnc |= (PPMU_ENABLE << PPMU_PMNC_COUNTER_RESET_SHIFT); | ||
145 | pmnc |= (PPMU_ENABLE << PPMU_PMNC_CC_RESET_SHIFT); | ||
146 | __raw_writel(pmnc, info->ppmu.base + PPMU_PMNC); | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int exynos_ppmu_get_event(struct devfreq_event_dev *edev, | ||
152 | struct devfreq_event_data *edata) | ||
153 | { | ||
154 | struct exynos_ppmu *info = devfreq_event_get_drvdata(edev); | ||
155 | int id = exynos_ppmu_find_ppmu_id(edev); | ||
156 | u32 pmnc, cntenc; | ||
157 | |||
158 | if (id < 0) | ||
159 | return -EINVAL; | ||
160 | |||
161 | /* Disable PPMU */ | ||
162 | pmnc = __raw_readl(info->ppmu.base + PPMU_PMNC); | ||
163 | pmnc &= ~PPMU_PMNC_ENABLE_MASK; | ||
164 | __raw_writel(pmnc, info->ppmu.base + PPMU_PMNC); | ||
165 | |||
166 | /* Read cycle count */ | ||
167 | edata->total_count = __raw_readl(info->ppmu.base + PPMU_CCNT); | ||
168 | |||
169 | /* Read performance count */ | ||
170 | switch (id) { | ||
171 | case PPMU_PMNCNT0: | ||
172 | case PPMU_PMNCNT1: | ||
173 | case PPMU_PMNCNT2: | ||
174 | edata->load_count | ||
175 | = __raw_readl(info->ppmu.base + PPMU_PMNCT(id)); | ||
176 | break; | ||
177 | case PPMU_PMNCNT3: | ||
178 | edata->load_count = | ||
179 | ((__raw_readl(info->ppmu.base + PPMU_PMCNT3_HIGH) << 8) | ||
180 | | __raw_readl(info->ppmu.base + PPMU_PMCNT3_LOW)); | ||
181 | break; | ||
182 | default: | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | /* Disable specific counter */ | ||
187 | cntenc = __raw_readl(info->ppmu.base + PPMU_CNTENC); | ||
188 | cntenc |= (PPMU_CCNT_MASK | (PPMU_ENABLE << id)); | ||
189 | __raw_writel(cntenc, info->ppmu.base + PPMU_CNTENC); | ||
190 | |||
191 | dev_dbg(&edev->dev, "%s (event: %ld/%ld)\n", edev->desc->name, | ||
192 | edata->load_count, edata->total_count); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static struct devfreq_event_ops exynos_ppmu_ops = { | ||
198 | .disable = exynos_ppmu_disable, | ||
199 | .set_event = exynos_ppmu_set_event, | ||
200 | .get_event = exynos_ppmu_get_event, | ||
201 | }; | ||
202 | |||
203 | static int of_get_devfreq_events(struct device_node *np, | ||
204 | struct exynos_ppmu *info) | ||
205 | { | ||
206 | struct devfreq_event_desc *desc; | ||
207 | struct device *dev = info->dev; | ||
208 | struct device_node *events_np, *node; | ||
209 | int i, j, count; | ||
210 | |||
211 | events_np = of_get_child_by_name(np, "events"); | ||
212 | if (!events_np) { | ||
213 | dev_err(dev, | ||
214 | "failed to get child node of devfreq-event devices\n"); | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | count = of_get_child_count(events_np); | ||
219 | desc = devm_kzalloc(dev, sizeof(*desc) * count, GFP_KERNEL); | ||
220 | if (!desc) | ||
221 | return -ENOMEM; | ||
222 | info->num_events = count; | ||
223 | |||
224 | j = 0; | ||
225 | for_each_child_of_node(events_np, node) { | ||
226 | for (i = 0; i < ARRAY_SIZE(ppmu_events); i++) { | ||
227 | if (!ppmu_events[i].name) | ||
228 | continue; | ||
229 | |||
230 | if (!of_node_cmp(node->name, ppmu_events[i].name)) | ||
231 | break; | ||
232 | } | ||
233 | |||
234 | if (i == ARRAY_SIZE(ppmu_events)) { | ||
235 | dev_warn(dev, | ||
236 | "don't know how to configure events : %s\n", | ||
237 | node->name); | ||
238 | continue; | ||
239 | } | ||
240 | |||
241 | desc[j].ops = &exynos_ppmu_ops; | ||
242 | desc[j].driver_data = info; | ||
243 | |||
244 | of_property_read_string(node, "event-name", &desc[j].name); | ||
245 | |||
246 | j++; | ||
247 | |||
248 | of_node_put(node); | ||
249 | } | ||
250 | info->desc = desc; | ||
251 | |||
252 | of_node_put(events_np); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static int exynos_ppmu_parse_dt(struct exynos_ppmu *info) | ||
258 | { | ||
259 | struct device *dev = info->dev; | ||
260 | struct device_node *np = dev->of_node; | ||
261 | int ret = 0; | ||
262 | |||
263 | if (!np) { | ||
264 | dev_err(dev, "failed to find devicetree node\n"); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | |||
268 | /* Maps the memory mapped IO to control PPMU register */ | ||
269 | info->ppmu.base = of_iomap(np, 0); | ||
270 | if (IS_ERR_OR_NULL(info->ppmu.base)) { | ||
271 | dev_err(dev, "failed to map memory region\n"); | ||
272 | return -ENOMEM; | ||
273 | } | ||
274 | |||
275 | info->ppmu.clk = devm_clk_get(dev, "ppmu"); | ||
276 | if (IS_ERR(info->ppmu.clk)) { | ||
277 | info->ppmu.clk = NULL; | ||
278 | dev_warn(dev, "cannot get PPMU clock\n"); | ||
279 | } | ||
280 | |||
281 | ret = of_get_devfreq_events(np, info); | ||
282 | if (ret < 0) { | ||
283 | dev_err(dev, "failed to parse exynos ppmu dt node\n"); | ||
284 | goto err; | ||
285 | } | ||
286 | |||
287 | return 0; | ||
288 | |||
289 | err: | ||
290 | iounmap(info->ppmu.base); | ||
291 | |||
292 | return ret; | ||
293 | } | ||
294 | |||
295 | static int exynos_ppmu_probe(struct platform_device *pdev) | ||
296 | { | ||
297 | struct exynos_ppmu *info; | ||
298 | struct devfreq_event_dev **edev; | ||
299 | struct devfreq_event_desc *desc; | ||
300 | int i, ret = 0, size; | ||
301 | |||
302 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
303 | if (!info) | ||
304 | return -ENOMEM; | ||
305 | |||
306 | mutex_init(&info->lock); | ||
307 | info->dev = &pdev->dev; | ||
308 | |||
309 | /* Parse dt data to get resource */ | ||
310 | ret = exynos_ppmu_parse_dt(info); | ||
311 | if (ret < 0) { | ||
312 | dev_err(&pdev->dev, | ||
313 | "failed to parse devicetree for resource\n"); | ||
314 | return ret; | ||
315 | } | ||
316 | desc = info->desc; | ||
317 | |||
318 | size = sizeof(struct devfreq_event_dev *) * info->num_events; | ||
319 | info->edev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
320 | if (!info->edev) { | ||
321 | dev_err(&pdev->dev, | ||
322 | "failed to allocate memory devfreq-event devices\n"); | ||
323 | return -ENOMEM; | ||
324 | } | ||
325 | edev = info->edev; | ||
326 | platform_set_drvdata(pdev, info); | ||
327 | |||
328 | for (i = 0; i < info->num_events; i++) { | ||
329 | edev[i] = devm_devfreq_event_add_edev(&pdev->dev, &desc[i]); | ||
330 | if (IS_ERR(edev)) { | ||
331 | ret = PTR_ERR(edev); | ||
332 | dev_err(&pdev->dev, | ||
333 | "failed to add devfreq-event device\n"); | ||
334 | goto err; | ||
335 | } | ||
336 | } | ||
337 | |||
338 | clk_prepare_enable(info->ppmu.clk); | ||
339 | |||
340 | return 0; | ||
341 | err: | ||
342 | iounmap(info->ppmu.base); | ||
343 | |||
344 | return ret; | ||
345 | } | ||
346 | |||
347 | static int exynos_ppmu_remove(struct platform_device *pdev) | ||
348 | { | ||
349 | struct exynos_ppmu *info = platform_get_drvdata(pdev); | ||
350 | |||
351 | clk_disable_unprepare(info->ppmu.clk); | ||
352 | iounmap(info->ppmu.base); | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | static struct of_device_id exynos_ppmu_id_match[] = { | ||
358 | { .compatible = "samsung,exynos-ppmu", }, | ||
359 | { /* sentinel */ }, | ||
360 | }; | ||
361 | |||
362 | static struct platform_driver exynos_ppmu_driver = { | ||
363 | .probe = exynos_ppmu_probe, | ||
364 | .remove = exynos_ppmu_remove, | ||
365 | .driver = { | ||
366 | .name = "exynos-ppmu", | ||
367 | .of_match_table = exynos_ppmu_id_match, | ||
368 | }, | ||
369 | }; | ||
370 | module_platform_driver(exynos_ppmu_driver); | ||
371 | |||
372 | MODULE_DESCRIPTION("Exynos PPMU(Platform Performance Monitoring Unit) driver"); | ||
373 | MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); | ||
374 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/devfreq/event/exynos-ppmu.h b/drivers/devfreq/event/exynos-ppmu.h new file mode 100644 index 000000000000..4e831d48c138 --- /dev/null +++ b/drivers/devfreq/event/exynos-ppmu.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * exynos_ppmu.h - EXYNOS PPMU header file | ||
3 | * | ||
4 | * Copyright (c) 2015 Samsung Electronics Co., Ltd. | ||
5 | * Author : Chanwoo Choi <cw00.choi@samsung.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 | #ifndef __EXYNOS_PPMU_H__ | ||
13 | #define __EXYNOS_PPMU_H__ | ||
14 | |||
15 | enum ppmu_state { | ||
16 | PPMU_DISABLE = 0, | ||
17 | PPMU_ENABLE, | ||
18 | }; | ||
19 | |||
20 | enum ppmu_counter { | ||
21 | PPMU_PMNCNT0 = 0, | ||
22 | PPMU_PMNCNT1, | ||
23 | PPMU_PMNCNT2, | ||
24 | PPMU_PMNCNT3, | ||
25 | |||
26 | PPMU_PMNCNT_MAX, | ||
27 | }; | ||
28 | |||
29 | enum ppmu_event_type { | ||
30 | PPMU_RO_BUSY_CYCLE_CNT = 0x0, | ||
31 | PPMU_WO_BUSY_CYCLE_CNT = 0x1, | ||
32 | PPMU_RW_BUSY_CYCLE_CNT = 0x2, | ||
33 | PPMU_RO_REQUEST_CNT = 0x3, | ||
34 | PPMU_WO_REQUEST_CNT = 0x4, | ||
35 | PPMU_RO_DATA_CNT = 0x5, | ||
36 | PPMU_WO_DATA_CNT = 0x6, | ||
37 | PPMU_RO_LATENCY = 0x12, | ||
38 | PPMU_WO_LATENCY = 0x16, | ||
39 | }; | ||
40 | |||
41 | enum ppmu_reg { | ||
42 | /* PPC control register */ | ||
43 | PPMU_PMNC = 0x00, | ||
44 | PPMU_CNTENS = 0x10, | ||
45 | PPMU_CNTENC = 0x20, | ||
46 | PPMU_INTENS = 0x30, | ||
47 | PPMU_INTENC = 0x40, | ||
48 | PPMU_FLAG = 0x50, | ||
49 | |||
50 | /* Cycle Counter and Performance Event Counter Register */ | ||
51 | PPMU_CCNT = 0x100, | ||
52 | PPMU_PMCNT0 = 0x110, | ||
53 | PPMU_PMCNT1 = 0x120, | ||
54 | PPMU_PMCNT2 = 0x130, | ||
55 | PPMU_PMCNT3_HIGH = 0x140, | ||
56 | PPMU_PMCNT3_LOW = 0x150, | ||
57 | |||
58 | /* Bus Event Generator */ | ||
59 | PPMU_BEVT0SEL = 0x1000, | ||
60 | PPMU_BEVT1SEL = 0x1100, | ||
61 | PPMU_BEVT2SEL = 0x1200, | ||
62 | PPMU_BEVT3SEL = 0x1300, | ||
63 | PPMU_COUNTER_RESET = 0x1810, | ||
64 | PPMU_READ_OVERFLOW_CNT = 0x1810, | ||
65 | PPMU_READ_UNDERFLOW_CNT = 0x1814, | ||
66 | PPMU_WRITE_OVERFLOW_CNT = 0x1850, | ||
67 | PPMU_WRITE_UNDERFLOW_CNT = 0x1854, | ||
68 | PPMU_READ_PENDING_CNT = 0x1880, | ||
69 | PPMU_WRITE_PENDING_CNT = 0x1884 | ||
70 | }; | ||
71 | |||
72 | /* PMNC register */ | ||
73 | #define PPMU_PMNC_CC_RESET_SHIFT 2 | ||
74 | #define PPMU_PMNC_COUNTER_RESET_SHIFT 1 | ||
75 | #define PPMU_PMNC_ENABLE_SHIFT 0 | ||
76 | #define PPMU_PMNC_START_MODE_MASK BIT(16) | ||
77 | #define PPMU_PMNC_CC_DIVIDER_MASK BIT(3) | ||
78 | #define PPMU_PMNC_CC_RESET_MASK BIT(2) | ||
79 | #define PPMU_PMNC_COUNTER_RESET_MASK BIT(1) | ||
80 | #define PPMU_PMNC_ENABLE_MASK BIT(0) | ||
81 | |||
82 | /* CNTENS/CNTENC/INTENS/INTENC/FLAG register */ | ||
83 | #define PPMU_CCNT_MASK BIT(31) | ||
84 | #define PPMU_PMCNT3_MASK BIT(3) | ||
85 | #define PPMU_PMCNT2_MASK BIT(2) | ||
86 | #define PPMU_PMCNT1_MASK BIT(1) | ||
87 | #define PPMU_PMCNT0_MASK BIT(0) | ||
88 | |||
89 | /* PPMU_PMNCTx/PPMU_BETxSEL registers */ | ||
90 | #define PPMU_PMNCT(x) (PPMU_PMCNT0 + (0x10 * x)) | ||
91 | #define PPMU_BEVTxSEL(x) (PPMU_BEVT0SEL + (0x100 * x)) | ||
92 | |||
93 | #endif /* __EXYNOS_PPMU_H__ */ | ||
diff --git a/drivers/devfreq/tegra-devfreq.c b/drivers/devfreq/tegra-devfreq.c new file mode 100644 index 000000000000..34790961af5a --- /dev/null +++ b/drivers/devfreq/tegra-devfreq.c | |||
@@ -0,0 +1,718 @@ | |||
1 | /* | ||
2 | * A devfreq driver for NVIDIA Tegra SoCs | ||
3 | * | ||
4 | * Copyright (c) 2014 NVIDIA CORPORATION. All rights reserved. | ||
5 | * Copyright (C) 2014 Google, Inc | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/clk.h> | ||
22 | #include <linux/cpufreq.h> | ||
23 | #include <linux/devfreq.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/pm_opp.h> | ||
29 | #include <linux/reset.h> | ||
30 | |||
31 | #include "governor.h" | ||
32 | |||
33 | #define ACTMON_GLB_STATUS 0x0 | ||
34 | #define ACTMON_GLB_PERIOD_CTRL 0x4 | ||
35 | |||
36 | #define ACTMON_DEV_CTRL 0x0 | ||
37 | #define ACTMON_DEV_CTRL_K_VAL_SHIFT 10 | ||
38 | #define ACTMON_DEV_CTRL_ENB_PERIODIC BIT(18) | ||
39 | #define ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN BIT(20) | ||
40 | #define ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN BIT(21) | ||
41 | #define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM_SHIFT 23 | ||
42 | #define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM_SHIFT 26 | ||
43 | #define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN BIT(29) | ||
44 | #define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN BIT(30) | ||
45 | #define ACTMON_DEV_CTRL_ENB BIT(31) | ||
46 | |||
47 | #define ACTMON_DEV_UPPER_WMARK 0x4 | ||
48 | #define ACTMON_DEV_LOWER_WMARK 0x8 | ||
49 | #define ACTMON_DEV_INIT_AVG 0xc | ||
50 | #define ACTMON_DEV_AVG_UPPER_WMARK 0x10 | ||
51 | #define ACTMON_DEV_AVG_LOWER_WMARK 0x14 | ||
52 | #define ACTMON_DEV_COUNT_WEIGHT 0x18 | ||
53 | #define ACTMON_DEV_AVG_COUNT 0x20 | ||
54 | #define ACTMON_DEV_INTR_STATUS 0x24 | ||
55 | |||
56 | #define ACTMON_INTR_STATUS_CLEAR 0xffffffff | ||
57 | |||
58 | #define ACTMON_DEV_INTR_CONSECUTIVE_UPPER BIT(31) | ||
59 | #define ACTMON_DEV_INTR_CONSECUTIVE_LOWER BIT(30) | ||
60 | |||
61 | #define ACTMON_ABOVE_WMARK_WINDOW 1 | ||
62 | #define ACTMON_BELOW_WMARK_WINDOW 3 | ||
63 | #define ACTMON_BOOST_FREQ_STEP 16000 | ||
64 | |||
65 | /* activity counter is incremented every 256 memory transactions, and each | ||
66 | * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is | ||
67 | * 4 * 256 = 1024. | ||
68 | */ | ||
69 | #define ACTMON_COUNT_WEIGHT 0x400 | ||
70 | |||
71 | /* | ||
72 | * ACTMON_AVERAGE_WINDOW_LOG2: default value for @DEV_CTRL_K_VAL, which | ||
73 | * translates to 2 ^ (K_VAL + 1). ex: 2 ^ (6 + 1) = 128 | ||
74 | */ | ||
75 | #define ACTMON_AVERAGE_WINDOW_LOG2 6 | ||
76 | #define ACTMON_SAMPLING_PERIOD 12 /* ms */ | ||
77 | #define ACTMON_DEFAULT_AVG_BAND 6 /* 1/10 of % */ | ||
78 | |||
79 | #define KHZ 1000 | ||
80 | |||
81 | /* Assume that the bus is saturated if the utilization is 25% */ | ||
82 | #define BUS_SATURATION_RATIO 25 | ||
83 | |||
84 | /** | ||
85 | * struct tegra_devfreq_device_config - configuration specific to an ACTMON | ||
86 | * device | ||
87 | * | ||
88 | * Coefficients and thresholds are in % | ||
89 | */ | ||
90 | struct tegra_devfreq_device_config { | ||
91 | u32 offset; | ||
92 | u32 irq_mask; | ||
93 | |||
94 | unsigned int boost_up_coeff; | ||
95 | unsigned int boost_down_coeff; | ||
96 | unsigned int boost_up_threshold; | ||
97 | unsigned int boost_down_threshold; | ||
98 | u32 avg_dependency_threshold; | ||
99 | }; | ||
100 | |||
101 | enum tegra_actmon_device { | ||
102 | MCALL = 0, | ||
103 | MCCPU, | ||
104 | }; | ||
105 | |||
106 | static struct tegra_devfreq_device_config actmon_device_configs[] = { | ||
107 | { | ||
108 | /* MCALL */ | ||
109 | .offset = 0x1c0, | ||
110 | .irq_mask = 1 << 26, | ||
111 | .boost_up_coeff = 200, | ||
112 | .boost_down_coeff = 50, | ||
113 | .boost_up_threshold = 60, | ||
114 | .boost_down_threshold = 40, | ||
115 | }, | ||
116 | { | ||
117 | /* MCCPU */ | ||
118 | .offset = 0x200, | ||
119 | .irq_mask = 1 << 25, | ||
120 | .boost_up_coeff = 800, | ||
121 | .boost_down_coeff = 90, | ||
122 | .boost_up_threshold = 27, | ||
123 | .boost_down_threshold = 10, | ||
124 | .avg_dependency_threshold = 50000, | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | /** | ||
129 | * struct tegra_devfreq_device - state specific to an ACTMON device | ||
130 | * | ||
131 | * Frequencies are in kHz. | ||
132 | */ | ||
133 | struct tegra_devfreq_device { | ||
134 | const struct tegra_devfreq_device_config *config; | ||
135 | |||
136 | void __iomem *regs; | ||
137 | u32 avg_band_freq; | ||
138 | u32 avg_count; | ||
139 | |||
140 | unsigned long target_freq; | ||
141 | unsigned long boost_freq; | ||
142 | }; | ||
143 | |||
144 | struct tegra_devfreq { | ||
145 | struct devfreq *devfreq; | ||
146 | |||
147 | struct platform_device *pdev; | ||
148 | struct reset_control *reset; | ||
149 | struct clk *clock; | ||
150 | void __iomem *regs; | ||
151 | |||
152 | spinlock_t lock; | ||
153 | |||
154 | struct clk *emc_clock; | ||
155 | unsigned long max_freq; | ||
156 | unsigned long cur_freq; | ||
157 | struct notifier_block rate_change_nb; | ||
158 | |||
159 | struct tegra_devfreq_device devices[ARRAY_SIZE(actmon_device_configs)]; | ||
160 | }; | ||
161 | |||
162 | struct tegra_actmon_emc_ratio { | ||
163 | unsigned long cpu_freq; | ||
164 | unsigned long emc_freq; | ||
165 | }; | ||
166 | |||
167 | static struct tegra_actmon_emc_ratio actmon_emc_ratios[] = { | ||
168 | { 1400000, ULONG_MAX }, | ||
169 | { 1200000, 750000 }, | ||
170 | { 1100000, 600000 }, | ||
171 | { 1000000, 500000 }, | ||
172 | { 800000, 375000 }, | ||
173 | { 500000, 200000 }, | ||
174 | { 250000, 100000 }, | ||
175 | }; | ||
176 | |||
177 | static unsigned long do_percent(unsigned long val, unsigned int pct) | ||
178 | { | ||
179 | return val * pct / 100; | ||
180 | } | ||
181 | |||
182 | static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq_device *dev) | ||
183 | { | ||
184 | u32 avg = dev->avg_count; | ||
185 | u32 band = dev->avg_band_freq * ACTMON_SAMPLING_PERIOD; | ||
186 | |||
187 | writel(avg + band, dev->regs + ACTMON_DEV_AVG_UPPER_WMARK); | ||
188 | avg = max(avg, band); | ||
189 | writel(avg - band, dev->regs + ACTMON_DEV_AVG_LOWER_WMARK); | ||
190 | } | ||
191 | |||
192 | static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra, | ||
193 | struct tegra_devfreq_device *dev) | ||
194 | { | ||
195 | u32 val = tegra->cur_freq * ACTMON_SAMPLING_PERIOD; | ||
196 | |||
197 | writel(do_percent(val, dev->config->boost_up_threshold), | ||
198 | dev->regs + ACTMON_DEV_UPPER_WMARK); | ||
199 | |||
200 | writel(do_percent(val, dev->config->boost_down_threshold), | ||
201 | dev->regs + ACTMON_DEV_LOWER_WMARK); | ||
202 | } | ||
203 | |||
204 | static void actmon_write_barrier(struct tegra_devfreq *tegra) | ||
205 | { | ||
206 | /* ensure the update has reached the ACTMON */ | ||
207 | wmb(); | ||
208 | readl(tegra->regs + ACTMON_GLB_STATUS); | ||
209 | } | ||
210 | |||
211 | static irqreturn_t actmon_isr(int irq, void *data) | ||
212 | { | ||
213 | struct tegra_devfreq *tegra = data; | ||
214 | struct tegra_devfreq_device *dev = NULL; | ||
215 | unsigned long flags; | ||
216 | u32 val; | ||
217 | unsigned int i; | ||
218 | |||
219 | val = readl(tegra->regs + ACTMON_GLB_STATUS); | ||
220 | |||
221 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { | ||
222 | if (val & tegra->devices[i].config->irq_mask) { | ||
223 | dev = tegra->devices + i; | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if (!dev) | ||
229 | return IRQ_NONE; | ||
230 | |||
231 | spin_lock_irqsave(&tegra->lock, flags); | ||
232 | |||
233 | dev->avg_count = readl(dev->regs + ACTMON_DEV_AVG_COUNT); | ||
234 | tegra_devfreq_update_avg_wmark(dev); | ||
235 | |||
236 | val = readl(dev->regs + ACTMON_DEV_INTR_STATUS); | ||
237 | if (val & ACTMON_DEV_INTR_CONSECUTIVE_UPPER) { | ||
238 | val = readl(dev->regs + ACTMON_DEV_CTRL) | | ||
239 | ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN | | ||
240 | ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
241 | |||
242 | /* | ||
243 | * new_boost = min(old_boost * up_coef + step, max_freq) | ||
244 | */ | ||
245 | dev->boost_freq = do_percent(dev->boost_freq, | ||
246 | dev->config->boost_up_coeff); | ||
247 | dev->boost_freq += ACTMON_BOOST_FREQ_STEP; | ||
248 | if (dev->boost_freq >= tegra->max_freq) { | ||
249 | dev->boost_freq = tegra->max_freq; | ||
250 | val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN; | ||
251 | } | ||
252 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
253 | } else if (val & ACTMON_DEV_INTR_CONSECUTIVE_LOWER) { | ||
254 | val = readl(dev->regs + ACTMON_DEV_CTRL) | | ||
255 | ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN | | ||
256 | ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
257 | |||
258 | /* | ||
259 | * new_boost = old_boost * down_coef | ||
260 | * or 0 if (old_boost * down_coef < step / 2) | ||
261 | */ | ||
262 | dev->boost_freq = do_percent(dev->boost_freq, | ||
263 | dev->config->boost_down_coeff); | ||
264 | if (dev->boost_freq < (ACTMON_BOOST_FREQ_STEP >> 1)) { | ||
265 | dev->boost_freq = 0; | ||
266 | val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
267 | } | ||
268 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
269 | } | ||
270 | |||
271 | if (dev->config->avg_dependency_threshold) { | ||
272 | val = readl(dev->regs + ACTMON_DEV_CTRL); | ||
273 | if (dev->avg_count >= dev->config->avg_dependency_threshold) | ||
274 | val |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
275 | else if (dev->boost_freq == 0) | ||
276 | val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; | ||
277 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
278 | } | ||
279 | |||
280 | writel(ACTMON_INTR_STATUS_CLEAR, dev->regs + ACTMON_DEV_INTR_STATUS); | ||
281 | |||
282 | actmon_write_barrier(tegra); | ||
283 | |||
284 | spin_unlock_irqrestore(&tegra->lock, flags); | ||
285 | |||
286 | return IRQ_WAKE_THREAD; | ||
287 | } | ||
288 | |||
289 | static unsigned long actmon_cpu_to_emc_rate(struct tegra_devfreq *tegra, | ||
290 | unsigned long cpu_freq) | ||
291 | { | ||
292 | unsigned int i; | ||
293 | struct tegra_actmon_emc_ratio *ratio = actmon_emc_ratios; | ||
294 | |||
295 | for (i = 0; i < ARRAY_SIZE(actmon_emc_ratios); i++, ratio++) { | ||
296 | if (cpu_freq >= ratio->cpu_freq) { | ||
297 | if (ratio->emc_freq >= tegra->max_freq) | ||
298 | return tegra->max_freq; | ||
299 | else | ||
300 | return ratio->emc_freq; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static void actmon_update_target(struct tegra_devfreq *tegra, | ||
308 | struct tegra_devfreq_device *dev) | ||
309 | { | ||
310 | unsigned long cpu_freq = 0; | ||
311 | unsigned long static_cpu_emc_freq = 0; | ||
312 | unsigned int avg_sustain_coef; | ||
313 | unsigned long flags; | ||
314 | |||
315 | if (dev->config->avg_dependency_threshold) { | ||
316 | cpu_freq = cpufreq_get(0); | ||
317 | static_cpu_emc_freq = actmon_cpu_to_emc_rate(tegra, cpu_freq); | ||
318 | } | ||
319 | |||
320 | spin_lock_irqsave(&tegra->lock, flags); | ||
321 | |||
322 | dev->target_freq = dev->avg_count / ACTMON_SAMPLING_PERIOD; | ||
323 | avg_sustain_coef = 100 * 100 / dev->config->boost_up_threshold; | ||
324 | dev->target_freq = do_percent(dev->target_freq, avg_sustain_coef); | ||
325 | dev->target_freq += dev->boost_freq; | ||
326 | |||
327 | if (dev->avg_count >= dev->config->avg_dependency_threshold) | ||
328 | dev->target_freq = max(dev->target_freq, static_cpu_emc_freq); | ||
329 | |||
330 | spin_unlock_irqrestore(&tegra->lock, flags); | ||
331 | } | ||
332 | |||
333 | static irqreturn_t actmon_thread_isr(int irq, void *data) | ||
334 | { | ||
335 | struct tegra_devfreq *tegra = data; | ||
336 | |||
337 | mutex_lock(&tegra->devfreq->lock); | ||
338 | update_devfreq(tegra->devfreq); | ||
339 | mutex_unlock(&tegra->devfreq->lock); | ||
340 | |||
341 | return IRQ_HANDLED; | ||
342 | } | ||
343 | |||
344 | static int tegra_actmon_rate_notify_cb(struct notifier_block *nb, | ||
345 | unsigned long action, void *ptr) | ||
346 | { | ||
347 | struct clk_notifier_data *data = ptr; | ||
348 | struct tegra_devfreq *tegra = container_of(nb, struct tegra_devfreq, | ||
349 | rate_change_nb); | ||
350 | unsigned int i; | ||
351 | unsigned long flags; | ||
352 | |||
353 | spin_lock_irqsave(&tegra->lock, flags); | ||
354 | |||
355 | switch (action) { | ||
356 | case POST_RATE_CHANGE: | ||
357 | tegra->cur_freq = data->new_rate / KHZ; | ||
358 | |||
359 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) | ||
360 | tegra_devfreq_update_wmark(tegra, tegra->devices + i); | ||
361 | |||
362 | actmon_write_barrier(tegra); | ||
363 | break; | ||
364 | case PRE_RATE_CHANGE: | ||
365 | /* fall through */ | ||
366 | case ABORT_RATE_CHANGE: | ||
367 | break; | ||
368 | }; | ||
369 | |||
370 | spin_unlock_irqrestore(&tegra->lock, flags); | ||
371 | |||
372 | return NOTIFY_OK; | ||
373 | } | ||
374 | |||
375 | static void tegra_actmon_configure_device(struct tegra_devfreq *tegra, | ||
376 | struct tegra_devfreq_device *dev) | ||
377 | { | ||
378 | u32 val; | ||
379 | |||
380 | dev->avg_band_freq = tegra->max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ; | ||
381 | dev->target_freq = tegra->cur_freq; | ||
382 | |||
383 | dev->avg_count = tegra->cur_freq * ACTMON_SAMPLING_PERIOD; | ||
384 | writel(dev->avg_count, dev->regs + ACTMON_DEV_INIT_AVG); | ||
385 | |||
386 | tegra_devfreq_update_avg_wmark(dev); | ||
387 | tegra_devfreq_update_wmark(tegra, dev); | ||
388 | |||
389 | writel(ACTMON_COUNT_WEIGHT, dev->regs + ACTMON_DEV_COUNT_WEIGHT); | ||
390 | writel(ACTMON_INTR_STATUS_CLEAR, dev->regs + ACTMON_DEV_INTR_STATUS); | ||
391 | |||
392 | val = 0; | ||
393 | val |= ACTMON_DEV_CTRL_ENB_PERIODIC | | ||
394 | ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN | | ||
395 | ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN; | ||
396 | val |= (ACTMON_AVERAGE_WINDOW_LOG2 - 1) | ||
397 | << ACTMON_DEV_CTRL_K_VAL_SHIFT; | ||
398 | val |= (ACTMON_BELOW_WMARK_WINDOW - 1) | ||
399 | << ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM_SHIFT; | ||
400 | val |= (ACTMON_ABOVE_WMARK_WINDOW - 1) | ||
401 | << ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM_SHIFT; | ||
402 | val |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN | | ||
403 | ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN; | ||
404 | |||
405 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
406 | |||
407 | actmon_write_barrier(tegra); | ||
408 | |||
409 | val = readl(dev->regs + ACTMON_DEV_CTRL); | ||
410 | val |= ACTMON_DEV_CTRL_ENB; | ||
411 | writel(val, dev->regs + ACTMON_DEV_CTRL); | ||
412 | |||
413 | actmon_write_barrier(tegra); | ||
414 | } | ||
415 | |||
416 | static int tegra_devfreq_suspend(struct device *dev) | ||
417 | { | ||
418 | struct platform_device *pdev; | ||
419 | struct tegra_devfreq *tegra; | ||
420 | struct tegra_devfreq_device *actmon_dev; | ||
421 | unsigned int i; | ||
422 | u32 val; | ||
423 | |||
424 | pdev = container_of(dev, struct platform_device, dev); | ||
425 | tegra = platform_get_drvdata(pdev); | ||
426 | |||
427 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { | ||
428 | actmon_dev = &tegra->devices[i]; | ||
429 | |||
430 | val = readl(actmon_dev->regs + ACTMON_DEV_CTRL); | ||
431 | val &= ~ACTMON_DEV_CTRL_ENB; | ||
432 | writel(val, actmon_dev->regs + ACTMON_DEV_CTRL); | ||
433 | |||
434 | writel(ACTMON_INTR_STATUS_CLEAR, | ||
435 | actmon_dev->regs + ACTMON_DEV_INTR_STATUS); | ||
436 | |||
437 | actmon_write_barrier(tegra); | ||
438 | } | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | static int tegra_devfreq_resume(struct device *dev) | ||
444 | { | ||
445 | struct platform_device *pdev; | ||
446 | struct tegra_devfreq *tegra; | ||
447 | struct tegra_devfreq_device *actmon_dev; | ||
448 | unsigned int i; | ||
449 | |||
450 | pdev = container_of(dev, struct platform_device, dev); | ||
451 | tegra = platform_get_drvdata(pdev); | ||
452 | |||
453 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { | ||
454 | actmon_dev = &tegra->devices[i]; | ||
455 | |||
456 | tegra_actmon_configure_device(tegra, actmon_dev); | ||
457 | } | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | static int tegra_devfreq_target(struct device *dev, unsigned long *freq, | ||
463 | u32 flags) | ||
464 | { | ||
465 | struct platform_device *pdev; | ||
466 | struct tegra_devfreq *tegra; | ||
467 | struct dev_pm_opp *opp; | ||
468 | unsigned long rate = *freq * KHZ; | ||
469 | |||
470 | pdev = container_of(dev, struct platform_device, dev); | ||
471 | tegra = platform_get_drvdata(pdev); | ||
472 | |||
473 | rcu_read_lock(); | ||
474 | opp = devfreq_recommended_opp(dev, &rate, flags); | ||
475 | if (IS_ERR(opp)) { | ||
476 | rcu_read_unlock(); | ||
477 | dev_err(dev, "Failed to find opp for %lu KHz\n", *freq); | ||
478 | return PTR_ERR(opp); | ||
479 | } | ||
480 | rate = dev_pm_opp_get_freq(opp); | ||
481 | rcu_read_unlock(); | ||
482 | |||
483 | /* TODO: Once we have per-user clk constraints, set a floor */ | ||
484 | clk_set_rate(tegra->emc_clock, rate); | ||
485 | |||
486 | /* TODO: Set voltage as well */ | ||
487 | |||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | static int tegra_devfreq_get_dev_status(struct device *dev, | ||
492 | struct devfreq_dev_status *stat) | ||
493 | { | ||
494 | struct platform_device *pdev; | ||
495 | struct tegra_devfreq *tegra; | ||
496 | struct tegra_devfreq_device *actmon_dev; | ||
497 | |||
498 | pdev = container_of(dev, struct platform_device, dev); | ||
499 | tegra = platform_get_drvdata(pdev); | ||
500 | |||
501 | stat->current_frequency = tegra->cur_freq; | ||
502 | |||
503 | /* To be used by the tegra governor */ | ||
504 | stat->private_data = tegra; | ||
505 | |||
506 | /* The below are to be used by the other governors */ | ||
507 | |||
508 | actmon_dev = &tegra->devices[MCALL]; | ||
509 | |||
510 | /* Number of cycles spent on memory access */ | ||
511 | stat->busy_time = actmon_dev->avg_count; | ||
512 | |||
513 | /* The bus can be considered to be saturated way before 100% */ | ||
514 | stat->busy_time *= 100 / BUS_SATURATION_RATIO; | ||
515 | |||
516 | /* Number of cycles in a sampling period */ | ||
517 | stat->total_time = ACTMON_SAMPLING_PERIOD * tegra->cur_freq; | ||
518 | |||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static int tegra_devfreq_get_target(struct devfreq *devfreq, | ||
523 | unsigned long *freq) | ||
524 | { | ||
525 | struct devfreq_dev_status stat; | ||
526 | struct tegra_devfreq *tegra; | ||
527 | struct tegra_devfreq_device *dev; | ||
528 | unsigned long target_freq = 0; | ||
529 | unsigned int i; | ||
530 | int err; | ||
531 | |||
532 | err = devfreq->profile->get_dev_status(devfreq->dev.parent, &stat); | ||
533 | if (err) | ||
534 | return err; | ||
535 | |||
536 | tegra = stat.private_data; | ||
537 | |||
538 | for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { | ||
539 | dev = &tegra->devices[i]; | ||
540 | |||
541 | actmon_update_target(tegra, dev); | ||
542 | |||
543 | target_freq = max(target_freq, dev->target_freq); | ||
544 | } | ||
545 | |||
546 | *freq = target_freq; | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | static int tegra_devfreq_event_handler(struct devfreq *devfreq, | ||
552 | unsigned int event, void *data) | ||
553 | { | ||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static struct devfreq_governor tegra_devfreq_governor = { | ||
558 | .name = "tegra", | ||
559 | .get_target_freq = tegra_devfreq_get_target, | ||
560 | .event_handler = tegra_devfreq_event_handler, | ||
561 | }; | ||
562 | |||
563 | static struct devfreq_dev_profile tegra_devfreq_profile = { | ||
564 | .polling_ms = 0, | ||
565 | .target = tegra_devfreq_target, | ||
566 | .get_dev_status = tegra_devfreq_get_dev_status, | ||
567 | }; | ||
568 | |||
569 | static int tegra_devfreq_probe(struct platform_device *pdev) | ||
570 | { | ||
571 | struct tegra_devfreq *tegra; | ||
572 | struct tegra_devfreq_device *dev; | ||
573 | struct resource *res; | ||
574 | unsigned long max_freq; | ||
575 | unsigned int i; | ||
576 | int irq; | ||
577 | int err; | ||
578 | |||
579 | tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); | ||
580 | if (!tegra) | ||
581 | return -ENOMEM; | ||
582 | |||
583 | spin_lock_init(&tegra->lock); | ||
584 | |||
585 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
586 | if (!res) { | ||
587 | dev_err(&pdev->dev, "Failed to get regs resource\n"); | ||
588 | return -ENODEV; | ||
589 | } | ||
590 | |||
591 | tegra->regs = devm_ioremap_resource(&pdev->dev, res); | ||
592 | if (IS_ERR(tegra->regs)) { | ||
593 | dev_err(&pdev->dev, "Failed to get IO memory\n"); | ||
594 | return PTR_ERR(tegra->regs); | ||
595 | } | ||
596 | |||
597 | tegra->reset = devm_reset_control_get(&pdev->dev, "actmon"); | ||
598 | if (IS_ERR(tegra->reset)) { | ||
599 | dev_err(&pdev->dev, "Failed to get reset\n"); | ||
600 | return PTR_ERR(tegra->reset); | ||
601 | } | ||
602 | |||
603 | tegra->clock = devm_clk_get(&pdev->dev, "actmon"); | ||
604 | if (IS_ERR(tegra->clock)) { | ||
605 | dev_err(&pdev->dev, "Failed to get actmon clock\n"); | ||
606 | return PTR_ERR(tegra->clock); | ||
607 | } | ||
608 | |||
609 | tegra->emc_clock = devm_clk_get(&pdev->dev, "emc"); | ||
610 | if (IS_ERR(tegra->emc_clock)) { | ||
611 | dev_err(&pdev->dev, "Failed to get emc clock\n"); | ||
612 | return PTR_ERR(tegra->emc_clock); | ||
613 | } | ||
614 | |||
615 | err = of_init_opp_table(&pdev->dev); | ||
616 | if (err) { | ||
617 | dev_err(&pdev->dev, "Failed to init operating point table\n"); | ||
618 | return err; | ||
619 | } | ||
620 | |||
621 | tegra->rate_change_nb.notifier_call = tegra_actmon_rate_notify_cb; | ||
622 | err = clk_notifier_register(tegra->emc_clock, &tegra->rate_change_nb); | ||
623 | if (err) { | ||
624 | dev_err(&pdev->dev, | ||
625 | "Failed to register rate change notifier\n"); | ||
626 | return err; | ||
627 | } | ||
628 | |||
629 | reset_control_assert(tegra->reset); | ||
630 | |||
631 | err = clk_prepare_enable(tegra->clock); | ||
632 | if (err) { | ||
633 | reset_control_deassert(tegra->reset); | ||
634 | return err; | ||
635 | } | ||
636 | |||
637 | reset_control_deassert(tegra->reset); | ||
638 | |||
639 | max_freq = clk_round_rate(tegra->emc_clock, ULONG_MAX); | ||
640 | tegra->max_freq = max_freq / KHZ; | ||
641 | |||
642 | clk_set_rate(tegra->emc_clock, max_freq); | ||
643 | |||
644 | tegra->cur_freq = clk_get_rate(tegra->emc_clock) / KHZ; | ||
645 | |||
646 | writel(ACTMON_SAMPLING_PERIOD - 1, | ||
647 | tegra->regs + ACTMON_GLB_PERIOD_CTRL); | ||
648 | |||
649 | for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) { | ||
650 | dev = tegra->devices + i; | ||
651 | dev->config = actmon_device_configs + i; | ||
652 | dev->regs = tegra->regs + dev->config->offset; | ||
653 | |||
654 | tegra_actmon_configure_device(tegra, tegra->devices + i); | ||
655 | } | ||
656 | |||
657 | err = devfreq_add_governor(&tegra_devfreq_governor); | ||
658 | if (err) { | ||
659 | dev_err(&pdev->dev, "Failed to add governor\n"); | ||
660 | return err; | ||
661 | } | ||
662 | |||
663 | tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock); | ||
664 | tegra->devfreq = devm_devfreq_add_device(&pdev->dev, | ||
665 | &tegra_devfreq_profile, | ||
666 | "tegra", | ||
667 | NULL); | ||
668 | |||
669 | irq = platform_get_irq(pdev, 0); | ||
670 | err = devm_request_threaded_irq(&pdev->dev, irq, actmon_isr, | ||
671 | actmon_thread_isr, IRQF_SHARED, | ||
672 | "tegra-devfreq", tegra); | ||
673 | if (err) { | ||
674 | dev_err(&pdev->dev, "Interrupt request failed\n"); | ||
675 | return err; | ||
676 | } | ||
677 | |||
678 | platform_set_drvdata(pdev, tegra); | ||
679 | |||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | static int tegra_devfreq_remove(struct platform_device *pdev) | ||
684 | { | ||
685 | struct tegra_devfreq *tegra = platform_get_drvdata(pdev); | ||
686 | |||
687 | clk_notifier_unregister(tegra->emc_clock, &tegra->rate_change_nb); | ||
688 | |||
689 | clk_disable_unprepare(tegra->clock); | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | static SIMPLE_DEV_PM_OPS(tegra_devfreq_pm_ops, | ||
695 | tegra_devfreq_suspend, | ||
696 | tegra_devfreq_resume); | ||
697 | |||
698 | static struct of_device_id tegra_devfreq_of_match[] = { | ||
699 | { .compatible = "nvidia,tegra124-actmon" }, | ||
700 | { }, | ||
701 | }; | ||
702 | |||
703 | static struct platform_driver tegra_devfreq_driver = { | ||
704 | .probe = tegra_devfreq_probe, | ||
705 | .remove = tegra_devfreq_remove, | ||
706 | .driver = { | ||
707 | .name = "tegra-devfreq", | ||
708 | .owner = THIS_MODULE, | ||
709 | .of_match_table = tegra_devfreq_of_match, | ||
710 | .pm = &tegra_devfreq_pm_ops, | ||
711 | }, | ||
712 | }; | ||
713 | module_platform_driver(tegra_devfreq_driver); | ||
714 | |||
715 | MODULE_LICENSE("GPL"); | ||
716 | MODULE_DESCRIPTION("Tegra devfreq driver"); | ||
717 | MODULE_AUTHOR("Tomeu Vizoso <tomeu.vizoso@collabora.com>"); | ||
718 | MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match); | ||
diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index de361a156b34..5a635646e05c 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c | |||
@@ -43,7 +43,7 @@ static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp, | |||
43 | { | 43 | { |
44 | const struct acpi_csrt_shared_info *si; | 44 | const struct acpi_csrt_shared_info *si; |
45 | struct list_head resource_list; | 45 | struct list_head resource_list; |
46 | struct resource_list_entry *rentry; | 46 | struct resource_entry *rentry; |
47 | resource_size_t mem = 0, irq = 0; | 47 | resource_size_t mem = 0, irq = 0; |
48 | int ret; | 48 | int ret; |
49 | 49 | ||
@@ -56,10 +56,10 @@ static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp, | |||
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | list_for_each_entry(rentry, &resource_list, node) { | 58 | list_for_each_entry(rentry, &resource_list, node) { |
59 | if (resource_type(&rentry->res) == IORESOURCE_MEM) | 59 | if (resource_type(rentry->res) == IORESOURCE_MEM) |
60 | mem = rentry->res.start; | 60 | mem = rentry->res->start; |
61 | else if (resource_type(&rentry->res) == IORESOURCE_IRQ) | 61 | else if (resource_type(rentry->res) == IORESOURCE_IRQ) |
62 | irq = rentry->res.start; | 62 | irq = rentry->res->start; |
63 | } | 63 | } |
64 | 64 | ||
65 | acpi_dev_free_resource_list(&resource_list); | 65 | acpi_dev_free_resource_list(&resource_list); |
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 4d6b26979fbd..bb3725b672cf 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c | |||
@@ -861,8 +861,8 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) | |||
861 | break; | 861 | break; |
862 | 862 | ||
863 | case ACPI_RESOURCE_TYPE_ADDRESS64: | 863 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
864 | hyperv_mmio.start = res->data.address64.minimum; | 864 | hyperv_mmio.start = res->data.address64.address.minimum; |
865 | hyperv_mmio.end = res->data.address64.maximum; | 865 | hyperv_mmio.end = res->data.address64.address.maximum; |
866 | break; | 866 | break; |
867 | } | 867 | } |
868 | 868 | ||
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 6dbf6fcbdfaf..e8902f8dddfc 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c | |||
@@ -386,7 +386,7 @@ static int __init pcc_init(void) | |||
386 | ret = acpi_pcc_probe(); | 386 | ret = acpi_pcc_probe(); |
387 | 387 | ||
388 | if (ret) { | 388 | if (ret) { |
389 | pr_err("ACPI PCC probe failed.\n"); | 389 | pr_debug("ACPI PCC probe failed.\n"); |
390 | return -ENODEV; | 390 | return -ENODEV; |
391 | } | 391 | } |
392 | 392 | ||
@@ -394,7 +394,7 @@ static int __init pcc_init(void) | |||
394 | pcc_mbox_probe, NULL, 0, NULL, 0); | 394 | pcc_mbox_probe, NULL, 0, NULL, 0); |
395 | 395 | ||
396 | if (!pcc_pdev) { | 396 | if (!pcc_pdev) { |
397 | pr_err("Err creating PCC platform bundle\n"); | 397 | pr_debug("Err creating PCC platform bundle\n"); |
398 | return -ENODEV; | 398 | return -ENODEV; |
399 | } | 399 | } |
400 | 400 | ||
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index 60dc36c865b5..110fece2ff53 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c | |||
@@ -140,7 +140,7 @@ int of_pci_get_host_bridge_resources(struct device_node *dev, | |||
140 | unsigned char busno, unsigned char bus_max, | 140 | unsigned char busno, unsigned char bus_max, |
141 | struct list_head *resources, resource_size_t *io_base) | 141 | struct list_head *resources, resource_size_t *io_base) |
142 | { | 142 | { |
143 | struct pci_host_bridge_window *window; | 143 | struct resource_entry *window; |
144 | struct resource *res; | 144 | struct resource *res; |
145 | struct resource *bus_range; | 145 | struct resource *bus_range; |
146 | struct of_pci_range range; | 146 | struct of_pci_range range; |
@@ -226,7 +226,7 @@ int of_pci_get_host_bridge_resources(struct device_node *dev, | |||
226 | conversion_failed: | 226 | conversion_failed: |
227 | kfree(res); | 227 | kfree(res); |
228 | parse_failed: | 228 | parse_failed: |
229 | list_for_each_entry(window, resources, list) | 229 | resource_list_for_each_entry(window, resources) |
230 | kfree(window->res); | 230 | kfree(window->res); |
231 | pci_free_resource_list(resources); | 231 | pci_free_resource_list(resources); |
232 | kfree(bus_range); | 232 | kfree(bus_range); |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 8fb16188cd82..90fa3a78fb7c 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -20,17 +20,16 @@ | |||
20 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, | 20 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, |
21 | resource_size_t offset) | 21 | resource_size_t offset) |
22 | { | 22 | { |
23 | struct pci_host_bridge_window *window; | 23 | struct resource_entry *entry; |
24 | 24 | ||
25 | window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL); | 25 | entry = resource_list_create_entry(res, 0); |
26 | if (!window) { | 26 | if (!entry) { |
27 | printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res); | 27 | printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res); |
28 | return; | 28 | return; |
29 | } | 29 | } |
30 | 30 | ||
31 | window->res = res; | 31 | entry->offset = offset; |
32 | window->offset = offset; | 32 | resource_list_add_tail(entry, resources); |
33 | list_add_tail(&window->list, resources); | ||
34 | } | 33 | } |
35 | EXPORT_SYMBOL(pci_add_resource_offset); | 34 | EXPORT_SYMBOL(pci_add_resource_offset); |
36 | 35 | ||
@@ -42,12 +41,7 @@ EXPORT_SYMBOL(pci_add_resource); | |||
42 | 41 | ||
43 | void pci_free_resource_list(struct list_head *resources) | 42 | void pci_free_resource_list(struct list_head *resources) |
44 | { | 43 | { |
45 | struct pci_host_bridge_window *window, *tmp; | 44 | resource_list_free(resources); |
46 | |||
47 | list_for_each_entry_safe(window, tmp, resources, list) { | ||
48 | list_del(&window->list); | ||
49 | kfree(window); | ||
50 | } | ||
51 | } | 45 | } |
52 | EXPORT_SYMBOL(pci_free_resource_list); | 46 | EXPORT_SYMBOL(pci_free_resource_list); |
53 | 47 | ||
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c index 0e5f3c95af5b..39b2dbe585aa 100644 --- a/drivers/pci/host-bridge.c +++ b/drivers/pci/host-bridge.c | |||
@@ -35,10 +35,10 @@ void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, | |||
35 | struct resource *res) | 35 | struct resource *res) |
36 | { | 36 | { |
37 | struct pci_host_bridge *bridge = find_pci_host_bridge(bus); | 37 | struct pci_host_bridge *bridge = find_pci_host_bridge(bus); |
38 | struct pci_host_bridge_window *window; | 38 | struct resource_entry *window; |
39 | resource_size_t offset = 0; | 39 | resource_size_t offset = 0; |
40 | 40 | ||
41 | list_for_each_entry(window, &bridge->windows, list) { | 41 | resource_list_for_each_entry(window, &bridge->windows) { |
42 | if (resource_contains(window->res, res)) { | 42 | if (resource_contains(window->res, res)) { |
43 | offset = window->offset; | 43 | offset = window->offset; |
44 | break; | 44 | break; |
@@ -60,10 +60,10 @@ void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res, | |||
60 | struct pci_bus_region *region) | 60 | struct pci_bus_region *region) |
61 | { | 61 | { |
62 | struct pci_host_bridge *bridge = find_pci_host_bridge(bus); | 62 | struct pci_host_bridge *bridge = find_pci_host_bridge(bus); |
63 | struct pci_host_bridge_window *window; | 63 | struct resource_entry *window; |
64 | resource_size_t offset = 0; | 64 | resource_size_t offset = 0; |
65 | 65 | ||
66 | list_for_each_entry(window, &bridge->windows, list) { | 66 | resource_list_for_each_entry(window, &bridge->windows) { |
67 | struct pci_bus_region bus_region; | 67 | struct pci_bus_region bus_region; |
68 | 68 | ||
69 | if (resource_type(res) != resource_type(window->res)) | 69 | if (resource_type(res) != resource_type(window->res)) |
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index 925e29e3d4c8..ba46e581db99 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c | |||
@@ -103,14 +103,14 @@ static int gen_pci_parse_request_of_pci_ranges(struct gen_pci *pci) | |||
103 | struct device *dev = pci->host.dev.parent; | 103 | struct device *dev = pci->host.dev.parent; |
104 | struct device_node *np = dev->of_node; | 104 | struct device_node *np = dev->of_node; |
105 | resource_size_t iobase; | 105 | resource_size_t iobase; |
106 | struct pci_host_bridge_window *win; | 106 | struct resource_entry *win; |
107 | 107 | ||
108 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, | 108 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, |
109 | &iobase); | 109 | &iobase); |
110 | if (err) | 110 | if (err) |
111 | return err; | 111 | return err; |
112 | 112 | ||
113 | list_for_each_entry(win, &pci->resources, list) { | 113 | resource_list_for_each_entry(win, &pci->resources) { |
114 | struct resource *parent, *res = win->res; | 114 | struct resource *parent, *res = win->res; |
115 | 115 | ||
116 | switch (resource_type(res)) { | 116 | switch (resource_type(res)) { |
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c index 341529ca23e8..1ec694a52379 100644 --- a/drivers/pci/host/pci-versatile.c +++ b/drivers/pci/host/pci-versatile.c | |||
@@ -74,13 +74,13 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, | |||
74 | int err, mem = 1, res_valid = 0; | 74 | int err, mem = 1, res_valid = 0; |
75 | struct device_node *np = dev->of_node; | 75 | struct device_node *np = dev->of_node; |
76 | resource_size_t iobase; | 76 | resource_size_t iobase; |
77 | struct pci_host_bridge_window *win; | 77 | struct resource_entry *win; |
78 | 78 | ||
79 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase); | 79 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase); |
80 | if (err) | 80 | if (err) |
81 | return err; | 81 | return err; |
82 | 82 | ||
83 | list_for_each_entry(win, res, list) { | 83 | resource_list_for_each_entry(win, res, list) { |
84 | struct resource *parent, *res = win->res; | 84 | struct resource *parent, *res = win->res; |
85 | 85 | ||
86 | switch (resource_type(res)) { | 86 | switch (resource_type(res)) { |
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index e77d831dc241..aab55474dd0d 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
@@ -269,11 +269,11 @@ static int xgene_pcie_map_ranges(struct xgene_pcie_port *port, | |||
269 | struct list_head *res, | 269 | struct list_head *res, |
270 | resource_size_t io_base) | 270 | resource_size_t io_base) |
271 | { | 271 | { |
272 | struct pci_host_bridge_window *window; | 272 | struct resource_entry *window; |
273 | struct device *dev = port->dev; | 273 | struct device *dev = port->dev; |
274 | int ret; | 274 | int ret; |
275 | 275 | ||
276 | list_for_each_entry(window, res, list) { | 276 | resource_list_for_each_entry(window, res) { |
277 | struct resource *res = window->res; | 277 | struct resource *res = window->res; |
278 | u64 restype = resource_type(res); | 278 | u64 restype = resource_type(res); |
279 | 279 | ||
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index eac4a4b957ca..f1a06a091ccb 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c | |||
@@ -667,7 +667,7 @@ static int xilinx_pcie_parse_and_add_res(struct xilinx_pcie_port *port) | |||
667 | resource_size_t offset; | 667 | resource_size_t offset; |
668 | struct of_pci_range_parser parser; | 668 | struct of_pci_range_parser parser; |
669 | struct of_pci_range range; | 669 | struct of_pci_range range; |
670 | struct pci_host_bridge_window *win; | 670 | struct resource_entry *win; |
671 | int err = 0, mem_resno = 0; | 671 | int err = 0, mem_resno = 0; |
672 | 672 | ||
673 | /* Get the ranges */ | 673 | /* Get the ranges */ |
@@ -737,7 +737,7 @@ static int xilinx_pcie_parse_and_add_res(struct xilinx_pcie_port *port) | |||
737 | 737 | ||
738 | free_resources: | 738 | free_resources: |
739 | release_child_resources(&iomem_resource); | 739 | release_child_resources(&iomem_resource); |
740 | list_for_each_entry(win, &port->resources, list) | 740 | resource_list_for_each_entry(win, &port->resources) |
741 | devm_kfree(dev, win->res); | 741 | devm_kfree(dev, win->res); |
742 | pci_free_resource_list(&port->resources); | 742 | pci_free_resource_list(&port->resources); |
743 | 743 | ||
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index bada20999870..c32fb786d48e 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -475,7 +475,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
475 | struct slot *slot = bss_hotplug_slot->private; | 475 | struct slot *slot = bss_hotplug_slot->private; |
476 | struct pci_dev *dev, *temp; | 476 | struct pci_dev *dev, *temp; |
477 | int rc; | 477 | int rc; |
478 | acpi_owner_id ssdt_id = 0; | 478 | acpi_handle ssdt_hdl = NULL; |
479 | 479 | ||
480 | /* Acquire update access to the bus */ | 480 | /* Acquire update access to the bus */ |
481 | mutex_lock(&sn_hotplug_mutex); | 481 | mutex_lock(&sn_hotplug_mutex); |
@@ -522,7 +522,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
522 | if (ACPI_SUCCESS(ret) && | 522 | if (ACPI_SUCCESS(ret) && |
523 | (adr>>16) == (slot->device_num + 1)) { | 523 | (adr>>16) == (slot->device_num + 1)) { |
524 | /* retain the owner id */ | 524 | /* retain the owner id */ |
525 | acpi_get_id(chandle, &ssdt_id); | 525 | ssdt_hdl = chandle; |
526 | 526 | ||
527 | ret = acpi_bus_get_device(chandle, | 527 | ret = acpi_bus_get_device(chandle, |
528 | &device); | 528 | &device); |
@@ -547,12 +547,13 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
547 | pci_unlock_rescan_remove(); | 547 | pci_unlock_rescan_remove(); |
548 | 548 | ||
549 | /* Remove the SSDT for the slot from the ACPI namespace */ | 549 | /* Remove the SSDT for the slot from the ACPI namespace */ |
550 | if (SN_ACPI_BASE_SUPPORT() && ssdt_id) { | 550 | if (SN_ACPI_BASE_SUPPORT() && ssdt_hdl) { |
551 | acpi_status ret; | 551 | acpi_status ret; |
552 | ret = acpi_unload_table_id(ssdt_id); | 552 | ret = acpi_unload_parent_table(ssdt_hdl); |
553 | if (ACPI_FAILURE(ret)) { | 553 | if (ACPI_FAILURE(ret)) { |
554 | printk(KERN_ERR "%s: acpi_unload_table_id failed (0x%x) for id %d\n", | 554 | acpi_handle_err(ssdt_hdl, |
555 | __func__, ret, ssdt_id); | 555 | "%s: acpi_unload_parent_table failed (0x%x)\n", |
556 | __func__, ret); | ||
556 | /* try to continue on */ | 557 | /* try to continue on */ |
557 | } | 558 | } |
558 | } | 559 | } |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 3542150fc8a3..489063987325 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -501,12 +501,29 @@ static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | |||
501 | return 0; | 501 | return 0; |
502 | } | 502 | } |
503 | 503 | ||
504 | static bool acpi_pci_need_resume(struct pci_dev *dev) | ||
505 | { | ||
506 | struct acpi_device *adev = ACPI_COMPANION(&dev->dev); | ||
507 | |||
508 | if (!adev || !acpi_device_power_manageable(adev)) | ||
509 | return false; | ||
510 | |||
511 | if (device_may_wakeup(&dev->dev) != !!adev->wakeup.prepare_count) | ||
512 | return true; | ||
513 | |||
514 | if (acpi_target_system_state() == ACPI_STATE_S0) | ||
515 | return false; | ||
516 | |||
517 | return !!adev->power.flags.dsw_present; | ||
518 | } | ||
519 | |||
504 | static struct pci_platform_pm_ops acpi_pci_platform_pm = { | 520 | static struct pci_platform_pm_ops acpi_pci_platform_pm = { |
505 | .is_manageable = acpi_pci_power_manageable, | 521 | .is_manageable = acpi_pci_power_manageable, |
506 | .set_state = acpi_pci_set_power_state, | 522 | .set_state = acpi_pci_set_power_state, |
507 | .choose_state = acpi_pci_choose_state, | 523 | .choose_state = acpi_pci_choose_state, |
508 | .sleep_wake = acpi_pci_sleep_wake, | 524 | .sleep_wake = acpi_pci_sleep_wake, |
509 | .run_wake = acpi_pci_run_wake, | 525 | .run_wake = acpi_pci_run_wake, |
526 | .need_resume = acpi_pci_need_resume, | ||
510 | }; | 527 | }; |
511 | 528 | ||
512 | void acpi_pci_add_bus(struct pci_bus *bus) | 529 | void acpi_pci_add_bus(struct pci_bus *bus) |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 09a66bad8018..3cb2210de553 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -653,7 +653,6 @@ static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) | |||
653 | static int pci_pm_prepare(struct device *dev) | 653 | static int pci_pm_prepare(struct device *dev) |
654 | { | 654 | { |
655 | struct device_driver *drv = dev->driver; | 655 | struct device_driver *drv = dev->driver; |
656 | int error = 0; | ||
657 | 656 | ||
658 | /* | 657 | /* |
659 | * Devices having power.ignore_children set may still be necessary for | 658 | * Devices having power.ignore_children set may still be necessary for |
@@ -662,10 +661,12 @@ static int pci_pm_prepare(struct device *dev) | |||
662 | if (dev->power.ignore_children) | 661 | if (dev->power.ignore_children) |
663 | pm_runtime_resume(dev); | 662 | pm_runtime_resume(dev); |
664 | 663 | ||
665 | if (drv && drv->pm && drv->pm->prepare) | 664 | if (drv && drv->pm && drv->pm->prepare) { |
666 | error = drv->pm->prepare(dev); | 665 | int error = drv->pm->prepare(dev); |
667 | 666 | if (error) | |
668 | return error; | 667 | return error; |
668 | } | ||
669 | return pci_dev_keep_suspended(to_pci_dev(dev)); | ||
669 | } | 670 | } |
670 | 671 | ||
671 | 672 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 460d046ab6fe..81f06e8dcc04 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -523,6 +523,11 @@ static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable) | |||
523 | pci_platform_pm->run_wake(dev, enable) : -ENODEV; | 523 | pci_platform_pm->run_wake(dev, enable) : -ENODEV; |
524 | } | 524 | } |
525 | 525 | ||
526 | static inline bool platform_pci_need_resume(struct pci_dev *dev) | ||
527 | { | ||
528 | return pci_platform_pm ? pci_platform_pm->need_resume(dev) : false; | ||
529 | } | ||
530 | |||
526 | /** | 531 | /** |
527 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of | 532 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of |
528 | * given PCI device | 533 | * given PCI device |
@@ -2001,6 +2006,27 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
2001 | } | 2006 | } |
2002 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); | 2007 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); |
2003 | 2008 | ||
2009 | /** | ||
2010 | * pci_dev_keep_suspended - Check if the device can stay in the suspended state. | ||
2011 | * @pci_dev: Device to check. | ||
2012 | * | ||
2013 | * Return 'true' if the device is runtime-suspended, it doesn't have to be | ||
2014 | * reconfigured due to wakeup settings difference between system and runtime | ||
2015 | * suspend and the current power state of it is suitable for the upcoming | ||
2016 | * (system) transition. | ||
2017 | */ | ||
2018 | bool pci_dev_keep_suspended(struct pci_dev *pci_dev) | ||
2019 | { | ||
2020 | struct device *dev = &pci_dev->dev; | ||
2021 | |||
2022 | if (!pm_runtime_suspended(dev) | ||
2023 | || (device_can_wakeup(dev) && !device_may_wakeup(dev)) | ||
2024 | || platform_pci_need_resume(pci_dev)) | ||
2025 | return false; | ||
2026 | |||
2027 | return pci_target_state(pci_dev) == pci_dev->current_state; | ||
2028 | } | ||
2029 | |||
2004 | void pci_config_pm_runtime_get(struct pci_dev *pdev) | 2030 | void pci_config_pm_runtime_get(struct pci_dev *pdev) |
2005 | { | 2031 | { |
2006 | struct device *dev = &pdev->dev; | 2032 | struct device *dev = &pdev->dev; |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d54632a1db43..4091f82239cd 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -50,6 +50,10 @@ int pci_probe_reset_function(struct pci_dev *dev); | |||
50 | * for given device (the device's wake-up capability has to be | 50 | * for given device (the device's wake-up capability has to be |
51 | * enabled by @sleep_wake for this feature to work) | 51 | * enabled by @sleep_wake for this feature to work) |
52 | * | 52 | * |
53 | * @need_resume: returns 'true' if the given device (which is currently | ||
54 | * suspended) needs to be resumed to be configured for system | ||
55 | * wakeup. | ||
56 | * | ||
53 | * If given platform is generally capable of power managing PCI devices, all of | 57 | * If given platform is generally capable of power managing PCI devices, all of |
54 | * these callbacks are mandatory. | 58 | * these callbacks are mandatory. |
55 | */ | 59 | */ |
@@ -59,6 +63,7 @@ struct pci_platform_pm_ops { | |||
59 | pci_power_t (*choose_state)(struct pci_dev *dev); | 63 | pci_power_t (*choose_state)(struct pci_dev *dev); |
60 | int (*sleep_wake)(struct pci_dev *dev, bool enable); | 64 | int (*sleep_wake)(struct pci_dev *dev, bool enable); |
61 | int (*run_wake)(struct pci_dev *dev, bool enable); | 65 | int (*run_wake)(struct pci_dev *dev, bool enable); |
66 | bool (*need_resume)(struct pci_dev *dev); | ||
62 | }; | 67 | }; |
63 | 68 | ||
64 | int pci_set_platform_pm(struct pci_platform_pm_ops *ops); | 69 | int pci_set_platform_pm(struct pci_platform_pm_ops *ops); |
@@ -67,6 +72,7 @@ void pci_power_up(struct pci_dev *dev); | |||
67 | void pci_disable_enabled_device(struct pci_dev *dev); | 72 | void pci_disable_enabled_device(struct pci_dev *dev); |
68 | int pci_finish_runtime_suspend(struct pci_dev *dev); | 73 | int pci_finish_runtime_suspend(struct pci_dev *dev); |
69 | int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | 74 | int __pci_pme_wakeup(struct pci_dev *dev, void *ign); |
75 | bool pci_dev_keep_suspended(struct pci_dev *dev); | ||
70 | void pci_config_pm_runtime_get(struct pci_dev *dev); | 76 | void pci_config_pm_runtime_get(struct pci_dev *dev); |
71 | void pci_config_pm_runtime_put(struct pci_dev *dev); | 77 | void pci_config_pm_runtime_put(struct pci_dev *dev); |
72 | void pci_pm_init(struct pci_dev *dev); | 78 | void pci_pm_init(struct pci_dev *dev); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 23212f8ae09b..8d2f400e96cb 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1895,7 +1895,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1895 | int error; | 1895 | int error; |
1896 | struct pci_host_bridge *bridge; | 1896 | struct pci_host_bridge *bridge; |
1897 | struct pci_bus *b, *b2; | 1897 | struct pci_bus *b, *b2; |
1898 | struct pci_host_bridge_window *window, *n; | 1898 | struct resource_entry *window, *n; |
1899 | struct resource *res; | 1899 | struct resource *res; |
1900 | resource_size_t offset; | 1900 | resource_size_t offset; |
1901 | char bus_addr[64]; | 1901 | char bus_addr[64]; |
@@ -1959,8 +1959,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1959 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1959 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
1960 | 1960 | ||
1961 | /* Add initial resources to the bus */ | 1961 | /* Add initial resources to the bus */ |
1962 | list_for_each_entry_safe(window, n, resources, list) { | 1962 | resource_list_for_each_entry_safe(window, n, resources) { |
1963 | list_move_tail(&window->list, &bridge->windows); | 1963 | list_move_tail(&window->node, &bridge->windows); |
1964 | res = window->res; | 1964 | res = window->res; |
1965 | offset = window->offset; | 1965 | offset = window->offset; |
1966 | if (res->flags & IORESOURCE_BUS) | 1966 | if (res->flags & IORESOURCE_BUS) |
@@ -2060,12 +2060,12 @@ void pci_bus_release_busn_res(struct pci_bus *b) | |||
2060 | struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, | 2060 | struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, |
2061 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 2061 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
2062 | { | 2062 | { |
2063 | struct pci_host_bridge_window *window; | 2063 | struct resource_entry *window; |
2064 | bool found = false; | 2064 | bool found = false; |
2065 | struct pci_bus *b; | 2065 | struct pci_bus *b; |
2066 | int max; | 2066 | int max; |
2067 | 2067 | ||
2068 | list_for_each_entry(window, resources, list) | 2068 | resource_list_for_each_entry(window, resources) |
2069 | if (window->res->flags & IORESOURCE_BUS) { | 2069 | if (window->res->flags & IORESOURCE_BUS) { |
2070 | found = true; | 2070 | found = true; |
2071 | break; | 2071 | break; |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 66977ebf13b3..ff0356fb378f 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -180,20 +180,21 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
180 | struct pnp_dev *dev = data; | 180 | struct pnp_dev *dev = data; |
181 | struct acpi_resource_dma *dma; | 181 | struct acpi_resource_dma *dma; |
182 | struct acpi_resource_vendor_typed *vendor_typed; | 182 | struct acpi_resource_vendor_typed *vendor_typed; |
183 | struct resource r = {0}; | 183 | struct resource_win win = {{0}, 0}; |
184 | struct resource *r = &win.res; | ||
184 | int i, flags; | 185 | int i, flags; |
185 | 186 | ||
186 | if (acpi_dev_resource_address_space(res, &r) | 187 | if (acpi_dev_resource_address_space(res, &win) |
187 | || acpi_dev_resource_ext_address_space(res, &r)) { | 188 | || acpi_dev_resource_ext_address_space(res, &win)) { |
188 | pnp_add_resource(dev, &r); | 189 | pnp_add_resource(dev, &win.res); |
189 | return AE_OK; | 190 | return AE_OK; |
190 | } | 191 | } |
191 | 192 | ||
192 | r.flags = 0; | 193 | r->flags = 0; |
193 | if (acpi_dev_resource_interrupt(res, 0, &r)) { | 194 | if (acpi_dev_resource_interrupt(res, 0, r)) { |
194 | pnpacpi_add_irqresource(dev, &r); | 195 | pnpacpi_add_irqresource(dev, r); |
195 | for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++) | 196 | for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++) |
196 | pnpacpi_add_irqresource(dev, &r); | 197 | pnpacpi_add_irqresource(dev, r); |
197 | 198 | ||
198 | if (i > 1) { | 199 | if (i > 1) { |
199 | /* | 200 | /* |
@@ -209,7 +210,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
209 | } | 210 | } |
210 | } | 211 | } |
211 | return AE_OK; | 212 | return AE_OK; |
212 | } else if (r.flags & IORESOURCE_DISABLED) { | 213 | } else if (r->flags & IORESOURCE_DISABLED) { |
213 | pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); | 214 | pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); |
214 | return AE_OK; | 215 | return AE_OK; |
215 | } | 216 | } |
@@ -218,13 +219,13 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
218 | case ACPI_RESOURCE_TYPE_MEMORY24: | 219 | case ACPI_RESOURCE_TYPE_MEMORY24: |
219 | case ACPI_RESOURCE_TYPE_MEMORY32: | 220 | case ACPI_RESOURCE_TYPE_MEMORY32: |
220 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 221 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
221 | if (acpi_dev_resource_memory(res, &r)) | 222 | if (acpi_dev_resource_memory(res, r)) |
222 | pnp_add_resource(dev, &r); | 223 | pnp_add_resource(dev, r); |
223 | break; | 224 | break; |
224 | case ACPI_RESOURCE_TYPE_IO: | 225 | case ACPI_RESOURCE_TYPE_IO: |
225 | case ACPI_RESOURCE_TYPE_FIXED_IO: | 226 | case ACPI_RESOURCE_TYPE_FIXED_IO: |
226 | if (acpi_dev_resource_io(res, &r)) | 227 | if (acpi_dev_resource_io(res, r)) |
227 | pnp_add_resource(dev, &r); | 228 | pnp_add_resource(dev, r); |
228 | break; | 229 | break; |
229 | case ACPI_RESOURCE_TYPE_DMA: | 230 | case ACPI_RESOURCE_TYPE_DMA: |
230 | dma = &res->data.dma; | 231 | dma = &res->data.dma; |
@@ -410,12 +411,12 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, | |||
410 | if (p->resource_type == ACPI_MEMORY_RANGE) { | 411 | if (p->resource_type == ACPI_MEMORY_RANGE) { |
411 | if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) | 412 | if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) |
412 | flags = IORESOURCE_MEM_WRITEABLE; | 413 | flags = IORESOURCE_MEM_WRITEABLE; |
413 | pnp_register_mem_resource(dev, option_flags, p->minimum, | 414 | pnp_register_mem_resource(dev, option_flags, p->address.minimum, |
414 | p->minimum, 0, p->address_length, | 415 | p->address.minimum, 0, p->address.address_length, |
415 | flags); | 416 | flags); |
416 | } else if (p->resource_type == ACPI_IO_RANGE) | 417 | } else if (p->resource_type == ACPI_IO_RANGE) |
417 | pnp_register_port_resource(dev, option_flags, p->minimum, | 418 | pnp_register_port_resource(dev, option_flags, p->address.minimum, |
418 | p->minimum, 0, p->address_length, | 419 | p->address.minimum, 0, p->address.address_length, |
419 | IORESOURCE_IO_FIXED); | 420 | IORESOURCE_IO_FIXED); |
420 | } | 421 | } |
421 | 422 | ||
@@ -429,12 +430,12 @@ static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev, | |||
429 | if (p->resource_type == ACPI_MEMORY_RANGE) { | 430 | if (p->resource_type == ACPI_MEMORY_RANGE) { |
430 | if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) | 431 | if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) |
431 | flags = IORESOURCE_MEM_WRITEABLE; | 432 | flags = IORESOURCE_MEM_WRITEABLE; |
432 | pnp_register_mem_resource(dev, option_flags, p->minimum, | 433 | pnp_register_mem_resource(dev, option_flags, p->address.minimum, |
433 | p->minimum, 0, p->address_length, | 434 | p->address.minimum, 0, p->address.address_length, |
434 | flags); | 435 | flags); |
435 | } else if (p->resource_type == ACPI_IO_RANGE) | 436 | } else if (p->resource_type == ACPI_IO_RANGE) |
436 | pnp_register_port_resource(dev, option_flags, p->minimum, | 437 | pnp_register_port_resource(dev, option_flags, p->address.minimum, |
437 | p->minimum, 0, p->address_length, | 438 | p->address.minimum, 0, p->address.address_length, |
438 | IORESOURCE_IO_FIXED); | 439 | IORESOURCE_IO_FIXED); |
439 | } | 440 | } |
440 | 441 | ||
diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c index 1e824fb1649b..296db7a69c27 100644 --- a/drivers/sfi/sfi_core.c +++ b/drivers/sfi/sfi_core.c | |||
@@ -161,7 +161,7 @@ static int sfi_verify_table(struct sfi_table_header *table) | |||
161 | * Check for common case that we can re-use mapping to SYST, | 161 | * Check for common case that we can re-use mapping to SYST, |
162 | * which requires syst_pa, syst_va to be initialized. | 162 | * which requires syst_pa, syst_va to be initialized. |
163 | */ | 163 | */ |
164 | struct sfi_table_header *sfi_map_table(u64 pa) | 164 | static struct sfi_table_header *sfi_map_table(u64 pa) |
165 | { | 165 | { |
166 | struct sfi_table_header *th; | 166 | struct sfi_table_header *th; |
167 | u32 length; | 167 | u32 length; |
@@ -189,7 +189,7 @@ struct sfi_table_header *sfi_map_table(u64 pa) | |||
189 | * Undoes effect of sfi_map_table() by unmapping table | 189 | * Undoes effect of sfi_map_table() by unmapping table |
190 | * if it did not completely fit on same page as SYST. | 190 | * if it did not completely fit on same page as SYST. |
191 | */ | 191 | */ |
192 | void sfi_unmap_table(struct sfi_table_header *th) | 192 | static void sfi_unmap_table(struct sfi_table_header *th) |
193 | { | 193 | { |
194 | if (!TABLE_ON_PAGE(syst_va, th, th->len)) | 194 | if (!TABLE_ON_PAGE(syst_va, th, th->len)) |
195 | sfi_unmap_memory(th, TABLE_ON_PAGE(th, th, th->len) ? | 195 | sfi_unmap_memory(th, TABLE_ON_PAGE(th, th, th->len) ? |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index aeb50bb6ba9c..eaffb0248de1 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -3452,8 +3452,6 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
3452 | return status; | 3452 | return status; |
3453 | } | 3453 | } |
3454 | 3454 | ||
3455 | #ifdef CONFIG_PM | ||
3456 | |||
3457 | int usb_remote_wakeup(struct usb_device *udev) | 3455 | int usb_remote_wakeup(struct usb_device *udev) |
3458 | { | 3456 | { |
3459 | int status = 0; | 3457 | int status = 0; |
@@ -3512,16 +3510,6 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, | |||
3512 | return connect_change; | 3510 | return connect_change; |
3513 | } | 3511 | } |
3514 | 3512 | ||
3515 | #else | ||
3516 | |||
3517 | static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, | ||
3518 | u16 portstatus, u16 portchange) | ||
3519 | { | ||
3520 | return 0; | ||
3521 | } | ||
3522 | |||
3523 | #endif | ||
3524 | |||
3525 | static int check_ports_changed(struct usb_hub *hub) | 3513 | static int check_ports_changed(struct usb_hub *hub) |
3526 | { | 3514 | { |
3527 | int port1; | 3515 | int port1; |
diff --git a/drivers/xen/xen-acpi-memhotplug.c b/drivers/xen/xen-acpi-memhotplug.c index 34e40b733f9a..4fc886cd5586 100644 --- a/drivers/xen/xen-acpi-memhotplug.c +++ b/drivers/xen/xen-acpi-memhotplug.c | |||
@@ -117,8 +117,8 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context) | |||
117 | list_for_each_entry(info, &mem_device->res_list, list) { | 117 | list_for_each_entry(info, &mem_device->res_list, list) { |
118 | if ((info->caching == address64.info.mem.caching) && | 118 | if ((info->caching == address64.info.mem.caching) && |
119 | (info->write_protect == address64.info.mem.write_protect) && | 119 | (info->write_protect == address64.info.mem.write_protect) && |
120 | (info->start_addr + info->length == address64.minimum)) { | 120 | (info->start_addr + info->length == address64.address.minimum)) { |
121 | info->length += address64.address_length; | 121 | info->length += address64.address.address_length; |
122 | return AE_OK; | 122 | return AE_OK; |
123 | } | 123 | } |
124 | } | 124 | } |
@@ -130,8 +130,8 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context) | |||
130 | INIT_LIST_HEAD(&new->list); | 130 | INIT_LIST_HEAD(&new->list); |
131 | new->caching = address64.info.mem.caching; | 131 | new->caching = address64.info.mem.caching; |
132 | new->write_protect = address64.info.mem.write_protect; | 132 | new->write_protect = address64.info.mem.write_protect; |
133 | new->start_addr = address64.minimum; | 133 | new->start_addr = address64.address.minimum; |
134 | new->length = address64.address_length; | 134 | new->length = address64.address.address_length; |
135 | list_add_tail(&new->list, &mem_device->res_list); | 135 | list_add_tail(&new->list, &mem_device->res_list); |
136 | 136 | ||
137 | return AE_OK; | 137 | return AE_OK; |
diff --git a/include/acpi/acbuffer.h b/include/acpi/acbuffer.h index d5ec6c87810f..6b040f4ddfab 100644 --- a/include/acpi/acbuffer.h +++ b/include/acpi/acbuffer.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 5a0a3e5daf85..03aacfb3e98b 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 8b06e4c1dd5d..11c3a011dcbf 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 7461327e14e4..273de709495c 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index 1baae6edda89..9318a87ee39a 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h index a08e55a263c9..b0bb30ebb807 100644 --- a/include/acpi/acpi.h +++ b/include/acpi/acpi.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 03b3e6d405ff..0bc78df66d4b 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -7,7 +7,7 @@ | |||
7 | *****************************************************************************/ | 7 | *****************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2014, Intel Corp. | 10 | * Copyright (C) 2000 - 2015, Intel Corp. |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 5ba78464c1b1..d56f5d722138 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -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 0x20141107 | 49 | #define ACPI_CA_VERSION 0x20150204 |
50 | 50 | ||
51 | #include <acpi/acconfig.h> | 51 | #include <acpi/acconfig.h> |
52 | #include <acpi/actypes.h> | 52 | #include <acpi/actypes.h> |
@@ -569,6 +569,14 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
569 | address, | 569 | address, |
570 | void *context)) | 570 | void *context)) |
571 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 571 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
572 | acpi_install_gpe_raw_handler(acpi_handle | ||
573 | gpe_device, | ||
574 | u32 gpe_number, | ||
575 | u32 type, | ||
576 | acpi_gpe_handler | ||
577 | address, | ||
578 | void *context)) | ||
579 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | ||
572 | acpi_remove_gpe_handler(acpi_handle gpe_device, | 580 | acpi_remove_gpe_handler(acpi_handle gpe_device, |
573 | u32 gpe_number, | 581 | u32 gpe_number, |
574 | acpi_gpe_handler | 582 | acpi_gpe_handler |
@@ -891,12 +899,6 @@ ACPI_APP_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(1) | |||
891 | ACPI_GLOBAL(u8, acpi_gbl_permanent_mmap); | 899 | ACPI_GLOBAL(u8, acpi_gbl_permanent_mmap); |
892 | 900 | ||
893 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | 901 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
894 | acpi_get_id(acpi_handle object, | ||
895 | acpi_owner_id * out_type)) | ||
896 | |||
897 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_unload_table_id(acpi_owner_id id)) | ||
898 | |||
899 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
900 | acpi_get_table_with_size(acpi_string signature, | 902 | acpi_get_table_with_size(acpi_string signature, |
901 | u32 instance, | 903 | u32 instance, |
902 | struct acpi_table_header | 904 | struct acpi_table_header |
diff --git a/include/acpi/acrestyp.h b/include/acpi/acrestyp.h index eb760ca0b2e0..ebe242638591 100644 --- a/include/acpi/acrestyp.h +++ b/include/acpi/acrestyp.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -305,43 +305,51 @@ struct acpi_resource_source { | |||
305 | u8 max_address_fixed; \ | 305 | u8 max_address_fixed; \ |
306 | union acpi_resource_attribute info; | 306 | union acpi_resource_attribute info; |
307 | 307 | ||
308 | struct acpi_resource_address { | 308 | struct acpi_address16_attribute { |
309 | ACPI_RESOURCE_ADDRESS_COMMON}; | 309 | u16 granularity; |
310 | |||
311 | struct acpi_resource_address16 { | ||
312 | ACPI_RESOURCE_ADDRESS_COMMON u16 granularity; | ||
313 | u16 minimum; | 310 | u16 minimum; |
314 | u16 maximum; | 311 | u16 maximum; |
315 | u16 translation_offset; | 312 | u16 translation_offset; |
316 | u16 address_length; | 313 | u16 address_length; |
317 | struct acpi_resource_source resource_source; | ||
318 | }; | 314 | }; |
319 | 315 | ||
320 | struct acpi_resource_address32 { | 316 | struct acpi_address32_attribute { |
321 | ACPI_RESOURCE_ADDRESS_COMMON u32 granularity; | 317 | u32 granularity; |
322 | u32 minimum; | 318 | u32 minimum; |
323 | u32 maximum; | 319 | u32 maximum; |
324 | u32 translation_offset; | 320 | u32 translation_offset; |
325 | u32 address_length; | 321 | u32 address_length; |
326 | struct acpi_resource_source resource_source; | ||
327 | }; | 322 | }; |
328 | 323 | ||
329 | struct acpi_resource_address64 { | 324 | struct acpi_address64_attribute { |
330 | ACPI_RESOURCE_ADDRESS_COMMON u64 granularity; | 325 | u64 granularity; |
331 | u64 minimum; | 326 | u64 minimum; |
332 | u64 maximum; | 327 | u64 maximum; |
333 | u64 translation_offset; | 328 | u64 translation_offset; |
334 | u64 address_length; | 329 | u64 address_length; |
330 | }; | ||
331 | |||
332 | struct acpi_resource_address { | ||
333 | ACPI_RESOURCE_ADDRESS_COMMON}; | ||
334 | |||
335 | struct acpi_resource_address16 { | ||
336 | ACPI_RESOURCE_ADDRESS_COMMON struct acpi_address16_attribute address; | ||
337 | struct acpi_resource_source resource_source; | ||
338 | }; | ||
339 | |||
340 | struct acpi_resource_address32 { | ||
341 | ACPI_RESOURCE_ADDRESS_COMMON struct acpi_address32_attribute address; | ||
342 | struct acpi_resource_source resource_source; | ||
343 | }; | ||
344 | |||
345 | struct acpi_resource_address64 { | ||
346 | ACPI_RESOURCE_ADDRESS_COMMON struct acpi_address64_attribute address; | ||
335 | struct acpi_resource_source resource_source; | 347 | struct acpi_resource_source resource_source; |
336 | }; | 348 | }; |
337 | 349 | ||
338 | struct acpi_resource_extended_address64 { | 350 | struct acpi_resource_extended_address64 { |
339 | ACPI_RESOURCE_ADDRESS_COMMON u8 revision_ID; | 351 | ACPI_RESOURCE_ADDRESS_COMMON u8 revision_ID; |
340 | u64 granularity; | 352 | struct acpi_address64_attribute address; |
341 | u64 minimum; | ||
342 | u64 maximum; | ||
343 | u64 translation_offset; | ||
344 | u64 address_length; | ||
345 | u64 type_specific; | 353 | u64 type_specific; |
346 | }; | 354 | }; |
347 | 355 | ||
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index bee19d8170c5..d4081fef1095 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 29e79370641d..b80b0e6dabc5 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index ecff62405f17..f06d75e5fa54 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h index 5480cb2236bf..440ca8104b43 100644 --- a/include/acpi/actbl3.h +++ b/include/acpi/actbl3.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index bbef17368e49..b034f1068dfe 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -744,7 +744,7 @@ typedef u32 acpi_event_status; | |||
744 | /* | 744 | /* |
745 | * GPE info flags - Per GPE | 745 | * GPE info flags - Per GPE |
746 | * +-------+-+-+---+ | 746 | * +-------+-+-+---+ |
747 | * | 7:4 |3|2|1:0| | 747 | * | 7:5 |4|3|2:0| |
748 | * +-------+-+-+---+ | 748 | * +-------+-+-+---+ |
749 | * | | | | | 749 | * | | | | |
750 | * | | | +-- Type of dispatch:to method, handler, notify, or none | 750 | * | | | +-- Type of dispatch:to method, handler, notify, or none |
@@ -756,13 +756,15 @@ typedef u32 acpi_event_status; | |||
756 | #define ACPI_GPE_DISPATCH_METHOD (u8) 0x01 | 756 | #define ACPI_GPE_DISPATCH_METHOD (u8) 0x01 |
757 | #define ACPI_GPE_DISPATCH_HANDLER (u8) 0x02 | 757 | #define ACPI_GPE_DISPATCH_HANDLER (u8) 0x02 |
758 | #define ACPI_GPE_DISPATCH_NOTIFY (u8) 0x03 | 758 | #define ACPI_GPE_DISPATCH_NOTIFY (u8) 0x03 |
759 | #define ACPI_GPE_DISPATCH_MASK (u8) 0x03 | 759 | #define ACPI_GPE_DISPATCH_RAW_HANDLER (u8) 0x04 |
760 | #define ACPI_GPE_DISPATCH_MASK (u8) 0x07 | ||
761 | #define ACPI_GPE_DISPATCH_TYPE(flags) ((u8) ((flags) & ACPI_GPE_DISPATCH_MASK)) | ||
760 | 762 | ||
761 | #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x04 | 763 | #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x08 |
762 | #define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 | 764 | #define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 |
763 | #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x04 | 765 | #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x08 |
764 | 766 | ||
765 | #define ACPI_GPE_CAN_WAKE (u8) 0x08 | 767 | #define ACPI_GPE_CAN_WAKE (u8) 0x10 |
766 | 768 | ||
767 | /* | 769 | /* |
768 | * Flags for GPE and Lock interfaces | 770 | * Flags for GPE and Lock interfaces |
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 5f8cc1fa3278..ad74dc51d5b7 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/platform/acenvex.h b/include/acpi/platform/acenvex.h index 2b612384c994..71e5ec5b07a3 100644 --- a/include/acpi/platform/acenvex.h +++ b/include/acpi/platform/acenvex.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 384875da3713..f54de0a63558 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 1ba7c190c2cc..74ba46c8157a 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h index 568d4b886712..acedc3f026de 100644 --- a/include/acpi/platform/aclinuxex.h +++ b/include/acpi/platform/aclinuxex.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d459cd17b477..24c7aa8b1d20 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/ioport.h> /* for struct resource */ | 29 | #include <linux/ioport.h> /* for struct resource */ |
30 | #include <linux/resource_ext.h> | ||
30 | #include <linux/device.h> | 31 | #include <linux/device.h> |
31 | #include <linux/property.h> | 32 | #include <linux/property.h> |
32 | 33 | ||
@@ -151,6 +152,10 @@ int acpi_map_cpu(acpi_handle handle, int physid, int *pcpu); | |||
151 | int acpi_unmap_cpu(int cpu); | 152 | int acpi_unmap_cpu(int cpu); |
152 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 153 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
153 | 154 | ||
155 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC | ||
156 | int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr); | ||
157 | #endif | ||
158 | |||
154 | int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); | 159 | int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); |
155 | int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); | 160 | int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); |
156 | int acpi_ioapic_registered(acpi_handle handle, u32 gsi_base); | 161 | int acpi_ioapic_registered(acpi_handle handle, u32 gsi_base); |
@@ -288,22 +293,25 @@ extern int pnpacpi_disabled; | |||
288 | bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res); | 293 | bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res); |
289 | bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res); | 294 | bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res); |
290 | bool acpi_dev_resource_address_space(struct acpi_resource *ares, | 295 | bool acpi_dev_resource_address_space(struct acpi_resource *ares, |
291 | struct resource *res); | 296 | struct resource_win *win); |
292 | bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, | 297 | bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, |
293 | struct resource *res); | 298 | struct resource_win *win); |
294 | unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable); | 299 | unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable); |
295 | bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, | 300 | bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, |
296 | struct resource *res); | 301 | struct resource *res); |
297 | 302 | ||
298 | struct resource_list_entry { | ||
299 | struct list_head node; | ||
300 | struct resource res; | ||
301 | }; | ||
302 | |||
303 | void acpi_dev_free_resource_list(struct list_head *list); | 303 | void acpi_dev_free_resource_list(struct list_head *list); |
304 | int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, | 304 | int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, |
305 | int (*preproc)(struct acpi_resource *, void *), | 305 | int (*preproc)(struct acpi_resource *, void *), |
306 | void *preproc_data); | 306 | void *preproc_data); |
307 | int acpi_dev_filter_resource_type(struct acpi_resource *ares, | ||
308 | unsigned long types); | ||
309 | |||
310 | static inline int acpi_dev_filter_resource_type_cb(struct acpi_resource *ares, | ||
311 | void *arg) | ||
312 | { | ||
313 | return acpi_dev_filter_resource_type(ares, (unsigned long)arg); | ||
314 | } | ||
307 | 315 | ||
308 | int acpi_check_resource_conflict(const struct resource *res); | 316 | int acpi_check_resource_conflict(const struct resource *res); |
309 | 317 | ||
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 4d078cebafd2..2ee4888c1f47 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -66,8 +66,6 @@ struct cpufreq_policy { | |||
66 | unsigned int shared_type; /* ACPI: ANY or ALL affected CPUs | 66 | unsigned int shared_type; /* ACPI: ANY or ALL affected CPUs |
67 | should set cpufreq */ | 67 | should set cpufreq */ |
68 | unsigned int cpu; /* cpu nr of CPU managing this policy */ | 68 | unsigned int cpu; /* cpu nr of CPU managing this policy */ |
69 | unsigned int last_cpu; /* cpu nr of previous CPU that managed | ||
70 | * this policy */ | ||
71 | struct clk *clk; | 69 | struct clk *clk; |
72 | struct cpufreq_cpuinfo cpuinfo;/* see above */ | 70 | struct cpufreq_cpuinfo cpuinfo;/* see above */ |
73 | 71 | ||
@@ -113,6 +111,9 @@ struct cpufreq_policy { | |||
113 | wait_queue_head_t transition_wait; | 111 | wait_queue_head_t transition_wait; |
114 | struct task_struct *transition_task; /* Task which is doing the transition */ | 112 | struct task_struct *transition_task; /* Task which is doing the transition */ |
115 | 113 | ||
114 | /* cpufreq-stats */ | ||
115 | struct cpufreq_stats *stats; | ||
116 | |||
116 | /* For cpufreq driver's internal use */ | 117 | /* For cpufreq driver's internal use */ |
117 | void *driver_data; | 118 | void *driver_data; |
118 | }; | 119 | }; |
@@ -367,9 +368,8 @@ static inline void cpufreq_resume(void) {} | |||
367 | #define CPUFREQ_INCOMPATIBLE (1) | 368 | #define CPUFREQ_INCOMPATIBLE (1) |
368 | #define CPUFREQ_NOTIFY (2) | 369 | #define CPUFREQ_NOTIFY (2) |
369 | #define CPUFREQ_START (3) | 370 | #define CPUFREQ_START (3) |
370 | #define CPUFREQ_UPDATE_POLICY_CPU (4) | 371 | #define CPUFREQ_CREATE_POLICY (4) |
371 | #define CPUFREQ_CREATE_POLICY (5) | 372 | #define CPUFREQ_REMOVE_POLICY (5) |
372 | #define CPUFREQ_REMOVE_POLICY (6) | ||
373 | 373 | ||
374 | #ifdef CONFIG_CPU_FREQ | 374 | #ifdef CONFIG_CPU_FREQ |
375 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); | 375 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); |
diff --git a/include/linux/devfreq-event.h b/include/linux/devfreq-event.h new file mode 100644 index 000000000000..602fbbfcfeed --- /dev/null +++ b/include/linux/devfreq-event.h | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * devfreq-event: a framework to provide raw data and events of devfreq devices | ||
3 | * | ||
4 | * Copyright (C) 2014 Samsung Electronics | ||
5 | * Author: Chanwoo Choi <cw00.choi@samsung.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 | #ifndef __LINUX_DEVFREQ_EVENT_H__ | ||
13 | #define __LINUX_DEVFREQ_EVENT_H__ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | |||
17 | /** | ||
18 | * struct devfreq_event_dev - the devfreq-event device | ||
19 | * | ||
20 | * @node : Contain the devfreq-event device that have been registered. | ||
21 | * @dev : the device registered by devfreq-event class. dev.parent is | ||
22 | * the device using devfreq-event. | ||
23 | * @lock : a mutex to protect accessing devfreq-event. | ||
24 | * @enable_count: the number of enable function have been called. | ||
25 | * @desc : the description for devfreq-event device. | ||
26 | * | ||
27 | * This structure contains devfreq-event device information. | ||
28 | */ | ||
29 | struct devfreq_event_dev { | ||
30 | struct list_head node; | ||
31 | |||
32 | struct device dev; | ||
33 | struct mutex lock; | ||
34 | u32 enable_count; | ||
35 | |||
36 | const struct devfreq_event_desc *desc; | ||
37 | }; | ||
38 | |||
39 | /** | ||
40 | * struct devfreq_event_data - the devfreq-event data | ||
41 | * | ||
42 | * @load_count : load count of devfreq-event device for the given period. | ||
43 | * @total_count : total count of devfreq-event device for the given period. | ||
44 | * each count may represent a clock cycle, a time unit | ||
45 | * (ns/us/...), or anything the device driver wants. | ||
46 | * Generally, utilization is load_count / total_count. | ||
47 | * | ||
48 | * This structure contains the data of devfreq-event device for polling period. | ||
49 | */ | ||
50 | struct devfreq_event_data { | ||
51 | unsigned long load_count; | ||
52 | unsigned long total_count; | ||
53 | }; | ||
54 | |||
55 | /** | ||
56 | * struct devfreq_event_ops - the operations of devfreq-event device | ||
57 | * | ||
58 | * @enable : Enable the devfreq-event device. | ||
59 | * @disable : Disable the devfreq-event device. | ||
60 | * @reset : Reset all setting of the devfreq-event device. | ||
61 | * @set_event : Set the specific event type for the devfreq-event device. | ||
62 | * @get_event : Get the result of the devfreq-event devie with specific | ||
63 | * event type. | ||
64 | * | ||
65 | * This structure contains devfreq-event device operations which can be | ||
66 | * implemented by devfreq-event device drivers. | ||
67 | */ | ||
68 | struct devfreq_event_ops { | ||
69 | /* Optional functions */ | ||
70 | int (*enable)(struct devfreq_event_dev *edev); | ||
71 | int (*disable)(struct devfreq_event_dev *edev); | ||
72 | int (*reset)(struct devfreq_event_dev *edev); | ||
73 | |||
74 | /* Mandatory functions */ | ||
75 | int (*set_event)(struct devfreq_event_dev *edev); | ||
76 | int (*get_event)(struct devfreq_event_dev *edev, | ||
77 | struct devfreq_event_data *edata); | ||
78 | }; | ||
79 | |||
80 | /** | ||
81 | * struct devfreq_event_desc - the descriptor of devfreq-event device | ||
82 | * | ||
83 | * @name : the name of devfreq-event device. | ||
84 | * @driver_data : the private data for devfreq-event driver. | ||
85 | * @ops : the operation to control devfreq-event device. | ||
86 | * | ||
87 | * Each devfreq-event device is described with a this structure. | ||
88 | * This structure contains the various data for devfreq-event device. | ||
89 | */ | ||
90 | struct devfreq_event_desc { | ||
91 | const char *name; | ||
92 | void *driver_data; | ||
93 | |||
94 | struct devfreq_event_ops *ops; | ||
95 | }; | ||
96 | |||
97 | #if defined(CONFIG_PM_DEVFREQ_EVENT) | ||
98 | extern int devfreq_event_enable_edev(struct devfreq_event_dev *edev); | ||
99 | extern int devfreq_event_disable_edev(struct devfreq_event_dev *edev); | ||
100 | extern bool devfreq_event_is_enabled(struct devfreq_event_dev *edev); | ||
101 | extern int devfreq_event_set_event(struct devfreq_event_dev *edev); | ||
102 | extern int devfreq_event_get_event(struct devfreq_event_dev *edev, | ||
103 | struct devfreq_event_data *edata); | ||
104 | extern int devfreq_event_reset_event(struct devfreq_event_dev *edev); | ||
105 | extern struct devfreq_event_dev *devfreq_event_get_edev_by_phandle( | ||
106 | struct device *dev, int index); | ||
107 | extern int devfreq_event_get_edev_count(struct device *dev); | ||
108 | extern struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev, | ||
109 | struct devfreq_event_desc *desc); | ||
110 | extern int devfreq_event_remove_edev(struct devfreq_event_dev *edev); | ||
111 | extern struct devfreq_event_dev *devm_devfreq_event_add_edev(struct device *dev, | ||
112 | struct devfreq_event_desc *desc); | ||
113 | extern void devm_devfreq_event_remove_edev(struct device *dev, | ||
114 | struct devfreq_event_dev *edev); | ||
115 | static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev) | ||
116 | { | ||
117 | return edev->desc->driver_data; | ||
118 | } | ||
119 | #else | ||
120 | static inline int devfreq_event_enable_edev(struct devfreq_event_dev *edev) | ||
121 | { | ||
122 | return -EINVAL; | ||
123 | } | ||
124 | |||
125 | static inline int devfreq_event_disable_edev(struct devfreq_event_dev *edev) | ||
126 | { | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | static inline bool devfreq_event_is_enabled(struct devfreq_event_dev *edev) | ||
131 | { | ||
132 | return false; | ||
133 | } | ||
134 | |||
135 | static inline int devfreq_event_set_event(struct devfreq_event_dev *edev) | ||
136 | { | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
140 | static inline int devfreq_event_get_event(struct devfreq_event_dev *edev, | ||
141 | struct devfreq_event_data *edata) | ||
142 | { | ||
143 | return -EINVAL; | ||
144 | } | ||
145 | |||
146 | static inline int devfreq_event_reset_event(struct devfreq_event_dev *edev) | ||
147 | { | ||
148 | return -EINVAL; | ||
149 | } | ||
150 | |||
151 | static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev) | ||
152 | { | ||
153 | return ERR_PTR(-EINVAL); | ||
154 | } | ||
155 | |||
156 | static inline struct devfreq_event_dev *devfreq_event_get_edev_by_phandle( | ||
157 | struct device *dev, int index) | ||
158 | { | ||
159 | return ERR_PTR(-EINVAL); | ||
160 | } | ||
161 | |||
162 | static inline int devfreq_event_get_edev_count(struct device *dev) | ||
163 | { | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | static inline struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev, | ||
168 | struct devfreq_event_desc *desc) | ||
169 | { | ||
170 | return ERR_PTR(-EINVAL); | ||
171 | } | ||
172 | |||
173 | static inline int devfreq_event_remove_edev(struct devfreq_event_dev *edev) | ||
174 | { | ||
175 | return -EINVAL; | ||
176 | } | ||
177 | |||
178 | static inline struct devfreq_event_dev *devm_devfreq_event_add_edev( | ||
179 | struct device *dev, | ||
180 | struct devfreq_event_desc *desc) | ||
181 | { | ||
182 | return ERR_PTR(-EINVAL); | ||
183 | } | ||
184 | |||
185 | static inline void devm_devfreq_event_remove_edev(struct device *dev, | ||
186 | struct devfreq_event_dev *edev) | ||
187 | { | ||
188 | } | ||
189 | |||
190 | static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev) | ||
191 | { | ||
192 | return NULL; | ||
193 | } | ||
194 | #endif /* CONFIG_PM_DEVFREQ_EVENT */ | ||
195 | |||
196 | #endif /* __LINUX_DEVFREQ_EVENT_H__ */ | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index 421eb6a9e600..211e9da8a7d7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/atomic.h> | 29 | #include <linux/atomic.h> |
30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/resource_ext.h> | ||
32 | #include <uapi/linux/pci.h> | 33 | #include <uapi/linux/pci.h> |
33 | 34 | ||
34 | #include <linux/pci_ids.h> | 35 | #include <linux/pci_ids.h> |
@@ -399,16 +400,10 @@ static inline int pci_channel_offline(struct pci_dev *pdev) | |||
399 | return (pdev->error_state != pci_channel_io_normal); | 400 | return (pdev->error_state != pci_channel_io_normal); |
400 | } | 401 | } |
401 | 402 | ||
402 | struct pci_host_bridge_window { | ||
403 | struct list_head list; | ||
404 | struct resource *res; /* host bridge aperture (CPU address) */ | ||
405 | resource_size_t offset; /* bus address + offset = CPU address */ | ||
406 | }; | ||
407 | |||
408 | struct pci_host_bridge { | 403 | struct pci_host_bridge { |
409 | struct device dev; | 404 | struct device dev; |
410 | struct pci_bus *bus; /* root bus */ | 405 | struct pci_bus *bus; /* root bus */ |
411 | struct list_head windows; /* pci_host_bridge_windows */ | 406 | struct list_head windows; /* resource_entry */ |
412 | void (*release_fn)(struct pci_host_bridge *); | 407 | void (*release_fn)(struct pci_host_bridge *); |
413 | void *release_data; | 408 | void *release_data; |
414 | }; | 409 | }; |
diff --git a/include/linux/pm.h b/include/linux/pm.h index 8b5976364619..e2f1be6dd9dd 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -597,7 +597,7 @@ struct dev_pm_info { | |||
597 | 597 | ||
598 | extern void update_pm_runtime_accounting(struct device *dev); | 598 | extern void update_pm_runtime_accounting(struct device *dev); |
599 | extern int dev_pm_get_subsys_data(struct device *dev); | 599 | extern int dev_pm_get_subsys_data(struct device *dev); |
600 | extern int dev_pm_put_subsys_data(struct device *dev); | 600 | extern void dev_pm_put_subsys_data(struct device *dev); |
601 | 601 | ||
602 | /* | 602 | /* |
603 | * Power domains provide callbacks that are executed during system suspend, | 603 | * Power domains provide callbacks that are executed during system suspend, |
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index a9edab2c787a..080e778118ba 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h | |||
@@ -113,8 +113,6 @@ struct generic_pm_domain_data { | |||
113 | struct pm_domain_data base; | 113 | struct pm_domain_data base; |
114 | struct gpd_timing_data td; | 114 | struct gpd_timing_data td; |
115 | struct notifier_block nb; | 115 | struct notifier_block nb; |
116 | struct mutex lock; | ||
117 | unsigned int refcount; | ||
118 | int need_restore; | 116 | int need_restore; |
119 | }; | 117 | }; |
120 | 118 | ||
@@ -140,7 +138,6 @@ extern int __pm_genpd_name_add_device(const char *domain_name, | |||
140 | 138 | ||
141 | extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, | 139 | extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, |
142 | struct device *dev); | 140 | struct device *dev); |
143 | extern void pm_genpd_dev_need_restore(struct device *dev, bool val); | ||
144 | extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, | 141 | extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, |
145 | struct generic_pm_domain *new_subdomain); | 142 | struct generic_pm_domain *new_subdomain); |
146 | extern int pm_genpd_add_subdomain_names(const char *master_name, | 143 | extern int pm_genpd_add_subdomain_names(const char *master_name, |
@@ -187,7 +184,6 @@ static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd, | |||
187 | { | 184 | { |
188 | return -ENOSYS; | 185 | return -ENOSYS; |
189 | } | 186 | } |
190 | static inline void pm_genpd_dev_need_restore(struct device *dev, bool val) {} | ||
191 | static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, | 187 | static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, |
192 | struct generic_pm_domain *new_sd) | 188 | struct generic_pm_domain *new_sd) |
193 | { | 189 | { |
diff --git a/include/linux/resource_ext.h b/include/linux/resource_ext.h new file mode 100644 index 000000000000..e2bf63d881d4 --- /dev/null +++ b/include/linux/resource_ext.h | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015, Intel Corporation | ||
3 | * Author: Jiang Liu <jiang.liu@linux.intel.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | #ifndef _LINUX_RESOURCE_EXT_H | ||
15 | #define _LINUX_RESOURCE_EXT_H | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | /* Represent resource window for bridge devices */ | ||
22 | struct resource_win { | ||
23 | struct resource res; /* In master (CPU) address space */ | ||
24 | resource_size_t offset; /* Translation offset for bridge */ | ||
25 | }; | ||
26 | |||
27 | /* | ||
28 | * Common resource list management data structure and interfaces to support | ||
29 | * ACPI, PNP and PCI host bridge etc. | ||
30 | */ | ||
31 | struct resource_entry { | ||
32 | struct list_head node; | ||
33 | struct resource *res; /* In master (CPU) address space */ | ||
34 | resource_size_t offset; /* Translation offset for bridge */ | ||
35 | struct resource __res; /* Default storage for res */ | ||
36 | }; | ||
37 | |||
38 | extern struct resource_entry * | ||
39 | resource_list_create_entry(struct resource *res, size_t extra_size); | ||
40 | extern void resource_list_free(struct list_head *head); | ||
41 | |||
42 | static inline void resource_list_add(struct resource_entry *entry, | ||
43 | struct list_head *head) | ||
44 | { | ||
45 | list_add(&entry->node, head); | ||
46 | } | ||
47 | |||
48 | static inline void resource_list_add_tail(struct resource_entry *entry, | ||
49 | struct list_head *head) | ||
50 | { | ||
51 | list_add_tail(&entry->node, head); | ||
52 | } | ||
53 | |||
54 | static inline void resource_list_del(struct resource_entry *entry) | ||
55 | { | ||
56 | list_del(&entry->node); | ||
57 | } | ||
58 | |||
59 | static inline void resource_list_free_entry(struct resource_entry *entry) | ||
60 | { | ||
61 | kfree(entry); | ||
62 | } | ||
63 | |||
64 | static inline void | ||
65 | resource_list_destroy_entry(struct resource_entry *entry) | ||
66 | { | ||
67 | resource_list_del(entry); | ||
68 | resource_list_free_entry(entry); | ||
69 | } | ||
70 | |||
71 | #define resource_list_for_each_entry(entry, list) \ | ||
72 | list_for_each_entry((entry), (list), node) | ||
73 | |||
74 | #define resource_list_for_each_entry_safe(entry, tmp, list) \ | ||
75 | list_for_each_entry_safe((entry), (tmp), (list), node) | ||
76 | |||
77 | #endif /* _LINUX_RESOURCE_EXT_H */ | ||
diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 5f4c006c4b1e..97b0df71303e 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c | |||
@@ -41,6 +41,8 @@ | |||
41 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
44 | #include <linux/debugfs.h> | ||
45 | #include <linux/seq_file.h> | ||
44 | 46 | ||
45 | #include <linux/uaccess.h> | 47 | #include <linux/uaccess.h> |
46 | #include <linux/export.h> | 48 | #include <linux/export.h> |
@@ -182,6 +184,81 @@ static inline void pm_qos_set_value(struct pm_qos_constraints *c, s32 value) | |||
182 | c->target_value = value; | 184 | c->target_value = value; |
183 | } | 185 | } |
184 | 186 | ||
187 | static inline int pm_qos_get_value(struct pm_qos_constraints *c); | ||
188 | static int pm_qos_dbg_show_requests(struct seq_file *s, void *unused) | ||
189 | { | ||
190 | struct pm_qos_object *qos = (struct pm_qos_object *)s->private; | ||
191 | struct pm_qos_constraints *c; | ||
192 | struct pm_qos_request *req; | ||
193 | char *type; | ||
194 | unsigned long flags; | ||
195 | int tot_reqs = 0; | ||
196 | int active_reqs = 0; | ||
197 | |||
198 | if (IS_ERR_OR_NULL(qos)) { | ||
199 | pr_err("%s: bad qos param!\n", __func__); | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | c = qos->constraints; | ||
203 | if (IS_ERR_OR_NULL(c)) { | ||
204 | pr_err("%s: Bad constraints on qos?\n", __func__); | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | /* Lock to ensure we have a snapshot */ | ||
209 | spin_lock_irqsave(&pm_qos_lock, flags); | ||
210 | if (plist_head_empty(&c->list)) { | ||
211 | seq_puts(s, "Empty!\n"); | ||
212 | goto out; | ||
213 | } | ||
214 | |||
215 | switch (c->type) { | ||
216 | case PM_QOS_MIN: | ||
217 | type = "Minimum"; | ||
218 | break; | ||
219 | case PM_QOS_MAX: | ||
220 | type = "Maximum"; | ||
221 | break; | ||
222 | case PM_QOS_SUM: | ||
223 | type = "Sum"; | ||
224 | break; | ||
225 | default: | ||
226 | type = "Unknown"; | ||
227 | } | ||
228 | |||
229 | plist_for_each_entry(req, &c->list, node) { | ||
230 | char *state = "Default"; | ||
231 | |||
232 | if ((req->node).prio != c->default_value) { | ||
233 | active_reqs++; | ||
234 | state = "Active"; | ||
235 | } | ||
236 | tot_reqs++; | ||
237 | seq_printf(s, "%d: %d: %s\n", tot_reqs, | ||
238 | (req->node).prio, state); | ||
239 | } | ||
240 | |||
241 | seq_printf(s, "Type=%s, Value=%d, Requests: active=%d / total=%d\n", | ||
242 | type, pm_qos_get_value(c), active_reqs, tot_reqs); | ||
243 | |||
244 | out: | ||
245 | spin_unlock_irqrestore(&pm_qos_lock, flags); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int pm_qos_dbg_open(struct inode *inode, struct file *file) | ||
250 | { | ||
251 | return single_open(file, pm_qos_dbg_show_requests, | ||
252 | inode->i_private); | ||
253 | } | ||
254 | |||
255 | static const struct file_operations pm_qos_debug_fops = { | ||
256 | .open = pm_qos_dbg_open, | ||
257 | .read = seq_read, | ||
258 | .llseek = seq_lseek, | ||
259 | .release = single_release, | ||
260 | }; | ||
261 | |||
185 | /** | 262 | /** |
186 | * pm_qos_update_target - manages the constraints list and calls the notifiers | 263 | * pm_qos_update_target - manages the constraints list and calls the notifiers |
187 | * if needed | 264 | * if needed |
@@ -509,12 +586,17 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) | |||
509 | EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); | 586 | EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); |
510 | 587 | ||
511 | /* User space interface to PM QoS classes via misc devices */ | 588 | /* User space interface to PM QoS classes via misc devices */ |
512 | static int register_pm_qos_misc(struct pm_qos_object *qos) | 589 | static int register_pm_qos_misc(struct pm_qos_object *qos, struct dentry *d) |
513 | { | 590 | { |
514 | qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; | 591 | qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; |
515 | qos->pm_qos_power_miscdev.name = qos->name; | 592 | qos->pm_qos_power_miscdev.name = qos->name; |
516 | qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops; | 593 | qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops; |
517 | 594 | ||
595 | if (d) { | ||
596 | (void)debugfs_create_file(qos->name, S_IRUGO, d, | ||
597 | (void *)qos, &pm_qos_debug_fops); | ||
598 | } | ||
599 | |||
518 | return misc_register(&qos->pm_qos_power_miscdev); | 600 | return misc_register(&qos->pm_qos_power_miscdev); |
519 | } | 601 | } |
520 | 602 | ||
@@ -608,11 +690,16 @@ static int __init pm_qos_power_init(void) | |||
608 | { | 690 | { |
609 | int ret = 0; | 691 | int ret = 0; |
610 | int i; | 692 | int i; |
693 | struct dentry *d; | ||
611 | 694 | ||
612 | BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES); | 695 | BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES); |
613 | 696 | ||
697 | d = debugfs_create_dir("pm_qos", NULL); | ||
698 | if (IS_ERR_OR_NULL(d)) | ||
699 | d = NULL; | ||
700 | |||
614 | for (i = PM_QOS_CPU_DMA_LATENCY; i < PM_QOS_NUM_CLASSES; i++) { | 701 | for (i = PM_QOS_CPU_DMA_LATENCY; i < PM_QOS_NUM_CLASSES; i++) { |
615 | ret = register_pm_qos_misc(pm_qos_array[i]); | 702 | ret = register_pm_qos_misc(pm_qos_array[i], d); |
616 | if (ret < 0) { | 703 | if (ret < 0) { |
617 | printk(KERN_ERR "pm_qos_param: %s setup failed\n", | 704 | printk(KERN_ERR "pm_qos_param: %s setup failed\n", |
618 | pm_qos_array[i]->name); | 705 | pm_qos_array[i]->name); |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 0c40c16174b4..c24d5a23bf93 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1472,9 +1472,9 @@ static inline unsigned long preallocate_highmem_fraction(unsigned long nr_pages, | |||
1472 | /** | 1472 | /** |
1473 | * free_unnecessary_pages - Release preallocated pages not needed for the image | 1473 | * free_unnecessary_pages - Release preallocated pages not needed for the image |
1474 | */ | 1474 | */ |
1475 | static void free_unnecessary_pages(void) | 1475 | static unsigned long free_unnecessary_pages(void) |
1476 | { | 1476 | { |
1477 | unsigned long save, to_free_normal, to_free_highmem; | 1477 | unsigned long save, to_free_normal, to_free_highmem, free; |
1478 | 1478 | ||
1479 | save = count_data_pages(); | 1479 | save = count_data_pages(); |
1480 | if (alloc_normal >= save) { | 1480 | if (alloc_normal >= save) { |
@@ -1495,6 +1495,7 @@ static void free_unnecessary_pages(void) | |||
1495 | else | 1495 | else |
1496 | to_free_normal = 0; | 1496 | to_free_normal = 0; |
1497 | } | 1497 | } |
1498 | free = to_free_normal + to_free_highmem; | ||
1498 | 1499 | ||
1499 | memory_bm_position_reset(©_bm); | 1500 | memory_bm_position_reset(©_bm); |
1500 | 1501 | ||
@@ -1518,6 +1519,8 @@ static void free_unnecessary_pages(void) | |||
1518 | swsusp_unset_page_free(page); | 1519 | swsusp_unset_page_free(page); |
1519 | __free_page(page); | 1520 | __free_page(page); |
1520 | } | 1521 | } |
1522 | |||
1523 | return free; | ||
1521 | } | 1524 | } |
1522 | 1525 | ||
1523 | /** | 1526 | /** |
@@ -1707,7 +1710,7 @@ int hibernate_preallocate_memory(void) | |||
1707 | * pages in memory, but we have allocated more. Release the excessive | 1710 | * pages in memory, but we have allocated more. Release the excessive |
1708 | * ones now. | 1711 | * ones now. |
1709 | */ | 1712 | */ |
1710 | free_unnecessary_pages(); | 1713 | pages -= free_unnecessary_pages(); |
1711 | 1714 | ||
1712 | out: | 1715 | out: |
1713 | stop = ktime_get(); | 1716 | stop = ktime_get(); |
@@ -2310,8 +2313,6 @@ static inline void free_highmem_data(void) | |||
2310 | free_image_page(buffer, PG_UNSAFE_CLEAR); | 2313 | free_image_page(buffer, PG_UNSAFE_CLEAR); |
2311 | } | 2314 | } |
2312 | #else | 2315 | #else |
2313 | static inline int get_safe_write_buffer(void) { return 0; } | ||
2314 | |||
2315 | static unsigned int | 2316 | static unsigned int |
2316 | count_highmem_image_pages(struct memory_bitmap *bm) { return 0; } | 2317 | count_highmem_image_pages(struct memory_bitmap *bm) { return 0; } |
2317 | 2318 | ||
diff --git a/kernel/resource.c b/kernel/resource.c index 0bcebffc4e77..19f2357dfda3 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/pfn.h> | 23 | #include <linux/pfn.h> |
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | #include <linux/resource_ext.h> | ||
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | 27 | ||
27 | 28 | ||
@@ -1529,6 +1530,30 @@ int iomem_is_exclusive(u64 addr) | |||
1529 | return err; | 1530 | return err; |
1530 | } | 1531 | } |
1531 | 1532 | ||
1533 | struct resource_entry *resource_list_create_entry(struct resource *res, | ||
1534 | size_t extra_size) | ||
1535 | { | ||
1536 | struct resource_entry *entry; | ||
1537 | |||
1538 | entry = kzalloc(sizeof(*entry) + extra_size, GFP_KERNEL); | ||
1539 | if (entry) { | ||
1540 | INIT_LIST_HEAD(&entry->node); | ||
1541 | entry->res = res ? res : &entry->__res; | ||
1542 | } | ||
1543 | |||
1544 | return entry; | ||
1545 | } | ||
1546 | EXPORT_SYMBOL(resource_list_create_entry); | ||
1547 | |||
1548 | void resource_list_free(struct list_head *head) | ||
1549 | { | ||
1550 | struct resource_entry *entry, *tmp; | ||
1551 | |||
1552 | list_for_each_entry_safe(entry, tmp, head, node) | ||
1553 | resource_list_destroy_entry(entry); | ||
1554 | } | ||
1555 | EXPORT_SYMBOL(resource_list_free); | ||
1556 | |||
1532 | static int __init strict_iomem(char *str) | 1557 | static int __init strict_iomem(char *str) |
1533 | { | 1558 | { |
1534 | if (strstr(str, "relaxed")) | 1559 | if (strstr(str, "relaxed")) |
diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c index 1c71382b283d..eb4220a132ec 100644 --- a/kernel/trace/power-traces.c +++ b/kernel/trace/power-traces.c | |||
@@ -13,5 +13,6 @@ | |||
13 | #define CREATE_TRACE_POINTS | 13 | #define CREATE_TRACE_POINTS |
14 | #include <trace/events/power.h> | 14 | #include <trace/events/power.h> |
15 | 15 | ||
16 | EXPORT_TRACEPOINT_SYMBOL_GPL(suspend_resume); | ||
16 | EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle); | 17 | EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle); |
17 | 18 | ||
diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c index f4b953354ff7..eec688041500 100644 --- a/tools/power/acpi/common/cmfsize.c +++ b/tools/power/acpi/common/cmfsize.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c index 2f0f34a36db4..5da129e10aa2 100644 --- a/tools/power/acpi/common/getopt.c +++ b/tools/power/acpi/common/getopt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/os_specific/service_layers/oslibcfs.c b/tools/power/acpi/os_specific/service_layers/oslibcfs.c index c13ff9c51d74..b51e40a9a120 100644 --- a/tools/power/acpi/os_specific/service_layers/oslibcfs.c +++ b/tools/power/acpi/os_specific/service_layers/oslibcfs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c index 0dc2485dedf5..92f1fd700344 100644 --- a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c +++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/os_specific/service_layers/osunixdir.c b/tools/power/acpi/os_specific/service_layers/osunixdir.c index 733f9e490fc4..e153fcb12b1a 100644 --- a/tools/power/acpi/os_specific/service_layers/osunixdir.c +++ b/tools/power/acpi/os_specific/service_layers/osunixdir.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/os_specific/service_layers/osunixmap.c b/tools/power/acpi/os_specific/service_layers/osunixmap.c index 99b47b6194a3..3853a7350440 100644 --- a/tools/power/acpi/os_specific/service_layers/osunixmap.c +++ b/tools/power/acpi/os_specific/service_layers/osunixmap.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c index 7ccb073f8316..6858c0893c91 100644 --- a/tools/power/acpi/os_specific/service_layers/osunixxf.c +++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h index a2d37d610639..84bdef0136cb 100644 --- a/tools/power/acpi/tools/acpidump/acpidump.h +++ b/tools/power/acpi/tools/acpidump/acpidump.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c index 24d32968802d..c736adf5fb55 100644 --- a/tools/power/acpi/tools/acpidump/apdump.c +++ b/tools/power/acpi/tools/acpidump/apdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index d470046a6d81..8f2fe168228e 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index 853b4da22c3e..d0ba6535f5af 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2014, Intel Corp. | 8 | * Copyright (C) 2000 - 2015, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index 2e2ba2efa0d9..3ed7c0476d48 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile | |||
@@ -209,7 +209,7 @@ $(OUTPUT)%.o: %.c | |||
209 | 209 | ||
210 | $(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ) | 210 | $(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ) |
211 | $(ECHO) " CC " $@ | 211 | $(ECHO) " CC " $@ |
212 | $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@ | 212 | $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -Wl,-rpath=./ -lrt -lpci -L$(OUTPUT) -o $@ |
213 | $(QUIET) $(STRIPCMD) $@ | 213 | $(QUIET) $(STRIPCMD) $@ |
214 | 214 | ||
215 | $(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC) | 215 | $(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC) |
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 56bfb523c5bb..9b950699e63d 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 | |||
@@ -12,16 +12,16 @@ turbostat \- Report processor frequency and idle statistics | |||
12 | .RB [ "\-i interval_sec" ] | 12 | .RB [ "\-i interval_sec" ] |
13 | .SH DESCRIPTION | 13 | .SH DESCRIPTION |
14 | \fBturbostat \fP reports processor topology, frequency, | 14 | \fBturbostat \fP reports processor topology, frequency, |
15 | idle power-state statistics, temperature and power on modern X86 processors. | 15 | idle power-state statistics, temperature and power on X86 processors. |
16 | Either \fBcommand\fP is forked and statistics are printed | 16 | There are two ways to invoke turbostat. |
17 | upon its completion, or statistics are printed periodically. | 17 | The first method is to supply a |
18 | 18 | \fBcommand\fP, which is forked and statistics are printed | |
19 | \fBturbostat \fP | 19 | upon its completion. |
20 | must be run on root, and | 20 | The second method is to omit the command, |
21 | minimally requires that the processor | 21 | and turbodstat will print statistics every 5 seconds. |
22 | supports an "invariant" TSC, plus the APERF and MPERF MSRs. | 22 | The 5-second interval can changed using the -i option. |
23 | Additional information is reported depending on hardware counter support. | 23 | |
24 | 24 | Some information is not availalbe on older processors. | |
25 | .SS Options | 25 | .SS Options |
26 | The \fB-p\fP option limits output to the 1st thread in 1st core of each package. | 26 | The \fB-p\fP option limits output to the 1st thread in 1st core of each package. |
27 | .PP | 27 | .PP |
@@ -130,12 +130,13 @@ cpu3: MSR_IA32_THERM_STATUS: 0x884e0000 (27 C +/- 1) | |||
130 | ... | 130 | ... |
131 | .fi | 131 | .fi |
132 | The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency | 132 | The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency |
133 | available at the minimum package voltage. The \fBTSC frequency\fP is the nominal | 133 | available at the minimum package voltage. The \fBTSC frequency\fP is the base |
134 | maximum frequency of the processor if turbo-mode were not available. This frequency | 134 | frequency of the processor -- this should match the brand string |
135 | in /proc/cpuinfo. This base frequency | ||
135 | should be sustainable on all CPUs indefinitely, given nominal power and cooling. | 136 | should be sustainable on all CPUs indefinitely, given nominal power and cooling. |
136 | The remaining rows show what maximum turbo frequency is possible | 137 | The remaining rows show what maximum turbo frequency is possible |
137 | depending on the number of idle cores. Note that this information is | 138 | depending on the number of idle cores. Note that not all information is |
138 | not available on all processors. | 139 | available on all processors. |
139 | .SH FORK EXAMPLE | 140 | .SH FORK EXAMPLE |
140 | If turbostat is invoked with a command, it will fork that command | 141 | If turbostat is invoked with a command, it will fork that command |
141 | and output the statistics gathered when the command exits. | 142 | and output the statistics gathered when the command exits. |
@@ -176,6 +177,11 @@ not including any non-busy idle time. | |||
176 | 177 | ||
177 | .B "turbostat " | 178 | .B "turbostat " |
178 | must be run as root. | 179 | must be run as root. |
180 | Alternatively, non-root users can be enabled to run turbostat this way: | ||
181 | |||
182 | # setcap cap_sys_rawio=ep ./turbostat | ||
183 | |||
184 | # chmod +r /dev/cpu/*/msr | ||
179 | 185 | ||
180 | .B "turbostat " | 186 | .B "turbostat " |
181 | reads hardware counters, but doesn't write them. | 187 | reads hardware counters, but doesn't write them. |
@@ -184,15 +190,33 @@ multiple invocations of itself. | |||
184 | 190 | ||
185 | \fBturbostat \fP | 191 | \fBturbostat \fP |
186 | may work poorly on Linux-2.6.20 through 2.6.29, | 192 | may work poorly on Linux-2.6.20 through 2.6.29, |
187 | as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF | 193 | as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF MSRs |
188 | in those kernels. | 194 | in those kernels. |
189 | 195 | ||
190 | If the TSC column does not make sense, then | 196 | AVG_MHz = APERF_delta/measurement_interval. This is the actual |
191 | the other numbers will also make no sense. | 197 | number of elapsed cycles divided by the entire sample interval -- |
192 | Turbostat is lightweight, and its data collection is not atomic. | 198 | including idle time. Note that this calculation is resiliant |
193 | These issues are usually caused by an extremely short measurement | 199 | to systems lacking a non-stop TSC. |
194 | interval (much less than 1 second), or system activity that prevents | 200 | |
195 | turbostat from being able to run on all CPUS to quickly collect data. | 201 | TSC_MHz = TSC_delta/measurement_interval. |
202 | On a system with an invariant TSC, this value will be constant | ||
203 | and will closely match the base frequency value shown | ||
204 | in the brand string in /proc/cpuinfo. On a system where | ||
205 | the TSC stops in idle, TSC_MHz will drop | ||
206 | below the processor's base frequency. | ||
207 | |||
208 | %Busy = MPERF_delta/TSC_delta | ||
209 | |||
210 | Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/measurement_interval | ||
211 | |||
212 | Note that these calculations depend on TSC_delta, so they | ||
213 | are not reliable during intervals when TSC_MHz is not running at the base frequency. | ||
214 | |||
215 | Turbostat data collection is not atomic. | ||
216 | Extremely short measurement intervals (much less than 1 second), | ||
217 | or system activity that prevents turbostat from being able | ||
218 | to run on all CPUS to quickly collect data, will result in | ||
219 | inconsistent results. | ||
196 | 220 | ||
197 | The APERF, MPERF MSRs are defined to count non-halted cycles. | 221 | The APERF, MPERF MSRs are defined to count non-halted cycles. |
198 | Although it is not guaranteed by the architecture, turbostat assumes | 222 | Although it is not guaranteed by the architecture, turbostat assumes |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 5b1b807265a1..a02c02f25e88 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <ctype.h> | 38 | #include <ctype.h> |
39 | #include <sched.h> | 39 | #include <sched.h> |
40 | #include <cpuid.h> | 40 | #include <cpuid.h> |
41 | #include <linux/capability.h> | ||
42 | #include <errno.h> | ||
41 | 43 | ||
42 | char *proc_stat = "/proc/stat"; | 44 | char *proc_stat = "/proc/stat"; |
43 | unsigned int interval_sec = 5; /* set with -i interval_sec */ | 45 | unsigned int interval_sec = 5; /* set with -i interval_sec */ |
@@ -59,8 +61,8 @@ unsigned int has_epb; | |||
59 | unsigned int units = 1000000; /* MHz etc */ | 61 | unsigned int units = 1000000; /* MHz etc */ |
60 | unsigned int genuine_intel; | 62 | unsigned int genuine_intel; |
61 | unsigned int has_invariant_tsc; | 63 | unsigned int has_invariant_tsc; |
62 | unsigned int do_nehalem_platform_info; | 64 | unsigned int do_nhm_platform_info; |
63 | unsigned int do_nehalem_turbo_ratio_limit; | 65 | unsigned int do_nhm_turbo_ratio_limit; |
64 | unsigned int do_ivt_turbo_ratio_limit; | 66 | unsigned int do_ivt_turbo_ratio_limit; |
65 | unsigned int extra_msr_offset32; | 67 | unsigned int extra_msr_offset32; |
66 | unsigned int extra_msr_offset64; | 68 | unsigned int extra_msr_offset64; |
@@ -81,6 +83,9 @@ unsigned int tcc_activation_temp; | |||
81 | unsigned int tcc_activation_temp_override; | 83 | unsigned int tcc_activation_temp_override; |
82 | double rapl_power_units, rapl_energy_units, rapl_time_units; | 84 | double rapl_power_units, rapl_energy_units, rapl_time_units; |
83 | double rapl_joule_counter_range; | 85 | double rapl_joule_counter_range; |
86 | unsigned int do_core_perf_limit_reasons; | ||
87 | unsigned int do_gfx_perf_limit_reasons; | ||
88 | unsigned int do_ring_perf_limit_reasons; | ||
84 | 89 | ||
85 | #define RAPL_PKG (1 << 0) | 90 | #define RAPL_PKG (1 << 0) |
86 | /* 0x610 MSR_PKG_POWER_LIMIT */ | 91 | /* 0x610 MSR_PKG_POWER_LIMIT */ |
@@ -251,15 +256,13 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) | |||
251 | sprintf(pathname, "/dev/cpu/%d/msr", cpu); | 256 | sprintf(pathname, "/dev/cpu/%d/msr", cpu); |
252 | fd = open(pathname, O_RDONLY); | 257 | fd = open(pathname, O_RDONLY); |
253 | if (fd < 0) | 258 | if (fd < 0) |
254 | return -1; | 259 | err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname); |
255 | 260 | ||
256 | retval = pread(fd, msr, sizeof *msr, offset); | 261 | retval = pread(fd, msr, sizeof *msr, offset); |
257 | close(fd); | 262 | close(fd); |
258 | 263 | ||
259 | if (retval != sizeof *msr) { | 264 | if (retval != sizeof *msr) |
260 | fprintf(stderr, "%s offset 0x%llx read failed\n", pathname, (unsigned long long)offset); | 265 | err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset); |
261 | return -1; | ||
262 | } | ||
263 | 266 | ||
264 | return 0; | 267 | return 0; |
265 | } | 268 | } |
@@ -281,7 +284,7 @@ void print_header(void) | |||
281 | outp += sprintf(outp, " CPU"); | 284 | outp += sprintf(outp, " CPU"); |
282 | if (has_aperf) | 285 | if (has_aperf) |
283 | outp += sprintf(outp, " Avg_MHz"); | 286 | outp += sprintf(outp, " Avg_MHz"); |
284 | if (do_nhm_cstates) | 287 | if (has_aperf) |
285 | outp += sprintf(outp, " %%Busy"); | 288 | outp += sprintf(outp, " %%Busy"); |
286 | if (has_aperf) | 289 | if (has_aperf) |
287 | outp += sprintf(outp, " Bzy_MHz"); | 290 | outp += sprintf(outp, " Bzy_MHz"); |
@@ -337,7 +340,7 @@ void print_header(void) | |||
337 | outp += sprintf(outp, " PKG_%%"); | 340 | outp += sprintf(outp, " PKG_%%"); |
338 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 341 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
339 | outp += sprintf(outp, " RAM_%%"); | 342 | outp += sprintf(outp, " RAM_%%"); |
340 | } else { | 343 | } else if (do_rapl && rapl_joules) { |
341 | if (do_rapl & RAPL_PKG) | 344 | if (do_rapl & RAPL_PKG) |
342 | outp += sprintf(outp, " Pkg_J"); | 345 | outp += sprintf(outp, " Pkg_J"); |
343 | if (do_rapl & RAPL_CORES) | 346 | if (do_rapl & RAPL_CORES) |
@@ -457,25 +460,25 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
457 | outp += sprintf(outp, "%8d", t->cpu_id); | 460 | outp += sprintf(outp, "%8d", t->cpu_id); |
458 | } | 461 | } |
459 | 462 | ||
460 | /* AvgMHz */ | 463 | /* Avg_MHz */ |
461 | if (has_aperf) | 464 | if (has_aperf) |
462 | outp += sprintf(outp, "%8.0f", | 465 | outp += sprintf(outp, "%8.0f", |
463 | 1.0 / units * t->aperf / interval_float); | 466 | 1.0 / units * t->aperf / interval_float); |
464 | 467 | ||
465 | /* %c0 */ | 468 | /* %Busy */ |
466 | if (do_nhm_cstates) { | 469 | if (has_aperf) { |
467 | if (!skip_c0) | 470 | if (!skip_c0) |
468 | outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc); | 471 | outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc); |
469 | else | 472 | else |
470 | outp += sprintf(outp, "********"); | 473 | outp += sprintf(outp, "********"); |
471 | } | 474 | } |
472 | 475 | ||
473 | /* BzyMHz */ | 476 | /* Bzy_MHz */ |
474 | if (has_aperf) | 477 | if (has_aperf) |
475 | outp += sprintf(outp, "%8.0f", | 478 | outp += sprintf(outp, "%8.0f", |
476 | 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); | 479 | 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); |
477 | 480 | ||
478 | /* TSC */ | 481 | /* TSC_MHz */ |
479 | outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); | 482 | outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); |
480 | 483 | ||
481 | /* SMI */ | 484 | /* SMI */ |
@@ -561,7 +564,7 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
561 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); | 564 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); |
562 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 565 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
563 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); | 566 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); |
564 | } else { | 567 | } else if (do_rapl && rapl_joules) { |
565 | if (do_rapl & RAPL_PKG) | 568 | if (do_rapl & RAPL_PKG) |
566 | outp += sprintf(outp, fmt8, | 569 | outp += sprintf(outp, fmt8, |
567 | p->energy_pkg * rapl_energy_units); | 570 | p->energy_pkg * rapl_energy_units); |
@@ -578,8 +581,8 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
578 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); | 581 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); |
579 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 582 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
580 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); | 583 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); |
581 | outp += sprintf(outp, fmt8, interval_float); | ||
582 | 584 | ||
585 | outp += sprintf(outp, fmt8, interval_float); | ||
583 | } | 586 | } |
584 | done: | 587 | done: |
585 | outp += sprintf(outp, "\n"); | 588 | outp += sprintf(outp, "\n"); |
@@ -670,24 +673,26 @@ delta_thread(struct thread_data *new, struct thread_data *old, | |||
670 | 673 | ||
671 | old->c1 = new->c1 - old->c1; | 674 | old->c1 = new->c1 - old->c1; |
672 | 675 | ||
673 | if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { | 676 | if (has_aperf) { |
674 | old->aperf = new->aperf - old->aperf; | 677 | if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { |
675 | old->mperf = new->mperf - old->mperf; | 678 | old->aperf = new->aperf - old->aperf; |
676 | } else { | 679 | old->mperf = new->mperf - old->mperf; |
680 | } else { | ||
677 | 681 | ||
678 | if (!aperf_mperf_unstable) { | 682 | if (!aperf_mperf_unstable) { |
679 | fprintf(stderr, "%s: APERF or MPERF went backwards *\n", progname); | 683 | fprintf(stderr, "%s: APERF or MPERF went backwards *\n", progname); |
680 | fprintf(stderr, "* Frequency results do not cover entire interval *\n"); | 684 | fprintf(stderr, "* Frequency results do not cover entire interval *\n"); |
681 | fprintf(stderr, "* fix this by running Linux-2.6.30 or later *\n"); | 685 | fprintf(stderr, "* fix this by running Linux-2.6.30 or later *\n"); |
682 | 686 | ||
683 | aperf_mperf_unstable = 1; | 687 | aperf_mperf_unstable = 1; |
688 | } | ||
689 | /* | ||
690 | * mperf delta is likely a huge "positive" number | ||
691 | * can not use it for calculating c0 time | ||
692 | */ | ||
693 | skip_c0 = 1; | ||
694 | skip_c1 = 1; | ||
684 | } | 695 | } |
685 | /* | ||
686 | * mperf delta is likely a huge "positive" number | ||
687 | * can not use it for calculating c0 time | ||
688 | */ | ||
689 | skip_c0 = 1; | ||
690 | skip_c1 = 1; | ||
691 | } | 696 | } |
692 | 697 | ||
693 | 698 | ||
@@ -1019,7 +1024,7 @@ void print_verbose_header(void) | |||
1019 | unsigned long long msr; | 1024 | unsigned long long msr; |
1020 | unsigned int ratio; | 1025 | unsigned int ratio; |
1021 | 1026 | ||
1022 | if (!do_nehalem_platform_info) | 1027 | if (!do_nhm_platform_info) |
1023 | return; | 1028 | return; |
1024 | 1029 | ||
1025 | get_msr(0, MSR_NHM_PLATFORM_INFO, &msr); | 1030 | get_msr(0, MSR_NHM_PLATFORM_INFO, &msr); |
@@ -1132,7 +1137,7 @@ print_nhm_turbo_ratio_limits: | |||
1132 | } | 1137 | } |
1133 | fprintf(stderr, ")\n"); | 1138 | fprintf(stderr, ")\n"); |
1134 | 1139 | ||
1135 | if (!do_nehalem_turbo_ratio_limit) | 1140 | if (!do_nhm_turbo_ratio_limit) |
1136 | return; | 1141 | return; |
1137 | 1142 | ||
1138 | get_msr(0, MSR_NHM_TURBO_RATIO_LIMIT, &msr); | 1143 | get_msr(0, MSR_NHM_TURBO_RATIO_LIMIT, &msr); |
@@ -1178,6 +1183,7 @@ print_nhm_turbo_ratio_limits: | |||
1178 | if (ratio) | 1183 | if (ratio) |
1179 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", | 1184 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", |
1180 | ratio, bclk, ratio * bclk); | 1185 | ratio, bclk, ratio * bclk); |
1186 | |||
1181 | } | 1187 | } |
1182 | 1188 | ||
1183 | void free_all_buffers(void) | 1189 | void free_all_buffers(void) |
@@ -1458,17 +1464,60 @@ void check_dev_msr() | |||
1458 | struct stat sb; | 1464 | struct stat sb; |
1459 | 1465 | ||
1460 | if (stat("/dev/cpu/0/msr", &sb)) | 1466 | if (stat("/dev/cpu/0/msr", &sb)) |
1461 | err(-5, "no /dev/cpu/0/msr\n" | 1467 | err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); |
1462 | "Try \"# modprobe msr\""); | ||
1463 | } | 1468 | } |
1464 | 1469 | ||
1465 | void check_super_user() | 1470 | void check_permissions() |
1466 | { | 1471 | { |
1467 | if (getuid() != 0) | 1472 | struct __user_cap_header_struct cap_header_data; |
1468 | errx(-6, "must be root"); | 1473 | cap_user_header_t cap_header = &cap_header_data; |
1474 | struct __user_cap_data_struct cap_data_data; | ||
1475 | cap_user_data_t cap_data = &cap_data_data; | ||
1476 | extern int capget(cap_user_header_t hdrp, cap_user_data_t datap); | ||
1477 | int do_exit = 0; | ||
1478 | |||
1479 | /* check for CAP_SYS_RAWIO */ | ||
1480 | cap_header->pid = getpid(); | ||
1481 | cap_header->version = _LINUX_CAPABILITY_VERSION; | ||
1482 | if (capget(cap_header, cap_data) < 0) | ||
1483 | err(-6, "capget(2) failed"); | ||
1484 | |||
1485 | if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) { | ||
1486 | do_exit++; | ||
1487 | warnx("capget(CAP_SYS_RAWIO) failed," | ||
1488 | " try \"# setcap cap_sys_rawio=ep %s\"", progname); | ||
1489 | } | ||
1490 | |||
1491 | /* test file permissions */ | ||
1492 | if (euidaccess("/dev/cpu/0/msr", R_OK)) { | ||
1493 | do_exit++; | ||
1494 | warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr"); | ||
1495 | } | ||
1496 | |||
1497 | /* if all else fails, thell them to be root */ | ||
1498 | if (do_exit) | ||
1499 | if (getuid() != 0) | ||
1500 | warnx("... or simply run as root"); | ||
1501 | |||
1502 | if (do_exit) | ||
1503 | exit(-6); | ||
1469 | } | 1504 | } |
1470 | 1505 | ||
1471 | int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) | 1506 | /* |
1507 | * NHM adds support for additional MSRs: | ||
1508 | * | ||
1509 | * MSR_SMI_COUNT 0x00000034 | ||
1510 | * | ||
1511 | * MSR_NHM_PLATFORM_INFO 0x000000ce | ||
1512 | * MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 | ||
1513 | * | ||
1514 | * MSR_PKG_C3_RESIDENCY 0x000003f8 | ||
1515 | * MSR_PKG_C6_RESIDENCY 0x000003f9 | ||
1516 | * MSR_CORE_C3_RESIDENCY 0x000003fc | ||
1517 | * MSR_CORE_C6_RESIDENCY 0x000003fd | ||
1518 | * | ||
1519 | */ | ||
1520 | int has_nhm_msrs(unsigned int family, unsigned int model) | ||
1472 | { | 1521 | { |
1473 | if (!genuine_intel) | 1522 | if (!genuine_intel) |
1474 | return 0; | 1523 | return 0; |
@@ -1495,13 +1544,27 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) | |||
1495 | case 0x3D: /* BDW */ | 1544 | case 0x3D: /* BDW */ |
1496 | case 0x4F: /* BDX */ | 1545 | case 0x4F: /* BDX */ |
1497 | case 0x56: /* BDX-DE */ | 1546 | case 0x56: /* BDX-DE */ |
1498 | return 1; | ||
1499 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ | 1547 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ |
1500 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ | 1548 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ |
1549 | return 1; | ||
1501 | default: | 1550 | default: |
1502 | return 0; | 1551 | return 0; |
1503 | } | 1552 | } |
1504 | } | 1553 | } |
1554 | int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) | ||
1555 | { | ||
1556 | if (!has_nhm_msrs(family, model)) | ||
1557 | return 0; | ||
1558 | |||
1559 | switch (model) { | ||
1560 | /* Nehalem compatible, but do not include turbo-ratio limit support */ | ||
1561 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ | ||
1562 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ | ||
1563 | return 0; | ||
1564 | default: | ||
1565 | return 1; | ||
1566 | } | ||
1567 | } | ||
1505 | int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) | 1568 | int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) |
1506 | { | 1569 | { |
1507 | if (!genuine_intel) | 1570 | if (!genuine_intel) |
@@ -1564,6 +1627,103 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1564 | return 0; | 1627 | return 0; |
1565 | } | 1628 | } |
1566 | 1629 | ||
1630 | /* | ||
1631 | * print_perf_limit() | ||
1632 | */ | ||
1633 | int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p) | ||
1634 | { | ||
1635 | unsigned long long msr; | ||
1636 | int cpu; | ||
1637 | |||
1638 | cpu = t->cpu_id; | ||
1639 | |||
1640 | /* per-package */ | ||
1641 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) | ||
1642 | return 0; | ||
1643 | |||
1644 | if (cpu_migrate(cpu)) { | ||
1645 | fprintf(stderr, "Could not migrate to CPU %d\n", cpu); | ||
1646 | return -1; | ||
1647 | } | ||
1648 | |||
1649 | if (do_core_perf_limit_reasons) { | ||
1650 | get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr); | ||
1651 | fprintf(stderr, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); | ||
1652 | fprintf(stderr, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)", | ||
1653 | (msr & 1 << 0) ? "PROCHOT, " : "", | ||
1654 | (msr & 1 << 1) ? "ThermStatus, " : "", | ||
1655 | (msr & 1 << 2) ? "bit2, " : "", | ||
1656 | (msr & 1 << 4) ? "Graphics, " : "", | ||
1657 | (msr & 1 << 5) ? "Auto-HWP, " : "", | ||
1658 | (msr & 1 << 6) ? "VR-Therm, " : "", | ||
1659 | (msr & 1 << 8) ? "Amps, " : "", | ||
1660 | (msr & 1 << 9) ? "CorePwr, " : "", | ||
1661 | (msr & 1 << 10) ? "PkgPwrL1, " : "", | ||
1662 | (msr & 1 << 11) ? "PkgPwrL2, " : "", | ||
1663 | (msr & 1 << 12) ? "MultiCoreTurbo, " : "", | ||
1664 | (msr & 1 << 13) ? "Transitions, " : "", | ||
1665 | (msr & 1 << 14) ? "bit14, " : "", | ||
1666 | (msr & 1 << 15) ? "bit15, " : ""); | ||
1667 | fprintf(stderr, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n", | ||
1668 | (msr & 1 << 16) ? "PROCHOT, " : "", | ||
1669 | (msr & 1 << 17) ? "ThermStatus, " : "", | ||
1670 | (msr & 1 << 18) ? "bit18, " : "", | ||
1671 | (msr & 1 << 20) ? "Graphics, " : "", | ||
1672 | (msr & 1 << 21) ? "Auto-HWP, " : "", | ||
1673 | (msr & 1 << 22) ? "VR-Therm, " : "", | ||
1674 | (msr & 1 << 24) ? "Amps, " : "", | ||
1675 | (msr & 1 << 25) ? "CorePwr, " : "", | ||
1676 | (msr & 1 << 26) ? "PkgPwrL1, " : "", | ||
1677 | (msr & 1 << 27) ? "PkgPwrL2, " : "", | ||
1678 | (msr & 1 << 28) ? "MultiCoreTurbo, " : "", | ||
1679 | (msr & 1 << 29) ? "Transitions, " : "", | ||
1680 | (msr & 1 << 30) ? "bit30, " : "", | ||
1681 | (msr & 1 << 31) ? "bit31, " : ""); | ||
1682 | |||
1683 | } | ||
1684 | if (do_gfx_perf_limit_reasons) { | ||
1685 | get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr); | ||
1686 | fprintf(stderr, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); | ||
1687 | fprintf(stderr, " (Active: %s%s%s%s%s%s%s%s)", | ||
1688 | (msr & 1 << 0) ? "PROCHOT, " : "", | ||
1689 | (msr & 1 << 1) ? "ThermStatus, " : "", | ||
1690 | (msr & 1 << 4) ? "Graphics, " : "", | ||
1691 | (msr & 1 << 6) ? "VR-Therm, " : "", | ||
1692 | (msr & 1 << 8) ? "Amps, " : "", | ||
1693 | (msr & 1 << 9) ? "GFXPwr, " : "", | ||
1694 | (msr & 1 << 10) ? "PkgPwrL1, " : "", | ||
1695 | (msr & 1 << 11) ? "PkgPwrL2, " : ""); | ||
1696 | fprintf(stderr, " (Logged: %s%s%s%s%s%s%s%s)\n", | ||
1697 | (msr & 1 << 16) ? "PROCHOT, " : "", | ||
1698 | (msr & 1 << 17) ? "ThermStatus, " : "", | ||
1699 | (msr & 1 << 20) ? "Graphics, " : "", | ||
1700 | (msr & 1 << 22) ? "VR-Therm, " : "", | ||
1701 | (msr & 1 << 24) ? "Amps, " : "", | ||
1702 | (msr & 1 << 25) ? "GFXPwr, " : "", | ||
1703 | (msr & 1 << 26) ? "PkgPwrL1, " : "", | ||
1704 | (msr & 1 << 27) ? "PkgPwrL2, " : ""); | ||
1705 | } | ||
1706 | if (do_ring_perf_limit_reasons) { | ||
1707 | get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr); | ||
1708 | fprintf(stderr, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); | ||
1709 | fprintf(stderr, " (Active: %s%s%s%s%s%s)", | ||
1710 | (msr & 1 << 0) ? "PROCHOT, " : "", | ||
1711 | (msr & 1 << 1) ? "ThermStatus, " : "", | ||
1712 | (msr & 1 << 6) ? "VR-Therm, " : "", | ||
1713 | (msr & 1 << 8) ? "Amps, " : "", | ||
1714 | (msr & 1 << 10) ? "PkgPwrL1, " : "", | ||
1715 | (msr & 1 << 11) ? "PkgPwrL2, " : ""); | ||
1716 | fprintf(stderr, " (Logged: %s%s%s%s%s%s)\n", | ||
1717 | (msr & 1 << 16) ? "PROCHOT, " : "", | ||
1718 | (msr & 1 << 17) ? "ThermStatus, " : "", | ||
1719 | (msr & 1 << 22) ? "VR-Therm, " : "", | ||
1720 | (msr & 1 << 24) ? "Amps, " : "", | ||
1721 | (msr & 1 << 26) ? "PkgPwrL1, " : "", | ||
1722 | (msr & 1 << 27) ? "PkgPwrL2, " : ""); | ||
1723 | } | ||
1724 | return 0; | ||
1725 | } | ||
1726 | |||
1567 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ | 1727 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ |
1568 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ | 1728 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ |
1569 | 1729 | ||
@@ -1653,6 +1813,27 @@ void rapl_probe(unsigned int family, unsigned int model) | |||
1653 | return; | 1813 | return; |
1654 | } | 1814 | } |
1655 | 1815 | ||
1816 | void perf_limit_reasons_probe(family, model) | ||
1817 | { | ||
1818 | if (!genuine_intel) | ||
1819 | return; | ||
1820 | |||
1821 | if (family != 6) | ||
1822 | return; | ||
1823 | |||
1824 | switch (model) { | ||
1825 | case 0x3C: /* HSW */ | ||
1826 | case 0x45: /* HSW */ | ||
1827 | case 0x46: /* HSW */ | ||
1828 | do_gfx_perf_limit_reasons = 1; | ||
1829 | case 0x3F: /* HSX */ | ||
1830 | do_core_perf_limit_reasons = 1; | ||
1831 | do_ring_perf_limit_reasons = 1; | ||
1832 | default: | ||
1833 | return; | ||
1834 | } | ||
1835 | } | ||
1836 | |||
1656 | int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p) | 1837 | int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p) |
1657 | { | 1838 | { |
1658 | unsigned long long msr; | 1839 | unsigned long long msr; |
@@ -1842,8 +2023,15 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1842 | return 0; | 2023 | return 0; |
1843 | } | 2024 | } |
1844 | 2025 | ||
2026 | /* | ||
2027 | * SNB adds support for additional MSRs: | ||
2028 | * | ||
2029 | * MSR_PKG_C7_RESIDENCY 0x000003fa | ||
2030 | * MSR_CORE_C7_RESIDENCY 0x000003fe | ||
2031 | * MSR_PKG_C2_RESIDENCY 0x0000060d | ||
2032 | */ | ||
1845 | 2033 | ||
1846 | int is_snb(unsigned int family, unsigned int model) | 2034 | int has_snb_msrs(unsigned int family, unsigned int model) |
1847 | { | 2035 | { |
1848 | if (!genuine_intel) | 2036 | if (!genuine_intel) |
1849 | return 0; | 2037 | return 0; |
@@ -1865,7 +2053,14 @@ int is_snb(unsigned int family, unsigned int model) | |||
1865 | return 0; | 2053 | return 0; |
1866 | } | 2054 | } |
1867 | 2055 | ||
1868 | int has_c8_c9_c10(unsigned int family, unsigned int model) | 2056 | /* |
2057 | * HSW adds support for additional MSRs: | ||
2058 | * | ||
2059 | * MSR_PKG_C8_RESIDENCY 0x00000630 | ||
2060 | * MSR_PKG_C9_RESIDENCY 0x00000631 | ||
2061 | * MSR_PKG_C10_RESIDENCY 0x00000632 | ||
2062 | */ | ||
2063 | int has_hsw_msrs(unsigned int family, unsigned int model) | ||
1869 | { | 2064 | { |
1870 | if (!genuine_intel) | 2065 | if (!genuine_intel) |
1871 | return 0; | 2066 | return 0; |
@@ -1917,7 +2112,7 @@ double slm_bclk(void) | |||
1917 | 2112 | ||
1918 | double discover_bclk(unsigned int family, unsigned int model) | 2113 | double discover_bclk(unsigned int family, unsigned int model) |
1919 | { | 2114 | { |
1920 | if (is_snb(family, model)) | 2115 | if (has_snb_msrs(family, model)) |
1921 | return 100.00; | 2116 | return 100.00; |
1922 | else if (is_slm(family, model)) | 2117 | else if (is_slm(family, model)) |
1923 | return slm_bclk(); | 2118 | return slm_bclk(); |
@@ -1965,7 +2160,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk | |||
1965 | } | 2160 | } |
1966 | 2161 | ||
1967 | /* Temperature Target MSR is Nehalem and newer only */ | 2162 | /* Temperature Target MSR is Nehalem and newer only */ |
1968 | if (!do_nehalem_platform_info) | 2163 | if (!do_nhm_platform_info) |
1969 | goto guess; | 2164 | goto guess; |
1970 | 2165 | ||
1971 | if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr)) | 2166 | if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr)) |
@@ -2029,18 +2224,15 @@ void check_cpuid() | |||
2029 | ebx = ecx = edx = 0; | 2224 | ebx = ecx = edx = 0; |
2030 | __get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx); | 2225 | __get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx); |
2031 | 2226 | ||
2032 | if (max_level < 0x80000007) | 2227 | if (max_level >= 0x80000007) { |
2033 | errx(1, "CPUID: no invariant TSC (max_level 0x%x)", max_level); | ||
2034 | 2228 | ||
2035 | /* | 2229 | /* |
2036 | * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 | 2230 | * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 |
2037 | * this check is valid for both Intel and AMD | 2231 | * this check is valid for both Intel and AMD |
2038 | */ | 2232 | */ |
2039 | __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx); | 2233 | __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx); |
2040 | has_invariant_tsc = edx & (1 << 8); | 2234 | has_invariant_tsc = edx & (1 << 8); |
2041 | 2235 | } | |
2042 | if (!has_invariant_tsc) | ||
2043 | errx(1, "No invariant TSC"); | ||
2044 | 2236 | ||
2045 | /* | 2237 | /* |
2046 | * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0 | 2238 | * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0 |
@@ -2054,26 +2246,22 @@ void check_cpuid() | |||
2054 | has_epb = ecx & (1 << 3); | 2246 | has_epb = ecx & (1 << 3); |
2055 | 2247 | ||
2056 | if (verbose) | 2248 | if (verbose) |
2057 | fprintf(stderr, "CPUID(6): %s%s%s%s\n", | 2249 | fprintf(stderr, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sEPB\n", |
2058 | has_aperf ? "APERF" : "No APERF!", | 2250 | has_aperf ? "" : "No ", |
2059 | do_dts ? ", DTS" : "", | 2251 | do_dts ? "" : "No ", |
2060 | do_ptm ? ", PTM": "", | 2252 | do_ptm ? "" : "No ", |
2061 | has_epb ? ", EPB": ""); | 2253 | has_epb ? "" : "No "); |
2062 | 2254 | ||
2063 | if (!has_aperf) | 2255 | do_nhm_platform_info = do_nhm_cstates = do_smi = has_nhm_msrs(family, model); |
2064 | errx(-1, "No APERF"); | 2256 | do_snb_cstates = has_snb_msrs(family, model); |
2065 | 2257 | do_c8_c9_c10 = has_hsw_msrs(family, model); | |
2066 | do_nehalem_platform_info = genuine_intel && has_invariant_tsc; | ||
2067 | do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */ | ||
2068 | do_smi = do_nhm_cstates; | ||
2069 | do_snb_cstates = is_snb(family, model); | ||
2070 | do_c8_c9_c10 = has_c8_c9_c10(family, model); | ||
2071 | do_slm_cstates = is_slm(family, model); | 2258 | do_slm_cstates = is_slm(family, model); |
2072 | bclk = discover_bclk(family, model); | 2259 | bclk = discover_bclk(family, model); |
2073 | 2260 | ||
2074 | do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); | 2261 | do_nhm_turbo_ratio_limit = has_nhm_turbo_ratio_limit(family, model); |
2075 | do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); | 2262 | do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); |
2076 | rapl_probe(family, model); | 2263 | rapl_probe(family, model); |
2264 | perf_limit_reasons_probe(family, model); | ||
2077 | 2265 | ||
2078 | return; | 2266 | return; |
2079 | } | 2267 | } |
@@ -2299,10 +2487,9 @@ void setup_all_buffers(void) | |||
2299 | 2487 | ||
2300 | void turbostat_init() | 2488 | void turbostat_init() |
2301 | { | 2489 | { |
2302 | check_cpuid(); | ||
2303 | |||
2304 | check_dev_msr(); | 2490 | check_dev_msr(); |
2305 | check_super_user(); | 2491 | check_permissions(); |
2492 | check_cpuid(); | ||
2306 | 2493 | ||
2307 | setup_all_buffers(); | 2494 | setup_all_buffers(); |
2308 | 2495 | ||
@@ -2313,6 +2500,9 @@ void turbostat_init() | |||
2313 | for_all_cpus(print_epb, ODD_COUNTERS); | 2500 | for_all_cpus(print_epb, ODD_COUNTERS); |
2314 | 2501 | ||
2315 | if (verbose) | 2502 | if (verbose) |
2503 | for_all_cpus(print_perf_limit, ODD_COUNTERS); | ||
2504 | |||
2505 | if (verbose) | ||
2316 | for_all_cpus(print_rapl, ODD_COUNTERS); | 2506 | for_all_cpus(print_rapl, ODD_COUNTERS); |
2317 | 2507 | ||
2318 | for_all_cpus(set_temperature_target, ODD_COUNTERS); | 2508 | for_all_cpus(set_temperature_target, ODD_COUNTERS); |
@@ -2441,7 +2631,7 @@ int main(int argc, char **argv) | |||
2441 | cmdline(argc, argv); | 2631 | cmdline(argc, argv); |
2442 | 2632 | ||
2443 | if (verbose) | 2633 | if (verbose) |
2444 | fprintf(stderr, "turbostat v3.7 Feb 6, 2014" | 2634 | fprintf(stderr, "turbostat v3.9 23-Jan, 2015" |
2445 | " - Len Brown <lenb@kernel.org>\n"); | 2635 | " - Len Brown <lenb@kernel.org>\n"); |
2446 | 2636 | ||
2447 | turbostat_init(); | 2637 | turbostat_init(); |