diff options
Diffstat (limited to 'drivers/acpi')
84 files changed, 2926 insertions, 1309 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 445ce28475b3..696c6f74a9c7 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -227,7 +227,6 @@ config ACPI_MCFG | |||
227 | config ACPI_CPPC_LIB | 227 | config ACPI_CPPC_LIB |
228 | bool | 228 | bool |
229 | depends on ACPI_PROCESSOR | 229 | depends on ACPI_PROCESSOR |
230 | depends on !ACPI_CPU_FREQ_PSS | ||
231 | select MAILBOX | 230 | select MAILBOX |
232 | select PCC | 231 | select PCC |
233 | help | 232 | help |
@@ -462,6 +461,9 @@ source "drivers/acpi/nfit/Kconfig" | |||
462 | source "drivers/acpi/apei/Kconfig" | 461 | source "drivers/acpi/apei/Kconfig" |
463 | source "drivers/acpi/dptf/Kconfig" | 462 | source "drivers/acpi/dptf/Kconfig" |
464 | 463 | ||
464 | config ACPI_WATCHDOG | ||
465 | bool | ||
466 | |||
465 | config ACPI_EXTLOG | 467 | config ACPI_EXTLOG |
466 | tristate "Extended Error Log support" | 468 | tristate "Extended Error Log support" |
467 | depends on X86_MCE && X86_LOCAL_APIC | 469 | depends on X86_MCE && X86_LOCAL_APIC |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 5ae9d85c5159..3a1fa8f03749 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -56,6 +56,7 @@ acpi-$(CONFIG_ACPI_NUMA) += numa.o | |||
56 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o | 56 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o |
57 | acpi-y += acpi_lpat.o | 57 | acpi-y += acpi_lpat.o |
58 | acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o | 58 | acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o |
59 | acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o | ||
59 | 60 | ||
60 | # These are (potentially) separate modules | 61 | # These are (potentially) separate modules |
61 | 62 | ||
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index 1daf9c46df8e..d58fbf7f04e6 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c | |||
@@ -42,6 +42,7 @@ struct apd_private_data; | |||
42 | struct apd_device_desc { | 42 | struct apd_device_desc { |
43 | unsigned int flags; | 43 | unsigned int flags; |
44 | unsigned int fixed_clk_rate; | 44 | unsigned int fixed_clk_rate; |
45 | struct property_entry *properties; | ||
45 | int (*setup)(struct apd_private_data *pdata); | 46 | int (*setup)(struct apd_private_data *pdata); |
46 | }; | 47 | }; |
47 | 48 | ||
@@ -71,22 +72,35 @@ static int acpi_apd_setup(struct apd_private_data *pdata) | |||
71 | } | 72 | } |
72 | 73 | ||
73 | #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE | 74 | #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE |
74 | static struct apd_device_desc cz_i2c_desc = { | 75 | static const struct apd_device_desc cz_i2c_desc = { |
75 | .setup = acpi_apd_setup, | 76 | .setup = acpi_apd_setup, |
76 | .fixed_clk_rate = 133000000, | 77 | .fixed_clk_rate = 133000000, |
77 | }; | 78 | }; |
78 | 79 | ||
79 | static struct apd_device_desc cz_uart_desc = { | 80 | static struct property_entry uart_properties[] = { |
81 | PROPERTY_ENTRY_U32("reg-io-width", 4), | ||
82 | PROPERTY_ENTRY_U32("reg-shift", 2), | ||
83 | PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"), | ||
84 | { }, | ||
85 | }; | ||
86 | |||
87 | static const struct apd_device_desc cz_uart_desc = { | ||
80 | .setup = acpi_apd_setup, | 88 | .setup = acpi_apd_setup, |
81 | .fixed_clk_rate = 48000000, | 89 | .fixed_clk_rate = 48000000, |
90 | .properties = uart_properties, | ||
82 | }; | 91 | }; |
83 | #endif | 92 | #endif |
84 | 93 | ||
85 | #ifdef CONFIG_ARM64 | 94 | #ifdef CONFIG_ARM64 |
86 | static struct apd_device_desc xgene_i2c_desc = { | 95 | static const struct apd_device_desc xgene_i2c_desc = { |
87 | .setup = acpi_apd_setup, | 96 | .setup = acpi_apd_setup, |
88 | .fixed_clk_rate = 100000000, | 97 | .fixed_clk_rate = 100000000, |
89 | }; | 98 | }; |
99 | |||
100 | static const struct apd_device_desc vulcan_spi_desc = { | ||
101 | .setup = acpi_apd_setup, | ||
102 | .fixed_clk_rate = 133000000, | ||
103 | }; | ||
90 | #endif | 104 | #endif |
91 | 105 | ||
92 | #else | 106 | #else |
@@ -125,6 +139,12 @@ static int acpi_apd_create_device(struct acpi_device *adev, | |||
125 | goto err_out; | 139 | goto err_out; |
126 | } | 140 | } |
127 | 141 | ||
142 | if (dev_desc->properties) { | ||
143 | ret = device_add_properties(&adev->dev, dev_desc->properties); | ||
144 | if (ret) | ||
145 | goto err_out; | ||
146 | } | ||
147 | |||
128 | adev->driver_data = pdata; | 148 | adev->driver_data = pdata; |
129 | pdev = acpi_create_platform_device(adev); | 149 | pdev = acpi_create_platform_device(adev); |
130 | if (!IS_ERR_OR_NULL(pdev)) | 150 | if (!IS_ERR_OR_NULL(pdev)) |
@@ -149,6 +169,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { | |||
149 | #endif | 169 | #endif |
150 | #ifdef CONFIG_ARM64 | 170 | #ifdef CONFIG_ARM64 |
151 | { "APMC0D0F", APD_ADDR(xgene_i2c_desc) }, | 171 | { "APMC0D0F", APD_ADDR(xgene_i2c_desc) }, |
172 | { "BRCM900D", APD_ADDR(vulcan_spi_desc) }, | ||
152 | #endif | 173 | #endif |
153 | { } | 174 | { } |
154 | }; | 175 | }; |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 357a0b8f860b..552010288135 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -75,6 +75,7 @@ struct lpss_device_desc { | |||
75 | const char *clk_con_id; | 75 | const char *clk_con_id; |
76 | unsigned int prv_offset; | 76 | unsigned int prv_offset; |
77 | size_t prv_size_override; | 77 | size_t prv_size_override; |
78 | struct property_entry *properties; | ||
78 | void (*setup)(struct lpss_private_data *pdata); | 79 | void (*setup)(struct lpss_private_data *pdata); |
79 | }; | 80 | }; |
80 | 81 | ||
@@ -163,11 +164,19 @@ static const struct lpss_device_desc lpt_i2c_dev_desc = { | |||
163 | .prv_offset = 0x800, | 164 | .prv_offset = 0x800, |
164 | }; | 165 | }; |
165 | 166 | ||
167 | static struct property_entry uart_properties[] = { | ||
168 | PROPERTY_ENTRY_U32("reg-io-width", 4), | ||
169 | PROPERTY_ENTRY_U32("reg-shift", 2), | ||
170 | PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"), | ||
171 | { }, | ||
172 | }; | ||
173 | |||
166 | static const struct lpss_device_desc lpt_uart_dev_desc = { | 174 | static const struct lpss_device_desc lpt_uart_dev_desc = { |
167 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR, | 175 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR, |
168 | .clk_con_id = "baudclk", | 176 | .clk_con_id = "baudclk", |
169 | .prv_offset = 0x800, | 177 | .prv_offset = 0x800, |
170 | .setup = lpss_uart_setup, | 178 | .setup = lpss_uart_setup, |
179 | .properties = uart_properties, | ||
171 | }; | 180 | }; |
172 | 181 | ||
173 | static const struct lpss_device_desc lpt_sdio_dev_desc = { | 182 | static const struct lpss_device_desc lpt_sdio_dev_desc = { |
@@ -189,6 +198,7 @@ static const struct lpss_device_desc byt_uart_dev_desc = { | |||
189 | .clk_con_id = "baudclk", | 198 | .clk_con_id = "baudclk", |
190 | .prv_offset = 0x800, | 199 | .prv_offset = 0x800, |
191 | .setup = lpss_uart_setup, | 200 | .setup = lpss_uart_setup, |
201 | .properties = uart_properties, | ||
192 | }; | 202 | }; |
193 | 203 | ||
194 | static const struct lpss_device_desc bsw_uart_dev_desc = { | 204 | static const struct lpss_device_desc bsw_uart_dev_desc = { |
@@ -197,6 +207,7 @@ static const struct lpss_device_desc bsw_uart_dev_desc = { | |||
197 | .clk_con_id = "baudclk", | 207 | .clk_con_id = "baudclk", |
198 | .prv_offset = 0x800, | 208 | .prv_offset = 0x800, |
199 | .setup = lpss_uart_setup, | 209 | .setup = lpss_uart_setup, |
210 | .properties = uart_properties, | ||
200 | }; | 211 | }; |
201 | 212 | ||
202 | static const struct lpss_device_desc byt_spi_dev_desc = { | 213 | static const struct lpss_device_desc byt_spi_dev_desc = { |
@@ -440,6 +451,12 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
440 | goto err_out; | 451 | goto err_out; |
441 | } | 452 | } |
442 | 453 | ||
454 | if (dev_desc->properties) { | ||
455 | ret = device_add_properties(&adev->dev, dev_desc->properties); | ||
456 | if (ret) | ||
457 | goto err_out; | ||
458 | } | ||
459 | |||
443 | adev->driver_data = pdata; | 460 | adev->driver_data = pdata; |
444 | pdev = acpi_create_platform_device(adev); | 461 | pdev = acpi_create_platform_device(adev); |
445 | if (!IS_ERR_OR_NULL(pdev)) { | 462 | if (!IS_ERR_OR_NULL(pdev)) { |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 8ea8211b2d58..eb76a4c10dbf 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
28 | #include <asm/mwait.h> | 28 | #include <asm/mwait.h> |
29 | #include <xen/xen.h> | ||
29 | 30 | ||
30 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" | 31 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" |
31 | #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" | 32 | #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" |
@@ -477,6 +478,10 @@ static struct acpi_driver acpi_pad_driver = { | |||
477 | 478 | ||
478 | static int __init acpi_pad_init(void) | 479 | static int __init acpi_pad_init(void) |
479 | { | 480 | { |
481 | /* Xen ACPI PAD is used when running as Xen Dom0. */ | ||
482 | if (xen_initial_domain()) | ||
483 | return -ENODEV; | ||
484 | |||
480 | power_saving_mwait_init(); | 485 | power_saving_mwait_init(); |
481 | if (power_saving_mwait_eax == 0) | 486 | if (power_saving_mwait_eax == 0) |
482 | return -EINVAL; | 487 | return -EINVAL; |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 159f7f19abce..b200ae1f3c6f 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/pci.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | 22 | ||
22 | #include "internal.h" | 23 | #include "internal.h" |
@@ -30,6 +31,22 @@ static const struct acpi_device_id forbidden_id_list[] = { | |||
30 | {"", 0}, | 31 | {"", 0}, |
31 | }; | 32 | }; |
32 | 33 | ||
34 | static void acpi_platform_fill_resource(struct acpi_device *adev, | ||
35 | const struct resource *src, struct resource *dest) | ||
36 | { | ||
37 | struct device *parent; | ||
38 | |||
39 | *dest = *src; | ||
40 | |||
41 | /* | ||
42 | * If the device has parent we need to take its resources into | ||
43 | * account as well because this device might consume part of those. | ||
44 | */ | ||
45 | parent = acpi_get_first_physical_node(adev->parent); | ||
46 | if (parent && dev_is_pci(parent)) | ||
47 | dest->parent = pci_find_resource(to_pci_dev(parent), dest); | ||
48 | } | ||
49 | |||
33 | /** | 50 | /** |
34 | * acpi_create_platform_device - Create platform device for ACPI device node | 51 | * acpi_create_platform_device - Create platform device for ACPI device node |
35 | * @adev: ACPI device node to create a platform device for. | 52 | * @adev: ACPI device node to create a platform device for. |
@@ -70,7 +87,8 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) | |||
70 | } | 87 | } |
71 | count = 0; | 88 | count = 0; |
72 | list_for_each_entry(rentry, &resource_list, node) | 89 | list_for_each_entry(rentry, &resource_list, node) |
73 | resources[count++] = *rentry->res; | 90 | acpi_platform_fill_resource(adev, rentry->res, |
91 | &resources[count++]); | ||
74 | 92 | ||
75 | acpi_dev_free_resource_list(&resource_list); | 93 | acpi_dev_free_resource_list(&resource_list); |
76 | } | 94 | } |
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c new file mode 100644 index 000000000000..13caebd679f5 --- /dev/null +++ b/drivers/acpi/acpi_watchdog.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * ACPI watchdog table parsing support. | ||
3 | * | ||
4 | * Copyright (C) 2016, Intel Corporation | ||
5 | * Author: Mika Westerberg <mika.westerberg@linux.intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #define pr_fmt(fmt) "ACPI: watchdog: " fmt | ||
13 | |||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/ioport.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "internal.h" | ||
19 | |||
20 | /** | ||
21 | * Returns true if this system should prefer ACPI based watchdog instead of | ||
22 | * the native one (which are typically the same hardware). | ||
23 | */ | ||
24 | bool acpi_has_watchdog(void) | ||
25 | { | ||
26 | struct acpi_table_header hdr; | ||
27 | |||
28 | if (acpi_disabled) | ||
29 | return false; | ||
30 | |||
31 | return ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_WDAT, 0, &hdr)); | ||
32 | } | ||
33 | EXPORT_SYMBOL_GPL(acpi_has_watchdog); | ||
34 | |||
35 | void __init acpi_watchdog_init(void) | ||
36 | { | ||
37 | const struct acpi_wdat_entry *entries; | ||
38 | const struct acpi_table_wdat *wdat; | ||
39 | struct list_head resource_list; | ||
40 | struct resource_entry *rentry; | ||
41 | struct platform_device *pdev; | ||
42 | struct resource *resources; | ||
43 | size_t nresources = 0; | ||
44 | acpi_status status; | ||
45 | int i; | ||
46 | |||
47 | status = acpi_get_table(ACPI_SIG_WDAT, 0, | ||
48 | (struct acpi_table_header **)&wdat); | ||
49 | if (ACPI_FAILURE(status)) { | ||
50 | /* It is fine if there is no WDAT */ | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | /* Watchdog disabled by BIOS */ | ||
55 | if (!(wdat->flags & ACPI_WDAT_ENABLED)) | ||
56 | return; | ||
57 | |||
58 | /* Skip legacy PCI WDT devices */ | ||
59 | if (wdat->pci_segment != 0xff || wdat->pci_bus != 0xff || | ||
60 | wdat->pci_device != 0xff || wdat->pci_function != 0xff) | ||
61 | return; | ||
62 | |||
63 | INIT_LIST_HEAD(&resource_list); | ||
64 | |||
65 | entries = (struct acpi_wdat_entry *)(wdat + 1); | ||
66 | for (i = 0; i < wdat->entries; i++) { | ||
67 | const struct acpi_generic_address *gas; | ||
68 | struct resource_entry *rentry; | ||
69 | struct resource res; | ||
70 | bool found; | ||
71 | |||
72 | gas = &entries[i].register_region; | ||
73 | |||
74 | res.start = gas->address; | ||
75 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
76 | res.flags = IORESOURCE_MEM; | ||
77 | res.end = res.start + ALIGN(gas->access_width, 4); | ||
78 | } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { | ||
79 | res.flags = IORESOURCE_IO; | ||
80 | res.end = res.start + gas->access_width; | ||
81 | } else { | ||
82 | pr_warn("Unsupported address space: %u\n", | ||
83 | gas->space_id); | ||
84 | goto fail_free_resource_list; | ||
85 | } | ||
86 | |||
87 | found = false; | ||
88 | resource_list_for_each_entry(rentry, &resource_list) { | ||
89 | if (resource_contains(rentry->res, &res)) { | ||
90 | found = true; | ||
91 | break; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | if (!found) { | ||
96 | rentry = resource_list_create_entry(NULL, 0); | ||
97 | if (!rentry) | ||
98 | goto fail_free_resource_list; | ||
99 | |||
100 | *rentry->res = res; | ||
101 | resource_list_add_tail(rentry, &resource_list); | ||
102 | nresources++; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | resources = kcalloc(nresources, sizeof(*resources), GFP_KERNEL); | ||
107 | if (!resources) | ||
108 | goto fail_free_resource_list; | ||
109 | |||
110 | i = 0; | ||
111 | resource_list_for_each_entry(rentry, &resource_list) | ||
112 | resources[i++] = *rentry->res; | ||
113 | |||
114 | pdev = platform_device_register_simple("wdat_wdt", PLATFORM_DEVID_NONE, | ||
115 | resources, nresources); | ||
116 | if (IS_ERR(pdev)) | ||
117 | pr_err("Failed to create platform device\n"); | ||
118 | |||
119 | kfree(resources); | ||
120 | |||
121 | fail_free_resource_list: | ||
122 | resource_list_free(&resource_list); | ||
123 | } | ||
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 227bb7bb19d7..32d93edbc479 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -175,6 +175,7 @@ acpi-y += \ | |||
175 | utresrc.o \ | 175 | utresrc.o \ |
176 | utstate.o \ | 176 | utstate.o \ |
177 | utstring.o \ | 177 | utstring.o \ |
178 | utstrtoul64.o \ | ||
178 | utxface.o \ | 179 | utxface.o \ |
179 | utxfinit.o \ | 180 | utxfinit.o \ |
180 | utxferror.o \ | 181 | utxferror.o \ |
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index ca2c0607104b..0bd6307e1f3c 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h | |||
@@ -44,7 +44,9 @@ | |||
44 | #ifndef _ACAPPS | 44 | #ifndef _ACAPPS |
45 | #define _ACAPPS | 45 | #define _ACAPPS |
46 | 46 | ||
47 | #include <stdio.h> | 47 | #ifdef ACPI_USE_STANDARD_HEADERS |
48 | #include <sys/stat.h> | ||
49 | #endif /* ACPI_USE_STANDARD_HEADERS */ | ||
48 | 50 | ||
49 | /* Common info for tool signons */ | 51 | /* Common info for tool signons */ |
50 | 52 | ||
@@ -81,13 +83,13 @@ | |||
81 | /* Macros for usage messages */ | 83 | /* Macros for usage messages */ |
82 | 84 | ||
83 | #define ACPI_USAGE_HEADER(usage) \ | 85 | #define ACPI_USAGE_HEADER(usage) \ |
84 | acpi_os_printf ("Usage: %s\nOptions:\n", usage); | 86 | printf ("Usage: %s\nOptions:\n", usage); |
85 | 87 | ||
86 | #define ACPI_USAGE_TEXT(description) \ | 88 | #define ACPI_USAGE_TEXT(description) \ |
87 | acpi_os_printf (description); | 89 | printf (description); |
88 | 90 | ||
89 | #define ACPI_OPTION(name, description) \ | 91 | #define ACPI_OPTION(name, description) \ |
90 | acpi_os_printf (" %-20s%s\n", name, description); | 92 | printf (" %-20s%s\n", name, description); |
91 | 93 | ||
92 | /* Check for unexpected exceptions */ | 94 | /* Check for unexpected exceptions */ |
93 | 95 | ||
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index f6404ea928cb..94737f8845ac 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -155,7 +155,7 @@ acpi_status acpi_db_disassemble_method(char *name); | |||
155 | 155 | ||
156 | void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op); | 156 | void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op); |
157 | 157 | ||
158 | void acpi_db_batch_execute(char *count_arg); | 158 | void acpi_db_evaluate_predefined_names(void); |
159 | 159 | ||
160 | /* | 160 | /* |
161 | * dbnames - namespace commands | 161 | * dbnames - namespace commands |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 77af91cf46d4..92fa47c6498c 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -86,6 +86,9 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); | |||
86 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 86 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
87 | 87 | ||
88 | acpi_status | 88 | acpi_status |
89 | acpi_ev_mask_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 is_masked); | ||
90 | |||
91 | acpi_status | ||
89 | acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); | 92 | acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); |
90 | 93 | ||
91 | acpi_status | 94 | acpi_status |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index fded776236e2..750fa824d42c 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -317,6 +317,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE); | |||
317 | ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE); | 317 | ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE); |
318 | ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE); | 318 | ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE); |
319 | ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_opt_verbose, TRUE); | 319 | ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_opt_verbose, TRUE); |
320 | ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_emit_external_opcodes, FALSE); | ||
320 | 321 | ||
321 | ACPI_GLOBAL(u8, acpi_gbl_dm_opt_disasm); | 322 | ACPI_GLOBAL(u8, acpi_gbl_dm_opt_disasm); |
322 | ACPI_GLOBAL(u8, acpi_gbl_dm_opt_listing); | 323 | ACPI_GLOBAL(u8, acpi_gbl_dm_opt_listing); |
@@ -382,6 +383,7 @@ ACPI_GLOBAL(const char, *acpi_gbl_pld_shape_list[]); | |||
382 | 383 | ||
383 | ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); | 384 | ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); |
384 | ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL); | 385 | ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL); |
386 | ACPI_INIT_GLOBAL(u8, acpi_gbl_debug_timeout, FALSE); | ||
385 | 387 | ||
386 | /* Print buffer */ | 388 | /* Print buffer */ |
387 | 389 | ||
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 13331d70dea0..dff1207a6078 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -484,6 +484,7 @@ struct acpi_gpe_event_info { | |||
484 | u8 flags; /* Misc info about this GPE */ | 484 | u8 flags; /* Misc info about this GPE */ |
485 | u8 gpe_number; /* This GPE */ | 485 | u8 gpe_number; /* This GPE */ |
486 | u8 runtime_count; /* References to a run GPE */ | 486 | u8 runtime_count; /* References to a run GPE */ |
487 | u8 disable_for_dispatch; /* Masked during dispatching */ | ||
487 | }; | 488 | }; |
488 | 489 | ||
489 | /* Information about a GPE register pair, one per each status/enable pair in an array */ | 490 | /* Information about a GPE register pair, one per each status/enable pair in an array */ |
@@ -494,6 +495,7 @@ struct acpi_gpe_register_info { | |||
494 | u16 base_gpe_number; /* Base GPE number for this register */ | 495 | u16 base_gpe_number; /* Base GPE number for this register */ |
495 | u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ | 496 | u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ |
496 | u8 enable_for_run; /* GPEs to keep enabled when running */ | 497 | u8 enable_for_run; /* GPEs to keep enabled when running */ |
498 | u8 mask_for_run; /* GPEs to keep masked when running */ | ||
497 | u8 enable_mask; /* Current mask of enabled GPEs */ | 499 | u8 enable_mask; /* Current mask of enabled GPEs */ |
498 | }; | 500 | }; |
499 | 501 | ||
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index f33a4ba8e0cb..bb7fca1c8ba3 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -130,6 +130,9 @@ acpi_status | |||
130 | acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node); | 130 | acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node); |
131 | 131 | ||
132 | acpi_status | 132 | acpi_status |
133 | acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node); | ||
134 | |||
135 | acpi_status | ||
133 | acpi_ns_one_complete_parse(u32 pass_number, | 136 | acpi_ns_one_complete_parse(u32 pass_number, |
134 | u32 table_index, | 137 | u32 table_index, |
135 | struct acpi_namespace_node *start_node); | 138 | struct acpi_namespace_node *start_node); |
@@ -296,6 +299,11 @@ u8 | |||
296 | acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for); | 299 | acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for); |
297 | 300 | ||
298 | acpi_status | 301 | acpi_status |
302 | acpi_ns_get_node_unlocked(struct acpi_namespace_node *prefix_node, | ||
303 | const char *external_pathname, | ||
304 | u32 flags, struct acpi_namespace_node **out_node); | ||
305 | |||
306 | acpi_status | ||
299 | acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | 307 | acpi_ns_get_node(struct acpi_namespace_node *prefix_node, |
300 | const char *external_pathname, | 308 | const char *external_pathname, |
301 | u32 flags, struct acpi_namespace_node **out_node); | 309 | u32 flags, struct acpi_namespace_node **out_node); |
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index fc305775c3d7..939d41113970 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h | |||
@@ -78,6 +78,8 @@ extern const u8 acpi_gbl_long_op_index[]; | |||
78 | */ | 78 | */ |
79 | acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info); | 79 | acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info); |
80 | 80 | ||
81 | acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info); | ||
82 | |||
81 | /* | 83 | /* |
82 | * psargs - Parse AML opcode arguments | 84 | * psargs - Parse AML opcode arguments |
83 | */ | 85 | */ |
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index cd5a135fcf29..e85953b6fa0e 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -123,6 +123,14 @@ acpi_tb_install_standard_table(acpi_physical_address address, | |||
123 | 123 | ||
124 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc); | 124 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc); |
125 | 125 | ||
126 | acpi_status | ||
127 | acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node); | ||
128 | |||
129 | acpi_status | ||
130 | acpi_tb_install_and_load_table(struct acpi_table_header *table, | ||
131 | acpi_physical_address address, | ||
132 | u8 flags, u8 override, u32 *table_index); | ||
133 | |||
126 | void acpi_tb_terminate(void); | 134 | void acpi_tb_terminate(void); |
127 | 135 | ||
128 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index); | 136 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index); |
@@ -155,10 +163,6 @@ void | |||
155 | acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, | 163 | acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, |
156 | u8 override, u32 *table_index); | 164 | u8 override, u32 *table_index); |
157 | 165 | ||
158 | acpi_status | ||
159 | acpi_tb_install_fixed_table(acpi_physical_address address, | ||
160 | char *signature, u32 *table_index); | ||
161 | |||
162 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); | 166 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); |
163 | 167 | ||
164 | /* | 168 | /* |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index a7dbb2b882cf..0a1b53c9ee0e 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -114,13 +114,25 @@ extern const char *acpi_gbl_pt_decode[]; | |||
114 | /* | 114 | /* |
115 | * Common error message prefixes | 115 | * Common error message prefixes |
116 | */ | 116 | */ |
117 | #ifndef ACPI_MSG_ERROR | ||
117 | #define ACPI_MSG_ERROR "ACPI Error: " | 118 | #define ACPI_MSG_ERROR "ACPI Error: " |
119 | #endif | ||
120 | #ifndef ACPI_MSG_EXCEPTION | ||
118 | #define ACPI_MSG_EXCEPTION "ACPI Exception: " | 121 | #define ACPI_MSG_EXCEPTION "ACPI Exception: " |
122 | #endif | ||
123 | #ifndef ACPI_MSG_WARNING | ||
119 | #define ACPI_MSG_WARNING "ACPI Warning: " | 124 | #define ACPI_MSG_WARNING "ACPI Warning: " |
125 | #endif | ||
126 | #ifndef ACPI_MSG_INFO | ||
120 | #define ACPI_MSG_INFO "ACPI: " | 127 | #define ACPI_MSG_INFO "ACPI: " |
128 | #endif | ||
121 | 129 | ||
130 | #ifndef ACPI_MSG_BIOS_ERROR | ||
122 | #define ACPI_MSG_BIOS_ERROR "ACPI BIOS Error (bug): " | 131 | #define ACPI_MSG_BIOS_ERROR "ACPI BIOS Error (bug): " |
132 | #endif | ||
133 | #ifndef ACPI_MSG_BIOS_WARNING | ||
123 | #define ACPI_MSG_BIOS_WARNING "ACPI BIOS Warning (bug): " | 134 | #define ACPI_MSG_BIOS_WARNING "ACPI BIOS Warning (bug): " |
135 | #endif | ||
124 | 136 | ||
125 | /* | 137 | /* |
126 | * Common message suffix | 138 | * Common message suffix |
@@ -184,14 +196,15 @@ void acpi_ut_strlwr(char *src_string); | |||
184 | 196 | ||
185 | int acpi_ut_stricmp(char *string1, char *string2); | 197 | int acpi_ut_stricmp(char *string1, char *string2); |
186 | 198 | ||
187 | acpi_status | 199 | acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *ret_integer); |
188 | acpi_ut_strtoul64(char *string, | ||
189 | u32 base, u32 max_integer_byte_width, u64 *ret_integer); | ||
190 | |||
191 | /* Values for max_integer_byte_width above */ | ||
192 | 200 | ||
193 | #define ACPI_MAX32_BYTE_WIDTH 4 | 201 | /* |
194 | #define ACPI_MAX64_BYTE_WIDTH 8 | 202 | * Values for Flags above |
203 | * Note: LIMIT values correspond to acpi_gbl_integer_byte_width values (4/8) | ||
204 | */ | ||
205 | #define ACPI_STRTOUL_32BIT 0x04 /* 4 bytes */ | ||
206 | #define ACPI_STRTOUL_64BIT 0x08 /* 8 bytes */ | ||
207 | #define ACPI_STRTOUL_BASE16 0x10 /* Default: Base10/16 */ | ||
195 | 208 | ||
196 | /* | 209 | /* |
197 | * utglobal - Global data structures and procedures | 210 | * utglobal - Global data structures and procedures |
@@ -221,6 +234,8 @@ const char *acpi_ut_get_event_name(u32 event_id); | |||
221 | 234 | ||
222 | char acpi_ut_hex_to_ascii_char(u64 integer, u32 position); | 235 | char acpi_ut_hex_to_ascii_char(u64 integer, u32 position); |
223 | 236 | ||
237 | acpi_status acpi_ut_ascii_to_hex_byte(char *two_ascii_chars, u8 *return_byte); | ||
238 | |||
224 | u8 acpi_ut_ascii_char_to_hex(int hex_char); | 239 | u8 acpi_ut_ascii_char_to_hex(int hex_char); |
225 | 240 | ||
226 | u8 acpi_ut_valid_object_type(acpi_object_type type); | 241 | u8 acpi_ut_valid_object_type(acpi_object_type type); |
@@ -318,6 +333,11 @@ acpi_ut_ptr_exit(u32 line_number, | |||
318 | const char *module_name, u32 component_id, u8 *ptr); | 333 | const char *module_name, u32 component_id, u8 *ptr); |
319 | 334 | ||
320 | void | 335 | void |
336 | acpi_ut_str_exit(u32 line_number, | ||
337 | const char *function_name, | ||
338 | const char *module_name, u32 component_id, const char *string); | ||
339 | |||
340 | void | ||
321 | acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id); | 341 | acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id); |
322 | 342 | ||
323 | void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset); | 343 | void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset); |
@@ -707,25 +727,6 @@ const struct ah_device_id *acpi_ah_match_hardware_id(char *hid); | |||
707 | const char *acpi_ah_match_uuid(u8 *data); | 727 | const char *acpi_ah_match_uuid(u8 *data); |
708 | 728 | ||
709 | /* | 729 | /* |
710 | * utprint - printf/vprintf output functions | ||
711 | */ | ||
712 | const char *acpi_ut_scan_number(const char *string, u64 *number_ptr); | ||
713 | |||
714 | const char *acpi_ut_print_number(char *string, u64 number); | ||
715 | |||
716 | int | ||
717 | acpi_ut_vsnprintf(char *string, | ||
718 | acpi_size size, const char *format, va_list args); | ||
719 | |||
720 | int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...); | ||
721 | |||
722 | #ifdef ACPI_APPLICATION | ||
723 | int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args); | ||
724 | |||
725 | int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...); | ||
726 | #endif | ||
727 | |||
728 | /* | ||
729 | * utuuid -- UUID support functions | 730 | * utuuid -- UUID support functions |
730 | */ | 731 | */ |
731 | #if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_HELP_APP) | 732 | #if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_HELP_APP) |
diff --git a/drivers/acpi/acpica/dbconvert.c b/drivers/acpi/acpica/dbconvert.c index 7cd07b27f758..147ce8894f76 100644 --- a/drivers/acpi/acpica/dbconvert.c +++ b/drivers/acpi/acpica/dbconvert.c | |||
@@ -277,9 +277,10 @@ acpi_db_convert_to_object(acpi_object_type type, | |||
277 | default: | 277 | default: |
278 | 278 | ||
279 | object->type = ACPI_TYPE_INTEGER; | 279 | object->type = ACPI_TYPE_INTEGER; |
280 | status = | 280 | status = acpi_ut_strtoul64(string, |
281 | acpi_ut_strtoul64(string, 16, acpi_gbl_integer_byte_width, | 281 | (acpi_gbl_integer_byte_width | |
282 | &object->integer.value); | 282 | ACPI_STRTOUL_BASE16), |
283 | &object->integer.value); | ||
283 | break; | 284 | break; |
284 | } | 285 | } |
285 | 286 | ||
diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c index 12df2915ad74..fe3da7c31bb7 100644 --- a/drivers/acpi/acpica/dbexec.c +++ b/drivers/acpi/acpica/dbexec.c | |||
@@ -392,42 +392,48 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags) | |||
392 | acpi_db_execution_walk, NULL, NULL, | 392 | acpi_db_execution_walk, NULL, NULL, |
393 | NULL); | 393 | NULL); |
394 | return; | 394 | return; |
395 | } else { | 395 | } |
396 | name_string = ACPI_ALLOCATE(strlen(name) + 1); | ||
397 | if (!name_string) { | ||
398 | return; | ||
399 | } | ||
400 | 396 | ||
401 | memset(&acpi_gbl_db_method_info, 0, | 397 | name_string = ACPI_ALLOCATE(strlen(name) + 1); |
402 | sizeof(struct acpi_db_method_info)); | 398 | if (!name_string) { |
399 | return; | ||
400 | } | ||
403 | 401 | ||
404 | strcpy(name_string, name); | 402 | memset(&acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info)); |
405 | acpi_ut_strupr(name_string); | 403 | strcpy(name_string, name); |
406 | acpi_gbl_db_method_info.name = name_string; | 404 | acpi_ut_strupr(name_string); |
407 | acpi_gbl_db_method_info.args = args; | ||
408 | acpi_gbl_db_method_info.types = types; | ||
409 | acpi_gbl_db_method_info.flags = flags; | ||
410 | 405 | ||
411 | return_obj.pointer = NULL; | 406 | /* Subcommand to Execute all predefined names in the namespace */ |
412 | return_obj.length = ACPI_ALLOCATE_BUFFER; | ||
413 | 407 | ||
414 | status = acpi_db_execute_setup(&acpi_gbl_db_method_info); | 408 | if (!strncmp(name_string, "PREDEF", 6)) { |
415 | if (ACPI_FAILURE(status)) { | 409 | acpi_db_evaluate_predefined_names(); |
416 | ACPI_FREE(name_string); | 410 | ACPI_FREE(name_string); |
417 | return; | 411 | return; |
418 | } | 412 | } |
419 | 413 | ||
420 | /* Get the NS node, determines existence also */ | 414 | acpi_gbl_db_method_info.name = name_string; |
415 | acpi_gbl_db_method_info.args = args; | ||
416 | acpi_gbl_db_method_info.types = types; | ||
417 | acpi_gbl_db_method_info.flags = flags; | ||
421 | 418 | ||
422 | status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname, | 419 | return_obj.pointer = NULL; |
423 | &acpi_gbl_db_method_info.method); | 420 | return_obj.length = ACPI_ALLOCATE_BUFFER; |
424 | if (ACPI_SUCCESS(status)) { | 421 | |
425 | status = | 422 | status = acpi_db_execute_setup(&acpi_gbl_db_method_info); |
426 | acpi_db_execute_method(&acpi_gbl_db_method_info, | 423 | if (ACPI_FAILURE(status)) { |
427 | &return_obj); | ||
428 | } | ||
429 | ACPI_FREE(name_string); | 424 | ACPI_FREE(name_string); |
425 | return; | ||
426 | } | ||
427 | |||
428 | /* Get the NS node, determines existence also */ | ||
429 | |||
430 | status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname, | ||
431 | &acpi_gbl_db_method_info.method); | ||
432 | if (ACPI_SUCCESS(status)) { | ||
433 | status = acpi_db_execute_method(&acpi_gbl_db_method_info, | ||
434 | &return_obj); | ||
430 | } | 435 | } |
436 | ACPI_FREE(name_string); | ||
431 | 437 | ||
432 | /* | 438 | /* |
433 | * Allow any handlers in separate threads to complete. | 439 | * Allow any handlers in separate threads to complete. |
diff --git a/drivers/acpi/acpica/dbfileio.c b/drivers/acpi/acpica/dbfileio.c index 483287942372..6f05b8c271a5 100644 --- a/drivers/acpi/acpica/dbfileio.c +++ b/drivers/acpi/acpica/dbfileio.c | |||
@@ -46,14 +46,12 @@ | |||
46 | #include "accommon.h" | 46 | #include "accommon.h" |
47 | #include "acdebug.h" | 47 | #include "acdebug.h" |
48 | #include "actables.h" | 48 | #include "actables.h" |
49 | #include <stdio.h> | ||
50 | #ifdef ACPI_APPLICATION | ||
51 | #include "acapps.h" | ||
52 | #endif | ||
53 | 49 | ||
54 | #define _COMPONENT ACPI_CA_DEBUGGER | 50 | #define _COMPONENT ACPI_CA_DEBUGGER |
55 | ACPI_MODULE_NAME("dbfileio") | 51 | ACPI_MODULE_NAME("dbfileio") |
56 | 52 | ||
53 | #ifdef ACPI_APPLICATION | ||
54 | #include "acapps.h" | ||
57 | #ifdef ACPI_DEBUGGER | 55 | #ifdef ACPI_DEBUGGER |
58 | /******************************************************************************* | 56 | /******************************************************************************* |
59 | * | 57 | * |
@@ -69,8 +67,6 @@ ACPI_MODULE_NAME("dbfileio") | |||
69 | void acpi_db_close_debug_file(void) | 67 | void acpi_db_close_debug_file(void) |
70 | { | 68 | { |
71 | 69 | ||
72 | #ifdef ACPI_APPLICATION | ||
73 | |||
74 | if (acpi_gbl_debug_file) { | 70 | if (acpi_gbl_debug_file) { |
75 | fclose(acpi_gbl_debug_file); | 71 | fclose(acpi_gbl_debug_file); |
76 | acpi_gbl_debug_file = NULL; | 72 | acpi_gbl_debug_file = NULL; |
@@ -78,7 +74,6 @@ void acpi_db_close_debug_file(void) | |||
78 | acpi_os_printf("Debug output file %s closed\n", | 74 | acpi_os_printf("Debug output file %s closed\n", |
79 | acpi_gbl_db_debug_filename); | 75 | acpi_gbl_db_debug_filename); |
80 | } | 76 | } |
81 | #endif | ||
82 | } | 77 | } |
83 | 78 | ||
84 | /******************************************************************************* | 79 | /******************************************************************************* |
@@ -96,8 +91,6 @@ void acpi_db_close_debug_file(void) | |||
96 | void acpi_db_open_debug_file(char *name) | 91 | void acpi_db_open_debug_file(char *name) |
97 | { | 92 | { |
98 | 93 | ||
99 | #ifdef ACPI_APPLICATION | ||
100 | |||
101 | acpi_db_close_debug_file(); | 94 | acpi_db_close_debug_file(); |
102 | acpi_gbl_debug_file = fopen(name, "w+"); | 95 | acpi_gbl_debug_file = fopen(name, "w+"); |
103 | if (!acpi_gbl_debug_file) { | 96 | if (!acpi_gbl_debug_file) { |
@@ -109,8 +102,6 @@ void acpi_db_open_debug_file(char *name) | |||
109 | strncpy(acpi_gbl_db_debug_filename, name, | 102 | strncpy(acpi_gbl_db_debug_filename, name, |
110 | sizeof(acpi_gbl_db_debug_filename)); | 103 | sizeof(acpi_gbl_db_debug_filename)); |
111 | acpi_gbl_db_output_to_file = TRUE; | 104 | acpi_gbl_db_output_to_file = TRUE; |
112 | |||
113 | #endif | ||
114 | } | 105 | } |
115 | #endif | 106 | #endif |
116 | 107 | ||
@@ -152,12 +143,13 @@ acpi_status acpi_db_load_tables(struct acpi_new_table_desc *list_head) | |||
152 | return (status); | 143 | return (status); |
153 | } | 144 | } |
154 | 145 | ||
155 | fprintf(stderr, | 146 | acpi_os_printf |
156 | "Acpi table [%4.4s] successfully installed and loaded\n", | 147 | ("Acpi table [%4.4s] successfully installed and loaded\n", |
157 | table->signature); | 148 | table->signature); |
158 | 149 | ||
159 | table_list_head = table_list_head->next; | 150 | table_list_head = table_list_head->next; |
160 | } | 151 | } |
161 | 152 | ||
162 | return (AE_OK); | 153 | return (AE_OK); |
163 | } | 154 | } |
155 | #endif | ||
diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c index 7cd5d2e022da..068214f9cc9d 100644 --- a/drivers/acpi/acpica/dbinput.c +++ b/drivers/acpi/acpica/dbinput.c | |||
@@ -286,6 +286,8 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = { | |||
286 | {1, " \"Ascii String\"", "String method argument\n"}, | 286 | {1, " \"Ascii String\"", "String method argument\n"}, |
287 | {1, " (Hex Byte List)", "Buffer method argument\n"}, | 287 | {1, " (Hex Byte List)", "Buffer method argument\n"}, |
288 | {1, " [Package Element List]", "Package method argument\n"}, | 288 | {1, " [Package Element List]", "Package method argument\n"}, |
289 | {5, " Execute predefined", | ||
290 | "Execute all predefined (public) methods\n"}, | ||
289 | {1, " Go", "Allow method to run to completion\n"}, | 291 | {1, " Go", "Allow method to run to completion\n"}, |
290 | {1, " Information", "Display info about the current method\n"}, | 292 | {1, " Information", "Display info about the current method\n"}, |
291 | {1, " Into", "Step into (not over) a method call\n"}, | 293 | {1, " Into", "Step into (not over) a method call\n"}, |
diff --git a/drivers/acpi/acpica/dbmethod.c b/drivers/acpi/acpica/dbmethod.c index f17a86f6b16b..314b94cf086a 100644 --- a/drivers/acpi/acpica/dbmethod.c +++ b/drivers/acpi/acpica/dbmethod.c | |||
@@ -52,6 +52,11 @@ | |||
52 | #define _COMPONENT ACPI_CA_DEBUGGER | 52 | #define _COMPONENT ACPI_CA_DEBUGGER |
53 | ACPI_MODULE_NAME("dbmethod") | 53 | ACPI_MODULE_NAME("dbmethod") |
54 | 54 | ||
55 | /* Local prototypes */ | ||
56 | static acpi_status | ||
57 | acpi_db_walk_for_execute(acpi_handle obj_handle, | ||
58 | u32 nesting_level, void *context, void **return_value); | ||
59 | |||
55 | /******************************************************************************* | 60 | /******************************************************************************* |
56 | * | 61 | * |
57 | * FUNCTION: acpi_db_set_method_breakpoint | 62 | * FUNCTION: acpi_db_set_method_breakpoint |
@@ -66,6 +71,7 @@ ACPI_MODULE_NAME("dbmethod") | |||
66 | * AML offset | 71 | * AML offset |
67 | * | 72 | * |
68 | ******************************************************************************/ | 73 | ******************************************************************************/ |
74 | |||
69 | void | 75 | void |
70 | acpi_db_set_method_breakpoint(char *location, | 76 | acpi_db_set_method_breakpoint(char *location, |
71 | struct acpi_walk_state *walk_state, | 77 | struct acpi_walk_state *walk_state, |
@@ -367,3 +373,129 @@ acpi_status acpi_db_disassemble_method(char *name) | |||
367 | acpi_ut_release_owner_id(&obj_desc->method.owner_id); | 373 | acpi_ut_release_owner_id(&obj_desc->method.owner_id); |
368 | return (AE_OK); | 374 | return (AE_OK); |
369 | } | 375 | } |
376 | |||
377 | /******************************************************************************* | ||
378 | * | ||
379 | * FUNCTION: acpi_db_walk_for_execute | ||
380 | * | ||
381 | * PARAMETERS: Callback from walk_namespace | ||
382 | * | ||
383 | * RETURN: Status | ||
384 | * | ||
385 | * DESCRIPTION: Batch execution module. Currently only executes predefined | ||
386 | * ACPI names. | ||
387 | * | ||
388 | ******************************************************************************/ | ||
389 | |||
390 | static acpi_status | ||
391 | acpi_db_walk_for_execute(acpi_handle obj_handle, | ||
392 | u32 nesting_level, void *context, void **return_value) | ||
393 | { | ||
394 | struct acpi_namespace_node *node = | ||
395 | (struct acpi_namespace_node *)obj_handle; | ||
396 | struct acpi_db_execute_walk *info = | ||
397 | (struct acpi_db_execute_walk *)context; | ||
398 | struct acpi_buffer return_obj; | ||
399 | acpi_status status; | ||
400 | char *pathname; | ||
401 | u32 i; | ||
402 | struct acpi_device_info *obj_info; | ||
403 | struct acpi_object_list param_objects; | ||
404 | union acpi_object params[ACPI_METHOD_NUM_ARGS]; | ||
405 | const union acpi_predefined_info *predefined; | ||
406 | |||
407 | predefined = acpi_ut_match_predefined_method(node->name.ascii); | ||
408 | if (!predefined) { | ||
409 | return (AE_OK); | ||
410 | } | ||
411 | |||
412 | if (node->type == ACPI_TYPE_LOCAL_SCOPE) { | ||
413 | return (AE_OK); | ||
414 | } | ||
415 | |||
416 | pathname = acpi_ns_get_external_pathname(node); | ||
417 | if (!pathname) { | ||
418 | return (AE_OK); | ||
419 | } | ||
420 | |||
421 | /* Get the object info for number of method parameters */ | ||
422 | |||
423 | status = acpi_get_object_info(obj_handle, &obj_info); | ||
424 | if (ACPI_FAILURE(status)) { | ||
425 | return (status); | ||
426 | } | ||
427 | |||
428 | param_objects.pointer = NULL; | ||
429 | param_objects.count = 0; | ||
430 | |||
431 | if (obj_info->type == ACPI_TYPE_METHOD) { | ||
432 | |||
433 | /* Setup default parameters */ | ||
434 | |||
435 | for (i = 0; i < obj_info->param_count; i++) { | ||
436 | params[i].type = ACPI_TYPE_INTEGER; | ||
437 | params[i].integer.value = 1; | ||
438 | } | ||
439 | |||
440 | param_objects.pointer = params; | ||
441 | param_objects.count = obj_info->param_count; | ||
442 | } | ||
443 | |||
444 | ACPI_FREE(obj_info); | ||
445 | return_obj.pointer = NULL; | ||
446 | return_obj.length = ACPI_ALLOCATE_BUFFER; | ||
447 | |||
448 | /* Do the actual method execution */ | ||
449 | |||
450 | acpi_gbl_method_executing = TRUE; | ||
451 | |||
452 | status = acpi_evaluate_object(node, NULL, ¶m_objects, &return_obj); | ||
453 | |||
454 | acpi_os_printf("%-32s returned %s\n", pathname, | ||
455 | acpi_format_exception(status)); | ||
456 | acpi_gbl_method_executing = FALSE; | ||
457 | ACPI_FREE(pathname); | ||
458 | |||
459 | /* Ignore status from method execution */ | ||
460 | |||
461 | status = AE_OK; | ||
462 | |||
463 | /* Update count, check if we have executed enough methods */ | ||
464 | |||
465 | info->count++; | ||
466 | if (info->count >= info->max_count) { | ||
467 | status = AE_CTRL_TERMINATE; | ||
468 | } | ||
469 | |||
470 | return (status); | ||
471 | } | ||
472 | |||
473 | /******************************************************************************* | ||
474 | * | ||
475 | * FUNCTION: acpi_db_evaluate_predefined_names | ||
476 | * | ||
477 | * PARAMETERS: None | ||
478 | * | ||
479 | * RETURN: None | ||
480 | * | ||
481 | * DESCRIPTION: Namespace batch execution. Execute predefined names in the | ||
482 | * namespace, up to the max count, if specified. | ||
483 | * | ||
484 | ******************************************************************************/ | ||
485 | |||
486 | void acpi_db_evaluate_predefined_names(void) | ||
487 | { | ||
488 | struct acpi_db_execute_walk info; | ||
489 | |||
490 | info.count = 0; | ||
491 | info.max_count = ACPI_UINT32_MAX; | ||
492 | |||
493 | /* Search all nodes in namespace */ | ||
494 | |||
495 | (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | ||
496 | ACPI_UINT32_MAX, acpi_db_walk_for_execute, | ||
497 | NULL, (void *)&info, NULL); | ||
498 | |||
499 | acpi_os_printf("Evaluated %u predefined names in the namespace\n", | ||
500 | info.count); | ||
501 | } | ||
diff --git a/drivers/acpi/acpica/dbobject.c b/drivers/acpi/acpica/dbobject.c index 1d59e8b6f859..08eaaf350b24 100644 --- a/drivers/acpi/acpica/dbobject.c +++ b/drivers/acpi/acpica/dbobject.c | |||
@@ -142,11 +142,11 @@ void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc) | |||
142 | 142 | ||
143 | case ACPI_TYPE_STRING: | 143 | case ACPI_TYPE_STRING: |
144 | 144 | ||
145 | acpi_os_printf("(%u) \"%.24s", | 145 | acpi_os_printf("(%u) \"%.60s", |
146 | obj_desc->string.length, | 146 | obj_desc->string.length, |
147 | obj_desc->string.pointer); | 147 | obj_desc->string.pointer); |
148 | 148 | ||
149 | if (obj_desc->string.length > 24) { | 149 | if (obj_desc->string.length > 60) { |
150 | acpi_os_printf("..."); | 150 | acpi_os_printf("..."); |
151 | } else { | 151 | } else { |
152 | acpi_os_printf("\""); | 152 | acpi_os_printf("\""); |
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 47c7b52a519c..32e9ddc0cf2b 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c | |||
@@ -99,11 +99,14 @@ acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, | |||
99 | "Method auto-serialization parse [%4.4s] %p\n", | 99 | "Method auto-serialization parse [%4.4s] %p\n", |
100 | acpi_ut_get_node_name(node), node)); | 100 | acpi_ut_get_node_name(node), node)); |
101 | 101 | ||
102 | acpi_ex_enter_interpreter(); | ||
103 | |||
102 | /* Create/Init a root op for the method parse tree */ | 104 | /* Create/Init a root op for the method parse tree */ |
103 | 105 | ||
104 | op = acpi_ps_alloc_op(AML_METHOD_OP, obj_desc->method.aml_start); | 106 | op = acpi_ps_alloc_op(AML_METHOD_OP, obj_desc->method.aml_start); |
105 | if (!op) { | 107 | if (!op) { |
106 | return_ACPI_STATUS(AE_NO_MEMORY); | 108 | status = AE_NO_MEMORY; |
109 | goto unlock; | ||
107 | } | 110 | } |
108 | 111 | ||
109 | acpi_ps_set_name(op, node->name.integer); | 112 | acpi_ps_set_name(op, node->name.integer); |
@@ -115,7 +118,8 @@ acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, | |||
115 | acpi_ds_create_walk_state(node->owner_id, NULL, NULL, NULL); | 118 | acpi_ds_create_walk_state(node->owner_id, NULL, NULL, NULL); |
116 | if (!walk_state) { | 119 | if (!walk_state) { |
117 | acpi_ps_free_op(op); | 120 | acpi_ps_free_op(op); |
118 | return_ACPI_STATUS(AE_NO_MEMORY); | 121 | status = AE_NO_MEMORY; |
122 | goto unlock; | ||
119 | } | 123 | } |
120 | 124 | ||
121 | status = acpi_ds_init_aml_walk(walk_state, op, node, | 125 | status = acpi_ds_init_aml_walk(walk_state, op, node, |
@@ -134,6 +138,8 @@ acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, | |||
134 | status = acpi_ps_parse_aml(walk_state); | 138 | status = acpi_ps_parse_aml(walk_state); |
135 | 139 | ||
136 | acpi_ps_delete_parse_tree(op); | 140 | acpi_ps_delete_parse_tree(op); |
141 | unlock: | ||
142 | acpi_ex_exit_interpreter(); | ||
137 | return_ACPI_STATUS(status); | 143 | return_ACPI_STATUS(status); |
138 | } | 144 | } |
139 | 145 | ||
@@ -757,8 +763,10 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
757 | 763 | ||
758 | /* Delete any direct children of (created by) this method */ | 764 | /* Delete any direct children of (created by) this method */ |
759 | 765 | ||
766 | (void)acpi_ex_exit_interpreter(); | ||
760 | acpi_ns_delete_namespace_subtree(walk_state-> | 767 | acpi_ns_delete_namespace_subtree(walk_state-> |
761 | method_node); | 768 | method_node); |
769 | (void)acpi_ex_enter_interpreter(); | ||
762 | 770 | ||
763 | /* | 771 | /* |
764 | * Delete any objects that were created by this method | 772 | * Delete any objects that were created by this method |
@@ -769,9 +777,11 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
769 | */ | 777 | */ |
770 | if (method_desc->method. | 778 | if (method_desc->method. |
771 | info_flags & ACPI_METHOD_MODIFIED_NAMESPACE) { | 779 | info_flags & ACPI_METHOD_MODIFIED_NAMESPACE) { |
780 | (void)acpi_ex_exit_interpreter(); | ||
772 | acpi_ns_delete_namespace_by_owner(method_desc-> | 781 | acpi_ns_delete_namespace_by_owner(method_desc-> |
773 | method. | 782 | method. |
774 | owner_id); | 783 | owner_id); |
784 | (void)acpi_ex_enter_interpreter(); | ||
775 | method_desc->method.info_flags &= | 785 | method_desc->method.info_flags &= |
776 | ~ACPI_METHOD_MODIFIED_NAMESPACE; | 786 | ~ACPI_METHOD_MODIFIED_NAMESPACE; |
777 | } | 787 | } |
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index f393de9f5887..7d8ef52fb88d 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c | |||
@@ -565,15 +565,14 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
565 | status = AE_OK; | 565 | status = AE_OK; |
566 | } else if (parent_op->common.aml_opcode == | 566 | } else if (parent_op->common.aml_opcode == |
567 | AML_EXTERNAL_OP) { | 567 | AML_EXTERNAL_OP) { |
568 | 568 | /* | |
569 | /* TBD: May only be temporary */ | 569 | * This opcode should never appear here. It is used only |
570 | 570 | * by AML disassemblers and is surrounded by an If(0) | |
571 | obj_desc = | 571 | * by the ASL compiler. |
572 | acpi_ut_create_string_object((acpi_size)name_length); | 572 | * |
573 | 573 | * Therefore, if we see it here, it is a serious error. | |
574 | strncpy(obj_desc->string.pointer, | 574 | */ |
575 | name_string, name_length); | 575 | status = AE_AML_BAD_OPCODE; |
576 | status = AE_OK; | ||
577 | } else { | 576 | } else { |
578 | /* | 577 | /* |
579 | * We just plain didn't find it -- which is a | 578 | * We just plain didn't find it -- which is a |
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 402ecc590c56..438597cf6cc5 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c | |||
@@ -133,7 +133,8 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, | |||
133 | * Result of predicate evaluation must be an Integer | 133 | * Result of predicate evaluation must be an Integer |
134 | * object. Implicitly convert the argument if necessary. | 134 | * object. Implicitly convert the argument if necessary. |
135 | */ | 135 | */ |
136 | status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, 16); | 136 | status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, |
137 | ACPI_STRTOUL_BASE16); | ||
137 | if (ACPI_FAILURE(status)) { | 138 | if (ACPI_FAILURE(status)) { |
138 | goto cleanup; | 139 | goto cleanup; |
139 | } | 140 | } |
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index 762db3fa70e0..028b22a3154e 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c | |||
@@ -605,16 +605,13 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
605 | if (ACPI_FAILURE(status)) { | 605 | if (ACPI_FAILURE(status)) { |
606 | return_ACPI_STATUS(status); | 606 | return_ACPI_STATUS(status); |
607 | } | 607 | } |
608 | |||
609 | acpi_ex_exit_interpreter(); | ||
610 | } | 608 | } |
611 | 609 | ||
610 | acpi_ex_exit_interpreter(); | ||
612 | status = | 611 | status = |
613 | acpi_ev_initialize_region | 612 | acpi_ev_initialize_region |
614 | (acpi_ns_get_attached_object(node), FALSE); | 613 | (acpi_ns_get_attached_object(node), FALSE); |
615 | if (walk_state->method_node) { | 614 | acpi_ex_enter_interpreter(); |
616 | acpi_ex_enter_interpreter(); | ||
617 | } | ||
618 | 615 | ||
619 | if (ACPI_FAILURE(status)) { | 616 | if (ACPI_FAILURE(status)) { |
620 | /* | 617 | /* |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 4b4949ce05bc..bdb10bee13ce 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -130,6 +130,60 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
130 | 130 | ||
131 | /******************************************************************************* | 131 | /******************************************************************************* |
132 | * | 132 | * |
133 | * FUNCTION: acpi_ev_mask_gpe | ||
134 | * | ||
135 | * PARAMETERS: gpe_event_info - GPE to be blocked/unblocked | ||
136 | * is_masked - Whether the GPE is masked or not | ||
137 | * | ||
138 | * RETURN: Status | ||
139 | * | ||
140 | * DESCRIPTION: Unconditionally mask/unmask a GPE during runtime. | ||
141 | * | ||
142 | ******************************************************************************/ | ||
143 | |||
144 | acpi_status | ||
145 | acpi_ev_mask_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 is_masked) | ||
146 | { | ||
147 | struct acpi_gpe_register_info *gpe_register_info; | ||
148 | u32 register_bit; | ||
149 | |||
150 | ACPI_FUNCTION_TRACE(ev_mask_gpe); | ||
151 | |||
152 | gpe_register_info = gpe_event_info->register_info; | ||
153 | if (!gpe_register_info) { | ||
154 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
155 | } | ||
156 | |||
157 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); | ||
158 | |||
159 | /* Perform the action */ | ||
160 | |||
161 | if (is_masked) { | ||
162 | if (register_bit & gpe_register_info->mask_for_run) { | ||
163 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
164 | } | ||
165 | |||
166 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
167 | ACPI_SET_BIT(gpe_register_info->mask_for_run, (u8)register_bit); | ||
168 | } else { | ||
169 | if (!(register_bit & gpe_register_info->mask_for_run)) { | ||
170 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
171 | } | ||
172 | |||
173 | ACPI_CLEAR_BIT(gpe_register_info->mask_for_run, | ||
174 | (u8)register_bit); | ||
175 | if (gpe_event_info->runtime_count | ||
176 | && !gpe_event_info->disable_for_dispatch) { | ||
177 | (void)acpi_hw_low_set_gpe(gpe_event_info, | ||
178 | ACPI_GPE_ENABLE); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | return_ACPI_STATUS(AE_OK); | ||
183 | } | ||
184 | |||
185 | /******************************************************************************* | ||
186 | * | ||
133 | * FUNCTION: acpi_ev_add_gpe_reference | 187 | * FUNCTION: acpi_ev_add_gpe_reference |
134 | * | 188 | * |
135 | * PARAMETERS: gpe_event_info - Add a reference to this GPE | 189 | * PARAMETERS: gpe_event_info - Add a reference to this GPE |
@@ -674,6 +728,7 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
674 | * in the event_info. | 728 | * in the event_info. |
675 | */ | 729 | */ |
676 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE); | 730 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE); |
731 | gpe_event_info->disable_for_dispatch = FALSE; | ||
677 | return (AE_OK); | 732 | return (AE_OK); |
678 | } | 733 | } |
679 | 734 | ||
@@ -737,6 +792,8 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
737 | } | 792 | } |
738 | } | 793 | } |
739 | 794 | ||
795 | gpe_event_info->disable_for_dispatch = TRUE; | ||
796 | |||
740 | /* | 797 | /* |
741 | * Dispatch the GPE to either an installed handler or the control | 798 | * Dispatch the GPE to either an installed handler or the control |
742 | * method associated with this GPE (_Lxx or _Exx). If a handler | 799 | * method associated with this GPE (_Lxx or _Exx). If a handler |
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 7dc75474c897..16ce4835e7d0 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -323,7 +323,9 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
323 | struct acpi_gpe_walk_info *walk_info = | 323 | struct acpi_gpe_walk_info *walk_info = |
324 | ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); | 324 | ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); |
325 | struct acpi_gpe_event_info *gpe_event_info; | 325 | struct acpi_gpe_event_info *gpe_event_info; |
326 | acpi_status status; | ||
326 | u32 gpe_number; | 327 | u32 gpe_number; |
328 | u8 temp_gpe_number; | ||
327 | char name[ACPI_NAME_SIZE + 1]; | 329 | char name[ACPI_NAME_SIZE + 1]; |
328 | u8 type; | 330 | u8 type; |
329 | 331 | ||
@@ -377,8 +379,8 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
377 | 379 | ||
378 | /* 4) The last two characters of the name are the hex GPE Number */ | 380 | /* 4) The last two characters of the name are the hex GPE Number */ |
379 | 381 | ||
380 | gpe_number = strtoul(&name[2], NULL, 16); | 382 | status = acpi_ut_ascii_to_hex_byte(&name[2], &temp_gpe_number); |
381 | if (gpe_number == ACPI_UINT32_MAX) { | 383 | if (ACPI_FAILURE(status)) { |
382 | 384 | ||
383 | /* Conversion failed; invalid method, just ignore it */ | 385 | /* Conversion failed; invalid method, just ignore it */ |
384 | 386 | ||
@@ -390,6 +392,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
390 | 392 | ||
391 | /* Ensure that we have a valid GPE number for this GPE block */ | 393 | /* Ensure that we have a valid GPE number for this GPE block */ |
392 | 394 | ||
395 | gpe_number = (u32)temp_gpe_number; | ||
393 | gpe_event_info = | 396 | gpe_event_info = |
394 | acpi_ev_low_get_gpe_info(gpe_number, walk_info->gpe_block); | 397 | acpi_ev_low_get_gpe_info(gpe_number, walk_info->gpe_block); |
395 | if (!gpe_event_info) { | 398 | if (!gpe_event_info) { |
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index b6ea9c0d0d8c..3843f1fc5dbb 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -553,7 +553,8 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
553 | * | 553 | * |
554 | * See acpi_ns_exec_module_code | 554 | * See acpi_ns_exec_module_code |
555 | */ | 555 | */ |
556 | if (obj_desc->method. | 556 | if (!acpi_gbl_parse_table_as_term_list && |
557 | obj_desc->method. | ||
557 | info_flags & ACPI_METHOD_MODULE_LEVEL) { | 558 | info_flags & ACPI_METHOD_MODULE_LEVEL) { |
558 | handler_obj = | 559 | handler_obj = |
559 | obj_desc->method.dispatch.handler; | 560 | obj_desc->method.dispatch.handler; |
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 17cfef721d00..d7a3b2775505 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -235,11 +235,13 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) | |||
235 | case ACPI_GPE_ENABLE: | 235 | case ACPI_GPE_ENABLE: |
236 | 236 | ||
237 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); | 237 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); |
238 | gpe_event_info->disable_for_dispatch = FALSE; | ||
238 | break; | 239 | break; |
239 | 240 | ||
240 | case ACPI_GPE_DISABLE: | 241 | case ACPI_GPE_DISABLE: |
241 | 242 | ||
242 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | 243 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); |
244 | gpe_event_info->disable_for_dispatch = TRUE; | ||
243 | break; | 245 | break; |
244 | 246 | ||
245 | default: | 247 | default: |
@@ -257,6 +259,47 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe) | |||
257 | 259 | ||
258 | /******************************************************************************* | 260 | /******************************************************************************* |
259 | * | 261 | * |
262 | * FUNCTION: acpi_mask_gpe | ||
263 | * | ||
264 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
265 | * gpe_number - GPE level within the GPE block | ||
266 | * is_masked - Whether the GPE is masked or not | ||
267 | * | ||
268 | * RETURN: Status | ||
269 | * | ||
270 | * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to | ||
271 | * prevent a GPE flooding. | ||
272 | * | ||
273 | ******************************************************************************/ | ||
274 | acpi_status acpi_mask_gpe(acpi_handle gpe_device, u32 gpe_number, u8 is_masked) | ||
275 | { | ||
276 | struct acpi_gpe_event_info *gpe_event_info; | ||
277 | acpi_status status; | ||
278 | acpi_cpu_flags flags; | ||
279 | |||
280 | ACPI_FUNCTION_TRACE(acpi_mask_gpe); | ||
281 | |||
282 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
283 | |||
284 | /* Ensure that we have a valid GPE number */ | ||
285 | |||
286 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
287 | if (!gpe_event_info) { | ||
288 | status = AE_BAD_PARAMETER; | ||
289 | goto unlock_and_exit; | ||
290 | } | ||
291 | |||
292 | status = acpi_ev_mask_gpe(gpe_event_info, is_masked); | ||
293 | |||
294 | unlock_and_exit: | ||
295 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
296 | return_ACPI_STATUS(status); | ||
297 | } | ||
298 | |||
299 | ACPI_EXPORT_SYMBOL(acpi_mask_gpe) | ||
300 | |||
301 | /******************************************************************************* | ||
302 | * | ||
260 | * FUNCTION: acpi_mark_gpe_for_wake | 303 | * FUNCTION: acpi_mark_gpe_for_wake |
261 | * | 304 | * |
262 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | 305 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 |
diff --git a/drivers/acpi/acpica/exconcat.c b/drivers/acpi/acpica/exconcat.c index 2423fe03e879..5429c2a6bc41 100644 --- a/drivers/acpi/acpica/exconcat.c +++ b/drivers/acpi/acpica/exconcat.c | |||
@@ -156,7 +156,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
156 | 156 | ||
157 | status = | 157 | status = |
158 | acpi_ex_convert_to_integer(local_operand1, &temp_operand1, | 158 | acpi_ex_convert_to_integer(local_operand1, &temp_operand1, |
159 | 16); | 159 | ACPI_STRTOUL_BASE16); |
160 | break; | 160 | break; |
161 | 161 | ||
162 | case ACPI_TYPE_BUFFER: | 162 | case ACPI_TYPE_BUFFER: |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index a1d177d58254..718428ba0b89 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -55,9 +55,7 @@ ACPI_MODULE_NAME("exconfig") | |||
55 | 55 | ||
56 | /* Local prototypes */ | 56 | /* Local prototypes */ |
57 | static acpi_status | 57 | static acpi_status |
58 | acpi_ex_add_table(u32 table_index, | 58 | acpi_ex_add_table(u32 table_index, union acpi_operand_object **ddb_handle); |
59 | struct acpi_namespace_node *parent_node, | ||
60 | union acpi_operand_object **ddb_handle); | ||
61 | 59 | ||
62 | static acpi_status | 60 | static acpi_status |
63 | acpi_ex_region_read(union acpi_operand_object *obj_desc, | 61 | acpi_ex_region_read(union acpi_operand_object *obj_desc, |
@@ -79,13 +77,9 @@ acpi_ex_region_read(union acpi_operand_object *obj_desc, | |||
79 | ******************************************************************************/ | 77 | ******************************************************************************/ |
80 | 78 | ||
81 | static acpi_status | 79 | static acpi_status |
82 | acpi_ex_add_table(u32 table_index, | 80 | acpi_ex_add_table(u32 table_index, union acpi_operand_object **ddb_handle) |
83 | struct acpi_namespace_node *parent_node, | ||
84 | union acpi_operand_object **ddb_handle) | ||
85 | { | 81 | { |
86 | union acpi_operand_object *obj_desc; | 82 | union acpi_operand_object *obj_desc; |
87 | acpi_status status; | ||
88 | acpi_owner_id owner_id; | ||
89 | 83 | ||
90 | ACPI_FUNCTION_TRACE(ex_add_table); | 84 | ACPI_FUNCTION_TRACE(ex_add_table); |
91 | 85 | ||
@@ -100,39 +94,8 @@ acpi_ex_add_table(u32 table_index, | |||
100 | 94 | ||
101 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; | 95 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; |
102 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; | 96 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; |
103 | *ddb_handle = obj_desc; | ||
104 | |||
105 | /* Install the new table into the local data structures */ | ||
106 | |||
107 | obj_desc->reference.value = table_index; | 97 | obj_desc->reference.value = table_index; |
108 | 98 | *ddb_handle = obj_desc; | |
109 | /* Add the table to the namespace */ | ||
110 | |||
111 | status = acpi_ns_load_table(table_index, parent_node); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | acpi_ut_remove_reference(obj_desc); | ||
114 | *ddb_handle = NULL; | ||
115 | return_ACPI_STATUS(status); | ||
116 | } | ||
117 | |||
118 | /* Execute any module-level code that was found in the table */ | ||
119 | |||
120 | acpi_ex_exit_interpreter(); | ||
121 | if (acpi_gbl_group_module_level_code) { | ||
122 | acpi_ns_exec_module_code_list(); | ||
123 | } | ||
124 | acpi_ex_enter_interpreter(); | ||
125 | |||
126 | /* | ||
127 | * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is | ||
128 | * responsible for discovering any new wake GPEs by running _PRW methods | ||
129 | * that may have been loaded by this table. | ||
130 | */ | ||
131 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
132 | if (ACPI_SUCCESS(status)) { | ||
133 | acpi_ev_update_gpes(owner_id); | ||
134 | } | ||
135 | |||
136 | return_ACPI_STATUS(AE_OK); | 99 | return_ACPI_STATUS(AE_OK); |
137 | } | 100 | } |
138 | 101 | ||
@@ -159,16 +122,17 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
159 | struct acpi_namespace_node *start_node; | 122 | struct acpi_namespace_node *start_node; |
160 | struct acpi_namespace_node *parameter_node = NULL; | 123 | struct acpi_namespace_node *parameter_node = NULL; |
161 | union acpi_operand_object *ddb_handle; | 124 | union acpi_operand_object *ddb_handle; |
162 | struct acpi_table_header *table; | ||
163 | u32 table_index; | 125 | u32 table_index; |
164 | 126 | ||
165 | ACPI_FUNCTION_TRACE(ex_load_table_op); | 127 | ACPI_FUNCTION_TRACE(ex_load_table_op); |
166 | 128 | ||
167 | /* Find the ACPI table in the RSDT/XSDT */ | 129 | /* Find the ACPI table in the RSDT/XSDT */ |
168 | 130 | ||
131 | acpi_ex_exit_interpreter(); | ||
169 | status = acpi_tb_find_table(operand[0]->string.pointer, | 132 | status = acpi_tb_find_table(operand[0]->string.pointer, |
170 | operand[1]->string.pointer, | 133 | operand[1]->string.pointer, |
171 | operand[2]->string.pointer, &table_index); | 134 | operand[2]->string.pointer, &table_index); |
135 | acpi_ex_enter_interpreter(); | ||
172 | if (ACPI_FAILURE(status)) { | 136 | if (ACPI_FAILURE(status)) { |
173 | if (status != AE_NOT_FOUND) { | 137 | if (status != AE_NOT_FOUND) { |
174 | return_ACPI_STATUS(status); | 138 | return_ACPI_STATUS(status); |
@@ -197,9 +161,10 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
197 | * Find the node referenced by the root_path_string. This is the | 161 | * Find the node referenced by the root_path_string. This is the |
198 | * location within the namespace where the table will be loaded. | 162 | * location within the namespace where the table will be loaded. |
199 | */ | 163 | */ |
200 | status = | 164 | status = acpi_ns_get_node_unlocked(start_node, |
201 | acpi_ns_get_node(start_node, operand[3]->string.pointer, | 165 | operand[3]->string.pointer, |
202 | ACPI_NS_SEARCH_PARENT, &parent_node); | 166 | ACPI_NS_SEARCH_PARENT, |
167 | &parent_node); | ||
203 | if (ACPI_FAILURE(status)) { | 168 | if (ACPI_FAILURE(status)) { |
204 | return_ACPI_STATUS(status); | 169 | return_ACPI_STATUS(status); |
205 | } | 170 | } |
@@ -219,9 +184,10 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
219 | 184 | ||
220 | /* Find the node referenced by the parameter_path_string */ | 185 | /* Find the node referenced by the parameter_path_string */ |
221 | 186 | ||
222 | status = | 187 | status = acpi_ns_get_node_unlocked(start_node, |
223 | acpi_ns_get_node(start_node, operand[4]->string.pointer, | 188 | operand[4]->string.pointer, |
224 | ACPI_NS_SEARCH_PARENT, ¶meter_node); | 189 | ACPI_NS_SEARCH_PARENT, |
190 | ¶meter_node); | ||
225 | if (ACPI_FAILURE(status)) { | 191 | if (ACPI_FAILURE(status)) { |
226 | return_ACPI_STATUS(status); | 192 | return_ACPI_STATUS(status); |
227 | } | 193 | } |
@@ -229,7 +195,15 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
229 | 195 | ||
230 | /* Load the table into the namespace */ | 196 | /* Load the table into the namespace */ |
231 | 197 | ||
232 | status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); | 198 | ACPI_INFO(("Dynamic OEM Table Load:")); |
199 | acpi_ex_exit_interpreter(); | ||
200 | status = acpi_tb_load_table(table_index, parent_node); | ||
201 | acpi_ex_enter_interpreter(); | ||
202 | if (ACPI_FAILURE(status)) { | ||
203 | return_ACPI_STATUS(status); | ||
204 | } | ||
205 | |||
206 | status = acpi_ex_add_table(table_index, &ddb_handle); | ||
233 | if (ACPI_FAILURE(status)) { | 207 | if (ACPI_FAILURE(status)) { |
234 | return_ACPI_STATUS(status); | 208 | return_ACPI_STATUS(status); |
235 | } | 209 | } |
@@ -252,19 +226,6 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
252 | } | 226 | } |
253 | } | 227 | } |
254 | 228 | ||
255 | status = acpi_get_table_by_index(table_index, &table); | ||
256 | if (ACPI_SUCCESS(status)) { | ||
257 | ACPI_INFO(("Dynamic OEM Table Load:")); | ||
258 | acpi_tb_print_table_header(0, table); | ||
259 | } | ||
260 | |||
261 | /* Invoke table handler if present */ | ||
262 | |||
263 | if (acpi_gbl_table_handler) { | ||
264 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
265 | acpi_gbl_table_handler_context); | ||
266 | } | ||
267 | |||
268 | *return_desc = ddb_handle; | 229 | *return_desc = ddb_handle; |
269 | return_ACPI_STATUS(status); | 230 | return_ACPI_STATUS(status); |
270 | } | 231 | } |
@@ -475,13 +436,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
475 | /* Install the new table into the local data structures */ | 436 | /* Install the new table into the local data structures */ |
476 | 437 | ||
477 | ACPI_INFO(("Dynamic OEM Table Load:")); | 438 | ACPI_INFO(("Dynamic OEM Table Load:")); |
478 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 439 | acpi_ex_exit_interpreter(); |
479 | 440 | status = | |
480 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), | 441 | acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table), |
481 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | 442 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, |
482 | TRUE, TRUE, &table_index); | 443 | TRUE, &table_index); |
483 | 444 | acpi_ex_enter_interpreter(); | |
484 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
485 | if (ACPI_FAILURE(status)) { | 445 | if (ACPI_FAILURE(status)) { |
486 | 446 | ||
487 | /* Delete allocated table buffer */ | 447 | /* Delete allocated table buffer */ |
@@ -491,25 +451,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
491 | } | 451 | } |
492 | 452 | ||
493 | /* | 453 | /* |
494 | * Note: Now table is "INSTALLED", it must be validated before | ||
495 | * loading. | ||
496 | */ | ||
497 | status = | ||
498 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | ||
499 | tables[table_index]); | ||
500 | if (ACPI_FAILURE(status)) { | ||
501 | return_ACPI_STATUS(status); | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * Add the table to the namespace. | 454 | * Add the table to the namespace. |
506 | * | 455 | * |
507 | * Note: Load the table objects relative to the root of the namespace. | 456 | * Note: Load the table objects relative to the root of the namespace. |
508 | * This appears to go against the ACPI specification, but we do it for | 457 | * This appears to go against the ACPI specification, but we do it for |
509 | * compatibility with other ACPI implementations. | 458 | * compatibility with other ACPI implementations. |
510 | */ | 459 | */ |
511 | status = | 460 | status = acpi_ex_add_table(table_index, &ddb_handle); |
512 | acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); | ||
513 | if (ACPI_FAILURE(status)) { | 461 | if (ACPI_FAILURE(status)) { |
514 | 462 | ||
515 | /* On error, table_ptr was deallocated above */ | 463 | /* On error, table_ptr was deallocated above */ |
@@ -532,14 +480,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
532 | /* Remove the reference by added by acpi_ex_store above */ | 480 | /* Remove the reference by added by acpi_ex_store above */ |
533 | 481 | ||
534 | acpi_ut_remove_reference(ddb_handle); | 482 | acpi_ut_remove_reference(ddb_handle); |
535 | |||
536 | /* Invoke table handler if present */ | ||
537 | |||
538 | if (acpi_gbl_table_handler) { | ||
539 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
540 | acpi_gbl_table_handler_context); | ||
541 | } | ||
542 | |||
543 | return_ACPI_STATUS(status); | 483 | return_ACPI_STATUS(status); |
544 | } | 484 | } |
545 | 485 | ||
@@ -592,10 +532,17 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
592 | 532 | ||
593 | table_index = table_desc->reference.value; | 533 | table_index = table_desc->reference.value; |
594 | 534 | ||
535 | /* | ||
536 | * Release the interpreter lock so that the table lock won't have | ||
537 | * strict order requirement against it. | ||
538 | */ | ||
539 | acpi_ex_exit_interpreter(); | ||
540 | |||
595 | /* Ensure the table is still loaded */ | 541 | /* Ensure the table is still loaded */ |
596 | 542 | ||
597 | if (!acpi_tb_is_table_loaded(table_index)) { | 543 | if (!acpi_tb_is_table_loaded(table_index)) { |
598 | return_ACPI_STATUS(AE_NOT_EXIST); | 544 | status = AE_NOT_EXIST; |
545 | goto lock_and_exit; | ||
599 | } | 546 | } |
600 | 547 | ||
601 | /* Invoke table handler if present */ | 548 | /* Invoke table handler if present */ |
@@ -613,16 +560,24 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
613 | 560 | ||
614 | status = acpi_tb_delete_namespace_by_owner(table_index); | 561 | status = acpi_tb_delete_namespace_by_owner(table_index); |
615 | if (ACPI_FAILURE(status)) { | 562 | if (ACPI_FAILURE(status)) { |
616 | return_ACPI_STATUS(status); | 563 | goto lock_and_exit; |
617 | } | 564 | } |
618 | 565 | ||
619 | (void)acpi_tb_release_owner_id(table_index); | 566 | (void)acpi_tb_release_owner_id(table_index); |
620 | acpi_tb_set_table_loaded_flag(table_index, FALSE); | 567 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
621 | 568 | ||
569 | lock_and_exit: | ||
570 | |||
571 | /* Re-acquire the interpreter lock */ | ||
572 | |||
573 | acpi_ex_enter_interpreter(); | ||
574 | |||
622 | /* | 575 | /* |
623 | * Invalidate the handle. We do this because the handle may be stored | 576 | * Invalidate the handle. We do this because the handle may be stored |
624 | * in a named object and may not be actually deleted until much later. | 577 | * in a named object and may not be actually deleted until much later. |
625 | */ | 578 | */ |
626 | ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID; | 579 | if (ACPI_SUCCESS(status)) { |
627 | return_ACPI_STATUS(AE_OK); | 580 | ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID; |
581 | } | ||
582 | return_ACPI_STATUS(status); | ||
628 | } | 583 | } |
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index b7e9b3d803e1..588ad1409dbe 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c | |||
@@ -124,9 +124,9 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | |||
124 | * of ACPI 3.0) is that the to_integer() operator allows both decimal | 124 | * of ACPI 3.0) is that the to_integer() operator allows both decimal |
125 | * and hexadecimal strings (hex prefixed with "0x"). | 125 | * and hexadecimal strings (hex prefixed with "0x"). |
126 | */ | 126 | */ |
127 | status = acpi_ut_strtoul64((char *)pointer, flags, | 127 | status = acpi_ut_strtoul64(ACPI_CAST_PTR(char, pointer), |
128 | acpi_gbl_integer_byte_width, | 128 | (acpi_gbl_integer_byte_width | |
129 | &result); | 129 | flags), &result); |
130 | if (ACPI_FAILURE(status)) { | 130 | if (ACPI_FAILURE(status)) { |
131 | return_ACPI_STATUS(status); | 131 | return_ACPI_STATUS(status); |
132 | } | 132 | } |
@@ -632,7 +632,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, | |||
632 | */ | 632 | */ |
633 | status = | 633 | status = |
634 | acpi_ex_convert_to_integer(source_desc, result_desc, | 634 | acpi_ex_convert_to_integer(source_desc, result_desc, |
635 | 16); | 635 | ACPI_STRTOUL_BASE16); |
636 | break; | 636 | break; |
637 | 637 | ||
638 | case ACPI_TYPE_STRING: | 638 | case ACPI_TYPE_STRING: |
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 4f7e667624b3..37c88b424a02 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c | |||
@@ -327,8 +327,8 @@ acpi_ex_do_logical_op(u16 opcode, | |||
327 | switch (operand0->common.type) { | 327 | switch (operand0->common.type) { |
328 | case ACPI_TYPE_INTEGER: | 328 | case ACPI_TYPE_INTEGER: |
329 | 329 | ||
330 | status = | 330 | status = acpi_ex_convert_to_integer(operand1, &local_operand1, |
331 | acpi_ex_convert_to_integer(operand1, &local_operand1, 16); | 331 | ACPI_STRTOUL_BASE16); |
332 | break; | 332 | break; |
333 | 333 | ||
334 | case ACPI_TYPE_STRING: | 334 | case ACPI_TYPE_STRING: |
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 4e17506a7384..007300433cde 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c | |||
@@ -521,9 +521,10 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) | |||
521 | 521 | ||
522 | case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */ | 522 | case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */ |
523 | 523 | ||
524 | /* Perform "explicit" conversion */ | ||
525 | |||
524 | status = | 526 | status = |
525 | acpi_ex_convert_to_integer(operand[0], &return_desc, | 527 | acpi_ex_convert_to_integer(operand[0], &return_desc, 0); |
526 | ACPI_ANY_BASE); | ||
527 | if (return_desc == operand[0]) { | 528 | if (return_desc == operand[0]) { |
528 | 529 | ||
529 | /* No conversion performed, add ref to handle return value */ | 530 | /* No conversion performed, add ref to handle return value */ |
@@ -890,14 +891,16 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
890 | * Field, so we need to resolve the node to a value. | 891 | * Field, so we need to resolve the node to a value. |
891 | */ | 892 | */ |
892 | status = | 893 | status = |
893 | acpi_ns_get_node(walk_state->scope_info-> | 894 | acpi_ns_get_node_unlocked(walk_state-> |
894 | scope.node, | 895 | scope_info->scope. |
895 | operand[0]->string.pointer, | 896 | node, |
896 | ACPI_NS_SEARCH_PARENT, | 897 | operand[0]-> |
897 | ACPI_CAST_INDIRECT_PTR | 898 | string.pointer, |
898 | (struct | 899 | ACPI_NS_SEARCH_PARENT, |
899 | acpi_namespace_node, | 900 | ACPI_CAST_INDIRECT_PTR |
900 | &return_desc)); | 901 | (struct |
902 | acpi_namespace_node, | ||
903 | &return_desc)); | ||
901 | if (ACPI_FAILURE(status)) { | 904 | if (ACPI_FAILURE(status)) { |
902 | goto cleanup; | 905 | goto cleanup; |
903 | } | 906 | } |
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 27b41fd7542d..f29eba1dc5e9 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c | |||
@@ -410,12 +410,13 @@ acpi_ex_resolve_operands(u16 opcode, | |||
410 | case ARGI_INTEGER: | 410 | case ARGI_INTEGER: |
411 | 411 | ||
412 | /* | 412 | /* |
413 | * Need an operand of type ACPI_TYPE_INTEGER, | 413 | * Need an operand of type ACPI_TYPE_INTEGER, but we can |
414 | * But we can implicitly convert from a STRING or BUFFER | 414 | * implicitly convert from a STRING or BUFFER. |
415 | * aka - "Implicit Source Operand Conversion" | 415 | * |
416 | * Known as "Implicit Source Operand Conversion" | ||
416 | */ | 417 | */ |
417 | status = | 418 | status = acpi_ex_convert_to_integer(obj_desc, stack_ptr, |
418 | acpi_ex_convert_to_integer(obj_desc, stack_ptr, 16); | 419 | ACPI_STRTOUL_BASE16); |
419 | if (ACPI_FAILURE(status)) { | 420 | if (ACPI_FAILURE(status)) { |
420 | if (status == AE_TYPE) { | 421 | if (status == AE_TYPE) { |
421 | ACPI_ERROR((AE_INFO, | 422 | ACPI_ERROR((AE_INFO, |
diff --git a/drivers/acpi/acpica/extrace.c b/drivers/acpi/acpica/extrace.c index b52e84841c1a..c9ca82610d77 100644 --- a/drivers/acpi/acpica/extrace.c +++ b/drivers/acpi/acpica/extrace.c | |||
@@ -201,7 +201,6 @@ acpi_ex_start_trace_method(struct acpi_namespace_node *method_node, | |||
201 | union acpi_operand_object *obj_desc, | 201 | union acpi_operand_object *obj_desc, |
202 | struct acpi_walk_state *walk_state) | 202 | struct acpi_walk_state *walk_state) |
203 | { | 203 | { |
204 | acpi_status status; | ||
205 | char *pathname = NULL; | 204 | char *pathname = NULL; |
206 | u8 enabled = FALSE; | 205 | u8 enabled = FALSE; |
207 | 206 | ||
@@ -211,11 +210,6 @@ acpi_ex_start_trace_method(struct acpi_namespace_node *method_node, | |||
211 | pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); | 210 | pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); |
212 | } | 211 | } |
213 | 212 | ||
214 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
215 | if (ACPI_FAILURE(status)) { | ||
216 | goto exit; | ||
217 | } | ||
218 | |||
219 | enabled = acpi_ex_interpreter_trace_enabled(pathname); | 213 | enabled = acpi_ex_interpreter_trace_enabled(pathname); |
220 | if (enabled && !acpi_gbl_trace_method_object) { | 214 | if (enabled && !acpi_gbl_trace_method_object) { |
221 | acpi_gbl_trace_method_object = obj_desc; | 215 | acpi_gbl_trace_method_object = obj_desc; |
@@ -233,9 +227,6 @@ acpi_ex_start_trace_method(struct acpi_namespace_node *method_node, | |||
233 | } | 227 | } |
234 | } | 228 | } |
235 | 229 | ||
236 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
237 | |||
238 | exit: | ||
239 | if (enabled) { | 230 | if (enabled) { |
240 | ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, TRUE, | 231 | ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, TRUE, |
241 | obj_desc ? obj_desc->method.aml_start : NULL, | 232 | obj_desc ? obj_desc->method.aml_start : NULL, |
@@ -267,7 +258,6 @@ acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node, | |||
267 | union acpi_operand_object *obj_desc, | 258 | union acpi_operand_object *obj_desc, |
268 | struct acpi_walk_state *walk_state) | 259 | struct acpi_walk_state *walk_state) |
269 | { | 260 | { |
270 | acpi_status status; | ||
271 | char *pathname = NULL; | 261 | char *pathname = NULL; |
272 | u8 enabled; | 262 | u8 enabled; |
273 | 263 | ||
@@ -277,26 +267,14 @@ acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node, | |||
277 | pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); | 267 | pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); |
278 | } | 268 | } |
279 | 269 | ||
280 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
281 | if (ACPI_FAILURE(status)) { | ||
282 | goto exit_path; | ||
283 | } | ||
284 | |||
285 | enabled = acpi_ex_interpreter_trace_enabled(NULL); | 270 | enabled = acpi_ex_interpreter_trace_enabled(NULL); |
286 | 271 | ||
287 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
288 | |||
289 | if (enabled) { | 272 | if (enabled) { |
290 | ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, FALSE, | 273 | ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, FALSE, |
291 | obj_desc ? obj_desc->method.aml_start : NULL, | 274 | obj_desc ? obj_desc->method.aml_start : NULL, |
292 | pathname); | 275 | pathname); |
293 | } | 276 | } |
294 | 277 | ||
295 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
296 | if (ACPI_FAILURE(status)) { | ||
297 | goto exit_path; | ||
298 | } | ||
299 | |||
300 | /* Check whether the tracer should be stopped */ | 278 | /* Check whether the tracer should be stopped */ |
301 | 279 | ||
302 | if (acpi_gbl_trace_method_object == obj_desc) { | 280 | if (acpi_gbl_trace_method_object == obj_desc) { |
@@ -312,9 +290,6 @@ acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node, | |||
312 | acpi_gbl_trace_method_object = NULL; | 290 | acpi_gbl_trace_method_object = NULL; |
313 | } | 291 | } |
314 | 292 | ||
315 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
316 | |||
317 | exit_path: | ||
318 | if (pathname) { | 293 | if (pathname) { |
319 | ACPI_FREE(pathname); | 294 | ACPI_FREE(pathname); |
320 | } | 295 | } |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 425f13372e68..a8b857a7e9fb 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -94,6 +94,10 @@ void acpi_ex_enter_interpreter(void) | |||
94 | ACPI_ERROR((AE_INFO, | 94 | ACPI_ERROR((AE_INFO, |
95 | "Could not acquire AML Interpreter mutex")); | 95 | "Could not acquire AML Interpreter mutex")); |
96 | } | 96 | } |
97 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
98 | if (ACPI_FAILURE(status)) { | ||
99 | ACPI_ERROR((AE_INFO, "Could not acquire AML Namespace mutex")); | ||
100 | } | ||
97 | 101 | ||
98 | return_VOID; | 102 | return_VOID; |
99 | } | 103 | } |
@@ -127,6 +131,10 @@ void acpi_ex_exit_interpreter(void) | |||
127 | 131 | ||
128 | ACPI_FUNCTION_TRACE(ex_exit_interpreter); | 132 | ACPI_FUNCTION_TRACE(ex_exit_interpreter); |
129 | 133 | ||
134 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
135 | if (ACPI_FAILURE(status)) { | ||
136 | ACPI_ERROR((AE_INFO, "Could not release AML Namespace mutex")); | ||
137 | } | ||
130 | status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 138 | status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); |
131 | if (ACPI_FAILURE(status)) { | 139 | if (ACPI_FAILURE(status)) { |
132 | ACPI_ERROR((AE_INFO, | 140 | ACPI_ERROR((AE_INFO, |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index bdecd5e76e87..76b0e350f5bb 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -98,7 +98,7 @@ acpi_status | |||
98 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) | 98 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) |
99 | { | 99 | { |
100 | struct acpi_gpe_register_info *gpe_register_info; | 100 | struct acpi_gpe_register_info *gpe_register_info; |
101 | acpi_status status; | 101 | acpi_status status = AE_OK; |
102 | u32 enable_mask; | 102 | u32 enable_mask; |
103 | u32 register_bit; | 103 | u32 register_bit; |
104 | 104 | ||
@@ -148,9 +148,14 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) | |||
148 | return (AE_BAD_PARAMETER); | 148 | return (AE_BAD_PARAMETER); |
149 | } | 149 | } |
150 | 150 | ||
151 | /* Write the updated enable mask */ | 151 | if (!(register_bit & gpe_register_info->mask_for_run)) { |
152 | 152 | ||
153 | status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); | 153 | /* Write the updated enable mask */ |
154 | |||
155 | status = | ||
156 | acpi_hw_write(enable_mask, | ||
157 | &gpe_register_info->enable_address); | ||
158 | } | ||
154 | return (status); | 159 | return (status); |
155 | } | 160 | } |
156 | 161 | ||
@@ -242,6 +247,12 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, | |||
242 | local_event_status |= ACPI_EVENT_FLAG_ENABLED; | 247 | local_event_status |= ACPI_EVENT_FLAG_ENABLED; |
243 | } | 248 | } |
244 | 249 | ||
250 | /* GPE currently masked? (masked for runtime?) */ | ||
251 | |||
252 | if (register_bit & gpe_register_info->mask_for_run) { | ||
253 | local_event_status |= ACPI_EVENT_FLAG_MASKED; | ||
254 | } | ||
255 | |||
245 | /* GPE enabled for wake? */ | 256 | /* GPE enabled for wake? */ |
246 | 257 | ||
247 | if (register_bit & gpe_register_info->enable_for_wake) { | 258 | if (register_bit & gpe_register_info->enable_for_wake) { |
@@ -397,6 +408,7 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
397 | u32 i; | 408 | u32 i; |
398 | acpi_status status; | 409 | acpi_status status; |
399 | struct acpi_gpe_register_info *gpe_register_info; | 410 | struct acpi_gpe_register_info *gpe_register_info; |
411 | u8 enable_mask; | ||
400 | 412 | ||
401 | /* NOTE: assumes that all GPEs are currently disabled */ | 413 | /* NOTE: assumes that all GPEs are currently disabled */ |
402 | 414 | ||
@@ -410,9 +422,10 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
410 | 422 | ||
411 | /* Enable all "runtime" GPEs in this register */ | 423 | /* Enable all "runtime" GPEs in this register */ |
412 | 424 | ||
425 | enable_mask = gpe_register_info->enable_for_run & | ||
426 | ~gpe_register_info->mask_for_run; | ||
413 | status = | 427 | status = |
414 | acpi_hw_gpe_enable_write(gpe_register_info->enable_for_run, | 428 | acpi_hw_gpe_enable_write(enable_mask, gpe_register_info); |
415 | gpe_register_info); | ||
416 | if (ACPI_FAILURE(status)) { | 429 | if (ACPI_FAILURE(status)) { |
417 | return (status); | 430 | return (status); |
418 | } | 431 | } |
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 426a6307eafa..73f98d3fed25 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c | |||
@@ -108,9 +108,9 @@ acpi_status acpi_ns_root_initialize(void) | |||
108 | } | 108 | } |
109 | 109 | ||
110 | status = | 110 | status = |
111 | acpi_ns_lookup(NULL, (char *)init_val->name, init_val->type, | 111 | acpi_ns_lookup(NULL, ACPI_CAST_PTR(char, init_val->name), |
112 | ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, | 112 | init_val->type, ACPI_IMODE_LOAD_PASS2, |
113 | NULL, &new_node); | 113 | ACPI_NS_NO_UPSEARCH, NULL, &new_node); |
114 | if (ACPI_FAILURE(status)) { | 114 | if (ACPI_FAILURE(status)) { |
115 | ACPI_EXCEPTION((AE_INFO, status, | 115 | ACPI_EXCEPTION((AE_INFO, status, |
116 | "Could not create predefined name %s", | 116 | "Could not create predefined name %s", |
diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c index c803bda7915c..2b85dee6d4c0 100644 --- a/drivers/acpi/acpica/nsconvert.c +++ b/drivers/acpi/acpica/nsconvert.c | |||
@@ -79,7 +79,6 @@ acpi_ns_convert_to_integer(union acpi_operand_object *original_object, | |||
79 | /* String-to-Integer conversion */ | 79 | /* String-to-Integer conversion */ |
80 | 80 | ||
81 | status = acpi_ut_strtoul64(original_object->string.pointer, | 81 | status = acpi_ut_strtoul64(original_object->string.pointer, |
82 | ACPI_ANY_BASE, | ||
83 | acpi_gbl_integer_byte_width, &value); | 82 | acpi_gbl_integer_byte_width, &value); |
84 | if (ACPI_FAILURE(status)) { | 83 | if (ACPI_FAILURE(status)) { |
85 | return (status); | 84 | return (status); |
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index ce1f8605d996..84f35dd27033 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -338,7 +338,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
338 | case ACPI_TYPE_STRING: | 338 | case ACPI_TYPE_STRING: |
339 | 339 | ||
340 | acpi_os_printf("Len %.2X ", obj_desc->string.length); | 340 | acpi_os_printf("Len %.2X ", obj_desc->string.length); |
341 | acpi_ut_print_string(obj_desc->string.pointer, 32); | 341 | acpi_ut_print_string(obj_desc->string.pointer, 80); |
342 | acpi_os_printf("\n"); | 342 | acpi_os_printf("\n"); |
343 | break; | 343 | break; |
344 | 344 | ||
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index b5e2b0ada0ab..334d3c5ba617 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | #include "acdispat.h" | 47 | #include "acdispat.h" |
48 | #include "actables.h" | 48 | #include "actables.h" |
49 | #include "acinterp.h" | ||
49 | 50 | ||
50 | #define _COMPONENT ACPI_NAMESPACE | 51 | #define _COMPONENT ACPI_NAMESPACE |
51 | ACPI_MODULE_NAME("nsload") | 52 | ACPI_MODULE_NAME("nsload") |
@@ -78,20 +79,6 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) | |||
78 | 79 | ||
79 | ACPI_FUNCTION_TRACE(ns_load_table); | 80 | ACPI_FUNCTION_TRACE(ns_load_table); |
80 | 81 | ||
81 | /* | ||
82 | * Parse the table and load the namespace with all named | ||
83 | * objects found within. Control methods are NOT parsed | ||
84 | * at this time. In fact, the control methods cannot be | ||
85 | * parsed until the entire namespace is loaded, because | ||
86 | * if a control method makes a forward reference (call) | ||
87 | * to another control method, we can't continue parsing | ||
88 | * because we don't know how many arguments to parse next! | ||
89 | */ | ||
90 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* If table already loaded into namespace, just return */ | 82 | /* If table already loaded into namespace, just return */ |
96 | 83 | ||
97 | if (acpi_tb_is_table_loaded(table_index)) { | 84 | if (acpi_tb_is_table_loaded(table_index)) { |
@@ -107,6 +94,15 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) | |||
107 | goto unlock; | 94 | goto unlock; |
108 | } | 95 | } |
109 | 96 | ||
97 | /* | ||
98 | * Parse the table and load the namespace with all named | ||
99 | * objects found within. Control methods are NOT parsed | ||
100 | * at this time. In fact, the control methods cannot be | ||
101 | * parsed until the entire namespace is loaded, because | ||
102 | * if a control method makes a forward reference (call) | ||
103 | * to another control method, we can't continue parsing | ||
104 | * because we don't know how many arguments to parse next! | ||
105 | */ | ||
110 | status = acpi_ns_parse_table(table_index, node); | 106 | status = acpi_ns_parse_table(table_index, node); |
111 | if (ACPI_SUCCESS(status)) { | 107 | if (ACPI_SUCCESS(status)) { |
112 | acpi_tb_set_table_loaded_flag(table_index, TRUE); | 108 | acpi_tb_set_table_loaded_flag(table_index, TRUE); |
@@ -120,7 +116,6 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) | |||
120 | * exist. This target of Scope must already exist in the | 116 | * exist. This target of Scope must already exist in the |
121 | * namespace, as per the ACPI specification. | 117 | * namespace, as per the ACPI specification. |
122 | */ | 118 | */ |
123 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
124 | acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list. | 119 | acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list. |
125 | tables[table_index].owner_id); | 120 | tables[table_index].owner_id); |
126 | 121 | ||
@@ -129,8 +124,6 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) | |||
129 | } | 124 | } |
130 | 125 | ||
131 | unlock: | 126 | unlock: |
132 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
133 | |||
134 | if (ACPI_FAILURE(status)) { | 127 | if (ACPI_FAILURE(status)) { |
135 | return_ACPI_STATUS(status); | 128 | return_ACPI_STATUS(status); |
136 | } | 129 | } |
@@ -162,7 +155,8 @@ unlock: | |||
162 | * other ACPI implementations. Optionally, the execution can be deferred | 155 | * other ACPI implementations. Optionally, the execution can be deferred |
163 | * until later, see acpi_initialize_objects. | 156 | * until later, see acpi_initialize_objects. |
164 | */ | 157 | */ |
165 | if (!acpi_gbl_group_module_level_code) { | 158 | if (!acpi_gbl_parse_table_as_term_list |
159 | && !acpi_gbl_group_module_level_code) { | ||
166 | acpi_ns_exec_module_code_list(); | 160 | acpi_ns_exec_module_code_list(); |
167 | } | 161 | } |
168 | 162 | ||
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index f631a47724f0..4f14e9205bff 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c | |||
@@ -47,12 +47,103 @@ | |||
47 | #include "acparser.h" | 47 | #include "acparser.h" |
48 | #include "acdispat.h" | 48 | #include "acdispat.h" |
49 | #include "actables.h" | 49 | #include "actables.h" |
50 | #include "acinterp.h" | ||
50 | 51 | ||
51 | #define _COMPONENT ACPI_NAMESPACE | 52 | #define _COMPONENT ACPI_NAMESPACE |
52 | ACPI_MODULE_NAME("nsparse") | 53 | ACPI_MODULE_NAME("nsparse") |
53 | 54 | ||
54 | /******************************************************************************* | 55 | /******************************************************************************* |
55 | * | 56 | * |
57 | * FUNCTION: ns_execute_table | ||
58 | * | ||
59 | * PARAMETERS: table_desc - An ACPI table descriptor for table to parse | ||
60 | * start_node - Where to enter the table into the namespace | ||
61 | * | ||
62 | * RETURN: Status | ||
63 | * | ||
64 | * DESCRIPTION: Load ACPI/AML table by executing the entire table as a | ||
65 | * term_list. | ||
66 | * | ||
67 | ******************************************************************************/ | ||
68 | acpi_status | ||
69 | acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node) | ||
70 | { | ||
71 | acpi_status status; | ||
72 | struct acpi_table_header *table; | ||
73 | acpi_owner_id owner_id; | ||
74 | struct acpi_evaluate_info *info = NULL; | ||
75 | u32 aml_length; | ||
76 | u8 *aml_start; | ||
77 | union acpi_operand_object *method_obj = NULL; | ||
78 | |||
79 | ACPI_FUNCTION_TRACE(ns_execute_table); | ||
80 | |||
81 | status = acpi_get_table_by_index(table_index, &table); | ||
82 | if (ACPI_FAILURE(status)) { | ||
83 | return_ACPI_STATUS(status); | ||
84 | } | ||
85 | |||
86 | /* Table must consist of at least a complete header */ | ||
87 | |||
88 | if (table->length < sizeof(struct acpi_table_header)) { | ||
89 | return_ACPI_STATUS(AE_BAD_HEADER); | ||
90 | } | ||
91 | |||
92 | aml_start = (u8 *)table + sizeof(struct acpi_table_header); | ||
93 | aml_length = table->length - sizeof(struct acpi_table_header); | ||
94 | |||
95 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
96 | if (ACPI_FAILURE(status)) { | ||
97 | return_ACPI_STATUS(status); | ||
98 | } | ||
99 | |||
100 | /* Create, initialize, and link a new temporary method object */ | ||
101 | |||
102 | method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | ||
103 | if (!method_obj) { | ||
104 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
105 | } | ||
106 | |||
107 | /* Allocate the evaluation information block */ | ||
108 | |||
109 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
110 | if (!info) { | ||
111 | status = AE_NO_MEMORY; | ||
112 | goto cleanup; | ||
113 | } | ||
114 | |||
115 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | ||
116 | "Create table code block: %p\n", method_obj)); | ||
117 | |||
118 | method_obj->method.aml_start = aml_start; | ||
119 | method_obj->method.aml_length = aml_length; | ||
120 | method_obj->method.owner_id = owner_id; | ||
121 | method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL; | ||
122 | |||
123 | info->pass_number = ACPI_IMODE_EXECUTE; | ||
124 | info->node = start_node; | ||
125 | info->obj_desc = method_obj; | ||
126 | info->node_flags = info->node->flags; | ||
127 | info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE); | ||
128 | if (!info->full_pathname) { | ||
129 | status = AE_NO_MEMORY; | ||
130 | goto cleanup; | ||
131 | } | ||
132 | |||
133 | status = acpi_ps_execute_table(info); | ||
134 | |||
135 | cleanup: | ||
136 | if (info) { | ||
137 | ACPI_FREE(info->full_pathname); | ||
138 | info->full_pathname = NULL; | ||
139 | } | ||
140 | ACPI_FREE(info); | ||
141 | acpi_ut_remove_reference(method_obj); | ||
142 | return_ACPI_STATUS(status); | ||
143 | } | ||
144 | |||
145 | /******************************************************************************* | ||
146 | * | ||
56 | * FUNCTION: ns_one_complete_parse | 147 | * FUNCTION: ns_one_complete_parse |
57 | * | 148 | * |
58 | * PARAMETERS: pass_number - 1 or 2 | 149 | * PARAMETERS: pass_number - 1 or 2 |
@@ -63,6 +154,7 @@ ACPI_MODULE_NAME("nsparse") | |||
63 | * DESCRIPTION: Perform one complete parse of an ACPI/AML table. | 154 | * DESCRIPTION: Perform one complete parse of an ACPI/AML table. |
64 | * | 155 | * |
65 | ******************************************************************************/ | 156 | ******************************************************************************/ |
157 | |||
66 | acpi_status | 158 | acpi_status |
67 | acpi_ns_one_complete_parse(u32 pass_number, | 159 | acpi_ns_one_complete_parse(u32 pass_number, |
68 | u32 table_index, | 160 | u32 table_index, |
@@ -143,7 +235,9 @@ acpi_ns_one_complete_parse(u32 pass_number, | |||
143 | 235 | ||
144 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 236 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
145 | "*PARSE* pass %u parse\n", pass_number)); | 237 | "*PARSE* pass %u parse\n", pass_number)); |
238 | acpi_ex_enter_interpreter(); | ||
146 | status = acpi_ps_parse_aml(walk_state); | 239 | status = acpi_ps_parse_aml(walk_state); |
240 | acpi_ex_exit_interpreter(); | ||
147 | 241 | ||
148 | cleanup: | 242 | cleanup: |
149 | acpi_ps_delete_parse_tree(parse_root); | 243 | acpi_ps_delete_parse_tree(parse_root); |
@@ -170,38 +264,47 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) | |||
170 | 264 | ||
171 | ACPI_FUNCTION_TRACE(ns_parse_table); | 265 | ACPI_FUNCTION_TRACE(ns_parse_table); |
172 | 266 | ||
173 | /* | 267 | if (acpi_gbl_parse_table_as_term_list) { |
174 | * AML Parse, pass 1 | 268 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start load pass\n")); |
175 | * | ||
176 | * In this pass, we load most of the namespace. Control methods | ||
177 | * are not parsed until later. A parse tree is not created. Instead, | ||
178 | * each Parser Op subtree is deleted when it is finished. This saves | ||
179 | * a great deal of memory, and allows a small cache of parse objects | ||
180 | * to service the entire parse. The second pass of the parse then | ||
181 | * performs another complete parse of the AML. | ||
182 | */ | ||
183 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); | ||
184 | |||
185 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, | ||
186 | table_index, start_node); | ||
187 | if (ACPI_FAILURE(status)) { | ||
188 | return_ACPI_STATUS(status); | ||
189 | } | ||
190 | 269 | ||
191 | /* | 270 | status = acpi_ns_execute_table(table_index, start_node); |
192 | * AML Parse, pass 2 | 271 | if (ACPI_FAILURE(status)) { |
193 | * | 272 | return_ACPI_STATUS(status); |
194 | * In this pass, we resolve forward references and other things | 273 | } |
195 | * that could not be completed during the first pass. | 274 | } else { |
196 | * Another complete parse of the AML is performed, but the | 275 | /* |
197 | * overhead of this is compensated for by the fact that the | 276 | * AML Parse, pass 1 |
198 | * parse objects are all cached. | 277 | * |
199 | */ | 278 | * In this pass, we load most of the namespace. Control methods |
200 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); | 279 | * are not parsed until later. A parse tree is not created. |
201 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, | 280 | * Instead, each Parser Op subtree is deleted when it is finished. |
202 | table_index, start_node); | 281 | * This saves a great deal of memory, and allows a small cache of |
203 | if (ACPI_FAILURE(status)) { | 282 | * parse objects to service the entire parse. The second pass of |
204 | return_ACPI_STATUS(status); | 283 | * the parse then performs another complete parse of the AML. |
284 | */ | ||
285 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); | ||
286 | |||
287 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, | ||
288 | table_index, start_node); | ||
289 | if (ACPI_FAILURE(status)) { | ||
290 | return_ACPI_STATUS(status); | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * AML Parse, pass 2 | ||
295 | * | ||
296 | * In this pass, we resolve forward references and other things | ||
297 | * that could not be completed during the first pass. | ||
298 | * Another complete parse of the AML is performed, but the | ||
299 | * overhead of this is compensated for by the fact that the | ||
300 | * parse objects are all cached. | ||
301 | */ | ||
302 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); | ||
303 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, | ||
304 | table_index, start_node); | ||
305 | if (ACPI_FAILURE(status)) { | ||
306 | return_ACPI_STATUS(status); | ||
307 | } | ||
205 | } | 308 | } |
206 | 309 | ||
207 | return_ACPI_STATUS(status); | 310 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 784a30b76e0f..691814dfed31 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -662,7 +662,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type) | |||
662 | 662 | ||
663 | /******************************************************************************* | 663 | /******************************************************************************* |
664 | * | 664 | * |
665 | * FUNCTION: acpi_ns_get_node | 665 | * FUNCTION: acpi_ns_get_node_unlocked |
666 | * | 666 | * |
667 | * PARAMETERS: *pathname - Name to be found, in external (ASL) format. The | 667 | * PARAMETERS: *pathname - Name to be found, in external (ASL) format. The |
668 | * \ (backslash) and ^ (carat) prefixes, and the | 668 | * \ (backslash) and ^ (carat) prefixes, and the |
@@ -678,20 +678,21 @@ u32 acpi_ns_opens_scope(acpi_object_type type) | |||
678 | * DESCRIPTION: Look up a name relative to a given scope and return the | 678 | * DESCRIPTION: Look up a name relative to a given scope and return the |
679 | * corresponding Node. NOTE: Scope can be null. | 679 | * corresponding Node. NOTE: Scope can be null. |
680 | * | 680 | * |
681 | * MUTEX: Locks namespace | 681 | * MUTEX: Doesn't locks namespace |
682 | * | 682 | * |
683 | ******************************************************************************/ | 683 | ******************************************************************************/ |
684 | 684 | ||
685 | acpi_status | 685 | acpi_status |
686 | acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | 686 | acpi_ns_get_node_unlocked(struct acpi_namespace_node *prefix_node, |
687 | const char *pathname, | 687 | const char *pathname, |
688 | u32 flags, struct acpi_namespace_node **return_node) | 688 | u32 flags, struct acpi_namespace_node **return_node) |
689 | { | 689 | { |
690 | union acpi_generic_state scope_info; | 690 | union acpi_generic_state scope_info; |
691 | acpi_status status; | 691 | acpi_status status; |
692 | char *internal_path; | 692 | char *internal_path; |
693 | 693 | ||
694 | ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname)); | 694 | ACPI_FUNCTION_TRACE_PTR(ns_get_node_unlocked, |
695 | ACPI_CAST_PTR(char, pathname)); | ||
695 | 696 | ||
696 | /* Simplest case is a null pathname */ | 697 | /* Simplest case is a null pathname */ |
697 | 698 | ||
@@ -718,13 +719,6 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | |||
718 | return_ACPI_STATUS(status); | 719 | return_ACPI_STATUS(status); |
719 | } | 720 | } |
720 | 721 | ||
721 | /* Must lock namespace during lookup */ | ||
722 | |||
723 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
724 | if (ACPI_FAILURE(status)) { | ||
725 | goto cleanup; | ||
726 | } | ||
727 | |||
728 | /* Setup lookup scope (search starting point) */ | 722 | /* Setup lookup scope (search starting point) */ |
729 | 723 | ||
730 | scope_info.scope.node = prefix_node; | 724 | scope_info.scope.node = prefix_node; |
@@ -740,9 +734,49 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | |||
740 | pathname, acpi_format_exception(status))); | 734 | pathname, acpi_format_exception(status))); |
741 | } | 735 | } |
742 | 736 | ||
743 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
744 | |||
745 | cleanup: | ||
746 | ACPI_FREE(internal_path); | 737 | ACPI_FREE(internal_path); |
747 | return_ACPI_STATUS(status); | 738 | return_ACPI_STATUS(status); |
748 | } | 739 | } |
740 | |||
741 | /******************************************************************************* | ||
742 | * | ||
743 | * FUNCTION: acpi_ns_get_node | ||
744 | * | ||
745 | * PARAMETERS: *pathname - Name to be found, in external (ASL) format. The | ||
746 | * \ (backslash) and ^ (carat) prefixes, and the | ||
747 | * . (period) to separate segments are supported. | ||
748 | * prefix_node - Root of subtree to be searched, or NS_ALL for the | ||
749 | * root of the name space. If Name is fully | ||
750 | * qualified (first s8 is '\'), the passed value | ||
751 | * of Scope will not be accessed. | ||
752 | * flags - Used to indicate whether to perform upsearch or | ||
753 | * not. | ||
754 | * return_node - Where the Node is returned | ||
755 | * | ||
756 | * DESCRIPTION: Look up a name relative to a given scope and return the | ||
757 | * corresponding Node. NOTE: Scope can be null. | ||
758 | * | ||
759 | * MUTEX: Locks namespace | ||
760 | * | ||
761 | ******************************************************************************/ | ||
762 | |||
763 | acpi_status | ||
764 | acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | ||
765 | const char *pathname, | ||
766 | u32 flags, struct acpi_namespace_node **return_node) | ||
767 | { | ||
768 | acpi_status status; | ||
769 | |||
770 | ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname)); | ||
771 | |||
772 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
773 | if (ACPI_FAILURE(status)) { | ||
774 | return_ACPI_STATUS(status); | ||
775 | } | ||
776 | |||
777 | status = acpi_ns_get_node_unlocked(prefix_node, pathname, | ||
778 | flags, return_node); | ||
779 | |||
780 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
781 | return_ACPI_STATUS(status); | ||
782 | } | ||
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 0a23897d8adf..1ce26d9f8ff6 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c | |||
@@ -537,9 +537,11 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
537 | 537 | ||
538 | /* Either the method parse or actual execution failed */ | 538 | /* Either the method parse or actual execution failed */ |
539 | 539 | ||
540 | acpi_ex_exit_interpreter(); | ||
540 | ACPI_ERROR_METHOD("Method parse/execution failed", | 541 | ACPI_ERROR_METHOD("Method parse/execution failed", |
541 | walk_state->method_node, NULL, | 542 | walk_state->method_node, NULL, |
542 | status); | 543 | status); |
544 | acpi_ex_enter_interpreter(); | ||
543 | 545 | ||
544 | /* Check for possible multi-thread reentrancy problem */ | 546 | /* Check for possible multi-thread reentrancy problem */ |
545 | 547 | ||
@@ -571,7 +573,9 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
571 | * cleanup to do | 573 | * cleanup to do |
572 | */ | 574 | */ |
573 | if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == | 575 | if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == |
574 | ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) { | 576 | ACPI_PARSE_EXECUTE && |
577 | !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) || | ||
578 | (ACPI_FAILURE(status))) { | ||
575 | acpi_ds_terminate_control_method(walk_state-> | 579 | acpi_ds_terminate_control_method(walk_state-> |
576 | method_desc, | 580 | method_desc, |
577 | walk_state); | 581 | walk_state); |
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index cf30cd821f5e..f3c87264bd1b 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c | |||
@@ -252,6 +252,90 @@ cleanup: | |||
252 | 252 | ||
253 | /******************************************************************************* | 253 | /******************************************************************************* |
254 | * | 254 | * |
255 | * FUNCTION: acpi_ps_execute_table | ||
256 | * | ||
257 | * PARAMETERS: info - Method info block, contains: | ||
258 | * node - Node to where the is entered into the | ||
259 | * namespace | ||
260 | * obj_desc - Pseudo method object describing the AML | ||
261 | * code of the entire table | ||
262 | * pass_number - Parse or execute pass | ||
263 | * | ||
264 | * RETURN: Status | ||
265 | * | ||
266 | * DESCRIPTION: Execute a table | ||
267 | * | ||
268 | ******************************************************************************/ | ||
269 | |||
270 | acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info) | ||
271 | { | ||
272 | acpi_status status; | ||
273 | union acpi_parse_object *op = NULL; | ||
274 | struct acpi_walk_state *walk_state = NULL; | ||
275 | |||
276 | ACPI_FUNCTION_TRACE(ps_execute_table); | ||
277 | |||
278 | /* Create and init a Root Node */ | ||
279 | |||
280 | op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start); | ||
281 | if (!op) { | ||
282 | status = AE_NO_MEMORY; | ||
283 | goto cleanup; | ||
284 | } | ||
285 | |||
286 | /* Create and initialize a new walk state */ | ||
287 | |||
288 | walk_state = | ||
289 | acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, | ||
290 | NULL, NULL); | ||
291 | if (!walk_state) { | ||
292 | status = AE_NO_MEMORY; | ||
293 | goto cleanup; | ||
294 | } | ||
295 | |||
296 | status = acpi_ds_init_aml_walk(walk_state, op, info->node, | ||
297 | info->obj_desc->method.aml_start, | ||
298 | info->obj_desc->method.aml_length, info, | ||
299 | info->pass_number); | ||
300 | if (ACPI_FAILURE(status)) { | ||
301 | goto cleanup; | ||
302 | } | ||
303 | |||
304 | if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) { | ||
305 | walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL; | ||
306 | } | ||
307 | |||
308 | /* Info->Node is the default location to load the table */ | ||
309 | |||
310 | if (info->node && info->node != acpi_gbl_root_node) { | ||
311 | status = | ||
312 | acpi_ds_scope_stack_push(info->node, ACPI_TYPE_METHOD, | ||
313 | walk_state); | ||
314 | if (ACPI_FAILURE(status)) { | ||
315 | goto cleanup; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * Parse the AML, walk_state will be deleted by parse_aml | ||
321 | */ | ||
322 | acpi_ex_enter_interpreter(); | ||
323 | status = acpi_ps_parse_aml(walk_state); | ||
324 | acpi_ex_exit_interpreter(); | ||
325 | walk_state = NULL; | ||
326 | |||
327 | cleanup: | ||
328 | if (walk_state) { | ||
329 | acpi_ds_delete_walk_state(walk_state); | ||
330 | } | ||
331 | if (op) { | ||
332 | acpi_ps_delete_parse_tree(op); | ||
333 | } | ||
334 | return_ACPI_STATUS(status); | ||
335 | } | ||
336 | |||
337 | /******************************************************************************* | ||
338 | * | ||
255 | * FUNCTION: acpi_ps_update_parameter_list | 339 | * FUNCTION: acpi_ps_update_parameter_list |
256 | * | 340 | * |
257 | * PARAMETERS: info - See struct acpi_evaluate_info | 341 | * PARAMETERS: info - See struct acpi_evaluate_info |
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c index 1388a19e5db8..d9ca8c2aa2d3 100644 --- a/drivers/acpi/acpica/tbdata.c +++ b/drivers/acpi/acpica/tbdata.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | #include "actables.h" | 47 | #include "actables.h" |
48 | #include "acevents.h" | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_TABLES | 50 | #define _COMPONENT ACPI_TABLES |
50 | ACPI_MODULE_NAME("tbdata") | 51 | ACPI_MODULE_NAME("tbdata") |
@@ -613,17 +614,12 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | |||
613 | * lock may block, and also since the execution of a namespace walk | 614 | * lock may block, and also since the execution of a namespace walk |
614 | * must be allowed to use the interpreter. | 615 | * must be allowed to use the interpreter. |
615 | */ | 616 | */ |
616 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | ||
617 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | 617 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); |
618 | |||
619 | acpi_ns_delete_namespace_by_owner(owner_id); | ||
620 | if (ACPI_FAILURE(status)) { | 618 | if (ACPI_FAILURE(status)) { |
621 | return_ACPI_STATUS(status); | 619 | return_ACPI_STATUS(status); |
622 | } | 620 | } |
623 | 621 | acpi_ns_delete_namespace_by_owner(owner_id); | |
624 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); | 622 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); |
625 | |||
626 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
627 | return_ACPI_STATUS(status); | 623 | return_ACPI_STATUS(status); |
628 | } | 624 | } |
629 | 625 | ||
@@ -771,3 +767,142 @@ void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) | |||
771 | 767 | ||
772 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 768 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
773 | } | 769 | } |
770 | |||
771 | /******************************************************************************* | ||
772 | * | ||
773 | * FUNCTION: acpi_tb_load_table | ||
774 | * | ||
775 | * PARAMETERS: table_index - Table index | ||
776 | * parent_node - Where table index is returned | ||
777 | * | ||
778 | * RETURN: Status | ||
779 | * | ||
780 | * DESCRIPTION: Load an ACPI table | ||
781 | * | ||
782 | ******************************************************************************/ | ||
783 | |||
784 | acpi_status | ||
785 | acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) | ||
786 | { | ||
787 | struct acpi_table_header *table; | ||
788 | acpi_status status; | ||
789 | acpi_owner_id owner_id; | ||
790 | |||
791 | ACPI_FUNCTION_TRACE(tb_load_table); | ||
792 | |||
793 | /* | ||
794 | * Note: Now table is "INSTALLED", it must be validated before | ||
795 | * using. | ||
796 | */ | ||
797 | status = acpi_get_table_by_index(table_index, &table); | ||
798 | if (ACPI_FAILURE(status)) { | ||
799 | return_ACPI_STATUS(status); | ||
800 | } | ||
801 | |||
802 | status = acpi_ns_load_table(table_index, parent_node); | ||
803 | |||
804 | /* Execute any module-level code that was found in the table */ | ||
805 | |||
806 | if (!acpi_gbl_parse_table_as_term_list | ||
807 | && acpi_gbl_group_module_level_code) { | ||
808 | acpi_ns_exec_module_code_list(); | ||
809 | } | ||
810 | |||
811 | /* | ||
812 | * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is | ||
813 | * responsible for discovering any new wake GPEs by running _PRW methods | ||
814 | * that may have been loaded by this table. | ||
815 | */ | ||
816 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
817 | if (ACPI_SUCCESS(status)) { | ||
818 | acpi_ev_update_gpes(owner_id); | ||
819 | } | ||
820 | |||
821 | /* Invoke table handler if present */ | ||
822 | |||
823 | if (acpi_gbl_table_handler) { | ||
824 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
825 | acpi_gbl_table_handler_context); | ||
826 | } | ||
827 | |||
828 | return_ACPI_STATUS(status); | ||
829 | } | ||
830 | |||
831 | /******************************************************************************* | ||
832 | * | ||
833 | * FUNCTION: acpi_tb_install_and_load_table | ||
834 | * | ||
835 | * PARAMETERS: table - Pointer to the table | ||
836 | * address - Physical address of the table | ||
837 | * flags - Allocation flags of the table | ||
838 | * table_index - Where table index is returned | ||
839 | * | ||
840 | * RETURN: Status | ||
841 | * | ||
842 | * DESCRIPTION: Install and load an ACPI table | ||
843 | * | ||
844 | ******************************************************************************/ | ||
845 | |||
846 | acpi_status | ||
847 | acpi_tb_install_and_load_table(struct acpi_table_header *table, | ||
848 | acpi_physical_address address, | ||
849 | u8 flags, u8 override, u32 *table_index) | ||
850 | { | ||
851 | acpi_status status; | ||
852 | u32 i; | ||
853 | acpi_owner_id owner_id; | ||
854 | |||
855 | ACPI_FUNCTION_TRACE(acpi_load_table); | ||
856 | |||
857 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
858 | |||
859 | /* Install the table and load it into the namespace */ | ||
860 | |||
861 | status = acpi_tb_install_standard_table(address, flags, TRUE, | ||
862 | override, &i); | ||
863 | if (ACPI_FAILURE(status)) { | ||
864 | goto unlock_and_exit; | ||
865 | } | ||
866 | |||
867 | /* | ||
868 | * Note: Now table is "INSTALLED", it must be validated before | ||
869 | * using. | ||
870 | */ | ||
871 | status = acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]); | ||
872 | if (ACPI_FAILURE(status)) { | ||
873 | goto unlock_and_exit; | ||
874 | } | ||
875 | |||
876 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
877 | status = acpi_ns_load_table(i, acpi_gbl_root_node); | ||
878 | |||
879 | /* Execute any module-level code that was found in the table */ | ||
880 | |||
881 | if (!acpi_gbl_parse_table_as_term_list | ||
882 | && acpi_gbl_group_module_level_code) { | ||
883 | acpi_ns_exec_module_code_list(); | ||
884 | } | ||
885 | |||
886 | /* | ||
887 | * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is | ||
888 | * responsible for discovering any new wake GPEs by running _PRW methods | ||
889 | * that may have been loaded by this table. | ||
890 | */ | ||
891 | status = acpi_tb_get_owner_id(i, &owner_id); | ||
892 | if (ACPI_SUCCESS(status)) { | ||
893 | acpi_ev_update_gpes(owner_id); | ||
894 | } | ||
895 | |||
896 | /* Invoke table handler if present */ | ||
897 | |||
898 | if (acpi_gbl_table_handler) { | ||
899 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
900 | acpi_gbl_table_handler_context); | ||
901 | } | ||
902 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
903 | |||
904 | unlock_and_exit: | ||
905 | *table_index = i; | ||
906 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
907 | return_ACPI_STATUS(status); | ||
908 | } | ||
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 620806965243..046c4d0394ee 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -344,23 +344,27 @@ void acpi_tb_parse_fadt(void) | |||
344 | 344 | ||
345 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ | 345 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ |
346 | 346 | ||
347 | acpi_tb_install_fixed_table((acpi_physical_address)acpi_gbl_FADT.Xdsdt, | 347 | acpi_tb_install_standard_table((acpi_physical_address)acpi_gbl_FADT. |
348 | ACPI_SIG_DSDT, &acpi_gbl_dsdt_index); | 348 | Xdsdt, |
349 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, | ||
350 | FALSE, TRUE, &acpi_gbl_dsdt_index); | ||
349 | 351 | ||
350 | /* If Hardware Reduced flag is set, there is no FACS */ | 352 | /* If Hardware Reduced flag is set, there is no FACS */ |
351 | 353 | ||
352 | if (!acpi_gbl_reduced_hardware) { | 354 | if (!acpi_gbl_reduced_hardware) { |
353 | if (acpi_gbl_FADT.facs) { | 355 | if (acpi_gbl_FADT.facs) { |
354 | acpi_tb_install_fixed_table((acpi_physical_address) | 356 | acpi_tb_install_standard_table((acpi_physical_address) |
355 | acpi_gbl_FADT.facs, | 357 | acpi_gbl_FADT.facs, |
356 | ACPI_SIG_FACS, | 358 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, |
357 | &acpi_gbl_facs_index); | 359 | FALSE, TRUE, |
360 | &acpi_gbl_facs_index); | ||
358 | } | 361 | } |
359 | if (acpi_gbl_FADT.Xfacs) { | 362 | if (acpi_gbl_FADT.Xfacs) { |
360 | acpi_tb_install_fixed_table((acpi_physical_address) | 363 | acpi_tb_install_standard_table((acpi_physical_address) |
361 | acpi_gbl_FADT.Xfacs, | 364 | acpi_gbl_FADT.Xfacs, |
362 | ACPI_SIG_FACS, | 365 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, |
363 | &acpi_gbl_xfacs_index); | 366 | FALSE, TRUE, |
367 | &acpi_gbl_xfacs_index); | ||
364 | } | 368 | } |
365 | } | 369 | } |
366 | } | 370 | } |
@@ -476,17 +480,19 @@ static void acpi_tb_convert_fadt(void) | |||
476 | u32 i; | 480 | u32 i; |
477 | 481 | ||
478 | /* | 482 | /* |
479 | * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which | 483 | * For ACPI 1.0 FADTs (revision 1), ensure that reserved fields which |
480 | * should be zero are indeed zero. This will workaround BIOSs that | 484 | * should be zero are indeed zero. This will workaround BIOSs that |
481 | * inadvertently place values in these fields. | 485 | * inadvertently place values in these fields. |
482 | * | 486 | * |
483 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located | 487 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located |
484 | * at offset 45, 55, 95, and the word located at offset 109, 110. | 488 | * at offset 45, 55, 95, and the word located at offset 109, 110. |
485 | * | 489 | * |
486 | * Note: The FADT revision value is unreliable. Only the length can be | 490 | * Note: The FADT revision value is unreliable because of BIOS errors. |
487 | * trusted. | 491 | * The table length is instead used as the final word on the version. |
492 | * | ||
493 | * Note: FADT revision 3 is the ACPI 2.0 version of the FADT. | ||
488 | */ | 494 | */ |
489 | if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) { | 495 | if (acpi_gbl_FADT.header.length <= ACPI_FADT_V3_SIZE) { |
490 | acpi_gbl_FADT.preferred_profile = 0; | 496 | acpi_gbl_FADT.preferred_profile = 0; |
491 | acpi_gbl_FADT.pstate_control = 0; | 497 | acpi_gbl_FADT.pstate_control = 0; |
492 | acpi_gbl_FADT.cst_control = 0; | 498 | acpi_gbl_FADT.cst_control = 0; |
@@ -552,78 +558,74 @@ static void acpi_tb_convert_fadt(void) | |||
552 | * | 558 | * |
553 | * Address32 zero, Address64 [don't care] - Use Address64 | 559 | * Address32 zero, Address64 [don't care] - Use Address64 |
554 | * | 560 | * |
561 | * No override: if acpi_gbl_use32_bit_fadt_addresses is FALSE, and: | ||
555 | * Address32 non-zero, Address64 zero - Copy/use Address32 | 562 | * Address32 non-zero, Address64 zero - Copy/use Address32 |
556 | * Address32 non-zero == Address64 non-zero - Use Address64 | 563 | * Address32 non-zero == Address64 non-zero - Use Address64 |
557 | * Address32 non-zero != Address64 non-zero - Warning, use Address64 | 564 | * Address32 non-zero != Address64 non-zero - Warning, use Address64 |
558 | * | 565 | * |
559 | * Override: if acpi_gbl_use32_bit_fadt_addresses is TRUE, and: | 566 | * Override: if acpi_gbl_use32_bit_fadt_addresses is TRUE, and: |
567 | * Address32 non-zero, Address64 zero - Copy/use Address32 | ||
568 | * Address32 non-zero == Address64 non-zero - Copy/use Address32 | ||
560 | * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32 | 569 | * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32 |
561 | * | 570 | * |
562 | * Note: space_id is always I/O for 32-bit legacy address fields | 571 | * Note: space_id is always I/O for 32-bit legacy address fields |
563 | */ | 572 | */ |
564 | if (address32) { | 573 | if (address32) { |
565 | if (!address64->address) { | 574 | if (address64->address) { |
575 | if (address64->address != (u64)address32) { | ||
576 | |||
577 | /* Address mismatch */ | ||
578 | |||
579 | ACPI_BIOS_WARNING((AE_INFO, | ||
580 | "32/64X address mismatch in FADT/%s: " | ||
581 | "0x%8.8X/0x%8.8X%8.8X, using %u-bit address", | ||
582 | name, address32, | ||
583 | ACPI_FORMAT_UINT64 | ||
584 | (address64->address), | ||
585 | acpi_gbl_use32_bit_fadt_addresses | ||
586 | ? 32 : 64)); | ||
587 | } | ||
566 | 588 | ||
567 | /* 64-bit address is zero, use 32-bit address */ | 589 | /* |
590 | * For each extended field, check for length mismatch | ||
591 | * between the legacy length field and the corresponding | ||
592 | * 64-bit X length field. | ||
593 | * Note: If the legacy length field is > 0xFF bits, ignore | ||
594 | * this check. (GPE registers can be larger than the | ||
595 | * 64-bit GAS structure can accomodate, 0xFF bits). | ||
596 | */ | ||
597 | if ((ACPI_MUL_8(length) <= ACPI_UINT8_MAX) && | ||
598 | (address64->bit_width != | ||
599 | ACPI_MUL_8(length))) { | ||
600 | ACPI_BIOS_WARNING((AE_INFO, | ||
601 | "32/64X length mismatch in FADT/%s: %u/%u", | ||
602 | name, | ||
603 | ACPI_MUL_8(length), | ||
604 | address64-> | ||
605 | bit_width)); | ||
606 | } | ||
607 | } | ||
568 | 608 | ||
609 | /* | ||
610 | * Hardware register access code always uses the 64-bit fields. | ||
611 | * So if the 64-bit field is zero or is to be overridden, | ||
612 | * initialize it with the 32-bit fields. | ||
613 | * Note that when the 32-bit address favor is specified, the | ||
614 | * 64-bit fields are always re-initialized so that | ||
615 | * access_size/bit_width/bit_offset fields can be correctly | ||
616 | * configured to the values to trigger a 32-bit compatible | ||
617 | * access mode in the hardware register access code. | ||
618 | */ | ||
619 | if (!address64->address | ||
620 | || acpi_gbl_use32_bit_fadt_addresses) { | ||
569 | acpi_tb_init_generic_address(address64, | 621 | acpi_tb_init_generic_address(address64, |
570 | ACPI_ADR_SPACE_SYSTEM_IO, | 622 | ACPI_ADR_SPACE_SYSTEM_IO, |
571 | *ACPI_ADD_PTR(u8, | 623 | length, |
572 | &acpi_gbl_FADT, | ||
573 | fadt_info_table | ||
574 | [i]. | ||
575 | length), | ||
576 | (u64)address32, | 624 | (u64)address32, |
577 | name, flags); | 625 | name, flags); |
578 | } else if (address64->address != (u64)address32) { | ||
579 | |||
580 | /* Address mismatch */ | ||
581 | |||
582 | ACPI_BIOS_WARNING((AE_INFO, | ||
583 | "32/64X address mismatch in FADT/%s: " | ||
584 | "0x%8.8X/0x%8.8X%8.8X, using %u-bit address", | ||
585 | name, address32, | ||
586 | ACPI_FORMAT_UINT64 | ||
587 | (address64->address), | ||
588 | acpi_gbl_use32_bit_fadt_addresses | ||
589 | ? 32 : 64)); | ||
590 | |||
591 | if (acpi_gbl_use32_bit_fadt_addresses) { | ||
592 | |||
593 | /* 32-bit address override */ | ||
594 | |||
595 | acpi_tb_init_generic_address(address64, | ||
596 | ACPI_ADR_SPACE_SYSTEM_IO, | ||
597 | *ACPI_ADD_PTR | ||
598 | (u8, | ||
599 | &acpi_gbl_FADT, | ||
600 | fadt_info_table | ||
601 | [i]. | ||
602 | length), | ||
603 | (u64) | ||
604 | address32, | ||
605 | name, | ||
606 | flags); | ||
607 | } | ||
608 | } | 626 | } |
609 | } | 627 | } |
610 | 628 | ||
611 | /* | ||
612 | * For each extended field, check for length mismatch between the | ||
613 | * legacy length field and the corresponding 64-bit X length field. | ||
614 | * Note: If the legacy length field is > 0xFF bits, ignore this | ||
615 | * check. (GPE registers can be larger than the 64-bit GAS structure | ||
616 | * can accomodate, 0xFF bits). | ||
617 | */ | ||
618 | if (address64->address && | ||
619 | (ACPI_MUL_8(length) <= ACPI_UINT8_MAX) && | ||
620 | (address64->bit_width != ACPI_MUL_8(length))) { | ||
621 | ACPI_BIOS_WARNING((AE_INFO, | ||
622 | "32/64X length mismatch in FADT/%s: %u/%u", | ||
623 | name, ACPI_MUL_8(length), | ||
624 | address64->bit_width)); | ||
625 | } | ||
626 | |||
627 | if (fadt_info_table[i].flags & ACPI_FADT_REQUIRED) { | 629 | if (fadt_info_table[i].flags & ACPI_FADT_REQUIRED) { |
628 | /* | 630 | /* |
629 | * Field is required (Pm1a_event, Pm1a_control). | 631 | * Field is required (Pm1a_event, Pm1a_control). |
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index e348d616e60f..f6b9b4e4298b 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c | |||
@@ -68,7 +68,7 @@ acpi_status | |||
68 | acpi_tb_find_table(char *signature, | 68 | acpi_tb_find_table(char *signature, |
69 | char *oem_id, char *oem_table_id, u32 *table_index) | 69 | char *oem_id, char *oem_table_id, u32 *table_index) |
70 | { | 70 | { |
71 | acpi_status status; | 71 | acpi_status status = AE_OK; |
72 | struct acpi_table_header header; | 72 | struct acpi_table_header header; |
73 | u32 i; | 73 | u32 i; |
74 | 74 | ||
@@ -96,6 +96,7 @@ acpi_tb_find_table(char *signature, | |||
96 | 96 | ||
97 | /* Search for the table */ | 97 | /* Search for the table */ |
98 | 98 | ||
99 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
99 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | 100 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { |
100 | if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature), | 101 | if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature), |
101 | header.signature, ACPI_NAME_SIZE)) { | 102 | header.signature, ACPI_NAME_SIZE)) { |
@@ -115,7 +116,7 @@ acpi_tb_find_table(char *signature, | |||
115 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | 116 | acpi_tb_validate_table(&acpi_gbl_root_table_list. |
116 | tables[i]); | 117 | tables[i]); |
117 | if (ACPI_FAILURE(status)) { | 118 | if (ACPI_FAILURE(status)) { |
118 | return_ACPI_STATUS(status); | 119 | goto unlock_and_exit; |
119 | } | 120 | } |
120 | 121 | ||
121 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | 122 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
@@ -144,9 +145,12 @@ acpi_tb_find_table(char *signature, | |||
144 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | 145 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, |
145 | "Found table [%4.4s]\n", | 146 | "Found table [%4.4s]\n", |
146 | header.signature)); | 147 | header.signature)); |
147 | return_ACPI_STATUS(AE_OK); | 148 | goto unlock_and_exit; |
148 | } | 149 | } |
149 | } | 150 | } |
151 | status = AE_NOT_FOUND; | ||
150 | 152 | ||
151 | return_ACPI_STATUS(AE_NOT_FOUND); | 153 | unlock_and_exit: |
154 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
155 | return_ACPI_STATUS(status); | ||
152 | } | 156 | } |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 8b13052128fc..5fdf251a9f97 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -157,68 +157,6 @@ acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, | |||
157 | 157 | ||
158 | /******************************************************************************* | 158 | /******************************************************************************* |
159 | * | 159 | * |
160 | * FUNCTION: acpi_tb_install_fixed_table | ||
161 | * | ||
162 | * PARAMETERS: address - Physical address of DSDT or FACS | ||
163 | * signature - Table signature, NULL if no need to | ||
164 | * match | ||
165 | * table_index - Where the table index is returned | ||
166 | * | ||
167 | * RETURN: Status | ||
168 | * | ||
169 | * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data | ||
170 | * structure. | ||
171 | * | ||
172 | ******************************************************************************/ | ||
173 | |||
174 | acpi_status | ||
175 | acpi_tb_install_fixed_table(acpi_physical_address address, | ||
176 | char *signature, u32 *table_index) | ||
177 | { | ||
178 | struct acpi_table_desc new_table_desc; | ||
179 | acpi_status status; | ||
180 | |||
181 | ACPI_FUNCTION_TRACE(tb_install_fixed_table); | ||
182 | |||
183 | if (!address) { | ||
184 | ACPI_ERROR((AE_INFO, | ||
185 | "Null physical address for ACPI table [%s]", | ||
186 | signature)); | ||
187 | return (AE_NO_MEMORY); | ||
188 | } | ||
189 | |||
190 | /* Fill a table descriptor for validation */ | ||
191 | |||
192 | status = acpi_tb_acquire_temp_table(&new_table_desc, address, | ||
193 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); | ||
194 | if (ACPI_FAILURE(status)) { | ||
195 | ACPI_ERROR((AE_INFO, | ||
196 | "Could not acquire table length at %8.8X%8.8X", | ||
197 | ACPI_FORMAT_UINT64(address))); | ||
198 | return_ACPI_STATUS(status); | ||
199 | } | ||
200 | |||
201 | /* Validate and verify a table before installation */ | ||
202 | |||
203 | status = acpi_tb_verify_temp_table(&new_table_desc, signature); | ||
204 | if (ACPI_FAILURE(status)) { | ||
205 | goto release_and_exit; | ||
206 | } | ||
207 | |||
208 | /* Add the table to the global root table list */ | ||
209 | |||
210 | acpi_tb_install_table_with_override(&new_table_desc, TRUE, table_index); | ||
211 | |||
212 | release_and_exit: | ||
213 | |||
214 | /* Release the temporary table descriptor */ | ||
215 | |||
216 | acpi_tb_release_temp_table(&new_table_desc); | ||
217 | return_ACPI_STATUS(status); | ||
218 | } | ||
219 | |||
220 | /******************************************************************************* | ||
221 | * | ||
222 | * FUNCTION: acpi_tb_install_standard_table | 160 | * FUNCTION: acpi_tb_install_standard_table |
223 | * | 161 | * |
224 | * PARAMETERS: address - Address of the table (might be a virtual | 162 | * PARAMETERS: address - Address of the table (might be a virtual |
@@ -230,8 +168,7 @@ release_and_exit: | |||
230 | * | 168 | * |
231 | * RETURN: Status | 169 | * RETURN: Status |
232 | * | 170 | * |
233 | * DESCRIPTION: This function is called to install an ACPI table that is | 171 | * DESCRIPTION: This function is called to verify and install an ACPI table. |
234 | * neither DSDT nor FACS (a "standard" table.) | ||
235 | * When this function is called by "Load" or "LoadTable" opcodes, | 172 | * When this function is called by "Load" or "LoadTable" opcodes, |
236 | * or by acpi_load_table() API, the "Reload" parameter is set. | 173 | * or by acpi_load_table() API, the "Reload" parameter is set. |
237 | * After sucessfully returning from this function, table is | 174 | * After sucessfully returning from this function, table is |
@@ -364,6 +301,14 @@ acpi_tb_install_standard_table(acpi_physical_address address, | |||
364 | acpi_tb_install_table_with_override(&new_table_desc, override, | 301 | acpi_tb_install_table_with_override(&new_table_desc, override, |
365 | table_index); | 302 | table_index); |
366 | 303 | ||
304 | /* Invoke table handler if present */ | ||
305 | |||
306 | if (acpi_gbl_table_handler) { | ||
307 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_INSTALL, | ||
308 | new_table_desc.pointer, | ||
309 | acpi_gbl_table_handler_context); | ||
310 | } | ||
311 | |||
367 | release_and_exit: | 312 | release_and_exit: |
368 | 313 | ||
369 | /* Release the temporary table descriptor */ | 314 | /* Release the temporary table descriptor */ |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index e28553914bf5..51eb07cf9898 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -252,7 +252,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
252 | * | 252 | * |
253 | ******************************************************************************/ | 253 | ******************************************************************************/ |
254 | 254 | ||
255 | acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | 255 | acpi_status ACPI_INIT_FUNCTION |
256 | acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | ||
256 | { | 257 | { |
257 | struct acpi_table_rsdp *rsdp; | 258 | struct acpi_table_rsdp *rsdp; |
258 | u32 table_entry_size; | 259 | u32 table_entry_size; |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 3ecec937e8c9..4ab6b9cd0aec 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -98,7 +98,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count) | |||
98 | * | 98 | * |
99 | ******************************************************************************/ | 99 | ******************************************************************************/ |
100 | 100 | ||
101 | acpi_status __init | 101 | acpi_status ACPI_INIT_FUNCTION |
102 | acpi_initialize_tables(struct acpi_table_desc *initial_table_array, | 102 | acpi_initialize_tables(struct acpi_table_desc *initial_table_array, |
103 | u32 initial_table_count, u8 allow_resize) | 103 | u32 initial_table_count, u8 allow_resize) |
104 | { | 104 | { |
@@ -164,7 +164,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables) | |||
164 | * kernel. | 164 | * kernel. |
165 | * | 165 | * |
166 | ******************************************************************************/ | 166 | ******************************************************************************/ |
167 | acpi_status __init acpi_reallocate_root_table(void) | 167 | acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void) |
168 | { | 168 | { |
169 | acpi_status status; | 169 | acpi_status status; |
170 | 170 | ||
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index ac71abcd32bb..5569f637f669 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c | |||
@@ -63,7 +63,7 @@ ACPI_MODULE_NAME("tbxfload") | |||
63 | * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT | 63 | * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT |
64 | * | 64 | * |
65 | ******************************************************************************/ | 65 | ******************************************************************************/ |
66 | acpi_status __init acpi_load_tables(void) | 66 | acpi_status ACPI_INIT_FUNCTION acpi_load_tables(void) |
67 | { | 67 | { |
68 | acpi_status status; | 68 | acpi_status status; |
69 | 69 | ||
@@ -103,7 +103,8 @@ acpi_status __init acpi_load_tables(void) | |||
103 | "While loading namespace from ACPI tables")); | 103 | "While loading namespace from ACPI tables")); |
104 | } | 104 | } |
105 | 105 | ||
106 | if (!acpi_gbl_group_module_level_code) { | 106 | if (acpi_gbl_parse_table_as_term_list |
107 | || !acpi_gbl_group_module_level_code) { | ||
107 | /* | 108 | /* |
108 | * Initialize the objects that remain uninitialized. This | 109 | * Initialize the objects that remain uninitialized. This |
109 | * runs the executable AML that may be part of the | 110 | * runs the executable AML that may be part of the |
@@ -188,11 +189,11 @@ acpi_status acpi_tb_load_namespace(void) | |||
188 | memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT, | 189 | memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT, |
189 | sizeof(struct acpi_table_header)); | 190 | sizeof(struct acpi_table_header)); |
190 | 191 | ||
191 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
192 | |||
193 | /* Load and parse tables */ | 192 | /* Load and parse tables */ |
194 | 193 | ||
194 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
195 | status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node); | 195 | status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node); |
196 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
196 | if (ACPI_FAILURE(status)) { | 197 | if (ACPI_FAILURE(status)) { |
197 | ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed")); | 198 | ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed")); |
198 | tables_failed++; | 199 | tables_failed++; |
@@ -202,7 +203,6 @@ acpi_status acpi_tb_load_namespace(void) | |||
202 | 203 | ||
203 | /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ | 204 | /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ |
204 | 205 | ||
205 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
206 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | 206 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { |
207 | table = &acpi_gbl_root_table_list.tables[i]; | 207 | table = &acpi_gbl_root_table_list.tables[i]; |
208 | 208 | ||
@@ -220,6 +220,7 @@ acpi_status acpi_tb_load_namespace(void) | |||
220 | 220 | ||
221 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 221 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
222 | status = acpi_ns_load_table(i, acpi_gbl_root_node); | 222 | status = acpi_ns_load_table(i, acpi_gbl_root_node); |
223 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
223 | if (ACPI_FAILURE(status)) { | 224 | if (ACPI_FAILURE(status)) { |
224 | ACPI_EXCEPTION((AE_INFO, status, | 225 | ACPI_EXCEPTION((AE_INFO, status, |
225 | "(%4.4s:%8.8s) while loading table", | 226 | "(%4.4s:%8.8s) while loading table", |
@@ -235,8 +236,6 @@ acpi_status acpi_tb_load_namespace(void) | |||
235 | } else { | 236 | } else { |
236 | tables_loaded++; | 237 | tables_loaded++; |
237 | } | 238 | } |
238 | |||
239 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
240 | } | 239 | } |
241 | 240 | ||
242 | if (!tables_failed) { | 241 | if (!tables_failed) { |
@@ -272,7 +271,7 @@ unlock_and_exit: | |||
272 | * | 271 | * |
273 | ******************************************************************************/ | 272 | ******************************************************************************/ |
274 | 273 | ||
275 | acpi_status __init | 274 | acpi_status ACPI_INIT_FUNCTION |
276 | acpi_install_table(acpi_physical_address address, u8 physical) | 275 | acpi_install_table(acpi_physical_address address, u8 physical) |
277 | { | 276 | { |
278 | acpi_status status; | 277 | acpi_status status; |
@@ -324,49 +323,13 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
324 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 323 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
325 | } | 324 | } |
326 | 325 | ||
327 | /* Must acquire the interpreter lock during this operation */ | ||
328 | |||
329 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
330 | if (ACPI_FAILURE(status)) { | ||
331 | return_ACPI_STATUS(status); | ||
332 | } | ||
333 | |||
334 | /* Install the table and load it into the namespace */ | 326 | /* Install the table and load it into the namespace */ |
335 | 327 | ||
336 | ACPI_INFO(("Host-directed Dynamic ACPI Table Load:")); | 328 | ACPI_INFO(("Host-directed Dynamic ACPI Table Load:")); |
337 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
338 | |||
339 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), | ||
340 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, | ||
341 | TRUE, FALSE, &table_index); | ||
342 | |||
343 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
344 | if (ACPI_FAILURE(status)) { | ||
345 | goto unlock_and_exit; | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | * Note: Now table is "INSTALLED", it must be validated before | ||
350 | * using. | ||
351 | */ | ||
352 | status = | 329 | status = |
353 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | 330 | acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table), |
354 | tables[table_index]); | 331 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, |
355 | if (ACPI_FAILURE(status)) { | 332 | FALSE, &table_index); |
356 | goto unlock_and_exit; | ||
357 | } | ||
358 | |||
359 | status = acpi_ns_load_table(table_index, acpi_gbl_root_node); | ||
360 | |||
361 | /* Invoke table handler if present */ | ||
362 | |||
363 | if (acpi_gbl_table_handler) { | ||
364 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
365 | acpi_gbl_table_handler_context); | ||
366 | } | ||
367 | |||
368 | unlock_and_exit: | ||
369 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | ||
370 | return_ACPI_STATUS(status); | 333 | return_ACPI_STATUS(status); |
371 | } | 334 | } |
372 | 335 | ||
@@ -415,9 +378,9 @@ acpi_status acpi_unload_parent_table(acpi_handle object) | |||
415 | return_ACPI_STATUS(AE_TYPE); | 378 | return_ACPI_STATUS(AE_TYPE); |
416 | } | 379 | } |
417 | 380 | ||
418 | /* Must acquire the interpreter lock during this operation */ | 381 | /* Must acquire the table lock during this operation */ |
419 | 382 | ||
420 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | 383 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
421 | if (ACPI_FAILURE(status)) { | 384 | if (ACPI_FAILURE(status)) { |
422 | return_ACPI_STATUS(status); | 385 | return_ACPI_STATUS(status); |
423 | } | 386 | } |
@@ -444,8 +407,10 @@ acpi_status acpi_unload_parent_table(acpi_handle object) | |||
444 | 407 | ||
445 | /* Ensure the table is actually loaded */ | 408 | /* Ensure the table is actually loaded */ |
446 | 409 | ||
410 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
447 | if (!acpi_tb_is_table_loaded(i)) { | 411 | if (!acpi_tb_is_table_loaded(i)) { |
448 | status = AE_NOT_EXIST; | 412 | status = AE_NOT_EXIST; |
413 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
449 | break; | 414 | break; |
450 | } | 415 | } |
451 | 416 | ||
@@ -471,10 +436,11 @@ acpi_status acpi_unload_parent_table(acpi_handle object) | |||
471 | 436 | ||
472 | status = acpi_tb_release_owner_id(i); | 437 | status = acpi_tb_release_owner_id(i); |
473 | acpi_tb_set_table_loaded_flag(i, FALSE); | 438 | acpi_tb_set_table_loaded_flag(i, FALSE); |
439 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
474 | break; | 440 | break; |
475 | } | 441 | } |
476 | 442 | ||
477 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 443 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
478 | return_ACPI_STATUS(status); | 444 | return_ACPI_STATUS(status); |
479 | } | 445 | } |
480 | 446 | ||
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index adb6cfc54661..0adb1c78d863 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c | |||
@@ -142,7 +142,8 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) | |||
142 | * | 142 | * |
143 | ******************************************************************************/ | 143 | ******************************************************************************/ |
144 | 144 | ||
145 | acpi_status __init acpi_find_root_pointer(acpi_physical_address *table_address) | 145 | acpi_status ACPI_INIT_FUNCTION |
146 | acpi_find_root_pointer(acpi_physical_address *table_address) | ||
146 | { | 147 | { |
147 | u8 *table_ptr; | 148 | u8 *table_ptr; |
148 | u8 *mem_rover; | 149 | u8 *mem_rover; |
@@ -244,6 +245,8 @@ acpi_status __init acpi_find_root_pointer(acpi_physical_address *table_address) | |||
244 | return_ACPI_STATUS(AE_NOT_FOUND); | 245 | return_ACPI_STATUS(AE_NOT_FOUND); |
245 | } | 246 | } |
246 | 247 | ||
248 | ACPI_EXPORT_SYMBOL_INIT(acpi_find_root_pointer) | ||
249 | |||
247 | /******************************************************************************* | 250 | /******************************************************************************* |
248 | * | 251 | * |
249 | * FUNCTION: acpi_tb_scan_memory_for_rsdp | 252 | * FUNCTION: acpi_tb_scan_memory_for_rsdp |
diff --git a/drivers/acpi/acpica/utaddress.c b/drivers/acpi/acpica/utaddress.c index c986ec66a118..433d822798b6 100644 --- a/drivers/acpi/acpica/utaddress.c +++ b/drivers/acpi/acpica/utaddress.c | |||
@@ -77,7 +77,6 @@ acpi_ut_add_address_range(acpi_adr_space_type space_id, | |||
77 | u32 length, struct acpi_namespace_node *region_node) | 77 | u32 length, struct acpi_namespace_node *region_node) |
78 | { | 78 | { |
79 | struct acpi_address_range *range_info; | 79 | struct acpi_address_range *range_info; |
80 | acpi_status status; | ||
81 | 80 | ||
82 | ACPI_FUNCTION_TRACE(ut_add_address_range); | 81 | ACPI_FUNCTION_TRACE(ut_add_address_range); |
83 | 82 | ||
@@ -97,12 +96,6 @@ acpi_ut_add_address_range(acpi_adr_space_type space_id, | |||
97 | range_info->end_address = (address + length - 1); | 96 | range_info->end_address = (address + length - 1); |
98 | range_info->region_node = region_node; | 97 | range_info->region_node = region_node; |
99 | 98 | ||
100 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
101 | if (ACPI_FAILURE(status)) { | ||
102 | ACPI_FREE(range_info); | ||
103 | return_ACPI_STATUS(status); | ||
104 | } | ||
105 | |||
106 | range_info->next = acpi_gbl_address_range_list[space_id]; | 99 | range_info->next = acpi_gbl_address_range_list[space_id]; |
107 | acpi_gbl_address_range_list[space_id] = range_info; | 100 | acpi_gbl_address_range_list[space_id] = range_info; |
108 | 101 | ||
@@ -112,7 +105,6 @@ acpi_ut_add_address_range(acpi_adr_space_type space_id, | |||
112 | ACPI_FORMAT_UINT64(address), | 105 | ACPI_FORMAT_UINT64(address), |
113 | ACPI_FORMAT_UINT64(range_info->end_address))); | 106 | ACPI_FORMAT_UINT64(range_info->end_address))); |
114 | 107 | ||
115 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
116 | return_ACPI_STATUS(AE_OK); | 108 | return_ACPI_STATUS(AE_OK); |
117 | } | 109 | } |
118 | 110 | ||
diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c index bd31faf5da7c..ff2981275b9a 100644 --- a/drivers/acpi/acpica/utbuffer.c +++ b/drivers/acpi/acpica/utbuffer.c | |||
@@ -239,8 +239,7 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file, | |||
239 | u8 buf_char; | 239 | u8 buf_char; |
240 | 240 | ||
241 | if (!buffer) { | 241 | if (!buffer) { |
242 | acpi_ut_file_printf(file, | 242 | fprintf(file, "Null Buffer Pointer in DumpBuffer!\n"); |
243 | "Null Buffer Pointer in DumpBuffer!\n"); | ||
244 | return; | 243 | return; |
245 | } | 244 | } |
246 | 245 | ||
@@ -254,7 +253,7 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file, | |||
254 | 253 | ||
255 | /* Print current offset */ | 254 | /* Print current offset */ |
256 | 255 | ||
257 | acpi_ut_file_printf(file, "%6.4X: ", (base_offset + i)); | 256 | fprintf(file, "%6.4X: ", (base_offset + i)); |
258 | 257 | ||
259 | /* Print 16 hex chars */ | 258 | /* Print 16 hex chars */ |
260 | 259 | ||
@@ -263,8 +262,7 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file, | |||
263 | 262 | ||
264 | /* Dump fill spaces */ | 263 | /* Dump fill spaces */ |
265 | 264 | ||
266 | acpi_ut_file_printf(file, "%*s", | 265 | fprintf(file, "%*s", ((display * 2) + 1), " "); |
267 | ((display * 2) + 1), " "); | ||
268 | j += display; | 266 | j += display; |
269 | continue; | 267 | continue; |
270 | } | 268 | } |
@@ -273,34 +271,34 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file, | |||
273 | case DB_BYTE_DISPLAY: | 271 | case DB_BYTE_DISPLAY: |
274 | default: /* Default is BYTE display */ | 272 | default: /* Default is BYTE display */ |
275 | 273 | ||
276 | acpi_ut_file_printf(file, "%02X ", | 274 | fprintf(file, "%02X ", |
277 | buffer[(acpi_size)i + j]); | 275 | buffer[(acpi_size)i + j]); |
278 | break; | 276 | break; |
279 | 277 | ||
280 | case DB_WORD_DISPLAY: | 278 | case DB_WORD_DISPLAY: |
281 | 279 | ||
282 | ACPI_MOVE_16_TO_32(&temp32, | 280 | ACPI_MOVE_16_TO_32(&temp32, |
283 | &buffer[(acpi_size)i + j]); | 281 | &buffer[(acpi_size)i + j]); |
284 | acpi_ut_file_printf(file, "%04X ", temp32); | 282 | fprintf(file, "%04X ", temp32); |
285 | break; | 283 | break; |
286 | 284 | ||
287 | case DB_DWORD_DISPLAY: | 285 | case DB_DWORD_DISPLAY: |
288 | 286 | ||
289 | ACPI_MOVE_32_TO_32(&temp32, | 287 | ACPI_MOVE_32_TO_32(&temp32, |
290 | &buffer[(acpi_size)i + j]); | 288 | &buffer[(acpi_size)i + j]); |
291 | acpi_ut_file_printf(file, "%08X ", temp32); | 289 | fprintf(file, "%08X ", temp32); |
292 | break; | 290 | break; |
293 | 291 | ||
294 | case DB_QWORD_DISPLAY: | 292 | case DB_QWORD_DISPLAY: |
295 | 293 | ||
296 | ACPI_MOVE_32_TO_32(&temp32, | 294 | ACPI_MOVE_32_TO_32(&temp32, |
297 | &buffer[(acpi_size)i + j]); | 295 | &buffer[(acpi_size)i + j]); |
298 | acpi_ut_file_printf(file, "%08X", temp32); | 296 | fprintf(file, "%08X", temp32); |
299 | 297 | ||
300 | ACPI_MOVE_32_TO_32(&temp32, | 298 | ACPI_MOVE_32_TO_32(&temp32, |
301 | &buffer[(acpi_size)i + j + | 299 | &buffer[(acpi_size)i + j + |
302 | 4]); | 300 | 4]); |
303 | acpi_ut_file_printf(file, "%08X ", temp32); | 301 | fprintf(file, "%08X ", temp32); |
304 | break; | 302 | break; |
305 | } | 303 | } |
306 | 304 | ||
@@ -311,24 +309,24 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file, | |||
311 | * Print the ASCII equivalent characters but watch out for the bad | 309 | * Print the ASCII equivalent characters but watch out for the bad |
312 | * unprintable ones (printable chars are 0x20 through 0x7E) | 310 | * unprintable ones (printable chars are 0x20 through 0x7E) |
313 | */ | 311 | */ |
314 | acpi_ut_file_printf(file, " "); | 312 | fprintf(file, " "); |
315 | for (j = 0; j < 16; j++) { | 313 | for (j = 0; j < 16; j++) { |
316 | if (i + j >= count) { | 314 | if (i + j >= count) { |
317 | acpi_ut_file_printf(file, "\n"); | 315 | fprintf(file, "\n"); |
318 | return; | 316 | return; |
319 | } | 317 | } |
320 | 318 | ||
321 | buf_char = buffer[(acpi_size)i + j]; | 319 | buf_char = buffer[(acpi_size)i + j]; |
322 | if (isprint(buf_char)) { | 320 | if (isprint(buf_char)) { |
323 | acpi_ut_file_printf(file, "%c", buf_char); | 321 | fprintf(file, "%c", buf_char); |
324 | } else { | 322 | } else { |
325 | acpi_ut_file_printf(file, "."); | 323 | fprintf(file, "."); |
326 | } | 324 | } |
327 | } | 325 | } |
328 | 326 | ||
329 | /* Done with that line. */ | 327 | /* Done with that line. */ |
330 | 328 | ||
331 | acpi_ut_file_printf(file, "\n"); | 329 | fprintf(file, "\n"); |
332 | i += 16; | 330 | i += 16; |
333 | } | 331 | } |
334 | 332 | ||
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 574422205005..044df9b0356e 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
@@ -562,6 +562,43 @@ acpi_ut_ptr_exit(u32 line_number, | |||
562 | 562 | ||
563 | /******************************************************************************* | 563 | /******************************************************************************* |
564 | * | 564 | * |
565 | * FUNCTION: acpi_ut_str_exit | ||
566 | * | ||
567 | * PARAMETERS: line_number - Caller's line number | ||
568 | * function_name - Caller's procedure name | ||
569 | * module_name - Caller's module name | ||
570 | * component_id - Caller's component ID | ||
571 | * string - String to display | ||
572 | * | ||
573 | * RETURN: None | ||
574 | * | ||
575 | * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is | ||
576 | * set in debug_level. Prints exit value also. | ||
577 | * | ||
578 | ******************************************************************************/ | ||
579 | |||
580 | void | ||
581 | acpi_ut_str_exit(u32 line_number, | ||
582 | const char *function_name, | ||
583 | const char *module_name, u32 component_id, const char *string) | ||
584 | { | ||
585 | |||
586 | /* Check if enabled up-front for performance */ | ||
587 | |||
588 | if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) { | ||
589 | acpi_debug_print(ACPI_LV_FUNCTIONS, | ||
590 | line_number, function_name, module_name, | ||
591 | component_id, "%s %s\n", | ||
592 | acpi_gbl_function_exit_prefix, string); | ||
593 | } | ||
594 | |||
595 | if (acpi_gbl_nesting_level) { | ||
596 | acpi_gbl_nesting_level--; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | /******************************************************************************* | ||
601 | * | ||
565 | * FUNCTION: acpi_trace_point | 602 | * FUNCTION: acpi_trace_point |
566 | * | 603 | * |
567 | * PARAMETERS: type - Trace event type | 604 | * PARAMETERS: type - Trace event type |
@@ -591,27 +628,3 @@ acpi_trace_point(acpi_trace_event_type type, u8 begin, u8 *aml, char *pathname) | |||
591 | 628 | ||
592 | ACPI_EXPORT_SYMBOL(acpi_trace_point) | 629 | ACPI_EXPORT_SYMBOL(acpi_trace_point) |
593 | #endif | 630 | #endif |
594 | #ifdef ACPI_APPLICATION | ||
595 | /******************************************************************************* | ||
596 | * | ||
597 | * FUNCTION: acpi_log_error | ||
598 | * | ||
599 | * PARAMETERS: format - Printf format field | ||
600 | * ... - Optional printf arguments | ||
601 | * | ||
602 | * RETURN: None | ||
603 | * | ||
604 | * DESCRIPTION: Print error message to the console, used by applications. | ||
605 | * | ||
606 | ******************************************************************************/ | ||
607 | void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...) | ||
608 | { | ||
609 | va_list args; | ||
610 | |||
611 | va_start(args, format); | ||
612 | (void)acpi_ut_file_vprintf(ACPI_FILE_ERR, format, args); | ||
613 | va_end(args); | ||
614 | } | ||
615 | |||
616 | ACPI_EXPORT_SYMBOL(acpi_log_error) | ||
617 | #endif | ||
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index efd7988e34cb..15728ad8356b 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -253,7 +253,7 @@ const char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) | |||
253 | return_PTR("Invalid object"); | 253 | return_PTR("Invalid object"); |
254 | } | 254 | } |
255 | 255 | ||
256 | return_PTR(acpi_ut_get_type_name(obj_desc->common.type)); | 256 | return_STR(acpi_ut_get_type_name(obj_desc->common.type)); |
257 | } | 257 | } |
258 | 258 | ||
259 | /******************************************************************************* | 259 | /******************************************************************************* |
diff --git a/drivers/acpi/acpica/uthex.c b/drivers/acpi/acpica/uthex.c index 4354fb800fe4..36d2fc789088 100644 --- a/drivers/acpi/acpica/uthex.c +++ b/drivers/acpi/acpica/uthex.c | |||
@@ -75,9 +75,41 @@ char acpi_ut_hex_to_ascii_char(u64 integer, u32 position) | |||
75 | 75 | ||
76 | /******************************************************************************* | 76 | /******************************************************************************* |
77 | * | 77 | * |
78 | * FUNCTION: acpi_ut_ascii_to_hex_byte | ||
79 | * | ||
80 | * PARAMETERS: two_ascii_chars - Pointer to two ASCII characters | ||
81 | * return_byte - Where converted byte is returned | ||
82 | * | ||
83 | * RETURN: Status and converted hex byte | ||
84 | * | ||
85 | * DESCRIPTION: Perform ascii-to-hex translation, exactly two ASCII characters | ||
86 | * to a single converted byte value. | ||
87 | * | ||
88 | ******************************************************************************/ | ||
89 | |||
90 | acpi_status acpi_ut_ascii_to_hex_byte(char *two_ascii_chars, u8 *return_byte) | ||
91 | { | ||
92 | |||
93 | /* Both ASCII characters must be valid hex digits */ | ||
94 | |||
95 | if (!isxdigit((int)two_ascii_chars[0]) || | ||
96 | !isxdigit((int)two_ascii_chars[1])) { | ||
97 | return (AE_BAD_HEX_CONSTANT); | ||
98 | } | ||
99 | |||
100 | *return_byte = | ||
101 | acpi_ut_ascii_char_to_hex(two_ascii_chars[1]) | | ||
102 | (acpi_ut_ascii_char_to_hex(two_ascii_chars[0]) << 4); | ||
103 | |||
104 | return (AE_OK); | ||
105 | } | ||
106 | |||
107 | /******************************************************************************* | ||
108 | * | ||
78 | * FUNCTION: acpi_ut_ascii_char_to_hex | 109 | * FUNCTION: acpi_ut_ascii_char_to_hex |
79 | * | 110 | * |
80 | * PARAMETERS: hex_char - Hex character in Ascii | 111 | * PARAMETERS: hex_char - Hex character in Ascii. Must be: |
112 | * 0-9 or A-F or a-f | ||
81 | * | 113 | * |
82 | * RETURN: The binary value of the ascii/hex character | 114 | * RETURN: The binary value of the ascii/hex character |
83 | * | 115 | * |
@@ -88,13 +120,19 @@ char acpi_ut_hex_to_ascii_char(u64 integer, u32 position) | |||
88 | u8 acpi_ut_ascii_char_to_hex(int hex_char) | 120 | u8 acpi_ut_ascii_char_to_hex(int hex_char) |
89 | { | 121 | { |
90 | 122 | ||
91 | if (hex_char <= 0x39) { | 123 | /* Values 0-9 */ |
92 | return ((u8)(hex_char - 0x30)); | 124 | |
125 | if (hex_char <= '9') { | ||
126 | return ((u8)(hex_char - '0')); | ||
93 | } | 127 | } |
94 | 128 | ||
95 | if (hex_char <= 0x46) { | 129 | /* Upper case A-F */ |
130 | |||
131 | if (hex_char <= 'F') { | ||
96 | return ((u8)(hex_char - 0x37)); | 132 | return ((u8)(hex_char - 0x37)); |
97 | } | 133 | } |
98 | 134 | ||
135 | /* Lower case a-f */ | ||
136 | |||
99 | return ((u8)(hex_char - 0x57)); | 137 | return ((u8)(hex_char - 0x57)); |
100 | } | 138 | } |
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index f91f724c487c..1711fdf41709 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c | |||
@@ -206,7 +206,7 @@ acpi_status acpi_ut_init_globals(void) | |||
206 | acpi_gbl_next_owner_id_offset = 0; | 206 | acpi_gbl_next_owner_id_offset = 0; |
207 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; | 207 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; |
208 | acpi_gbl_osi_mutex = NULL; | 208 | acpi_gbl_osi_mutex = NULL; |
209 | acpi_gbl_max_loop_iterations = 0xFFFF; | 209 | acpi_gbl_max_loop_iterations = ACPI_MAX_LOOP_COUNT; |
210 | 210 | ||
211 | /* Hardware oriented */ | 211 | /* Hardware oriented */ |
212 | 212 | ||
diff --git a/drivers/acpi/acpica/utnonansi.c b/drivers/acpi/acpica/utnonansi.c index 3465fe2c5a5c..2514239282c2 100644 --- a/drivers/acpi/acpica/utnonansi.c +++ b/drivers/acpi/acpica/utnonansi.c | |||
@@ -48,8 +48,8 @@ | |||
48 | ACPI_MODULE_NAME("utnonansi") | 48 | ACPI_MODULE_NAME("utnonansi") |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit | 51 | * Non-ANSI C library functions - strlwr, strupr, stricmp, and "safe" |
52 | * version of strtoul. | 52 | * string functions. |
53 | */ | 53 | */ |
54 | /******************************************************************************* | 54 | /******************************************************************************* |
55 | * | 55 | * |
@@ -200,356 +200,3 @@ acpi_ut_safe_strncat(char *dest, | |||
200 | return (FALSE); | 200 | return (FALSE); |
201 | } | 201 | } |
202 | #endif | 202 | #endif |
203 | |||
204 | /******************************************************************************* | ||
205 | * | ||
206 | * FUNCTION: acpi_ut_strtoul64 | ||
207 | * | ||
208 | * PARAMETERS: string - Null terminated string | ||
209 | * base - Radix of the string: 16 or 10 or | ||
210 | * ACPI_ANY_BASE | ||
211 | * max_integer_byte_width - Maximum allowable integer,in bytes: | ||
212 | * 4 or 8 (32 or 64 bits) | ||
213 | * ret_integer - Where the converted integer is | ||
214 | * returned | ||
215 | * | ||
216 | * RETURN: Status and Converted value | ||
217 | * | ||
218 | * DESCRIPTION: Convert a string into an unsigned value. Performs either a | ||
219 | * 32-bit or 64-bit conversion, depending on the input integer | ||
220 | * size (often the current mode of the interpreter). | ||
221 | * | ||
222 | * NOTES: Negative numbers are not supported, as they are not supported | ||
223 | * by ACPI. | ||
224 | * | ||
225 | * acpi_gbl_integer_byte_width should be set to the proper width. | ||
226 | * For the core ACPICA code, this width depends on the DSDT | ||
227 | * version. For iASL, the default byte width is always 8 for the | ||
228 | * parser, but error checking is performed later to flag cases | ||
229 | * where a 64-bit constant is defined in a 32-bit DSDT/SSDT. | ||
230 | * | ||
231 | * Does not support Octal strings, not needed at this time. | ||
232 | * | ||
233 | ******************************************************************************/ | ||
234 | |||
235 | acpi_status | ||
236 | acpi_ut_strtoul64(char *string, | ||
237 | u32 base, u32 max_integer_byte_width, u64 *ret_integer) | ||
238 | { | ||
239 | u32 this_digit = 0; | ||
240 | u64 return_value = 0; | ||
241 | u64 quotient; | ||
242 | u64 dividend; | ||
243 | u8 valid_digits = 0; | ||
244 | u8 sign_of0x = 0; | ||
245 | u8 term = 0; | ||
246 | |||
247 | ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string); | ||
248 | |||
249 | switch (base) { | ||
250 | case ACPI_ANY_BASE: | ||
251 | case 10: | ||
252 | case 16: | ||
253 | |||
254 | break; | ||
255 | |||
256 | default: | ||
257 | |||
258 | /* Invalid Base */ | ||
259 | |||
260 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
261 | } | ||
262 | |||
263 | if (!string) { | ||
264 | goto error_exit; | ||
265 | } | ||
266 | |||
267 | /* Skip over any white space in the buffer */ | ||
268 | |||
269 | while ((*string) && (isspace((int)*string) || *string == '\t')) { | ||
270 | string++; | ||
271 | } | ||
272 | |||
273 | if (base == ACPI_ANY_BASE) { | ||
274 | /* | ||
275 | * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'. | ||
276 | * We need to determine if it is decimal or hexadecimal. | ||
277 | */ | ||
278 | if ((*string == '0') && (tolower((int)*(string + 1)) == 'x')) { | ||
279 | sign_of0x = 1; | ||
280 | base = 16; | ||
281 | |||
282 | /* Skip over the leading '0x' */ | ||
283 | string += 2; | ||
284 | } else { | ||
285 | base = 10; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* Any string left? Check that '0x' is not followed by white space. */ | ||
290 | |||
291 | if (!(*string) || isspace((int)*string) || *string == '\t') { | ||
292 | if (base == ACPI_ANY_BASE) { | ||
293 | goto error_exit; | ||
294 | } else { | ||
295 | goto all_done; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * Perform a 32-bit or 64-bit conversion, depending upon the input | ||
301 | * byte width | ||
302 | */ | ||
303 | dividend = (max_integer_byte_width <= ACPI_MAX32_BYTE_WIDTH) ? | ||
304 | ACPI_UINT32_MAX : ACPI_UINT64_MAX; | ||
305 | |||
306 | /* Main loop: convert the string to a 32- or 64-bit integer */ | ||
307 | |||
308 | while (*string) { | ||
309 | if (isdigit((int)*string)) { | ||
310 | |||
311 | /* Convert ASCII 0-9 to Decimal value */ | ||
312 | |||
313 | this_digit = ((u8)*string) - '0'; | ||
314 | } else if (base == 10) { | ||
315 | |||
316 | /* Digit is out of range; possible in to_integer case only */ | ||
317 | |||
318 | term = 1; | ||
319 | } else { | ||
320 | this_digit = (u8)toupper((int)*string); | ||
321 | if (isxdigit((int)this_digit)) { | ||
322 | |||
323 | /* Convert ASCII Hex char to value */ | ||
324 | |||
325 | this_digit = this_digit - 'A' + 10; | ||
326 | } else { | ||
327 | term = 1; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | if (term) { | ||
332 | if (base == ACPI_ANY_BASE) { | ||
333 | goto error_exit; | ||
334 | } else { | ||
335 | break; | ||
336 | } | ||
337 | } else if ((valid_digits == 0) && (this_digit == 0) | ||
338 | && !sign_of0x) { | ||
339 | |||
340 | /* Skip zeros */ | ||
341 | string++; | ||
342 | continue; | ||
343 | } | ||
344 | |||
345 | valid_digits++; | ||
346 | |||
347 | if (sign_of0x && ((valid_digits > 16) || | ||
348 | ((valid_digits > 8) | ||
349 | && (max_integer_byte_width <= | ||
350 | ACPI_MAX32_BYTE_WIDTH)))) { | ||
351 | /* | ||
352 | * This is to_integer operation case. | ||
353 | * No restrictions for string-to-integer conversion, | ||
354 | * see ACPI spec. | ||
355 | */ | ||
356 | goto error_exit; | ||
357 | } | ||
358 | |||
359 | /* Divide the digit into the correct position */ | ||
360 | |||
361 | (void)acpi_ut_short_divide((dividend - (u64)this_digit), base, | ||
362 | "ient, NULL); | ||
363 | |||
364 | if (return_value > quotient) { | ||
365 | if (base == ACPI_ANY_BASE) { | ||
366 | goto error_exit; | ||
367 | } else { | ||
368 | break; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | return_value *= base; | ||
373 | return_value += this_digit; | ||
374 | string++; | ||
375 | } | ||
376 | |||
377 | /* All done, normal exit */ | ||
378 | |||
379 | all_done: | ||
380 | |||
381 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", | ||
382 | ACPI_FORMAT_UINT64(return_value))); | ||
383 | |||
384 | *ret_integer = return_value; | ||
385 | return_ACPI_STATUS(AE_OK); | ||
386 | |||
387 | error_exit: | ||
388 | |||
389 | /* Base was set/validated above (10 or 16) */ | ||
390 | |||
391 | if (base == 10) { | ||
392 | return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT); | ||
393 | } else { | ||
394 | return_ACPI_STATUS(AE_BAD_HEX_CONSTANT); | ||
395 | } | ||
396 | } | ||
397 | |||
398 | #ifdef _OBSOLETE_FUNCTIONS | ||
399 | /* Removed: 01/2016 */ | ||
400 | |||
401 | /******************************************************************************* | ||
402 | * | ||
403 | * FUNCTION: strtoul64 | ||
404 | * | ||
405 | * PARAMETERS: string - Null terminated string | ||
406 | * terminater - Where a pointer to the terminating byte | ||
407 | * is returned | ||
408 | * base - Radix of the string | ||
409 | * | ||
410 | * RETURN: Converted value | ||
411 | * | ||
412 | * DESCRIPTION: Convert a string into an unsigned value. | ||
413 | * | ||
414 | ******************************************************************************/ | ||
415 | |||
416 | acpi_status strtoul64(char *string, u32 base, u64 *ret_integer) | ||
417 | { | ||
418 | u32 index; | ||
419 | u32 sign; | ||
420 | u64 return_value = 0; | ||
421 | acpi_status status = AE_OK; | ||
422 | |||
423 | *ret_integer = 0; | ||
424 | |||
425 | switch (base) { | ||
426 | case 0: | ||
427 | case 8: | ||
428 | case 10: | ||
429 | case 16: | ||
430 | |||
431 | break; | ||
432 | |||
433 | default: | ||
434 | /* | ||
435 | * The specified Base parameter is not in the domain of | ||
436 | * this function: | ||
437 | */ | ||
438 | return (AE_BAD_PARAMETER); | ||
439 | } | ||
440 | |||
441 | /* Skip over any white space in the buffer: */ | ||
442 | |||
443 | while (isspace((int)*string) || *string == '\t') { | ||
444 | ++string; | ||
445 | } | ||
446 | |||
447 | /* | ||
448 | * The buffer may contain an optional plus or minus sign. | ||
449 | * If it does, then skip over it but remember what is was: | ||
450 | */ | ||
451 | if (*string == '-') { | ||
452 | sign = ACPI_SIGN_NEGATIVE; | ||
453 | ++string; | ||
454 | } else if (*string == '+') { | ||
455 | ++string; | ||
456 | sign = ACPI_SIGN_POSITIVE; | ||
457 | } else { | ||
458 | sign = ACPI_SIGN_POSITIVE; | ||
459 | } | ||
460 | |||
461 | /* | ||
462 | * If the input parameter Base is zero, then we need to | ||
463 | * determine if it is octal, decimal, or hexadecimal: | ||
464 | */ | ||
465 | if (base == 0) { | ||
466 | if (*string == '0') { | ||
467 | if (tolower((int)*(++string)) == 'x') { | ||
468 | base = 16; | ||
469 | ++string; | ||
470 | } else { | ||
471 | base = 8; | ||
472 | } | ||
473 | } else { | ||
474 | base = 10; | ||
475 | } | ||
476 | } | ||
477 | |||
478 | /* | ||
479 | * For octal and hexadecimal bases, skip over the leading | ||
480 | * 0 or 0x, if they are present. | ||
481 | */ | ||
482 | if (base == 8 && *string == '0') { | ||
483 | string++; | ||
484 | } | ||
485 | |||
486 | if (base == 16 && *string == '0' && tolower((int)*(++string)) == 'x') { | ||
487 | string++; | ||
488 | } | ||
489 | |||
490 | /* Main loop: convert the string to an unsigned long */ | ||
491 | |||
492 | while (*string) { | ||
493 | if (isdigit((int)*string)) { | ||
494 | index = ((u8)*string) - '0'; | ||
495 | } else { | ||
496 | index = (u8)toupper((int)*string); | ||
497 | if (isupper((int)index)) { | ||
498 | index = index - 'A' + 10; | ||
499 | } else { | ||
500 | goto error_exit; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | if (index >= base) { | ||
505 | goto error_exit; | ||
506 | } | ||
507 | |||
508 | /* Check to see if value is out of range: */ | ||
509 | |||
510 | if (return_value > ((ACPI_UINT64_MAX - (u64)index) / (u64)base)) { | ||
511 | goto error_exit; | ||
512 | } else { | ||
513 | return_value *= base; | ||
514 | return_value += index; | ||
515 | } | ||
516 | |||
517 | ++string; | ||
518 | } | ||
519 | |||
520 | /* If a minus sign was present, then "the conversion is negated": */ | ||
521 | |||
522 | if (sign == ACPI_SIGN_NEGATIVE) { | ||
523 | return_value = (ACPI_UINT32_MAX - return_value) + 1; | ||
524 | } | ||
525 | |||
526 | *ret_integer = return_value; | ||
527 | return (status); | ||
528 | |||
529 | error_exit: | ||
530 | switch (base) { | ||
531 | case 8: | ||
532 | |||
533 | status = AE_BAD_OCTAL_CONSTANT; | ||
534 | break; | ||
535 | |||
536 | case 10: | ||
537 | |||
538 | status = AE_BAD_DECIMAL_CONSTANT; | ||
539 | break; | ||
540 | |||
541 | case 16: | ||
542 | |||
543 | status = AE_BAD_HEX_CONSTANT; | ||
544 | break; | ||
545 | |||
546 | default: | ||
547 | |||
548 | /* Base validated above */ | ||
549 | |||
550 | break; | ||
551 | } | ||
552 | |||
553 | return (status); | ||
554 | } | ||
555 | #endif | ||
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 3f5fed670271..f0484b058c44 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c | |||
@@ -390,11 +390,22 @@ struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name) | |||
390 | * PARAMETERS: walk_state - Current walk state | 390 | * PARAMETERS: walk_state - Current walk state |
391 | * | 391 | * |
392 | * RETURN: Status | 392 | * RETURN: Status |
393 | * Integer: TRUE (0) if input string is matched | ||
394 | * FALSE (-1) if string is not matched | ||
393 | * | 395 | * |
394 | * DESCRIPTION: Implementation of the _OSI predefined control method. When | 396 | * DESCRIPTION: Implementation of the _OSI predefined control method. When |
395 | * an invocation of _OSI is encountered in the system AML, | 397 | * an invocation of _OSI is encountered in the system AML, |
396 | * control is transferred to this function. | 398 | * control is transferred to this function. |
397 | * | 399 | * |
400 | * (August 2016) | ||
401 | * Note: _OSI is now defined to return "Ones" to indicate a match, for | ||
402 | * compatibility with other ACPI implementations. On a 32-bit DSDT, Ones | ||
403 | * is 0xFFFFFFFF. On a 64-bit DSDT, Ones is 0xFFFFFFFFFFFFFFFF | ||
404 | * (ACPI_UINT64_MAX). | ||
405 | * | ||
406 | * This function always returns ACPI_UINT64_MAX for TRUE, and later code | ||
407 | * will truncate this to 32 bits if necessary. | ||
408 | * | ||
398 | ******************************************************************************/ | 409 | ******************************************************************************/ |
399 | 410 | ||
400 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | 411 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) |
@@ -404,7 +415,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
404 | struct acpi_interface_info *interface_info; | 415 | struct acpi_interface_info *interface_info; |
405 | acpi_interface_handler interface_handler; | 416 | acpi_interface_handler interface_handler; |
406 | acpi_status status; | 417 | acpi_status status; |
407 | u32 return_value; | 418 | u64 return_value; |
408 | 419 | ||
409 | ACPI_FUNCTION_TRACE(ut_osi_implementation); | 420 | ACPI_FUNCTION_TRACE(ut_osi_implementation); |
410 | 421 | ||
@@ -444,7 +455,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
444 | acpi_gbl_osi_data = interface_info->value; | 455 | acpi_gbl_osi_data = interface_info->value; |
445 | } | 456 | } |
446 | 457 | ||
447 | return_value = ACPI_UINT32_MAX; | 458 | return_value = ACPI_UINT64_MAX; |
448 | } | 459 | } |
449 | 460 | ||
450 | acpi_os_release_mutex(acpi_gbl_osi_mutex); | 461 | acpi_os_release_mutex(acpi_gbl_osi_mutex); |
@@ -456,9 +467,10 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
456 | */ | 467 | */ |
457 | interface_handler = acpi_gbl_interface_handler; | 468 | interface_handler = acpi_gbl_interface_handler; |
458 | if (interface_handler) { | 469 | if (interface_handler) { |
459 | return_value = | 470 | if (interface_handler |
460 | interface_handler(string_desc->string.pointer, | 471 | (string_desc->string.pointer, (u32)return_value)) { |
461 | return_value); | 472 | return_value = ACPI_UINT64_MAX; |
473 | } | ||
462 | } | 474 | } |
463 | 475 | ||
464 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, | 476 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, |
diff --git a/drivers/acpi/acpica/utpredef.c b/drivers/acpi/acpica/utpredef.c index 770a1775b264..ce18346b6144 100644 --- a/drivers/acpi/acpica/utpredef.c +++ b/drivers/acpi/acpica/utpredef.c | |||
@@ -176,8 +176,6 @@ void acpi_ut_get_expected_return_types(char *buffer, u32 expected_btypes) | |||
176 | ******************************************************************************/ | 176 | ******************************************************************************/ |
177 | 177 | ||
178 | #if (defined ACPI_ASL_COMPILER || defined ACPI_HELP_APP) | 178 | #if (defined ACPI_ASL_COMPILER || defined ACPI_HELP_APP) |
179 | #include <stdio.h> | ||
180 | #include <string.h> | ||
181 | 179 | ||
182 | /* Local prototypes */ | 180 | /* Local prototypes */ |
183 | 181 | ||
diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index dd084cf52502..40eba804d49c 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c | |||
@@ -336,7 +336,7 @@ static char *acpi_ut_format_number(char *string, | |||
336 | 336 | ||
337 | /******************************************************************************* | 337 | /******************************************************************************* |
338 | * | 338 | * |
339 | * FUNCTION: acpi_ut_vsnprintf | 339 | * FUNCTION: vsnprintf |
340 | * | 340 | * |
341 | * PARAMETERS: string - String with boundary | 341 | * PARAMETERS: string - String with boundary |
342 | * size - Boundary of the string | 342 | * size - Boundary of the string |
@@ -349,9 +349,7 @@ static char *acpi_ut_format_number(char *string, | |||
349 | * | 349 | * |
350 | ******************************************************************************/ | 350 | ******************************************************************************/ |
351 | 351 | ||
352 | int | 352 | int vsnprintf(char *string, acpi_size size, const char *format, va_list args) |
353 | acpi_ut_vsnprintf(char *string, | ||
354 | acpi_size size, const char *format, va_list args) | ||
355 | { | 353 | { |
356 | u8 base; | 354 | u8 base; |
357 | u8 type; | 355 | u8 type; |
@@ -586,7 +584,7 @@ acpi_ut_vsnprintf(char *string, | |||
586 | 584 | ||
587 | /******************************************************************************* | 585 | /******************************************************************************* |
588 | * | 586 | * |
589 | * FUNCTION: acpi_ut_snprintf | 587 | * FUNCTION: snprintf |
590 | * | 588 | * |
591 | * PARAMETERS: string - String with boundary | 589 | * PARAMETERS: string - String with boundary |
592 | * size - Boundary of the string | 590 | * size - Boundary of the string |
@@ -598,13 +596,38 @@ acpi_ut_vsnprintf(char *string, | |||
598 | * | 596 | * |
599 | ******************************************************************************/ | 597 | ******************************************************************************/ |
600 | 598 | ||
601 | int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...) | 599 | int snprintf(char *string, acpi_size size, const char *format, ...) |
602 | { | 600 | { |
603 | va_list args; | 601 | va_list args; |
604 | int length; | 602 | int length; |
605 | 603 | ||
606 | va_start(args, format); | 604 | va_start(args, format); |
607 | length = acpi_ut_vsnprintf(string, size, format, args); | 605 | length = vsnprintf(string, size, format, args); |
606 | va_end(args); | ||
607 | |||
608 | return (length); | ||
609 | } | ||
610 | |||
611 | /******************************************************************************* | ||
612 | * | ||
613 | * FUNCTION: sprintf | ||
614 | * | ||
615 | * PARAMETERS: string - String with boundary | ||
616 | * Format, ... - Standard printf format | ||
617 | * | ||
618 | * RETURN: Number of bytes actually written. | ||
619 | * | ||
620 | * DESCRIPTION: Formatted output to a string. | ||
621 | * | ||
622 | ******************************************************************************/ | ||
623 | |||
624 | int sprintf(char *string, const char *format, ...) | ||
625 | { | ||
626 | va_list args; | ||
627 | int length; | ||
628 | |||
629 | va_start(args, format); | ||
630 | length = vsnprintf(string, ACPI_UINT32_MAX, format, args); | ||
608 | va_end(args); | 631 | va_end(args); |
609 | 632 | ||
610 | return (length); | 633 | return (length); |
@@ -613,7 +636,59 @@ int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...) | |||
613 | #ifdef ACPI_APPLICATION | 636 | #ifdef ACPI_APPLICATION |
614 | /******************************************************************************* | 637 | /******************************************************************************* |
615 | * | 638 | * |
616 | * FUNCTION: acpi_ut_file_vprintf | 639 | * FUNCTION: vprintf |
640 | * | ||
641 | * PARAMETERS: format - Standard printf format | ||
642 | * args - Argument list | ||
643 | * | ||
644 | * RETURN: Number of bytes actually written. | ||
645 | * | ||
646 | * DESCRIPTION: Formatted output to stdout using argument list pointer. | ||
647 | * | ||
648 | ******************************************************************************/ | ||
649 | |||
650 | int vprintf(const char *format, va_list args) | ||
651 | { | ||
652 | acpi_cpu_flags flags; | ||
653 | int length; | ||
654 | |||
655 | flags = acpi_os_acquire_lock(acpi_gbl_print_lock); | ||
656 | length = vsnprintf(acpi_gbl_print_buffer, | ||
657 | sizeof(acpi_gbl_print_buffer), format, args); | ||
658 | |||
659 | (void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT); | ||
660 | acpi_os_release_lock(acpi_gbl_print_lock, flags); | ||
661 | |||
662 | return (length); | ||
663 | } | ||
664 | |||
665 | /******************************************************************************* | ||
666 | * | ||
667 | * FUNCTION: printf | ||
668 | * | ||
669 | * PARAMETERS: Format, ... - Standard printf format | ||
670 | * | ||
671 | * RETURN: Number of bytes actually written. | ||
672 | * | ||
673 | * DESCRIPTION: Formatted output to stdout. | ||
674 | * | ||
675 | ******************************************************************************/ | ||
676 | |||
677 | int printf(const char *format, ...) | ||
678 | { | ||
679 | va_list args; | ||
680 | int length; | ||
681 | |||
682 | va_start(args, format); | ||
683 | length = vprintf(format, args); | ||
684 | va_end(args); | ||
685 | |||
686 | return (length); | ||
687 | } | ||
688 | |||
689 | /******************************************************************************* | ||
690 | * | ||
691 | * FUNCTION: vfprintf | ||
617 | * | 692 | * |
618 | * PARAMETERS: file - File descriptor | 693 | * PARAMETERS: file - File descriptor |
619 | * format - Standard printf format | 694 | * format - Standard printf format |
@@ -625,16 +700,16 @@ int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...) | |||
625 | * | 700 | * |
626 | ******************************************************************************/ | 701 | ******************************************************************************/ |
627 | 702 | ||
628 | int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args) | 703 | int vfprintf(FILE * file, const char *format, va_list args) |
629 | { | 704 | { |
630 | acpi_cpu_flags flags; | 705 | acpi_cpu_flags flags; |
631 | int length; | 706 | int length; |
632 | 707 | ||
633 | flags = acpi_os_acquire_lock(acpi_gbl_print_lock); | 708 | flags = acpi_os_acquire_lock(acpi_gbl_print_lock); |
634 | length = acpi_ut_vsnprintf(acpi_gbl_print_buffer, | 709 | length = vsnprintf(acpi_gbl_print_buffer, |
635 | sizeof(acpi_gbl_print_buffer), format, args); | 710 | sizeof(acpi_gbl_print_buffer), format, args); |
636 | 711 | ||
637 | (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1); | 712 | (void)fwrite(acpi_gbl_print_buffer, length, 1, file); |
638 | acpi_os_release_lock(acpi_gbl_print_lock, flags); | 713 | acpi_os_release_lock(acpi_gbl_print_lock, flags); |
639 | 714 | ||
640 | return (length); | 715 | return (length); |
@@ -642,7 +717,7 @@ int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args) | |||
642 | 717 | ||
643 | /******************************************************************************* | 718 | /******************************************************************************* |
644 | * | 719 | * |
645 | * FUNCTION: acpi_ut_file_printf | 720 | * FUNCTION: fprintf |
646 | * | 721 | * |
647 | * PARAMETERS: file - File descriptor | 722 | * PARAMETERS: file - File descriptor |
648 | * Format, ... - Standard printf format | 723 | * Format, ... - Standard printf format |
@@ -653,13 +728,13 @@ int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args) | |||
653 | * | 728 | * |
654 | ******************************************************************************/ | 729 | ******************************************************************************/ |
655 | 730 | ||
656 | int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...) | 731 | int fprintf(FILE * file, const char *format, ...) |
657 | { | 732 | { |
658 | va_list args; | 733 | va_list args; |
659 | int length; | 734 | int length; |
660 | 735 | ||
661 | va_start(args, format); | 736 | va_start(args, format); |
662 | length = acpi_ut_file_vprintf(file, format, args); | 737 | length = vfprintf(file, format, args); |
663 | va_end(args); | 738 | va_end(args); |
664 | 739 | ||
665 | return (length); | 740 | return (length); |
diff --git a/drivers/acpi/acpica/utstrtoul64.c b/drivers/acpi/acpica/utstrtoul64.c new file mode 100644 index 000000000000..b4f341c98a95 --- /dev/null +++ b/drivers/acpi/acpica/utstrtoul64.c | |||
@@ -0,0 +1,348 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utstrtoul64 - string to 64-bit integer support | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2016, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | |||
47 | /******************************************************************************* | ||
48 | * | ||
49 | * The functions in this module satisfy the need for 64-bit string-to-integer | ||
50 | * conversions on both 32-bit and 64-bit platforms. | ||
51 | * | ||
52 | ******************************************************************************/ | ||
53 | |||
54 | #define _COMPONENT ACPI_UTILITIES | ||
55 | ACPI_MODULE_NAME("utstrtoul64") | ||
56 | |||
57 | /* Local prototypes */ | ||
58 | static u64 acpi_ut_strtoul_base10(char *string, u32 flags); | ||
59 | |||
60 | static u64 acpi_ut_strtoul_base16(char *string, u32 flags); | ||
61 | |||
62 | /******************************************************************************* | ||
63 | * | ||
64 | * String conversion rules as written in the ACPI specification. The error | ||
65 | * conditions and behavior are different depending on the type of conversion. | ||
66 | * | ||
67 | * | ||
68 | * Implicit data type conversion: string-to-integer | ||
69 | * -------------------------------------------------- | ||
70 | * | ||
71 | * Base is always 16. This is the ACPI_STRTOUL_BASE16 case. | ||
72 | * | ||
73 | * Example: | ||
74 | * Add ("BA98", Arg0, Local0) | ||
75 | * | ||
76 | * The integer is initialized to the value zero. | ||
77 | * The ASCII string is interpreted as a hexadecimal constant. | ||
78 | * | ||
79 | * 1) A "0x" prefix is not allowed. However, ACPICA allows this for | ||
80 | * compatibility with previous ACPICA. (NO ERROR) | ||
81 | * | ||
82 | * 2) Terminates when the size of an integer is reached (32 or 64 bits). | ||
83 | * (NO ERROR) | ||
84 | * | ||
85 | * 3) The first non-hex character terminates the conversion without error. | ||
86 | * (NO ERROR) | ||
87 | * | ||
88 | * 4) Conversion of a null (zero-length) string to an integer is not | ||
89 | * allowed. However, ACPICA allows this for compatibility with previous | ||
90 | * ACPICA. This conversion returns the value 0. (NO ERROR) | ||
91 | * | ||
92 | * | ||
93 | * Explicit data type conversion: to_integer() with string operand | ||
94 | * --------------------------------------------------------------- | ||
95 | * | ||
96 | * Base is either 10 (default) or 16 (with 0x prefix) | ||
97 | * | ||
98 | * Examples: | ||
99 | * to_integer ("1000") | ||
100 | * to_integer ("0xABCD") | ||
101 | * | ||
102 | * 1) Can be (must be) either a decimal or hexadecimal numeric string. | ||
103 | * A hex value must be prefixed by "0x" or it is interpreted as a decimal. | ||
104 | * | ||
105 | * 2) The value must not exceed the maximum of an integer value. ACPI spec | ||
106 | * states the behavior is "unpredictable", so ACPICA matches the behavior | ||
107 | * of the implicit conversion case.(NO ERROR) | ||
108 | * | ||
109 | * 3) Behavior on the first non-hex character is not specified by the ACPI | ||
110 | * spec, so ACPICA matches the behavior of the implicit conversion case | ||
111 | * and terminates. (NO ERROR) | ||
112 | * | ||
113 | * 4) A null (zero-length) string is illegal. | ||
114 | * However, ACPICA allows this for compatibility with previous ACPICA. | ||
115 | * This conversion returns the value 0. (NO ERROR) | ||
116 | * | ||
117 | ******************************************************************************/ | ||
118 | |||
119 | /******************************************************************************* | ||
120 | * | ||
121 | * FUNCTION: acpi_ut_strtoul64 | ||
122 | * | ||
123 | * PARAMETERS: string - Null terminated input string | ||
124 | * flags - Conversion info, see below | ||
125 | * return_value - Where the converted integer is | ||
126 | * returned | ||
127 | * | ||
128 | * RETURN: Status and Converted value | ||
129 | * | ||
130 | * DESCRIPTION: Convert a string into an unsigned value. Performs either a | ||
131 | * 32-bit or 64-bit conversion, depending on the input integer | ||
132 | * size in Flags (often the current mode of the interpreter). | ||
133 | * | ||
134 | * Values for Flags: | ||
135 | * ACPI_STRTOUL_32BIT - Max integer value is 32 bits | ||
136 | * ACPI_STRTOUL_64BIT - Max integer value is 64 bits | ||
137 | * ACPI_STRTOUL_BASE16 - Input string is hexadecimal. Default | ||
138 | * is 10/16 based on string prefix (0x). | ||
139 | * | ||
140 | * NOTES: | ||
141 | * Negative numbers are not supported, as they are not supported by ACPI. | ||
142 | * | ||
143 | * Supports only base 16 or base 10 strings/values. Does not | ||
144 | * support Octal strings, as these are not supported by ACPI. | ||
145 | * | ||
146 | * Current users of this support: | ||
147 | * | ||
148 | * interpreter - Implicit and explicit conversions, GPE method names | ||
149 | * debugger - Command line input string conversion | ||
150 | * iASL - Main parser, conversion of constants to integers | ||
151 | * iASL - Data Table Compiler parser (constant math expressions) | ||
152 | * iASL - Preprocessor (constant math expressions) | ||
153 | * acpi_dump - Input table addresses | ||
154 | * acpi_exec - Testing of the acpi_ut_strtoul64 function | ||
155 | * | ||
156 | * Note concerning callers: | ||
157 | * acpi_gbl_integer_byte_width can be used to set the 32/64 limit. If used, | ||
158 | * this global should be set to the proper width. For the core ACPICA code, | ||
159 | * this width depends on the DSDT version. For iASL, the default byte | ||
160 | * width is always 8 for the parser, but error checking is performed later | ||
161 | * to flag cases where a 64-bit constant is defined in a 32-bit DSDT/SSDT. | ||
162 | * | ||
163 | ******************************************************************************/ | ||
164 | |||
165 | acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *return_value) | ||
166 | { | ||
167 | acpi_status status = AE_OK; | ||
168 | u32 base; | ||
169 | |||
170 | ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string); | ||
171 | |||
172 | /* Parameter validation */ | ||
173 | |||
174 | if (!string || !return_value) { | ||
175 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
176 | } | ||
177 | |||
178 | *return_value = 0; | ||
179 | |||
180 | /* Check for zero-length string, returns 0 */ | ||
181 | |||
182 | if (*string == 0) { | ||
183 | return_ACPI_STATUS(AE_OK); | ||
184 | } | ||
185 | |||
186 | /* Skip over any white space at start of string */ | ||
187 | |||
188 | while (isspace((int)*string)) { | ||
189 | string++; | ||
190 | } | ||
191 | |||
192 | /* End of string? return 0 */ | ||
193 | |||
194 | if (*string == 0) { | ||
195 | return_ACPI_STATUS(AE_OK); | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * 1) The "0x" prefix indicates base 16. Per the ACPI specification, | ||
200 | * the "0x" prefix is only allowed for implicit (non-strict) conversions. | ||
201 | * However, we always allow it for compatibility with older ACPICA. | ||
202 | */ | ||
203 | if ((*string == ACPI_ASCII_ZERO) && | ||
204 | (tolower((int)*(string + 1)) == 'x')) { | ||
205 | string += 2; /* Go past the 0x */ | ||
206 | if (*string == 0) { | ||
207 | return_ACPI_STATUS(AE_OK); /* Return value 0 */ | ||
208 | } | ||
209 | |||
210 | base = 16; | ||
211 | } | ||
212 | |||
213 | /* 2) Force to base 16 (implicit conversion case) */ | ||
214 | |||
215 | else if (flags & ACPI_STRTOUL_BASE16) { | ||
216 | base = 16; | ||
217 | } | ||
218 | |||
219 | /* 3) Default fallback is to Base 10 */ | ||
220 | |||
221 | else { | ||
222 | base = 10; | ||
223 | } | ||
224 | |||
225 | /* Skip all leading zeros */ | ||
226 | |||
227 | while (*string == ACPI_ASCII_ZERO) { | ||
228 | string++; | ||
229 | if (*string == 0) { | ||
230 | return_ACPI_STATUS(AE_OK); /* Return value 0 */ | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /* Perform the base 16 or 10 conversion */ | ||
235 | |||
236 | if (base == 16) { | ||
237 | *return_value = acpi_ut_strtoul_base16(string, flags); | ||
238 | } else { | ||
239 | *return_value = acpi_ut_strtoul_base10(string, flags); | ||
240 | } | ||
241 | |||
242 | return_ACPI_STATUS(status); | ||
243 | } | ||
244 | |||
245 | /******************************************************************************* | ||
246 | * | ||
247 | * FUNCTION: acpi_ut_strtoul_base10 | ||
248 | * | ||
249 | * PARAMETERS: string - Null terminated input string | ||
250 | * flags - Conversion info | ||
251 | * | ||
252 | * RETURN: 64-bit converted integer | ||
253 | * | ||
254 | * DESCRIPTION: Performs a base 10 conversion of the input string to an | ||
255 | * integer value, either 32 or 64 bits. | ||
256 | * Note: String must be valid and non-null. | ||
257 | * | ||
258 | ******************************************************************************/ | ||
259 | |||
260 | static u64 acpi_ut_strtoul_base10(char *string, u32 flags) | ||
261 | { | ||
262 | int ascii_digit; | ||
263 | u64 next_value; | ||
264 | u64 return_value = 0; | ||
265 | |||
266 | /* Main loop: convert each ASCII byte in the input string */ | ||
267 | |||
268 | while (*string) { | ||
269 | ascii_digit = *string; | ||
270 | if (!isdigit(ascii_digit)) { | ||
271 | |||
272 | /* Not ASCII 0-9, terminate */ | ||
273 | |||
274 | goto exit; | ||
275 | } | ||
276 | |||
277 | /* Convert and insert (add) the decimal digit */ | ||
278 | |||
279 | next_value = | ||
280 | (return_value * 10) + (ascii_digit - ACPI_ASCII_ZERO); | ||
281 | |||
282 | /* Check for overflow (32 or 64 bit) - return current converted value */ | ||
283 | |||
284 | if (((flags & ACPI_STRTOUL_32BIT) && (next_value > ACPI_UINT32_MAX)) || (next_value < return_value)) { /* 64-bit overflow case */ | ||
285 | goto exit; | ||
286 | } | ||
287 | |||
288 | return_value = next_value; | ||
289 | string++; | ||
290 | } | ||
291 | |||
292 | exit: | ||
293 | return (return_value); | ||
294 | } | ||
295 | |||
296 | /******************************************************************************* | ||
297 | * | ||
298 | * FUNCTION: acpi_ut_strtoul_base16 | ||
299 | * | ||
300 | * PARAMETERS: string - Null terminated input string | ||
301 | * flags - conversion info | ||
302 | * | ||
303 | * RETURN: 64-bit converted integer | ||
304 | * | ||
305 | * DESCRIPTION: Performs a base 16 conversion of the input string to an | ||
306 | * integer value, either 32 or 64 bits. | ||
307 | * Note: String must be valid and non-null. | ||
308 | * | ||
309 | ******************************************************************************/ | ||
310 | |||
311 | static u64 acpi_ut_strtoul_base16(char *string, u32 flags) | ||
312 | { | ||
313 | int ascii_digit; | ||
314 | u32 valid_digits = 1; | ||
315 | u64 return_value = 0; | ||
316 | |||
317 | /* Main loop: convert each ASCII byte in the input string */ | ||
318 | |||
319 | while (*string) { | ||
320 | |||
321 | /* Check for overflow (32 or 64 bit) - return current converted value */ | ||
322 | |||
323 | if ((valid_digits > 16) || | ||
324 | ((valid_digits > 8) && (flags & ACPI_STRTOUL_32BIT))) { | ||
325 | goto exit; | ||
326 | } | ||
327 | |||
328 | ascii_digit = *string; | ||
329 | if (!isxdigit(ascii_digit)) { | ||
330 | |||
331 | /* Not Hex ASCII A-F, a-f, or 0-9, terminate */ | ||
332 | |||
333 | goto exit; | ||
334 | } | ||
335 | |||
336 | /* Convert and insert the hex digit */ | ||
337 | |||
338 | return_value = | ||
339 | (return_value << 4) | | ||
340 | acpi_ut_ascii_char_to_hex(ascii_digit); | ||
341 | |||
342 | string++; | ||
343 | valid_digits++; | ||
344 | } | ||
345 | |||
346 | exit: | ||
347 | return (return_value); | ||
348 | } | ||
diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c index 0df07dfa53b6..df31d71ce596 100644 --- a/drivers/acpi/acpica/uttrack.c +++ b/drivers/acpi/acpica/uttrack.c | |||
@@ -95,13 +95,11 @@ acpi_ut_create_list(const char *list_name, | |||
95 | { | 95 | { |
96 | struct acpi_memory_list *cache; | 96 | struct acpi_memory_list *cache; |
97 | 97 | ||
98 | cache = acpi_os_allocate(sizeof(struct acpi_memory_list)); | 98 | cache = acpi_os_allocate_zeroed(sizeof(struct acpi_memory_list)); |
99 | if (!cache) { | 99 | if (!cache) { |
100 | return (AE_NO_MEMORY); | 100 | return (AE_NO_MEMORY); |
101 | } | 101 | } |
102 | 102 | ||
103 | memset(cache, 0, sizeof(struct acpi_memory_list)); | ||
104 | |||
105 | cache->list_name = list_name; | 103 | cache->list_name = list_name; |
106 | cache->object_size = object_size; | 104 | cache->object_size = object_size; |
107 | 105 | ||
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index d9e6aac7dc83..ec503c862961 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -61,7 +61,7 @@ ACPI_MODULE_NAME("utxface") | |||
61 | * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. | 61 | * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. |
62 | * | 62 | * |
63 | ******************************************************************************/ | 63 | ******************************************************************************/ |
64 | acpi_status __init acpi_terminate(void) | 64 | acpi_status ACPI_INIT_FUNCTION acpi_terminate(void) |
65 | { | 65 | { |
66 | acpi_status status; | 66 | acpi_status status; |
67 | 67 | ||
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 75b5f27da267..a5ca0f57cd08 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c | |||
@@ -69,7 +69,7 @@ void ae_do_object_overrides(void); | |||
69 | * | 69 | * |
70 | ******************************************************************************/ | 70 | ******************************************************************************/ |
71 | 71 | ||
72 | acpi_status __init acpi_initialize_subsystem(void) | 72 | acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void) |
73 | { | 73 | { |
74 | acpi_status status; | 74 | acpi_status status; |
75 | 75 | ||
@@ -141,7 +141,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_subsystem) | |||
141 | * Puts system into ACPI mode if it isn't already. | 141 | * Puts system into ACPI mode if it isn't already. |
142 | * | 142 | * |
143 | ******************************************************************************/ | 143 | ******************************************************************************/ |
144 | acpi_status __init acpi_enable_subsystem(u32 flags) | 144 | acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags) |
145 | { | 145 | { |
146 | acpi_status status = AE_OK; | 146 | acpi_status status = AE_OK; |
147 | 147 | ||
@@ -239,7 +239,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_enable_subsystem) | |||
239 | * objects and executing AML code for Regions, buffers, etc. | 239 | * objects and executing AML code for Regions, buffers, etc. |
240 | * | 240 | * |
241 | ******************************************************************************/ | 241 | ******************************************************************************/ |
242 | acpi_status __init acpi_initialize_objects(u32 flags) | 242 | acpi_status ACPI_INIT_FUNCTION acpi_initialize_objects(u32 flags) |
243 | { | 243 | { |
244 | acpi_status status = AE_OK; | 244 | acpi_status status = AE_OK; |
245 | 245 | ||
@@ -265,7 +265,8 @@ acpi_status __init acpi_initialize_objects(u32 flags) | |||
265 | * all of the tables have been loaded. It is a legacy option and is | 265 | * all of the tables have been loaded. It is a legacy option and is |
266 | * not compatible with other ACPI implementations. See acpi_ns_load_table. | 266 | * not compatible with other ACPI implementations. See acpi_ns_load_table. |
267 | */ | 267 | */ |
268 | if (acpi_gbl_group_module_level_code) { | 268 | if (!acpi_gbl_parse_table_as_term_list |
269 | && acpi_gbl_group_module_level_code) { | ||
269 | acpi_ns_exec_module_code_list(); | 270 | acpi_ns_exec_module_code_list(); |
270 | 271 | ||
271 | /* | 272 | /* |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index ab234791a0ba..93ecae55fe6a 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -733,15 +733,17 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) | |||
733 | return result; | 733 | return result; |
734 | acpi_battery_init_alarm(battery); | 734 | acpi_battery_init_alarm(battery); |
735 | } | 735 | } |
736 | |||
737 | result = acpi_battery_get_state(battery); | ||
738 | if (result) | ||
739 | return result; | ||
740 | acpi_battery_quirks(battery); | ||
741 | |||
736 | if (!battery->bat) { | 742 | if (!battery->bat) { |
737 | result = sysfs_add_battery(battery); | 743 | result = sysfs_add_battery(battery); |
738 | if (result) | 744 | if (result) |
739 | return result; | 745 | return result; |
740 | } | 746 | } |
741 | result = acpi_battery_get_state(battery); | ||
742 | if (result) | ||
743 | return result; | ||
744 | acpi_battery_quirks(battery); | ||
745 | 747 | ||
746 | /* | 748 | /* |
747 | * Wakeup the system if battery is critical low | 749 | * Wakeup the system if battery is critical low |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 85b7d07fe5c8..658b4c4f169f 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -985,7 +985,8 @@ void __init acpi_early_init(void) | |||
985 | goto error0; | 985 | goto error0; |
986 | } | 986 | } |
987 | 987 | ||
988 | if (acpi_gbl_group_module_level_code) { | 988 | if (!acpi_gbl_parse_table_as_term_list && |
989 | acpi_gbl_group_module_level_code) { | ||
989 | status = acpi_load_tables(); | 990 | status = acpi_load_tables(); |
990 | if (ACPI_FAILURE(status)) { | 991 | if (ACPI_FAILURE(status)) { |
991 | printk(KERN_ERR PREFIX | 992 | printk(KERN_ERR PREFIX |
@@ -1074,7 +1075,8 @@ static int __init acpi_bus_init(void) | |||
1074 | status = acpi_ec_ecdt_probe(); | 1075 | status = acpi_ec_ecdt_probe(); |
1075 | /* Ignore result. Not having an ECDT is not fatal. */ | 1076 | /* Ignore result. Not having an ECDT is not fatal. */ |
1076 | 1077 | ||
1077 | if (!acpi_gbl_group_module_level_code) { | 1078 | if (acpi_gbl_parse_table_as_term_list || |
1079 | !acpi_gbl_group_module_level_code) { | ||
1078 | status = acpi_load_tables(); | 1080 | status = acpi_load_tables(); |
1079 | if (ACPI_FAILURE(status)) { | 1081 | if (ACPI_FAILURE(status)) { |
1080 | printk(KERN_ERR PREFIX | 1082 | printk(KERN_ERR PREFIX |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 31abb0bdd4f2..e19f530f1083 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) "ACPI : button: " fmt | ||
23 | |||
22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
24 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -104,6 +106,8 @@ struct acpi_button { | |||
104 | struct input_dev *input; | 106 | struct input_dev *input; |
105 | char phys[32]; /* for input device */ | 107 | char phys[32]; /* for input device */ |
106 | unsigned long pushed; | 108 | unsigned long pushed; |
109 | int last_state; | ||
110 | ktime_t last_time; | ||
107 | bool suspended; | 111 | bool suspended; |
108 | }; | 112 | }; |
109 | 113 | ||
@@ -111,6 +115,10 @@ static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); | |||
111 | static struct acpi_device *lid_device; | 115 | static struct acpi_device *lid_device; |
112 | static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; | 116 | static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; |
113 | 117 | ||
118 | static unsigned long lid_report_interval __read_mostly = 500; | ||
119 | module_param(lid_report_interval, ulong, 0644); | ||
120 | MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events"); | ||
121 | |||
114 | /* -------------------------------------------------------------------------- | 122 | /* -------------------------------------------------------------------------- |
115 | FS Interface (/proc) | 123 | FS Interface (/proc) |
116 | -------------------------------------------------------------------------- */ | 124 | -------------------------------------------------------------------------- */ |
@@ -134,10 +142,79 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) | |||
134 | { | 142 | { |
135 | struct acpi_button *button = acpi_driver_data(device); | 143 | struct acpi_button *button = acpi_driver_data(device); |
136 | int ret; | 144 | int ret; |
145 | ktime_t next_report; | ||
146 | bool do_update; | ||
147 | |||
148 | /* | ||
149 | * In lid_init_state=ignore mode, if user opens/closes lid | ||
150 | * frequently with "open" missing, and "last_time" is also updated | ||
151 | * frequently, "close" cannot be delivered to the userspace. | ||
152 | * So "last_time" is only updated after a timeout or an actual | ||
153 | * switch. | ||
154 | */ | ||
155 | if (lid_init_state != ACPI_BUTTON_LID_INIT_IGNORE || | ||
156 | button->last_state != !!state) | ||
157 | do_update = true; | ||
158 | else | ||
159 | do_update = false; | ||
160 | |||
161 | next_report = ktime_add(button->last_time, | ||
162 | ms_to_ktime(lid_report_interval)); | ||
163 | if (button->last_state == !!state && | ||
164 | ktime_after(ktime_get(), next_report)) { | ||
165 | /* Complain the buggy firmware */ | ||
166 | pr_warn_once("The lid device is not compliant to SW_LID.\n"); | ||
137 | 167 | ||
138 | /* input layer checks if event is redundant */ | 168 | /* |
139 | input_report_switch(button->input, SW_LID, !state); | 169 | * Send the unreliable complement switch event: |
140 | input_sync(button->input); | 170 | * |
171 | * On most platforms, the lid device is reliable. However | ||
172 | * there are exceptions: | ||
173 | * 1. Platforms returning initial lid state as "close" by | ||
174 | * default after booting/resuming: | ||
175 | * https://bugzilla.kernel.org/show_bug.cgi?id=89211 | ||
176 | * https://bugzilla.kernel.org/show_bug.cgi?id=106151 | ||
177 | * 2. Platforms never reporting "open" events: | ||
178 | * https://bugzilla.kernel.org/show_bug.cgi?id=106941 | ||
179 | * On these buggy platforms, the usage model of the ACPI | ||
180 | * lid device actually is: | ||
181 | * 1. The initial returning value of _LID may not be | ||
182 | * reliable. | ||
183 | * 2. The open event may not be reliable. | ||
184 | * 3. The close event is reliable. | ||
185 | * | ||
186 | * But SW_LID is typed as input switch event, the input | ||
187 | * layer checks if the event is redundant. Hence if the | ||
188 | * state is not switched, the userspace cannot see this | ||
189 | * platform triggered reliable event. By inserting a | ||
190 | * complement switch event, it then is guaranteed that the | ||
191 | * platform triggered reliable one can always be seen by | ||
192 | * the userspace. | ||
193 | */ | ||
194 | if (lid_init_state == ACPI_BUTTON_LID_INIT_IGNORE) { | ||
195 | do_update = true; | ||
196 | /* | ||
197 | * Do generate complement switch event for "close" | ||
198 | * as "close" is reliable and wrong "open" won't | ||
199 | * trigger unexpected behaviors. | ||
200 | * Do not generate complement switch event for | ||
201 | * "open" as "open" is not reliable and wrong | ||
202 | * "close" will trigger unexpected behaviors. | ||
203 | */ | ||
204 | if (!state) { | ||
205 | input_report_switch(button->input, | ||
206 | SW_LID, state); | ||
207 | input_sync(button->input); | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | /* Send the platform triggered reliable event */ | ||
212 | if (do_update) { | ||
213 | input_report_switch(button->input, SW_LID, !state); | ||
214 | input_sync(button->input); | ||
215 | button->last_state = !!state; | ||
216 | button->last_time = ktime_get(); | ||
217 | } | ||
141 | 218 | ||
142 | if (state) | 219 | if (state) |
143 | pm_wakeup_event(&device->dev, 0); | 220 | pm_wakeup_event(&device->dev, 0); |
@@ -411,6 +488,8 @@ static int acpi_button_add(struct acpi_device *device) | |||
411 | strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID); | 488 | strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID); |
412 | sprintf(class, "%s/%s", | 489 | sprintf(class, "%s/%s", |
413 | ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); | 490 | ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); |
491 | button->last_state = !!acpi_lid_evaluate_state(device); | ||
492 | button->last_time = ktime_get(); | ||
414 | } else { | 493 | } else { |
415 | printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); | 494 | printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); |
416 | error = -ENODEV; | 495 | error = -ENODEV; |
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 2e981732805b..d0d0504b7c89 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c | |||
@@ -40,15 +40,48 @@ | |||
40 | #include <linux/cpufreq.h> | 40 | #include <linux/cpufreq.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/ktime.h> | 42 | #include <linux/ktime.h> |
43 | #include <linux/rwsem.h> | ||
44 | #include <linux/wait.h> | ||
43 | 45 | ||
44 | #include <acpi/cppc_acpi.h> | 46 | #include <acpi/cppc_acpi.h> |
45 | /* | 47 | |
46 | * Lock to provide mutually exclusive access to the PCC | 48 | struct cppc_pcc_data { |
47 | * channel. e.g. When the remote updates the shared region | 49 | struct mbox_chan *pcc_channel; |
48 | * with new data, the reader needs to be protected from | 50 | void __iomem *pcc_comm_addr; |
49 | * other CPUs activity on the same channel. | 51 | int pcc_subspace_idx; |
50 | */ | 52 | bool pcc_channel_acquired; |
51 | static DEFINE_SPINLOCK(pcc_lock); | 53 | ktime_t deadline; |
54 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; | ||
55 | |||
56 | bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ | ||
57 | bool platform_owns_pcc; /* Ownership of PCC subspace */ | ||
58 | unsigned int pcc_write_cnt; /* Running count of PCC write commands */ | ||
59 | |||
60 | /* | ||
61 | * Lock to provide controlled access to the PCC channel. | ||
62 | * | ||
63 | * For performance critical usecases(currently cppc_set_perf) | ||
64 | * We need to take read_lock and check if channel belongs to OSPM | ||
65 | * before reading or writing to PCC subspace | ||
66 | * We need to take write_lock before transferring the channel | ||
67 | * ownership to the platform via a Doorbell | ||
68 | * This allows us to batch a number of CPPC requests if they happen | ||
69 | * to originate in about the same time | ||
70 | * | ||
71 | * For non-performance critical usecases(init) | ||
72 | * Take write_lock for all purposes which gives exclusive access | ||
73 | */ | ||
74 | struct rw_semaphore pcc_lock; | ||
75 | |||
76 | /* Wait queue for CPUs whose requests were batched */ | ||
77 | wait_queue_head_t pcc_write_wait_q; | ||
78 | }; | ||
79 | |||
80 | /* Structure to represent the single PCC channel */ | ||
81 | static struct cppc_pcc_data pcc_data = { | ||
82 | .pcc_subspace_idx = -1, | ||
83 | .platform_owns_pcc = true, | ||
84 | }; | ||
52 | 85 | ||
53 | /* | 86 | /* |
54 | * The cpc_desc structure contains the ACPI register details | 87 | * The cpc_desc structure contains the ACPI register details |
@@ -59,18 +92,25 @@ static DEFINE_SPINLOCK(pcc_lock); | |||
59 | */ | 92 | */ |
60 | static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); | 93 | static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); |
61 | 94 | ||
62 | /* This layer handles all the PCC specifics for CPPC. */ | ||
63 | static struct mbox_chan *pcc_channel; | ||
64 | static void __iomem *pcc_comm_addr; | ||
65 | static u64 comm_base_addr; | ||
66 | static int pcc_subspace_idx = -1; | ||
67 | static bool pcc_channel_acquired; | ||
68 | static ktime_t deadline; | ||
69 | static unsigned int pcc_mpar, pcc_mrtt; | ||
70 | |||
71 | /* pcc mapped address + header size + offset within PCC subspace */ | 95 | /* pcc mapped address + header size + offset within PCC subspace */ |
72 | #define GET_PCC_VADDR(offs) (pcc_comm_addr + 0x8 + (offs)) | 96 | #define GET_PCC_VADDR(offs) (pcc_data.pcc_comm_addr + 0x8 + (offs)) |
73 | 97 | ||
98 | /* Check if a CPC regsiter is in PCC */ | ||
99 | #define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \ | ||
100 | (cpc)->cpc_entry.reg.space_id == \ | ||
101 | ACPI_ADR_SPACE_PLATFORM_COMM) | ||
102 | |||
103 | /* Evalutes to True if reg is a NULL register descriptor */ | ||
104 | #define IS_NULL_REG(reg) ((reg)->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && \ | ||
105 | (reg)->address == 0 && \ | ||
106 | (reg)->bit_width == 0 && \ | ||
107 | (reg)->bit_offset == 0 && \ | ||
108 | (reg)->access_width == 0) | ||
109 | |||
110 | /* Evalutes to True if an optional cpc field is supported */ | ||
111 | #define CPC_SUPPORTED(cpc) ((cpc)->type == ACPI_TYPE_INTEGER ? \ | ||
112 | !!(cpc)->cpc_entry.int_value : \ | ||
113 | !IS_NULL_REG(&(cpc)->cpc_entry.reg)) | ||
74 | /* | 114 | /* |
75 | * Arbitrary Retries in case the remote processor is slow to respond | 115 | * Arbitrary Retries in case the remote processor is slow to respond |
76 | * to PCC commands. Keeping it high enough to cover emulators where | 116 | * to PCC commands. Keeping it high enough to cover emulators where |
@@ -78,11 +118,79 @@ static unsigned int pcc_mpar, pcc_mrtt; | |||
78 | */ | 118 | */ |
79 | #define NUM_RETRIES 500 | 119 | #define NUM_RETRIES 500 |
80 | 120 | ||
81 | static int check_pcc_chan(void) | 121 | struct cppc_attr { |
122 | struct attribute attr; | ||
123 | ssize_t (*show)(struct kobject *kobj, | ||
124 | struct attribute *attr, char *buf); | ||
125 | ssize_t (*store)(struct kobject *kobj, | ||
126 | struct attribute *attr, const char *c, ssize_t count); | ||
127 | }; | ||
128 | |||
129 | #define define_one_cppc_ro(_name) \ | ||
130 | static struct cppc_attr _name = \ | ||
131 | __ATTR(_name, 0444, show_##_name, NULL) | ||
132 | |||
133 | #define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj) | ||
134 | |||
135 | static ssize_t show_feedback_ctrs(struct kobject *kobj, | ||
136 | struct attribute *attr, char *buf) | ||
137 | { | ||
138 | struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); | ||
139 | struct cppc_perf_fb_ctrs fb_ctrs = {0}; | ||
140 | |||
141 | cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs); | ||
142 | |||
143 | return scnprintf(buf, PAGE_SIZE, "ref:%llu del:%llu\n", | ||
144 | fb_ctrs.reference, fb_ctrs.delivered); | ||
145 | } | ||
146 | define_one_cppc_ro(feedback_ctrs); | ||
147 | |||
148 | static ssize_t show_reference_perf(struct kobject *kobj, | ||
149 | struct attribute *attr, char *buf) | ||
150 | { | ||
151 | struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); | ||
152 | struct cppc_perf_fb_ctrs fb_ctrs = {0}; | ||
153 | |||
154 | cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs); | ||
155 | |||
156 | return scnprintf(buf, PAGE_SIZE, "%llu\n", | ||
157 | fb_ctrs.reference_perf); | ||
158 | } | ||
159 | define_one_cppc_ro(reference_perf); | ||
160 | |||
161 | static ssize_t show_wraparound_time(struct kobject *kobj, | ||
162 | struct attribute *attr, char *buf) | ||
163 | { | ||
164 | struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); | ||
165 | struct cppc_perf_fb_ctrs fb_ctrs = {0}; | ||
166 | |||
167 | cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs); | ||
168 | |||
169 | return scnprintf(buf, PAGE_SIZE, "%llu\n", fb_ctrs.ctr_wrap_time); | ||
170 | |||
171 | } | ||
172 | define_one_cppc_ro(wraparound_time); | ||
173 | |||
174 | static struct attribute *cppc_attrs[] = { | ||
175 | &feedback_ctrs.attr, | ||
176 | &reference_perf.attr, | ||
177 | &wraparound_time.attr, | ||
178 | NULL | ||
179 | }; | ||
180 | |||
181 | static struct kobj_type cppc_ktype = { | ||
182 | .sysfs_ops = &kobj_sysfs_ops, | ||
183 | .default_attrs = cppc_attrs, | ||
184 | }; | ||
185 | |||
186 | static int check_pcc_chan(bool chk_err_bit) | ||
82 | { | 187 | { |
83 | int ret = -EIO; | 188 | int ret = -EIO, status = 0; |
84 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_comm_addr; | 189 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_data.pcc_comm_addr; |
85 | ktime_t next_deadline = ktime_add(ktime_get(), deadline); | 190 | ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline); |
191 | |||
192 | if (!pcc_data.platform_owns_pcc) | ||
193 | return 0; | ||
86 | 194 | ||
87 | /* Retry in case the remote processor was too slow to catch up. */ | 195 | /* Retry in case the remote processor was too slow to catch up. */ |
88 | while (!ktime_after(ktime_get(), next_deadline)) { | 196 | while (!ktime_after(ktime_get(), next_deadline)) { |
@@ -91,8 +199,11 @@ static int check_pcc_chan(void) | |||
91 | * platform and should have set the command completion bit when | 199 | * platform and should have set the command completion bit when |
92 | * PCC can be used by OSPM | 200 | * PCC can be used by OSPM |
93 | */ | 201 | */ |
94 | if (readw_relaxed(&generic_comm_base->status) & PCC_CMD_COMPLETE) { | 202 | status = readw_relaxed(&generic_comm_base->status); |
203 | if (status & PCC_CMD_COMPLETE_MASK) { | ||
95 | ret = 0; | 204 | ret = 0; |
205 | if (chk_err_bit && (status & PCC_ERROR_MASK)) | ||
206 | ret = -EIO; | ||
96 | break; | 207 | break; |
97 | } | 208 | } |
98 | /* | 209 | /* |
@@ -102,14 +213,23 @@ static int check_pcc_chan(void) | |||
102 | udelay(3); | 213 | udelay(3); |
103 | } | 214 | } |
104 | 215 | ||
216 | if (likely(!ret)) | ||
217 | pcc_data.platform_owns_pcc = false; | ||
218 | else | ||
219 | pr_err("PCC check channel failed. Status=%x\n", status); | ||
220 | |||
105 | return ret; | 221 | return ret; |
106 | } | 222 | } |
107 | 223 | ||
224 | /* | ||
225 | * This function transfers the ownership of the PCC to the platform | ||
226 | * So it must be called while holding write_lock(pcc_lock) | ||
227 | */ | ||
108 | static int send_pcc_cmd(u16 cmd) | 228 | static int send_pcc_cmd(u16 cmd) |
109 | { | 229 | { |
110 | int ret = -EIO; | 230 | int ret = -EIO, i; |
111 | struct acpi_pcct_shared_memory *generic_comm_base = | 231 | struct acpi_pcct_shared_memory *generic_comm_base = |
112 | (struct acpi_pcct_shared_memory *) pcc_comm_addr; | 232 | (struct acpi_pcct_shared_memory *) pcc_data.pcc_comm_addr; |
113 | static ktime_t last_cmd_cmpl_time, last_mpar_reset; | 233 | static ktime_t last_cmd_cmpl_time, last_mpar_reset; |
114 | static int mpar_count; | 234 | static int mpar_count; |
115 | unsigned int time_delta; | 235 | unsigned int time_delta; |
@@ -119,20 +239,29 @@ static int send_pcc_cmd(u16 cmd) | |||
119 | * the channel before writing to PCC space | 239 | * the channel before writing to PCC space |
120 | */ | 240 | */ |
121 | if (cmd == CMD_READ) { | 241 | if (cmd == CMD_READ) { |
122 | ret = check_pcc_chan(); | 242 | /* |
243 | * If there are pending cpc_writes, then we stole the channel | ||
244 | * before write completion, so first send a WRITE command to | ||
245 | * platform | ||
246 | */ | ||
247 | if (pcc_data.pending_pcc_write_cmd) | ||
248 | send_pcc_cmd(CMD_WRITE); | ||
249 | |||
250 | ret = check_pcc_chan(false); | ||
123 | if (ret) | 251 | if (ret) |
124 | return ret; | 252 | goto end; |
125 | } | 253 | } else /* CMD_WRITE */ |
254 | pcc_data.pending_pcc_write_cmd = FALSE; | ||
126 | 255 | ||
127 | /* | 256 | /* |
128 | * Handle the Minimum Request Turnaround Time(MRTT) | 257 | * Handle the Minimum Request Turnaround Time(MRTT) |
129 | * "The minimum amount of time that OSPM must wait after the completion | 258 | * "The minimum amount of time that OSPM must wait after the completion |
130 | * of a command before issuing the next command, in microseconds" | 259 | * of a command before issuing the next command, in microseconds" |
131 | */ | 260 | */ |
132 | if (pcc_mrtt) { | 261 | if (pcc_data.pcc_mrtt) { |
133 | time_delta = ktime_us_delta(ktime_get(), last_cmd_cmpl_time); | 262 | time_delta = ktime_us_delta(ktime_get(), last_cmd_cmpl_time); |
134 | if (pcc_mrtt > time_delta) | 263 | if (pcc_data.pcc_mrtt > time_delta) |
135 | udelay(pcc_mrtt - time_delta); | 264 | udelay(pcc_data.pcc_mrtt - time_delta); |
136 | } | 265 | } |
137 | 266 | ||
138 | /* | 267 | /* |
@@ -146,15 +275,16 @@ static int send_pcc_cmd(u16 cmd) | |||
146 | * not send the request to the platform after hitting the MPAR limit in | 275 | * not send the request to the platform after hitting the MPAR limit in |
147 | * any 60s window | 276 | * any 60s window |
148 | */ | 277 | */ |
149 | if (pcc_mpar) { | 278 | if (pcc_data.pcc_mpar) { |
150 | if (mpar_count == 0) { | 279 | if (mpar_count == 0) { |
151 | time_delta = ktime_ms_delta(ktime_get(), last_mpar_reset); | 280 | time_delta = ktime_ms_delta(ktime_get(), last_mpar_reset); |
152 | if (time_delta < 60 * MSEC_PER_SEC) { | 281 | if (time_delta < 60 * MSEC_PER_SEC) { |
153 | pr_debug("PCC cmd not sent due to MPAR limit"); | 282 | pr_debug("PCC cmd not sent due to MPAR limit"); |
154 | return -EIO; | 283 | ret = -EIO; |
284 | goto end; | ||
155 | } | 285 | } |
156 | last_mpar_reset = ktime_get(); | 286 | last_mpar_reset = ktime_get(); |
157 | mpar_count = pcc_mpar; | 287 | mpar_count = pcc_data.pcc_mpar; |
158 | } | 288 | } |
159 | mpar_count--; | 289 | mpar_count--; |
160 | } | 290 | } |
@@ -165,33 +295,43 @@ static int send_pcc_cmd(u16 cmd) | |||
165 | /* Flip CMD COMPLETE bit */ | 295 | /* Flip CMD COMPLETE bit */ |
166 | writew_relaxed(0, &generic_comm_base->status); | 296 | writew_relaxed(0, &generic_comm_base->status); |
167 | 297 | ||
298 | pcc_data.platform_owns_pcc = true; | ||
299 | |||
168 | /* Ring doorbell */ | 300 | /* Ring doorbell */ |
169 | ret = mbox_send_message(pcc_channel, &cmd); | 301 | ret = mbox_send_message(pcc_data.pcc_channel, &cmd); |
170 | if (ret < 0) { | 302 | if (ret < 0) { |
171 | pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n", | 303 | pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n", |
172 | cmd, ret); | 304 | cmd, ret); |
173 | return ret; | 305 | goto end; |
174 | } | 306 | } |
175 | 307 | ||
176 | /* | 308 | /* wait for completion and check for PCC errro bit */ |
177 | * For READs we need to ensure the cmd completed to ensure | 309 | ret = check_pcc_chan(true); |
178 | * the ensuing read()s can proceed. For WRITEs we dont care | 310 | |
179 | * because the actual write()s are done before coming here | 311 | if (pcc_data.pcc_mrtt) |
180 | * and the next READ or WRITE will check if the channel | 312 | last_cmd_cmpl_time = ktime_get(); |
181 | * is busy/free at the entry of this call. | 313 | |
182 | * | 314 | if (pcc_data.pcc_channel->mbox->txdone_irq) |
183 | * If Minimum Request Turnaround Time is non-zero, we need | 315 | mbox_chan_txdone(pcc_data.pcc_channel, ret); |
184 | * to record the completion time of both READ and WRITE | 316 | else |
185 | * command for proper handling of MRTT, so we need to check | 317 | mbox_client_txdone(pcc_data.pcc_channel, ret); |
186 | * for pcc_mrtt in addition to CMD_READ | 318 | |
187 | */ | 319 | end: |
188 | if (cmd == CMD_READ || pcc_mrtt) { | 320 | if (cmd == CMD_WRITE) { |
189 | ret = check_pcc_chan(); | 321 | if (unlikely(ret)) { |
190 | if (pcc_mrtt) | 322 | for_each_possible_cpu(i) { |
191 | last_cmd_cmpl_time = ktime_get(); | 323 | struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i); |
324 | if (!desc) | ||
325 | continue; | ||
326 | |||
327 | if (desc->write_cmd_id == pcc_data.pcc_write_cnt) | ||
328 | desc->write_cmd_status = ret; | ||
329 | } | ||
330 | } | ||
331 | pcc_data.pcc_write_cnt++; | ||
332 | wake_up_all(&pcc_data.pcc_write_wait_q); | ||
192 | } | 333 | } |
193 | 334 | ||
194 | mbox_client_txdone(pcc_channel, ret); | ||
195 | return ret; | 335 | return ret; |
196 | } | 336 | } |
197 | 337 | ||
@@ -272,13 +412,13 @@ end: | |||
272 | * | 412 | * |
273 | * Return: 0 for success or negative value for err. | 413 | * Return: 0 for success or negative value for err. |
274 | */ | 414 | */ |
275 | int acpi_get_psd_map(struct cpudata **all_cpu_data) | 415 | int acpi_get_psd_map(struct cppc_cpudata **all_cpu_data) |
276 | { | 416 | { |
277 | int count_target; | 417 | int count_target; |
278 | int retval = 0; | 418 | int retval = 0; |
279 | unsigned int i, j; | 419 | unsigned int i, j; |
280 | cpumask_var_t covered_cpus; | 420 | cpumask_var_t covered_cpus; |
281 | struct cpudata *pr, *match_pr; | 421 | struct cppc_cpudata *pr, *match_pr; |
282 | struct acpi_psd_package *pdomain; | 422 | struct acpi_psd_package *pdomain; |
283 | struct acpi_psd_package *match_pdomain; | 423 | struct acpi_psd_package *match_pdomain; |
284 | struct cpc_desc *cpc_ptr, *match_cpc_ptr; | 424 | struct cpc_desc *cpc_ptr, *match_cpc_ptr; |
@@ -394,14 +534,13 @@ EXPORT_SYMBOL_GPL(acpi_get_psd_map); | |||
394 | static int register_pcc_channel(int pcc_subspace_idx) | 534 | static int register_pcc_channel(int pcc_subspace_idx) |
395 | { | 535 | { |
396 | struct acpi_pcct_hw_reduced *cppc_ss; | 536 | struct acpi_pcct_hw_reduced *cppc_ss; |
397 | unsigned int len; | ||
398 | u64 usecs_lat; | 537 | u64 usecs_lat; |
399 | 538 | ||
400 | if (pcc_subspace_idx >= 0) { | 539 | if (pcc_subspace_idx >= 0) { |
401 | pcc_channel = pcc_mbox_request_channel(&cppc_mbox_cl, | 540 | pcc_data.pcc_channel = pcc_mbox_request_channel(&cppc_mbox_cl, |
402 | pcc_subspace_idx); | 541 | pcc_subspace_idx); |
403 | 542 | ||
404 | if (IS_ERR(pcc_channel)) { | 543 | if (IS_ERR(pcc_data.pcc_channel)) { |
405 | pr_err("Failed to find PCC communication channel\n"); | 544 | pr_err("Failed to find PCC communication channel\n"); |
406 | return -ENODEV; | 545 | return -ENODEV; |
407 | } | 546 | } |
@@ -412,7 +551,7 @@ static int register_pcc_channel(int pcc_subspace_idx) | |||
412 | * PCC channels) and stored pointers to the | 551 | * PCC channels) and stored pointers to the |
413 | * subspace communication region in con_priv. | 552 | * subspace communication region in con_priv. |
414 | */ | 553 | */ |
415 | cppc_ss = pcc_channel->con_priv; | 554 | cppc_ss = (pcc_data.pcc_channel)->con_priv; |
416 | 555 | ||
417 | if (!cppc_ss) { | 556 | if (!cppc_ss) { |
418 | pr_err("No PCC subspace found for CPPC\n"); | 557 | pr_err("No PCC subspace found for CPPC\n"); |
@@ -420,35 +559,42 @@ static int register_pcc_channel(int pcc_subspace_idx) | |||
420 | } | 559 | } |
421 | 560 | ||
422 | /* | 561 | /* |
423 | * This is the shared communication region | ||
424 | * for the OS and Platform to communicate over. | ||
425 | */ | ||
426 | comm_base_addr = cppc_ss->base_address; | ||
427 | len = cppc_ss->length; | ||
428 | |||
429 | /* | ||
430 | * cppc_ss->latency is just a Nominal value. In reality | 562 | * cppc_ss->latency is just a Nominal value. In reality |
431 | * the remote processor could be much slower to reply. | 563 | * the remote processor could be much slower to reply. |
432 | * So add an arbitrary amount of wait on top of Nominal. | 564 | * So add an arbitrary amount of wait on top of Nominal. |
433 | */ | 565 | */ |
434 | usecs_lat = NUM_RETRIES * cppc_ss->latency; | 566 | usecs_lat = NUM_RETRIES * cppc_ss->latency; |
435 | deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); | 567 | pcc_data.deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); |
436 | pcc_mrtt = cppc_ss->min_turnaround_time; | 568 | pcc_data.pcc_mrtt = cppc_ss->min_turnaround_time; |
437 | pcc_mpar = cppc_ss->max_access_rate; | 569 | pcc_data.pcc_mpar = cppc_ss->max_access_rate; |
570 | pcc_data.pcc_nominal = cppc_ss->latency; | ||
438 | 571 | ||
439 | pcc_comm_addr = acpi_os_ioremap(comm_base_addr, len); | 572 | pcc_data.pcc_comm_addr = acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length); |
440 | if (!pcc_comm_addr) { | 573 | if (!pcc_data.pcc_comm_addr) { |
441 | pr_err("Failed to ioremap PCC comm region mem\n"); | 574 | pr_err("Failed to ioremap PCC comm region mem\n"); |
442 | return -ENOMEM; | 575 | return -ENOMEM; |
443 | } | 576 | } |
444 | 577 | ||
445 | /* Set flag so that we dont come here for each CPU. */ | 578 | /* Set flag so that we dont come here for each CPU. */ |
446 | pcc_channel_acquired = true; | 579 | pcc_data.pcc_channel_acquired = true; |
447 | } | 580 | } |
448 | 581 | ||
449 | return 0; | 582 | return 0; |
450 | } | 583 | } |
451 | 584 | ||
585 | /** | ||
586 | * cpc_ffh_supported() - check if FFH reading supported | ||
587 | * | ||
588 | * Check if the architecture has support for functional fixed hardware | ||
589 | * read/write capability. | ||
590 | * | ||
591 | * Return: true for supported, false for not supported | ||
592 | */ | ||
593 | bool __weak cpc_ffh_supported(void) | ||
594 | { | ||
595 | return false; | ||
596 | } | ||
597 | |||
452 | /* | 598 | /* |
453 | * An example CPC table looks like the following. | 599 | * An example CPC table looks like the following. |
454 | * | 600 | * |
@@ -507,6 +653,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
507 | union acpi_object *out_obj, *cpc_obj; | 653 | union acpi_object *out_obj, *cpc_obj; |
508 | struct cpc_desc *cpc_ptr; | 654 | struct cpc_desc *cpc_ptr; |
509 | struct cpc_reg *gas_t; | 655 | struct cpc_reg *gas_t; |
656 | struct device *cpu_dev; | ||
510 | acpi_handle handle = pr->handle; | 657 | acpi_handle handle = pr->handle; |
511 | unsigned int num_ent, i, cpc_rev; | 658 | unsigned int num_ent, i, cpc_rev; |
512 | acpi_status status; | 659 | acpi_status status; |
@@ -545,6 +692,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
545 | goto out_free; | 692 | goto out_free; |
546 | } | 693 | } |
547 | 694 | ||
695 | cpc_ptr->num_entries = num_ent; | ||
696 | |||
548 | /* Second entry should be revision. */ | 697 | /* Second entry should be revision. */ |
549 | cpc_obj = &out_obj->package.elements[1]; | 698 | cpc_obj = &out_obj->package.elements[1]; |
550 | if (cpc_obj->type == ACPI_TYPE_INTEGER) { | 699 | if (cpc_obj->type == ACPI_TYPE_INTEGER) { |
@@ -579,16 +728,27 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
579 | * so extract it only once. | 728 | * so extract it only once. |
580 | */ | 729 | */ |
581 | if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { | 730 | if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { |
582 | if (pcc_subspace_idx < 0) | 731 | if (pcc_data.pcc_subspace_idx < 0) |
583 | pcc_subspace_idx = gas_t->access_width; | 732 | pcc_data.pcc_subspace_idx = gas_t->access_width; |
584 | else if (pcc_subspace_idx != gas_t->access_width) { | 733 | else if (pcc_data.pcc_subspace_idx != gas_t->access_width) { |
585 | pr_debug("Mismatched PCC ids.\n"); | 734 | pr_debug("Mismatched PCC ids.\n"); |
586 | goto out_free; | 735 | goto out_free; |
587 | } | 736 | } |
588 | } else if (gas_t->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 737 | } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
589 | /* Support only PCC and SYS MEM type regs */ | 738 | if (gas_t->address) { |
590 | pr_debug("Unsupported register type: %d\n", gas_t->space_id); | 739 | void __iomem *addr; |
591 | goto out_free; | 740 | |
741 | addr = ioremap(gas_t->address, gas_t->bit_width/8); | ||
742 | if (!addr) | ||
743 | goto out_free; | ||
744 | cpc_ptr->cpc_regs[i-2].sys_mem_vaddr = addr; | ||
745 | } | ||
746 | } else { | ||
747 | if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) { | ||
748 | /* Support only PCC ,SYS MEM and FFH type regs */ | ||
749 | pr_debug("Unsupported register type: %d\n", gas_t->space_id); | ||
750 | goto out_free; | ||
751 | } | ||
592 | } | 752 | } |
593 | 753 | ||
594 | cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER; | 754 | cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER; |
@@ -607,10 +767,13 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
607 | goto out_free; | 767 | goto out_free; |
608 | 768 | ||
609 | /* Register PCC channel once for all CPUs. */ | 769 | /* Register PCC channel once for all CPUs. */ |
610 | if (!pcc_channel_acquired) { | 770 | if (!pcc_data.pcc_channel_acquired) { |
611 | ret = register_pcc_channel(pcc_subspace_idx); | 771 | ret = register_pcc_channel(pcc_data.pcc_subspace_idx); |
612 | if (ret) | 772 | if (ret) |
613 | goto out_free; | 773 | goto out_free; |
774 | |||
775 | init_rwsem(&pcc_data.pcc_lock); | ||
776 | init_waitqueue_head(&pcc_data.pcc_write_wait_q); | ||
614 | } | 777 | } |
615 | 778 | ||
616 | /* Plug PSD data into this CPUs CPC descriptor. */ | 779 | /* Plug PSD data into this CPUs CPC descriptor. */ |
@@ -619,10 +782,27 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
619 | /* Everything looks okay */ | 782 | /* Everything looks okay */ |
620 | pr_debug("Parsed CPC struct for CPU: %d\n", pr->id); | 783 | pr_debug("Parsed CPC struct for CPU: %d\n", pr->id); |
621 | 784 | ||
785 | /* Add per logical CPU nodes for reading its feedback counters. */ | ||
786 | cpu_dev = get_cpu_device(pr->id); | ||
787 | if (!cpu_dev) | ||
788 | goto out_free; | ||
789 | |||
790 | ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj, | ||
791 | "acpi_cppc"); | ||
792 | if (ret) | ||
793 | goto out_free; | ||
794 | |||
622 | kfree(output.pointer); | 795 | kfree(output.pointer); |
623 | return 0; | 796 | return 0; |
624 | 797 | ||
625 | out_free: | 798 | out_free: |
799 | /* Free all the mapped sys mem areas for this CPU */ | ||
800 | for (i = 2; i < cpc_ptr->num_entries; i++) { | ||
801 | void __iomem *addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr; | ||
802 | |||
803 | if (addr) | ||
804 | iounmap(addr); | ||
805 | } | ||
626 | kfree(cpc_ptr); | 806 | kfree(cpc_ptr); |
627 | 807 | ||
628 | out_buf_free: | 808 | out_buf_free: |
@@ -640,26 +820,82 @@ EXPORT_SYMBOL_GPL(acpi_cppc_processor_probe); | |||
640 | void acpi_cppc_processor_exit(struct acpi_processor *pr) | 820 | void acpi_cppc_processor_exit(struct acpi_processor *pr) |
641 | { | 821 | { |
642 | struct cpc_desc *cpc_ptr; | 822 | struct cpc_desc *cpc_ptr; |
823 | unsigned int i; | ||
824 | void __iomem *addr; | ||
825 | |||
643 | cpc_ptr = per_cpu(cpc_desc_ptr, pr->id); | 826 | cpc_ptr = per_cpu(cpc_desc_ptr, pr->id); |
827 | |||
828 | /* Free all the mapped sys mem areas for this CPU */ | ||
829 | for (i = 2; i < cpc_ptr->num_entries; i++) { | ||
830 | addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr; | ||
831 | if (addr) | ||
832 | iounmap(addr); | ||
833 | } | ||
834 | |||
835 | kobject_put(&cpc_ptr->kobj); | ||
644 | kfree(cpc_ptr); | 836 | kfree(cpc_ptr); |
645 | } | 837 | } |
646 | EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit); | 838 | EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit); |
647 | 839 | ||
840 | /** | ||
841 | * cpc_read_ffh() - Read FFH register | ||
842 | * @cpunum: cpu number to read | ||
843 | * @reg: cppc register information | ||
844 | * @val: place holder for return value | ||
845 | * | ||
846 | * Read bit_width bits from a specified address and bit_offset | ||
847 | * | ||
848 | * Return: 0 for success and error code | ||
849 | */ | ||
850 | int __weak cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val) | ||
851 | { | ||
852 | return -ENOTSUPP; | ||
853 | } | ||
854 | |||
855 | /** | ||
856 | * cpc_write_ffh() - Write FFH register | ||
857 | * @cpunum: cpu number to write | ||
858 | * @reg: cppc register information | ||
859 | * @val: value to write | ||
860 | * | ||
861 | * Write value of bit_width bits to a specified address and bit_offset | ||
862 | * | ||
863 | * Return: 0 for success and error code | ||
864 | */ | ||
865 | int __weak cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val) | ||
866 | { | ||
867 | return -ENOTSUPP; | ||
868 | } | ||
869 | |||
648 | /* | 870 | /* |
649 | * Since cpc_read and cpc_write are called while holding pcc_lock, it should be | 871 | * Since cpc_read and cpc_write are called while holding pcc_lock, it should be |
650 | * as fast as possible. We have already mapped the PCC subspace during init, so | 872 | * as fast as possible. We have already mapped the PCC subspace during init, so |
651 | * we can directly write to it. | 873 | * we can directly write to it. |
652 | */ | 874 | */ |
653 | 875 | ||
654 | static int cpc_read(struct cpc_reg *reg, u64 *val) | 876 | static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) |
655 | { | 877 | { |
656 | int ret_val = 0; | 878 | int ret_val = 0; |
879 | void __iomem *vaddr = 0; | ||
880 | struct cpc_reg *reg = ®_res->cpc_entry.reg; | ||
881 | |||
882 | if (reg_res->type == ACPI_TYPE_INTEGER) { | ||
883 | *val = reg_res->cpc_entry.int_value; | ||
884 | return ret_val; | ||
885 | } | ||
657 | 886 | ||
658 | *val = 0; | 887 | *val = 0; |
659 | if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { | 888 | if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) |
660 | void __iomem *vaddr = GET_PCC_VADDR(reg->address); | 889 | vaddr = GET_PCC_VADDR(reg->address); |
890 | else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | ||
891 | vaddr = reg_res->sys_mem_vaddr; | ||
892 | else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) | ||
893 | return cpc_read_ffh(cpu, reg, val); | ||
894 | else | ||
895 | return acpi_os_read_memory((acpi_physical_address)reg->address, | ||
896 | val, reg->bit_width); | ||
661 | 897 | ||
662 | switch (reg->bit_width) { | 898 | switch (reg->bit_width) { |
663 | case 8: | 899 | case 8: |
664 | *val = readb_relaxed(vaddr); | 900 | *val = readb_relaxed(vaddr); |
665 | break; | 901 | break; |
@@ -674,23 +910,30 @@ static int cpc_read(struct cpc_reg *reg, u64 *val) | |||
674 | break; | 910 | break; |
675 | default: | 911 | default: |
676 | pr_debug("Error: Cannot read %u bit width from PCC\n", | 912 | pr_debug("Error: Cannot read %u bit width from PCC\n", |
677 | reg->bit_width); | 913 | reg->bit_width); |
678 | ret_val = -EFAULT; | 914 | ret_val = -EFAULT; |
679 | } | 915 | } |
680 | } else | 916 | |
681 | ret_val = acpi_os_read_memory((acpi_physical_address)reg->address, | ||
682 | val, reg->bit_width); | ||
683 | return ret_val; | 917 | return ret_val; |
684 | } | 918 | } |
685 | 919 | ||
686 | static int cpc_write(struct cpc_reg *reg, u64 val) | 920 | static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) |
687 | { | 921 | { |
688 | int ret_val = 0; | 922 | int ret_val = 0; |
923 | void __iomem *vaddr = 0; | ||
924 | struct cpc_reg *reg = ®_res->cpc_entry.reg; | ||
925 | |||
926 | if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) | ||
927 | vaddr = GET_PCC_VADDR(reg->address); | ||
928 | else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | ||
929 | vaddr = reg_res->sys_mem_vaddr; | ||
930 | else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) | ||
931 | return cpc_write_ffh(cpu, reg, val); | ||
932 | else | ||
933 | return acpi_os_write_memory((acpi_physical_address)reg->address, | ||
934 | val, reg->bit_width); | ||
689 | 935 | ||
690 | if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { | 936 | switch (reg->bit_width) { |
691 | void __iomem *vaddr = GET_PCC_VADDR(reg->address); | ||
692 | |||
693 | switch (reg->bit_width) { | ||
694 | case 8: | 937 | case 8: |
695 | writeb_relaxed(val, vaddr); | 938 | writeb_relaxed(val, vaddr); |
696 | break; | 939 | break; |
@@ -705,13 +948,11 @@ static int cpc_write(struct cpc_reg *reg, u64 val) | |||
705 | break; | 948 | break; |
706 | default: | 949 | default: |
707 | pr_debug("Error: Cannot write %u bit width to PCC\n", | 950 | pr_debug("Error: Cannot write %u bit width to PCC\n", |
708 | reg->bit_width); | 951 | reg->bit_width); |
709 | ret_val = -EFAULT; | 952 | ret_val = -EFAULT; |
710 | break; | 953 | break; |
711 | } | 954 | } |
712 | } else | 955 | |
713 | ret_val = acpi_os_write_memory((acpi_physical_address)reg->address, | ||
714 | val, reg->bit_width); | ||
715 | return ret_val; | 956 | return ret_val; |
716 | } | 957 | } |
717 | 958 | ||
@@ -727,8 +968,8 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
727 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); | 968 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); |
728 | struct cpc_register_resource *highest_reg, *lowest_reg, *ref_perf, | 969 | struct cpc_register_resource *highest_reg, *lowest_reg, *ref_perf, |
729 | *nom_perf; | 970 | *nom_perf; |
730 | u64 high, low, ref, nom; | 971 | u64 high, low, nom; |
731 | int ret = 0; | 972 | int ret = 0, regs_in_pcc = 0; |
732 | 973 | ||
733 | if (!cpc_desc) { | 974 | if (!cpc_desc) { |
734 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | 975 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); |
@@ -740,13 +981,11 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
740 | ref_perf = &cpc_desc->cpc_regs[REFERENCE_PERF]; | 981 | ref_perf = &cpc_desc->cpc_regs[REFERENCE_PERF]; |
741 | nom_perf = &cpc_desc->cpc_regs[NOMINAL_PERF]; | 982 | nom_perf = &cpc_desc->cpc_regs[NOMINAL_PERF]; |
742 | 983 | ||
743 | spin_lock(&pcc_lock); | ||
744 | |||
745 | /* Are any of the regs PCC ?*/ | 984 | /* Are any of the regs PCC ?*/ |
746 | if ((highest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || | 985 | if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || |
747 | (lowest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || | 986 | CPC_IN_PCC(ref_perf) || CPC_IN_PCC(nom_perf)) { |
748 | (ref_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || | 987 | regs_in_pcc = 1; |
749 | (nom_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) { | 988 | down_write(&pcc_data.pcc_lock); |
750 | /* Ring doorbell once to update PCC subspace */ | 989 | /* Ring doorbell once to update PCC subspace */ |
751 | if (send_pcc_cmd(CMD_READ) < 0) { | 990 | if (send_pcc_cmd(CMD_READ) < 0) { |
752 | ret = -EIO; | 991 | ret = -EIO; |
@@ -754,26 +993,21 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
754 | } | 993 | } |
755 | } | 994 | } |
756 | 995 | ||
757 | cpc_read(&highest_reg->cpc_entry.reg, &high); | 996 | cpc_read(cpunum, highest_reg, &high); |
758 | perf_caps->highest_perf = high; | 997 | perf_caps->highest_perf = high; |
759 | 998 | ||
760 | cpc_read(&lowest_reg->cpc_entry.reg, &low); | 999 | cpc_read(cpunum, lowest_reg, &low); |
761 | perf_caps->lowest_perf = low; | 1000 | perf_caps->lowest_perf = low; |
762 | 1001 | ||
763 | cpc_read(&ref_perf->cpc_entry.reg, &ref); | 1002 | cpc_read(cpunum, nom_perf, &nom); |
764 | perf_caps->reference_perf = ref; | ||
765 | |||
766 | cpc_read(&nom_perf->cpc_entry.reg, &nom); | ||
767 | perf_caps->nominal_perf = nom; | 1003 | perf_caps->nominal_perf = nom; |
768 | 1004 | ||
769 | if (!ref) | ||
770 | perf_caps->reference_perf = perf_caps->nominal_perf; | ||
771 | |||
772 | if (!high || !low || !nom) | 1005 | if (!high || !low || !nom) |
773 | ret = -EFAULT; | 1006 | ret = -EFAULT; |
774 | 1007 | ||
775 | out_err: | 1008 | out_err: |
776 | spin_unlock(&pcc_lock); | 1009 | if (regs_in_pcc) |
1010 | up_write(&pcc_data.pcc_lock); | ||
777 | return ret; | 1011 | return ret; |
778 | } | 1012 | } |
779 | EXPORT_SYMBOL_GPL(cppc_get_perf_caps); | 1013 | EXPORT_SYMBOL_GPL(cppc_get_perf_caps); |
@@ -788,9 +1022,10 @@ EXPORT_SYMBOL_GPL(cppc_get_perf_caps); | |||
788 | int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | 1022 | int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) |
789 | { | 1023 | { |
790 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); | 1024 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); |
791 | struct cpc_register_resource *delivered_reg, *reference_reg; | 1025 | struct cpc_register_resource *delivered_reg, *reference_reg, |
792 | u64 delivered, reference; | 1026 | *ref_perf_reg, *ctr_wrap_reg; |
793 | int ret = 0; | 1027 | u64 delivered, reference, ref_perf, ctr_wrap_time; |
1028 | int ret = 0, regs_in_pcc = 0; | ||
794 | 1029 | ||
795 | if (!cpc_desc) { | 1030 | if (!cpc_desc) { |
796 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | 1031 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); |
@@ -799,12 +1034,21 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
799 | 1034 | ||
800 | delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; | 1035 | delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; |
801 | reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; | 1036 | reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; |
1037 | ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; | ||
1038 | ctr_wrap_reg = &cpc_desc->cpc_regs[CTR_WRAP_TIME]; | ||
802 | 1039 | ||
803 | spin_lock(&pcc_lock); | 1040 | /* |
1041 | * If refernce perf register is not supported then we should | ||
1042 | * use the nominal perf value | ||
1043 | */ | ||
1044 | if (!CPC_SUPPORTED(ref_perf_reg)) | ||
1045 | ref_perf_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; | ||
804 | 1046 | ||
805 | /* Are any of the regs PCC ?*/ | 1047 | /* Are any of the regs PCC ?*/ |
806 | if ((delivered_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || | 1048 | if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || |
807 | (reference_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) { | 1049 | CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { |
1050 | down_write(&pcc_data.pcc_lock); | ||
1051 | regs_in_pcc = 1; | ||
808 | /* Ring doorbell once to update PCC subspace */ | 1052 | /* Ring doorbell once to update PCC subspace */ |
809 | if (send_pcc_cmd(CMD_READ) < 0) { | 1053 | if (send_pcc_cmd(CMD_READ) < 0) { |
810 | ret = -EIO; | 1054 | ret = -EIO; |
@@ -812,25 +1056,31 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
812 | } | 1056 | } |
813 | } | 1057 | } |
814 | 1058 | ||
815 | cpc_read(&delivered_reg->cpc_entry.reg, &delivered); | 1059 | cpc_read(cpunum, delivered_reg, &delivered); |
816 | cpc_read(&reference_reg->cpc_entry.reg, &reference); | 1060 | cpc_read(cpunum, reference_reg, &reference); |
1061 | cpc_read(cpunum, ref_perf_reg, &ref_perf); | ||
817 | 1062 | ||
818 | if (!delivered || !reference) { | 1063 | /* |
1064 | * Per spec, if ctr_wrap_time optional register is unsupported, then the | ||
1065 | * performance counters are assumed to never wrap during the lifetime of | ||
1066 | * platform | ||
1067 | */ | ||
1068 | ctr_wrap_time = (u64)(~((u64)0)); | ||
1069 | if (CPC_SUPPORTED(ctr_wrap_reg)) | ||
1070 | cpc_read(cpunum, ctr_wrap_reg, &ctr_wrap_time); | ||
1071 | |||
1072 | if (!delivered || !reference || !ref_perf) { | ||
819 | ret = -EFAULT; | 1073 | ret = -EFAULT; |
820 | goto out_err; | 1074 | goto out_err; |
821 | } | 1075 | } |
822 | 1076 | ||
823 | perf_fb_ctrs->delivered = delivered; | 1077 | perf_fb_ctrs->delivered = delivered; |
824 | perf_fb_ctrs->reference = reference; | 1078 | perf_fb_ctrs->reference = reference; |
825 | 1079 | perf_fb_ctrs->reference_perf = ref_perf; | |
826 | perf_fb_ctrs->delivered -= perf_fb_ctrs->prev_delivered; | 1080 | perf_fb_ctrs->ctr_wrap_time = ctr_wrap_time; |
827 | perf_fb_ctrs->reference -= perf_fb_ctrs->prev_reference; | ||
828 | |||
829 | perf_fb_ctrs->prev_delivered = delivered; | ||
830 | perf_fb_ctrs->prev_reference = reference; | ||
831 | |||
832 | out_err: | 1081 | out_err: |
833 | spin_unlock(&pcc_lock); | 1082 | if (regs_in_pcc) |
1083 | up_write(&pcc_data.pcc_lock); | ||
834 | return ret; | 1084 | return ret; |
835 | } | 1085 | } |
836 | EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); | 1086 | EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); |
@@ -855,30 +1105,142 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
855 | 1105 | ||
856 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; | 1106 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; |
857 | 1107 | ||
858 | spin_lock(&pcc_lock); | 1108 | /* |
859 | 1109 | * This is Phase-I where we want to write to CPC registers | |
860 | /* If this is PCC reg, check if channel is free before writing */ | 1110 | * -> We want all CPUs to be able to execute this phase in parallel |
861 | if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { | 1111 | * |
862 | ret = check_pcc_chan(); | 1112 | * Since read_lock can be acquired by multiple CPUs simultaneously we |
863 | if (ret) | 1113 | * achieve that goal here |
864 | goto busy_channel; | 1114 | */ |
1115 | if (CPC_IN_PCC(desired_reg)) { | ||
1116 | down_read(&pcc_data.pcc_lock); /* BEGIN Phase-I */ | ||
1117 | if (pcc_data.platform_owns_pcc) { | ||
1118 | ret = check_pcc_chan(false); | ||
1119 | if (ret) { | ||
1120 | up_read(&pcc_data.pcc_lock); | ||
1121 | return ret; | ||
1122 | } | ||
1123 | } | ||
1124 | /* | ||
1125 | * Update the pending_write to make sure a PCC CMD_READ will not | ||
1126 | * arrive and steal the channel during the switch to write lock | ||
1127 | */ | ||
1128 | pcc_data.pending_pcc_write_cmd = true; | ||
1129 | cpc_desc->write_cmd_id = pcc_data.pcc_write_cnt; | ||
1130 | cpc_desc->write_cmd_status = 0; | ||
865 | } | 1131 | } |
866 | 1132 | ||
867 | /* | 1133 | /* |
868 | * Skip writing MIN/MAX until Linux knows how to come up with | 1134 | * Skip writing MIN/MAX until Linux knows how to come up with |
869 | * useful values. | 1135 | * useful values. |
870 | */ | 1136 | */ |
871 | cpc_write(&desired_reg->cpc_entry.reg, perf_ctrls->desired_perf); | 1137 | cpc_write(cpu, desired_reg, perf_ctrls->desired_perf); |
872 | 1138 | ||
873 | /* Is this a PCC reg ?*/ | 1139 | if (CPC_IN_PCC(desired_reg)) |
874 | if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { | 1140 | up_read(&pcc_data.pcc_lock); /* END Phase-I */ |
875 | /* Ring doorbell so Remote can get our perf request. */ | 1141 | /* |
876 | if (send_pcc_cmd(CMD_WRITE) < 0) | 1142 | * This is Phase-II where we transfer the ownership of PCC to Platform |
877 | ret = -EIO; | 1143 | * |
1144 | * Short Summary: Basically if we think of a group of cppc_set_perf | ||
1145 | * requests that happened in short overlapping interval. The last CPU to | ||
1146 | * come out of Phase-I will enter Phase-II and ring the doorbell. | ||
1147 | * | ||
1148 | * We have the following requirements for Phase-II: | ||
1149 | * 1. We want to execute Phase-II only when there are no CPUs | ||
1150 | * currently executing in Phase-I | ||
1151 | * 2. Once we start Phase-II we want to avoid all other CPUs from | ||
1152 | * entering Phase-I. | ||
1153 | * 3. We want only one CPU among all those who went through Phase-I | ||
1154 | * to run phase-II | ||
1155 | * | ||
1156 | * If write_trylock fails to get the lock and doesn't transfer the | ||
1157 | * PCC ownership to the platform, then one of the following will be TRUE | ||
1158 | * 1. There is at-least one CPU in Phase-I which will later execute | ||
1159 | * write_trylock, so the CPUs in Phase-I will be responsible for | ||
1160 | * executing the Phase-II. | ||
1161 | * 2. Some other CPU has beaten this CPU to successfully execute the | ||
1162 | * write_trylock and has already acquired the write_lock. We know for a | ||
1163 | * fact it(other CPU acquiring the write_lock) couldn't have happened | ||
1164 | * before this CPU's Phase-I as we held the read_lock. | ||
1165 | * 3. Some other CPU executing pcc CMD_READ has stolen the | ||
1166 | * down_write, in which case, send_pcc_cmd will check for pending | ||
1167 | * CMD_WRITE commands by checking the pending_pcc_write_cmd. | ||
1168 | * So this CPU can be certain that its request will be delivered | ||
1169 | * So in all cases, this CPU knows that its request will be delivered | ||
1170 | * by another CPU and can return | ||
1171 | * | ||
1172 | * After getting the down_write we still need to check for | ||
1173 | * pending_pcc_write_cmd to take care of the following scenario | ||
1174 | * The thread running this code could be scheduled out between | ||
1175 | * Phase-I and Phase-II. Before it is scheduled back on, another CPU | ||
1176 | * could have delivered the request to Platform by triggering the | ||
1177 | * doorbell and transferred the ownership of PCC to platform. So this | ||
1178 | * avoids triggering an unnecessary doorbell and more importantly before | ||
1179 | * triggering the doorbell it makes sure that the PCC channel ownership | ||
1180 | * is still with OSPM. | ||
1181 | * pending_pcc_write_cmd can also be cleared by a different CPU, if | ||
1182 | * there was a pcc CMD_READ waiting on down_write and it steals the lock | ||
1183 | * before the pcc CMD_WRITE is completed. pcc_send_cmd checks for this | ||
1184 | * case during a CMD_READ and if there are pending writes it delivers | ||
1185 | * the write command before servicing the read command | ||
1186 | */ | ||
1187 | if (CPC_IN_PCC(desired_reg)) { | ||
1188 | if (down_write_trylock(&pcc_data.pcc_lock)) { /* BEGIN Phase-II */ | ||
1189 | /* Update only if there are pending write commands */ | ||
1190 | if (pcc_data.pending_pcc_write_cmd) | ||
1191 | send_pcc_cmd(CMD_WRITE); | ||
1192 | up_write(&pcc_data.pcc_lock); /* END Phase-II */ | ||
1193 | } else | ||
1194 | /* Wait until pcc_write_cnt is updated by send_pcc_cmd */ | ||
1195 | wait_event(pcc_data.pcc_write_wait_q, | ||
1196 | cpc_desc->write_cmd_id != pcc_data.pcc_write_cnt); | ||
1197 | |||
1198 | /* send_pcc_cmd updates the status in case of failure */ | ||
1199 | ret = cpc_desc->write_cmd_status; | ||
878 | } | 1200 | } |
879 | busy_channel: | ||
880 | spin_unlock(&pcc_lock); | ||
881 | |||
882 | return ret; | 1201 | return ret; |
883 | } | 1202 | } |
884 | EXPORT_SYMBOL_GPL(cppc_set_perf); | 1203 | EXPORT_SYMBOL_GPL(cppc_set_perf); |
1204 | |||
1205 | /** | ||
1206 | * cppc_get_transition_latency - returns frequency transition latency in ns | ||
1207 | * | ||
1208 | * ACPI CPPC does not explicitly specifiy how a platform can specify the | ||
1209 | * transition latency for perfromance change requests. The closest we have | ||
1210 | * is the timing information from the PCCT tables which provides the info | ||
1211 | * on the number and frequency of PCC commands the platform can handle. | ||
1212 | */ | ||
1213 | unsigned int cppc_get_transition_latency(int cpu_num) | ||
1214 | { | ||
1215 | /* | ||
1216 | * Expected transition latency is based on the PCCT timing values | ||
1217 | * Below are definition from ACPI spec: | ||
1218 | * pcc_nominal- Expected latency to process a command, in microseconds | ||
1219 | * pcc_mpar - The maximum number of periodic requests that the subspace | ||
1220 | * channel can support, reported in commands per minute. 0 | ||
1221 | * indicates no limitation. | ||
1222 | * pcc_mrtt - The minimum amount of time that OSPM must wait after the | ||
1223 | * completion of a command before issuing the next command, | ||
1224 | * in microseconds. | ||
1225 | */ | ||
1226 | unsigned int latency_ns = 0; | ||
1227 | struct cpc_desc *cpc_desc; | ||
1228 | struct cpc_register_resource *desired_reg; | ||
1229 | |||
1230 | cpc_desc = per_cpu(cpc_desc_ptr, cpu_num); | ||
1231 | if (!cpc_desc) | ||
1232 | return CPUFREQ_ETERNAL; | ||
1233 | |||
1234 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; | ||
1235 | if (!CPC_IN_PCC(desired_reg)) | ||
1236 | return CPUFREQ_ETERNAL; | ||
1237 | |||
1238 | if (pcc_data.pcc_mpar) | ||
1239 | latency_ns = 60 * (1000 * 1000 * 1000 / pcc_data.pcc_mpar); | ||
1240 | |||
1241 | latency_ns = max(latency_ns, pcc_data.pcc_nominal * 1000); | ||
1242 | latency_ns = max(latency_ns, pcc_data.pcc_mrtt * 1000); | ||
1243 | |||
1244 | return latency_ns; | ||
1245 | } | ||
1246 | EXPORT_SYMBOL_GPL(cppc_get_transition_latency); | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e7bd57cc550a..48e19d013170 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -104,10 +104,12 @@ enum ec_command { | |||
104 | #define ACPI_EC_MAX_QUERIES 16 /* Maximum number of parallel queries */ | 104 | #define ACPI_EC_MAX_QUERIES 16 /* Maximum number of parallel queries */ |
105 | 105 | ||
106 | enum { | 106 | enum { |
107 | EC_FLAGS_QUERY_ENABLED, /* Query is enabled */ | ||
107 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 108 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
108 | EC_FLAGS_QUERY_GUARDING, /* Guard for SCI_EVT check */ | 109 | EC_FLAGS_QUERY_GUARDING, /* Guard for SCI_EVT check */ |
109 | EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */ | 110 | EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */ |
110 | EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */ | 111 | EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */ |
112 | EC_FLAGS_EVT_HANDLER_INSTALLED, /* _Qxx handlers installed */ | ||
111 | EC_FLAGS_STARTED, /* Driver is started */ | 113 | EC_FLAGS_STARTED, /* Driver is started */ |
112 | EC_FLAGS_STOPPED, /* Driver is stopped */ | 114 | EC_FLAGS_STOPPED, /* Driver is stopped */ |
113 | EC_FLAGS_COMMAND_STORM, /* GPE storms occurred to the | 115 | EC_FLAGS_COMMAND_STORM, /* GPE storms occurred to the |
@@ -145,6 +147,10 @@ static unsigned int ec_storm_threshold __read_mostly = 8; | |||
145 | module_param(ec_storm_threshold, uint, 0644); | 147 | module_param(ec_storm_threshold, uint, 0644); |
146 | MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); | 148 | MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); |
147 | 149 | ||
150 | static bool ec_freeze_events __read_mostly = true; | ||
151 | module_param(ec_freeze_events, bool, 0644); | ||
152 | MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume"); | ||
153 | |||
148 | struct acpi_ec_query_handler { | 154 | struct acpi_ec_query_handler { |
149 | struct list_head node; | 155 | struct list_head node; |
150 | acpi_ec_query_func func; | 156 | acpi_ec_query_func func; |
@@ -179,6 +185,7 @@ static void acpi_ec_event_processor(struct work_struct *work); | |||
179 | 185 | ||
180 | struct acpi_ec *boot_ec, *first_ec; | 186 | struct acpi_ec *boot_ec, *first_ec; |
181 | EXPORT_SYMBOL(first_ec); | 187 | EXPORT_SYMBOL(first_ec); |
188 | static bool boot_ec_is_ecdt = false; | ||
182 | static struct workqueue_struct *ec_query_wq; | 189 | static struct workqueue_struct *ec_query_wq; |
183 | 190 | ||
184 | static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ | 191 | static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ |
@@ -239,6 +246,30 @@ static bool acpi_ec_started(struct acpi_ec *ec) | |||
239 | !test_bit(EC_FLAGS_STOPPED, &ec->flags); | 246 | !test_bit(EC_FLAGS_STOPPED, &ec->flags); |
240 | } | 247 | } |
241 | 248 | ||
249 | static bool acpi_ec_event_enabled(struct acpi_ec *ec) | ||
250 | { | ||
251 | /* | ||
252 | * There is an OSPM early stage logic. During the early stages | ||
253 | * (boot/resume), OSPMs shouldn't enable the event handling, only | ||
254 | * the EC transactions are allowed to be performed. | ||
255 | */ | ||
256 | if (!test_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags)) | ||
257 | return false; | ||
258 | /* | ||
259 | * However, disabling the event handling is experimental for late | ||
260 | * stage (suspend), and is controlled by the boot parameter of | ||
261 | * "ec_freeze_events": | ||
262 | * 1. true: The EC event handling is disabled before entering | ||
263 | * the noirq stage. | ||
264 | * 2. false: The EC event handling is automatically disabled as | ||
265 | * soon as the EC driver is stopped. | ||
266 | */ | ||
267 | if (ec_freeze_events) | ||
268 | return acpi_ec_started(ec); | ||
269 | else | ||
270 | return test_bit(EC_FLAGS_STARTED, &ec->flags); | ||
271 | } | ||
272 | |||
242 | static bool acpi_ec_flushed(struct acpi_ec *ec) | 273 | static bool acpi_ec_flushed(struct acpi_ec *ec) |
243 | { | 274 | { |
244 | return ec->reference_count == 1; | 275 | return ec->reference_count == 1; |
@@ -429,7 +460,8 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec) | |||
429 | 460 | ||
430 | static void acpi_ec_submit_query(struct acpi_ec *ec) | 461 | static void acpi_ec_submit_query(struct acpi_ec *ec) |
431 | { | 462 | { |
432 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { | 463 | if (acpi_ec_event_enabled(ec) && |
464 | !test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { | ||
433 | ec_dbg_evt("Command(%s) submitted/blocked", | 465 | ec_dbg_evt("Command(%s) submitted/blocked", |
434 | acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); | 466 | acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); |
435 | ec->nr_pending_queries++; | 467 | ec->nr_pending_queries++; |
@@ -446,6 +478,88 @@ static void acpi_ec_complete_query(struct acpi_ec *ec) | |||
446 | } | 478 | } |
447 | } | 479 | } |
448 | 480 | ||
481 | static inline void __acpi_ec_enable_event(struct acpi_ec *ec) | ||
482 | { | ||
483 | if (!test_and_set_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags)) | ||
484 | ec_log_drv("event unblocked"); | ||
485 | if (!test_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) | ||
486 | advance_transaction(ec); | ||
487 | } | ||
488 | |||
489 | static inline void __acpi_ec_disable_event(struct acpi_ec *ec) | ||
490 | { | ||
491 | if (test_and_clear_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags)) | ||
492 | ec_log_drv("event blocked"); | ||
493 | } | ||
494 | |||
495 | /* | ||
496 | * Process _Q events that might have accumulated in the EC. | ||
497 | * Run with locked ec mutex. | ||
498 | */ | ||
499 | static void acpi_ec_clear(struct acpi_ec *ec) | ||
500 | { | ||
501 | int i, status; | ||
502 | u8 value = 0; | ||
503 | |||
504 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { | ||
505 | status = acpi_ec_query(ec, &value); | ||
506 | if (status || !value) | ||
507 | break; | ||
508 | } | ||
509 | if (unlikely(i == ACPI_EC_CLEAR_MAX)) | ||
510 | pr_warn("Warning: Maximum of %d stale EC events cleared\n", i); | ||
511 | else | ||
512 | pr_info("%d stale EC events cleared\n", i); | ||
513 | } | ||
514 | |||
515 | static void acpi_ec_enable_event(struct acpi_ec *ec) | ||
516 | { | ||
517 | unsigned long flags; | ||
518 | |||
519 | spin_lock_irqsave(&ec->lock, flags); | ||
520 | if (acpi_ec_started(ec)) | ||
521 | __acpi_ec_enable_event(ec); | ||
522 | spin_unlock_irqrestore(&ec->lock, flags); | ||
523 | |||
524 | /* Drain additional events if hardware requires that */ | ||
525 | if (EC_FLAGS_CLEAR_ON_RESUME) | ||
526 | acpi_ec_clear(ec); | ||
527 | } | ||
528 | |||
529 | #ifdef CONFIG_PM_SLEEP | ||
530 | static bool acpi_ec_query_flushed(struct acpi_ec *ec) | ||
531 | { | ||
532 | bool flushed; | ||
533 | unsigned long flags; | ||
534 | |||
535 | spin_lock_irqsave(&ec->lock, flags); | ||
536 | flushed = !ec->nr_pending_queries; | ||
537 | spin_unlock_irqrestore(&ec->lock, flags); | ||
538 | return flushed; | ||
539 | } | ||
540 | |||
541 | static void __acpi_ec_flush_event(struct acpi_ec *ec) | ||
542 | { | ||
543 | /* | ||
544 | * When ec_freeze_events is true, we need to flush events in | ||
545 | * the proper position before entering the noirq stage. | ||
546 | */ | ||
547 | wait_event(ec->wait, acpi_ec_query_flushed(ec)); | ||
548 | if (ec_query_wq) | ||
549 | flush_workqueue(ec_query_wq); | ||
550 | } | ||
551 | |||
552 | static void acpi_ec_disable_event(struct acpi_ec *ec) | ||
553 | { | ||
554 | unsigned long flags; | ||
555 | |||
556 | spin_lock_irqsave(&ec->lock, flags); | ||
557 | __acpi_ec_disable_event(ec); | ||
558 | spin_unlock_irqrestore(&ec->lock, flags); | ||
559 | __acpi_ec_flush_event(ec); | ||
560 | } | ||
561 | #endif /* CONFIG_PM_SLEEP */ | ||
562 | |||
449 | static bool acpi_ec_guard_event(struct acpi_ec *ec) | 563 | static bool acpi_ec_guard_event(struct acpi_ec *ec) |
450 | { | 564 | { |
451 | bool guarded = true; | 565 | bool guarded = true; |
@@ -832,27 +946,6 @@ acpi_handle ec_get_handle(void) | |||
832 | } | 946 | } |
833 | EXPORT_SYMBOL(ec_get_handle); | 947 | EXPORT_SYMBOL(ec_get_handle); |
834 | 948 | ||
835 | /* | ||
836 | * Process _Q events that might have accumulated in the EC. | ||
837 | * Run with locked ec mutex. | ||
838 | */ | ||
839 | static void acpi_ec_clear(struct acpi_ec *ec) | ||
840 | { | ||
841 | int i, status; | ||
842 | u8 value = 0; | ||
843 | |||
844 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { | ||
845 | status = acpi_ec_query(ec, &value); | ||
846 | if (status || !value) | ||
847 | break; | ||
848 | } | ||
849 | |||
850 | if (unlikely(i == ACPI_EC_CLEAR_MAX)) | ||
851 | pr_warn("Warning: Maximum of %d stale EC events cleared\n", i); | ||
852 | else | ||
853 | pr_info("%d stale EC events cleared\n", i); | ||
854 | } | ||
855 | |||
856 | static void acpi_ec_start(struct acpi_ec *ec, bool resuming) | 949 | static void acpi_ec_start(struct acpi_ec *ec, bool resuming) |
857 | { | 950 | { |
858 | unsigned long flags; | 951 | unsigned long flags; |
@@ -896,7 +989,8 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) | |||
896 | if (!suspending) { | 989 | if (!suspending) { |
897 | acpi_ec_complete_request(ec); | 990 | acpi_ec_complete_request(ec); |
898 | ec_dbg_ref(ec, "Decrease driver"); | 991 | ec_dbg_ref(ec, "Decrease driver"); |
899 | } | 992 | } else if (!ec_freeze_events) |
993 | __acpi_ec_disable_event(ec); | ||
900 | clear_bit(EC_FLAGS_STARTED, &ec->flags); | 994 | clear_bit(EC_FLAGS_STARTED, &ec->flags); |
901 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); | 995 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); |
902 | ec_log_drv("EC stopped"); | 996 | ec_log_drv("EC stopped"); |
@@ -919,20 +1013,6 @@ void acpi_ec_block_transactions(void) | |||
919 | 1013 | ||
920 | void acpi_ec_unblock_transactions(void) | 1014 | void acpi_ec_unblock_transactions(void) |
921 | { | 1015 | { |
922 | struct acpi_ec *ec = first_ec; | ||
923 | |||
924 | if (!ec) | ||
925 | return; | ||
926 | |||
927 | /* Allow transactions to be carried out again */ | ||
928 | acpi_ec_start(ec, true); | ||
929 | |||
930 | if (EC_FLAGS_CLEAR_ON_RESUME) | ||
931 | acpi_ec_clear(ec); | ||
932 | } | ||
933 | |||
934 | void acpi_ec_unblock_transactions_early(void) | ||
935 | { | ||
936 | /* | 1016 | /* |
937 | * Allow transactions to happen again (this function is called from | 1017 | * Allow transactions to happen again (this function is called from |
938 | * atomic context during wakeup, so we don't need to acquire the mutex). | 1018 | * atomic context during wakeup, so we don't need to acquire the mutex). |
@@ -1228,13 +1308,21 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
1228 | static acpi_status | 1308 | static acpi_status |
1229 | ec_parse_io_ports(struct acpi_resource *resource, void *context); | 1309 | ec_parse_io_ports(struct acpi_resource *resource, void *context); |
1230 | 1310 | ||
1231 | static struct acpi_ec *make_acpi_ec(void) | 1311 | static void acpi_ec_free(struct acpi_ec *ec) |
1312 | { | ||
1313 | if (first_ec == ec) | ||
1314 | first_ec = NULL; | ||
1315 | if (boot_ec == ec) | ||
1316 | boot_ec = NULL; | ||
1317 | kfree(ec); | ||
1318 | } | ||
1319 | |||
1320 | static struct acpi_ec *acpi_ec_alloc(void) | ||
1232 | { | 1321 | { |
1233 | struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 1322 | struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
1234 | 1323 | ||
1235 | if (!ec) | 1324 | if (!ec) |
1236 | return NULL; | 1325 | return NULL; |
1237 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; | ||
1238 | mutex_init(&ec->mutex); | 1326 | mutex_init(&ec->mutex); |
1239 | init_waitqueue_head(&ec->wait); | 1327 | init_waitqueue_head(&ec->wait); |
1240 | INIT_LIST_HEAD(&ec->list); | 1328 | INIT_LIST_HEAD(&ec->list); |
@@ -1290,7 +1378,12 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
1290 | return AE_CTRL_TERMINATE; | 1378 | return AE_CTRL_TERMINATE; |
1291 | } | 1379 | } |
1292 | 1380 | ||
1293 | static int ec_install_handlers(struct acpi_ec *ec) | 1381 | /* |
1382 | * Note: This function returns an error code only when the address space | ||
1383 | * handler is not installed, which means "not able to handle | ||
1384 | * transactions". | ||
1385 | */ | ||
1386 | static int ec_install_handlers(struct acpi_ec *ec, bool handle_events) | ||
1294 | { | 1387 | { |
1295 | acpi_status status; | 1388 | acpi_status status; |
1296 | 1389 | ||
@@ -1319,6 +1412,16 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
1319 | set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); | 1412 | set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); |
1320 | } | 1413 | } |
1321 | 1414 | ||
1415 | if (!handle_events) | ||
1416 | return 0; | ||
1417 | |||
1418 | if (!test_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags)) { | ||
1419 | /* Find and register all query methods */ | ||
1420 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, | ||
1421 | acpi_ec_register_query_methods, | ||
1422 | NULL, ec, NULL); | ||
1423 | set_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags); | ||
1424 | } | ||
1322 | if (!test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) { | 1425 | if (!test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) { |
1323 | status = acpi_install_gpe_raw_handler(NULL, ec->gpe, | 1426 | status = acpi_install_gpe_raw_handler(NULL, ec->gpe, |
1324 | ACPI_GPE_EDGE_TRIGGERED, | 1427 | ACPI_GPE_EDGE_TRIGGERED, |
@@ -1329,6 +1432,9 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
1329 | if (test_bit(EC_FLAGS_STARTED, &ec->flags) && | 1432 | if (test_bit(EC_FLAGS_STARTED, &ec->flags) && |
1330 | ec->reference_count >= 1) | 1433 | ec->reference_count >= 1) |
1331 | acpi_ec_enable_gpe(ec, true); | 1434 | acpi_ec_enable_gpe(ec, true); |
1435 | |||
1436 | /* EC is fully operational, allow queries */ | ||
1437 | acpi_ec_enable_event(ec); | ||
1332 | } | 1438 | } |
1333 | } | 1439 | } |
1334 | 1440 | ||
@@ -1363,23 +1469,104 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
1363 | pr_err("failed to remove gpe handler\n"); | 1469 | pr_err("failed to remove gpe handler\n"); |
1364 | clear_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); | 1470 | clear_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); |
1365 | } | 1471 | } |
1472 | if (test_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags)) { | ||
1473 | acpi_ec_remove_query_handlers(ec, true, 0); | ||
1474 | clear_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags); | ||
1475 | } | ||
1366 | } | 1476 | } |
1367 | 1477 | ||
1368 | static struct acpi_ec *acpi_ec_alloc(void) | 1478 | static int acpi_ec_setup(struct acpi_ec *ec, bool handle_events) |
1369 | { | 1479 | { |
1370 | struct acpi_ec *ec; | 1480 | int ret; |
1371 | 1481 | ||
1372 | /* Check for boot EC */ | 1482 | ret = ec_install_handlers(ec, handle_events); |
1373 | if (boot_ec) { | 1483 | if (ret) |
1374 | ec = boot_ec; | 1484 | return ret; |
1375 | boot_ec = NULL; | 1485 | |
1376 | ec_remove_handlers(ec); | 1486 | /* First EC capable of handling transactions */ |
1377 | if (first_ec == ec) | 1487 | if (!first_ec) { |
1378 | first_ec = NULL; | 1488 | first_ec = ec; |
1379 | } else { | 1489 | acpi_handle_info(first_ec->handle, "Used as first EC\n"); |
1380 | ec = make_acpi_ec(); | ||
1381 | } | 1490 | } |
1382 | return ec; | 1491 | |
1492 | acpi_handle_info(ec->handle, | ||
1493 | "GPE=0x%lx, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", | ||
1494 | ec->gpe, ec->command_addr, ec->data_addr); | ||
1495 | return ret; | ||
1496 | } | ||
1497 | |||
1498 | static int acpi_config_boot_ec(struct acpi_ec *ec, acpi_handle handle, | ||
1499 | bool handle_events, bool is_ecdt) | ||
1500 | { | ||
1501 | int ret; | ||
1502 | |||
1503 | /* | ||
1504 | * Changing the ACPI handle results in a re-configuration of the | ||
1505 | * boot EC. And if it happens after the namespace initialization, | ||
1506 | * it causes _REG evaluations. | ||
1507 | */ | ||
1508 | if (boot_ec && boot_ec->handle != handle) | ||
1509 | ec_remove_handlers(boot_ec); | ||
1510 | |||
1511 | /* Unset old boot EC */ | ||
1512 | if (boot_ec != ec) | ||
1513 | acpi_ec_free(boot_ec); | ||
1514 | |||
1515 | /* | ||
1516 | * ECDT device creation is split into acpi_ec_ecdt_probe() and | ||
1517 | * acpi_ec_ecdt_start(). This function takes care of completing the | ||
1518 | * ECDT parsing logic as the handle update should be performed | ||
1519 | * between the installation/uninstallation of the handlers. | ||
1520 | */ | ||
1521 | if (ec->handle != handle) | ||
1522 | ec->handle = handle; | ||
1523 | |||
1524 | ret = acpi_ec_setup(ec, handle_events); | ||
1525 | if (ret) | ||
1526 | return ret; | ||
1527 | |||
1528 | /* Set new boot EC */ | ||
1529 | if (!boot_ec) { | ||
1530 | boot_ec = ec; | ||
1531 | boot_ec_is_ecdt = is_ecdt; | ||
1532 | } | ||
1533 | |||
1534 | acpi_handle_info(boot_ec->handle, | ||
1535 | "Used as boot %s EC to handle transactions%s\n", | ||
1536 | is_ecdt ? "ECDT" : "DSDT", | ||
1537 | handle_events ? " and events" : ""); | ||
1538 | return ret; | ||
1539 | } | ||
1540 | |||
1541 | static bool acpi_ec_ecdt_get_handle(acpi_handle *phandle) | ||
1542 | { | ||
1543 | struct acpi_table_ecdt *ecdt_ptr; | ||
1544 | acpi_status status; | ||
1545 | acpi_handle handle; | ||
1546 | |||
1547 | status = acpi_get_table(ACPI_SIG_ECDT, 1, | ||
1548 | (struct acpi_table_header **)&ecdt_ptr); | ||
1549 | if (ACPI_FAILURE(status)) | ||
1550 | return false; | ||
1551 | |||
1552 | status = acpi_get_handle(NULL, ecdt_ptr->id, &handle); | ||
1553 | if (ACPI_FAILURE(status)) | ||
1554 | return false; | ||
1555 | |||
1556 | *phandle = handle; | ||
1557 | return true; | ||
1558 | } | ||
1559 | |||
1560 | static bool acpi_is_boot_ec(struct acpi_ec *ec) | ||
1561 | { | ||
1562 | if (!boot_ec) | ||
1563 | return false; | ||
1564 | if (ec->handle == boot_ec->handle && | ||
1565 | ec->gpe == boot_ec->gpe && | ||
1566 | ec->command_addr == boot_ec->command_addr && | ||
1567 | ec->data_addr == boot_ec->data_addr) | ||
1568 | return true; | ||
1569 | return false; | ||
1383 | } | 1570 | } |
1384 | 1571 | ||
1385 | static int acpi_ec_add(struct acpi_device *device) | 1572 | static int acpi_ec_add(struct acpi_device *device) |
@@ -1395,16 +1582,21 @@ static int acpi_ec_add(struct acpi_device *device) | |||
1395 | return -ENOMEM; | 1582 | return -ENOMEM; |
1396 | if (ec_parse_device(device->handle, 0, ec, NULL) != | 1583 | if (ec_parse_device(device->handle, 0, ec, NULL) != |
1397 | AE_CTRL_TERMINATE) { | 1584 | AE_CTRL_TERMINATE) { |
1398 | kfree(ec); | 1585 | ret = -EINVAL; |
1399 | return -EINVAL; | 1586 | goto err_alloc; |
1400 | } | 1587 | } |
1401 | 1588 | ||
1402 | /* Find and register all query methods */ | 1589 | if (acpi_is_boot_ec(ec)) { |
1403 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, | 1590 | boot_ec_is_ecdt = false; |
1404 | acpi_ec_register_query_methods, NULL, ec, NULL); | 1591 | acpi_handle_debug(ec->handle, "duplicated.\n"); |
1592 | acpi_ec_free(ec); | ||
1593 | ec = boot_ec; | ||
1594 | ret = acpi_config_boot_ec(ec, ec->handle, true, false); | ||
1595 | } else | ||
1596 | ret = acpi_ec_setup(ec, true); | ||
1597 | if (ret) | ||
1598 | goto err_query; | ||
1405 | 1599 | ||
1406 | if (!first_ec) | ||
1407 | first_ec = ec; | ||
1408 | device->driver_data = ec; | 1600 | device->driver_data = ec; |
1409 | 1601 | ||
1410 | ret = !!request_region(ec->data_addr, 1, "EC data"); | 1602 | ret = !!request_region(ec->data_addr, 1, "EC data"); |
@@ -1412,20 +1604,17 @@ static int acpi_ec_add(struct acpi_device *device) | |||
1412 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); | 1604 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); |
1413 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); | 1605 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); |
1414 | 1606 | ||
1415 | pr_info("GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | ||
1416 | ec->gpe, ec->command_addr, ec->data_addr); | ||
1417 | |||
1418 | ret = ec_install_handlers(ec); | ||
1419 | |||
1420 | /* Reprobe devices depending on the EC */ | 1607 | /* Reprobe devices depending on the EC */ |
1421 | acpi_walk_dep_device_list(ec->handle); | 1608 | acpi_walk_dep_device_list(ec->handle); |
1609 | acpi_handle_debug(ec->handle, "enumerated.\n"); | ||
1610 | return 0; | ||
1422 | 1611 | ||
1423 | /* EC is fully operational, allow queries */ | 1612 | err_query: |
1424 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 1613 | if (ec != boot_ec) |
1425 | 1614 | acpi_ec_remove_query_handlers(ec, true, 0); | |
1426 | /* Clear stale _Q events if hardware might require that */ | 1615 | err_alloc: |
1427 | if (EC_FLAGS_CLEAR_ON_RESUME) | 1616 | if (ec != boot_ec) |
1428 | acpi_ec_clear(ec); | 1617 | acpi_ec_free(ec); |
1429 | return ret; | 1618 | return ret; |
1430 | } | 1619 | } |
1431 | 1620 | ||
@@ -1437,14 +1626,13 @@ static int acpi_ec_remove(struct acpi_device *device) | |||
1437 | return -EINVAL; | 1626 | return -EINVAL; |
1438 | 1627 | ||
1439 | ec = acpi_driver_data(device); | 1628 | ec = acpi_driver_data(device); |
1440 | ec_remove_handlers(ec); | ||
1441 | acpi_ec_remove_query_handlers(ec, true, 0); | ||
1442 | release_region(ec->data_addr, 1); | 1629 | release_region(ec->data_addr, 1); |
1443 | release_region(ec->command_addr, 1); | 1630 | release_region(ec->command_addr, 1); |
1444 | device->driver_data = NULL; | 1631 | device->driver_data = NULL; |
1445 | if (ec == first_ec) | 1632 | if (ec != boot_ec) { |
1446 | first_ec = NULL; | 1633 | ec_remove_handlers(ec); |
1447 | kfree(ec); | 1634 | acpi_ec_free(ec); |
1635 | } | ||
1448 | return 0; | 1636 | return 0; |
1449 | } | 1637 | } |
1450 | 1638 | ||
@@ -1486,9 +1674,8 @@ int __init acpi_ec_dsdt_probe(void) | |||
1486 | if (!ec) | 1674 | if (!ec) |
1487 | return -ENOMEM; | 1675 | return -ENOMEM; |
1488 | /* | 1676 | /* |
1489 | * Finding EC from DSDT if there is no ECDT EC available. When this | 1677 | * At this point, the namespace is initialized, so start to find |
1490 | * function is invoked, ACPI tables have been fully loaded, we can | 1678 | * the namespace objects. |
1491 | * walk namespace now. | ||
1492 | */ | 1679 | */ |
1493 | status = acpi_get_devices(ec_device_ids[0].id, | 1680 | status = acpi_get_devices(ec_device_ids[0].id, |
1494 | ec_parse_device, ec, NULL); | 1681 | ec_parse_device, ec, NULL); |
@@ -1496,16 +1683,47 @@ int __init acpi_ec_dsdt_probe(void) | |||
1496 | ret = -ENODEV; | 1683 | ret = -ENODEV; |
1497 | goto error; | 1684 | goto error; |
1498 | } | 1685 | } |
1499 | ret = ec_install_handlers(ec); | 1686 | /* |
1500 | 1687 | * When the DSDT EC is available, always re-configure boot EC to | |
1688 | * have _REG evaluated. _REG can only be evaluated after the | ||
1689 | * namespace initialization. | ||
1690 | * At this point, the GPE is not fully initialized, so do not to | ||
1691 | * handle the events. | ||
1692 | */ | ||
1693 | ret = acpi_config_boot_ec(ec, ec->handle, false, false); | ||
1501 | error: | 1694 | error: |
1502 | if (ret) | 1695 | if (ret) |
1503 | kfree(ec); | 1696 | acpi_ec_free(ec); |
1504 | else | ||
1505 | first_ec = boot_ec = ec; | ||
1506 | return ret; | 1697 | return ret; |
1507 | } | 1698 | } |
1508 | 1699 | ||
1700 | /* | ||
1701 | * If the DSDT EC is not functioning, we still need to prepare a fully | ||
1702 | * functioning ECDT EC first in order to handle the events. | ||
1703 | * https://bugzilla.kernel.org/show_bug.cgi?id=115021 | ||
1704 | */ | ||
1705 | int __init acpi_ec_ecdt_start(void) | ||
1706 | { | ||
1707 | acpi_handle handle; | ||
1708 | |||
1709 | if (!boot_ec) | ||
1710 | return -ENODEV; | ||
1711 | /* | ||
1712 | * The DSDT EC should have already been started in | ||
1713 | * acpi_ec_add(). | ||
1714 | */ | ||
1715 | if (!boot_ec_is_ecdt) | ||
1716 | return -ENODEV; | ||
1717 | |||
1718 | /* | ||
1719 | * At this point, the namespace and the GPE is initialized, so | ||
1720 | * start to find the namespace objects and handle the events. | ||
1721 | */ | ||
1722 | if (!acpi_ec_ecdt_get_handle(&handle)) | ||
1723 | return -ENODEV; | ||
1724 | return acpi_config_boot_ec(boot_ec, handle, true, true); | ||
1725 | } | ||
1726 | |||
1509 | #if 0 | 1727 | #if 0 |
1510 | /* | 1728 | /* |
1511 | * Some EC firmware variations refuses to respond QR_EC when SCI_EVT is not | 1729 | * Some EC firmware variations refuses to respond QR_EC when SCI_EVT is not |
@@ -1600,7 +1818,6 @@ int __init acpi_ec_ecdt_probe(void) | |||
1600 | goto error; | 1818 | goto error; |
1601 | } | 1819 | } |
1602 | 1820 | ||
1603 | pr_info("EC description table is found, configuring boot EC\n"); | ||
1604 | if (EC_FLAGS_CORRECT_ECDT) { | 1821 | if (EC_FLAGS_CORRECT_ECDT) { |
1605 | ec->command_addr = ecdt_ptr->data.address; | 1822 | ec->command_addr = ecdt_ptr->data.address; |
1606 | ec->data_addr = ecdt_ptr->control.address; | 1823 | ec->data_addr = ecdt_ptr->control.address; |
@@ -1609,16 +1826,90 @@ int __init acpi_ec_ecdt_probe(void) | |||
1609 | ec->data_addr = ecdt_ptr->data.address; | 1826 | ec->data_addr = ecdt_ptr->data.address; |
1610 | } | 1827 | } |
1611 | ec->gpe = ecdt_ptr->gpe; | 1828 | ec->gpe = ecdt_ptr->gpe; |
1612 | ec->handle = ACPI_ROOT_OBJECT; | 1829 | |
1613 | ret = ec_install_handlers(ec); | 1830 | /* |
1831 | * At this point, the namespace is not initialized, so do not find | ||
1832 | * the namespace objects, or handle the events. | ||
1833 | */ | ||
1834 | ret = acpi_config_boot_ec(ec, ACPI_ROOT_OBJECT, false, true); | ||
1614 | error: | 1835 | error: |
1615 | if (ret) | 1836 | if (ret) |
1616 | kfree(ec); | 1837 | acpi_ec_free(ec); |
1617 | else | ||
1618 | first_ec = boot_ec = ec; | ||
1619 | return ret; | 1838 | return ret; |
1620 | } | 1839 | } |
1621 | 1840 | ||
1841 | #ifdef CONFIG_PM_SLEEP | ||
1842 | static void acpi_ec_enter_noirq(struct acpi_ec *ec) | ||
1843 | { | ||
1844 | unsigned long flags; | ||
1845 | |||
1846 | if (ec == first_ec) { | ||
1847 | spin_lock_irqsave(&ec->lock, flags); | ||
1848 | ec->saved_busy_polling = ec_busy_polling; | ||
1849 | ec->saved_polling_guard = ec_polling_guard; | ||
1850 | ec_busy_polling = true; | ||
1851 | ec_polling_guard = 0; | ||
1852 | ec_log_drv("interrupt blocked"); | ||
1853 | spin_unlock_irqrestore(&ec->lock, flags); | ||
1854 | } | ||
1855 | } | ||
1856 | |||
1857 | static void acpi_ec_leave_noirq(struct acpi_ec *ec) | ||
1858 | { | ||
1859 | unsigned long flags; | ||
1860 | |||
1861 | if (ec == first_ec) { | ||
1862 | spin_lock_irqsave(&ec->lock, flags); | ||
1863 | ec_busy_polling = ec->saved_busy_polling; | ||
1864 | ec_polling_guard = ec->saved_polling_guard; | ||
1865 | ec_log_drv("interrupt unblocked"); | ||
1866 | spin_unlock_irqrestore(&ec->lock, flags); | ||
1867 | } | ||
1868 | } | ||
1869 | |||
1870 | static int acpi_ec_suspend_noirq(struct device *dev) | ||
1871 | { | ||
1872 | struct acpi_ec *ec = | ||
1873 | acpi_driver_data(to_acpi_device(dev)); | ||
1874 | |||
1875 | acpi_ec_enter_noirq(ec); | ||
1876 | return 0; | ||
1877 | } | ||
1878 | |||
1879 | static int acpi_ec_resume_noirq(struct device *dev) | ||
1880 | { | ||
1881 | struct acpi_ec *ec = | ||
1882 | acpi_driver_data(to_acpi_device(dev)); | ||
1883 | |||
1884 | acpi_ec_leave_noirq(ec); | ||
1885 | return 0; | ||
1886 | } | ||
1887 | |||
1888 | static int acpi_ec_suspend(struct device *dev) | ||
1889 | { | ||
1890 | struct acpi_ec *ec = | ||
1891 | acpi_driver_data(to_acpi_device(dev)); | ||
1892 | |||
1893 | if (ec_freeze_events) | ||
1894 | acpi_ec_disable_event(ec); | ||
1895 | return 0; | ||
1896 | } | ||
1897 | |||
1898 | static int acpi_ec_resume(struct device *dev) | ||
1899 | { | ||
1900 | struct acpi_ec *ec = | ||
1901 | acpi_driver_data(to_acpi_device(dev)); | ||
1902 | |||
1903 | acpi_ec_enable_event(ec); | ||
1904 | return 0; | ||
1905 | } | ||
1906 | #endif | ||
1907 | |||
1908 | static const struct dev_pm_ops acpi_ec_pm = { | ||
1909 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend_noirq, acpi_ec_resume_noirq) | ||
1910 | SET_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend, acpi_ec_resume) | ||
1911 | }; | ||
1912 | |||
1622 | static int param_set_event_clearing(const char *val, struct kernel_param *kp) | 1913 | static int param_set_event_clearing(const char *val, struct kernel_param *kp) |
1623 | { | 1914 | { |
1624 | int result = 0; | 1915 | int result = 0; |
@@ -1664,6 +1955,7 @@ static struct acpi_driver acpi_ec_driver = { | |||
1664 | .add = acpi_ec_add, | 1955 | .add = acpi_ec_add, |
1665 | .remove = acpi_ec_remove, | 1956 | .remove = acpi_ec_remove, |
1666 | }, | 1957 | }, |
1958 | .drv.pm = &acpi_ec_pm, | ||
1667 | }; | 1959 | }; |
1668 | 1960 | ||
1669 | static inline int acpi_ec_query_init(void) | 1961 | static inline int acpi_ec_query_init(void) |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 384cfc3083e1..6cf4988206f2 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -129,8 +129,18 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state) | |||
129 | 129 | ||
130 | control = obj->package.elements[1].integer.value; | 130 | control = obj->package.elements[1].integer.value; |
131 | for (i = 0; i < fan->fps_count; i++) { | 131 | for (i = 0; i < fan->fps_count; i++) { |
132 | if (control == fan->fps[i].control) | 132 | /* |
133 | * When Fine Grain Control is set, return the state | ||
134 | * corresponding to maximum fan->fps[i].control | ||
135 | * value compared to the current speed. Here the | ||
136 | * fan->fps[] is sorted array with increasing speed. | ||
137 | */ | ||
138 | if (fan->fif.fine_grain_ctrl && control < fan->fps[i].control) { | ||
139 | i = (i > 0) ? i - 1 : 0; | ||
133 | break; | 140 | break; |
141 | } else if (control == fan->fps[i].control) { | ||
142 | break; | ||
143 | } | ||
134 | } | 144 | } |
135 | if (i == fan->fps_count) { | 145 | if (i == fan->fps_count) { |
136 | dev_dbg(&device->dev, "Invalid control value returned\n"); | 146 | dev_dbg(&device->dev, "Invalid control value returned\n"); |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 940218ff0193..4bf8bf16d096 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -116,7 +116,6 @@ bool acpi_device_is_present(struct acpi_device *adev); | |||
116 | bool acpi_device_is_battery(struct acpi_device *adev); | 116 | bool acpi_device_is_battery(struct acpi_device *adev); |
117 | bool acpi_device_is_first_physical_node(struct acpi_device *adev, | 117 | bool acpi_device_is_first_physical_node(struct acpi_device *adev, |
118 | const struct device *dev); | 118 | const struct device *dev); |
119 | struct device *acpi_get_first_physical_node(struct acpi_device *adev); | ||
120 | 119 | ||
121 | /* -------------------------------------------------------------------------- | 120 | /* -------------------------------------------------------------------------- |
122 | Device Matching and Notification | 121 | Device Matching and Notification |
@@ -174,6 +173,8 @@ struct acpi_ec { | |||
174 | struct work_struct work; | 173 | struct work_struct work; |
175 | unsigned long timestamp; | 174 | unsigned long timestamp; |
176 | unsigned long nr_pending_queries; | 175 | unsigned long nr_pending_queries; |
176 | bool saved_busy_polling; | ||
177 | unsigned int saved_polling_guard; | ||
177 | }; | 178 | }; |
178 | 179 | ||
179 | extern struct acpi_ec *first_ec; | 180 | extern struct acpi_ec *first_ec; |
@@ -185,9 +186,9 @@ typedef int (*acpi_ec_query_func) (void *data); | |||
185 | int acpi_ec_init(void); | 186 | int acpi_ec_init(void); |
186 | int acpi_ec_ecdt_probe(void); | 187 | int acpi_ec_ecdt_probe(void); |
187 | int acpi_ec_dsdt_probe(void); | 188 | int acpi_ec_dsdt_probe(void); |
189 | int acpi_ec_ecdt_start(void); | ||
188 | void acpi_ec_block_transactions(void); | 190 | void acpi_ec_block_transactions(void); |
189 | void acpi_ec_unblock_transactions(void); | 191 | void acpi_ec_unblock_transactions(void); |
190 | void acpi_ec_unblock_transactions_early(void); | ||
191 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | 192 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, |
192 | acpi_handle handle, acpi_ec_query_func func, | 193 | acpi_handle handle, acpi_ec_query_func func, |
193 | void *data); | 194 | void *data); |
@@ -225,4 +226,14 @@ static inline void suspend_nvs_restore(void) {} | |||
225 | void acpi_init_properties(struct acpi_device *adev); | 226 | void acpi_init_properties(struct acpi_device *adev); |
226 | void acpi_free_properties(struct acpi_device *adev); | 227 | void acpi_free_properties(struct acpi_device *adev); |
227 | 228 | ||
229 | /*-------------------------------------------------------------------------- | ||
230 | Watchdog | ||
231 | -------------------------------------------------------------------------- */ | ||
232 | |||
233 | #ifdef CONFIG_ACPI_WATCHDOG | ||
234 | void acpi_watchdog_init(void); | ||
235 | #else | ||
236 | static inline void acpi_watchdog_init(void) {} | ||
237 | #endif | ||
238 | |||
228 | #endif /* _ACPI_INTERNAL_H_ */ | 239 | #endif /* _ACPI_INTERNAL_H_ */ |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 2c45dd3acc17..c576a6fe4ebb 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -411,7 +411,15 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
411 | int gsi; | 411 | int gsi; |
412 | u8 pin; | 412 | u8 pin; |
413 | int triggering = ACPI_LEVEL_SENSITIVE; | 413 | int triggering = ACPI_LEVEL_SENSITIVE; |
414 | int polarity = ACPI_ACTIVE_LOW; | 414 | /* |
415 | * On ARM systems with the GIC interrupt model, level interrupts | ||
416 | * are always polarity high by specification; PCI legacy | ||
417 | * IRQs lines are inverted before reaching the interrupt | ||
418 | * controller and must therefore be considered active high | ||
419 | * as default. | ||
420 | */ | ||
421 | int polarity = acpi_irq_model == ACPI_IRQ_MODEL_GIC ? | ||
422 | ACPI_ACTIVE_HIGH : ACPI_ACTIVE_LOW; | ||
415 | char *link = NULL; | 423 | char *link = NULL; |
416 | char link_desc[16]; | 424 | char link_desc[16]; |
417 | int rc; | 425 | int rc; |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 0553aeebb228..8f8552a19e63 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -245,8 +245,8 @@ static int __acpi_processor_start(struct acpi_device *device) | |||
245 | return 0; | 245 | return 0; |
246 | 246 | ||
247 | result = acpi_cppc_processor_probe(pr); | 247 | result = acpi_cppc_processor_probe(pr); |
248 | if (result) | 248 | if (result && !IS_ENABLED(CONFIG_ACPI_CPU_FREQ_PSS)) |
249 | return -ENODEV; | 249 | dev_warn(&device->dev, "CPPC data invalid or not present\n"); |
250 | 250 | ||
251 | if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) | 251 | if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) |
252 | acpi_processor_power_init(pr); | 252 | acpi_processor_power_init(pr); |
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index f2fd3fee588a..03f5ec11ab31 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c | |||
@@ -468,10 +468,11 @@ static int acpi_data_get_property_array(struct acpi_device_data *data, | |||
468 | } | 468 | } |
469 | 469 | ||
470 | /** | 470 | /** |
471 | * acpi_data_get_property_reference - returns handle to the referenced object | 471 | * __acpi_node_get_property_reference - returns handle to the referenced object |
472 | * @data: ACPI device data object containing the property | 472 | * @fwnode: Firmware node to get the property from |
473 | * @propname: Name of the property | 473 | * @propname: Name of the property |
474 | * @index: Index of the reference to return | 474 | * @index: Index of the reference to return |
475 | * @num_args: Maximum number of arguments after each reference | ||
475 | * @args: Location to store the returned reference with optional arguments | 476 | * @args: Location to store the returned reference with optional arguments |
476 | * | 477 | * |
477 | * Find property with @name, verifify that it is a package containing at least | 478 | * Find property with @name, verifify that it is a package containing at least |
@@ -482,17 +483,40 @@ static int acpi_data_get_property_array(struct acpi_device_data *data, | |||
482 | * If there's more than one reference in the property value package, @index is | 483 | * If there's more than one reference in the property value package, @index is |
483 | * used to select the one to return. | 484 | * used to select the one to return. |
484 | * | 485 | * |
486 | * It is possible to leave holes in the property value set like in the | ||
487 | * example below: | ||
488 | * | ||
489 | * Package () { | ||
490 | * "cs-gpios", | ||
491 | * Package () { | ||
492 | * ^GPIO, 19, 0, 0, | ||
493 | * ^GPIO, 20, 0, 0, | ||
494 | * 0, | ||
495 | * ^GPIO, 21, 0, 0, | ||
496 | * } | ||
497 | * } | ||
498 | * | ||
499 | * Calling this function with index %2 return %-ENOENT and with index %3 | ||
500 | * returns the last entry. If the property does not contain any more values | ||
501 | * %-ENODATA is returned. The NULL entry must be single integer and | ||
502 | * preferably contain value %0. | ||
503 | * | ||
485 | * Return: %0 on success, negative error code on failure. | 504 | * Return: %0 on success, negative error code on failure. |
486 | */ | 505 | */ |
487 | static int acpi_data_get_property_reference(struct acpi_device_data *data, | 506 | int __acpi_node_get_property_reference(struct fwnode_handle *fwnode, |
488 | const char *propname, size_t index, | 507 | const char *propname, size_t index, size_t num_args, |
489 | struct acpi_reference_args *args) | 508 | struct acpi_reference_args *args) |
490 | { | 509 | { |
491 | const union acpi_object *element, *end; | 510 | const union acpi_object *element, *end; |
492 | const union acpi_object *obj; | 511 | const union acpi_object *obj; |
512 | struct acpi_device_data *data; | ||
493 | struct acpi_device *device; | 513 | struct acpi_device *device; |
494 | int ret, idx = 0; | 514 | int ret, idx = 0; |
495 | 515 | ||
516 | data = acpi_device_data_of_node(fwnode); | ||
517 | if (!data) | ||
518 | return -EINVAL; | ||
519 | |||
496 | ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); | 520 | ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); |
497 | if (ret) | 521 | if (ret) |
498 | return ret; | 522 | return ret; |
@@ -532,59 +556,54 @@ static int acpi_data_get_property_reference(struct acpi_device_data *data, | |||
532 | while (element < end) { | 556 | while (element < end) { |
533 | u32 nargs, i; | 557 | u32 nargs, i; |
534 | 558 | ||
535 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) | 559 | if (element->type == ACPI_TYPE_LOCAL_REFERENCE) { |
536 | return -EPROTO; | 560 | ret = acpi_bus_get_device(element->reference.handle, |
537 | 561 | &device); | |
538 | ret = acpi_bus_get_device(element->reference.handle, &device); | 562 | if (ret) |
539 | if (ret) | 563 | return -ENODEV; |
540 | return -ENODEV; | 564 | |
541 | 565 | nargs = 0; | |
542 | element++; | 566 | element++; |
543 | nargs = 0; | 567 | |
544 | 568 | /* assume following integer elements are all args */ | |
545 | /* assume following integer elements are all args */ | 569 | for (i = 0; element + i < end && i < num_args; i++) { |
546 | for (i = 0; element + i < end; i++) { | 570 | int type = element[i].type; |
547 | int type = element[i].type; | 571 | |
572 | if (type == ACPI_TYPE_INTEGER) | ||
573 | nargs++; | ||
574 | else if (type == ACPI_TYPE_LOCAL_REFERENCE) | ||
575 | break; | ||
576 | else | ||
577 | return -EPROTO; | ||
578 | } | ||
548 | 579 | ||
549 | if (type == ACPI_TYPE_INTEGER) | 580 | if (nargs > MAX_ACPI_REFERENCE_ARGS) |
550 | nargs++; | ||
551 | else if (type == ACPI_TYPE_LOCAL_REFERENCE) | ||
552 | break; | ||
553 | else | ||
554 | return -EPROTO; | 581 | return -EPROTO; |
555 | } | ||
556 | 582 | ||
557 | if (idx++ == index) { | 583 | if (idx == index) { |
558 | args->adev = device; | 584 | args->adev = device; |
559 | args->nargs = nargs; | 585 | args->nargs = nargs; |
560 | for (i = 0; i < nargs; i++) | 586 | for (i = 0; i < nargs; i++) |
561 | args->args[i] = element[i].integer.value; | 587 | args->args[i] = element[i].integer.value; |
562 | 588 | ||
563 | return 0; | 589 | return 0; |
590 | } | ||
591 | |||
592 | element += nargs; | ||
593 | } else if (element->type == ACPI_TYPE_INTEGER) { | ||
594 | if (idx == index) | ||
595 | return -ENOENT; | ||
596 | element++; | ||
597 | } else { | ||
598 | return -EPROTO; | ||
564 | } | 599 | } |
565 | 600 | ||
566 | element += nargs; | 601 | idx++; |
567 | } | 602 | } |
568 | 603 | ||
569 | return -EPROTO; | 604 | return -ENODATA; |
570 | } | ||
571 | |||
572 | /** | ||
573 | * acpi_node_get_property_reference - get a handle to the referenced object. | ||
574 | * @fwnode: Firmware node to get the property from. | ||
575 | * @propname: Name of the property. | ||
576 | * @index: Index of the reference to return. | ||
577 | * @args: Location to store the returned reference with optional arguments. | ||
578 | */ | ||
579 | int acpi_node_get_property_reference(struct fwnode_handle *fwnode, | ||
580 | const char *name, size_t index, | ||
581 | struct acpi_reference_args *args) | ||
582 | { | ||
583 | struct acpi_device_data *data = acpi_device_data_of_node(fwnode); | ||
584 | |||
585 | return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL; | ||
586 | } | 605 | } |
587 | EXPORT_SYMBOL_GPL(acpi_node_get_property_reference); | 606 | EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); |
588 | 607 | ||
589 | static int acpi_data_prop_read_single(struct acpi_device_data *data, | 608 | static int acpi_data_prop_read_single(struct acpi_device_data *data, |
590 | const char *propname, | 609 | const char *propname, |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e878fc799af7..035ac646d8db 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -2002,6 +2002,7 @@ int __init acpi_scan_init(void) | |||
2002 | acpi_pnp_init(); | 2002 | acpi_pnp_init(); |
2003 | acpi_int340x_thermal_init(); | 2003 | acpi_int340x_thermal_init(); |
2004 | acpi_amba_init(); | 2004 | acpi_amba_init(); |
2005 | acpi_watchdog_init(); | ||
2005 | 2006 | ||
2006 | acpi_scan_add_handler(&generic_device_handler); | 2007 | acpi_scan_add_handler(&generic_device_handler); |
2007 | 2008 | ||
@@ -2044,6 +2045,7 @@ int __init acpi_scan_init(void) | |||
2044 | } | 2045 | } |
2045 | 2046 | ||
2046 | acpi_update_all_gpes(); | 2047 | acpi_update_all_gpes(); |
2048 | acpi_ec_ecdt_start(); | ||
2047 | 2049 | ||
2048 | acpi_scan_initialized = true; | 2050 | acpi_scan_initialized = true; |
2049 | 2051 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 2b38c1bb0446..deb0ff78eba8 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -572,7 +572,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
572 | 572 | ||
573 | acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status); | 573 | acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status); |
574 | 574 | ||
575 | if (pwr_btn_status & ACPI_EVENT_FLAG_SET) { | 575 | if (pwr_btn_status & ACPI_EVENT_FLAG_STATUS_SET) { |
576 | acpi_clear_event(ACPI_EVENT_POWER_BUTTON); | 576 | acpi_clear_event(ACPI_EVENT_POWER_BUTTON); |
577 | /* Flag for later */ | 577 | /* Flag for later */ |
578 | pwr_btn_event_pending = true; | 578 | pwr_btn_event_pending = true; |
@@ -586,7 +586,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
586 | */ | 586 | */ |
587 | acpi_disable_all_gpes(); | 587 | acpi_disable_all_gpes(); |
588 | /* Allow EC transactions to happen. */ | 588 | /* Allow EC transactions to happen. */ |
589 | acpi_ec_unblock_transactions_early(); | 589 | acpi_ec_unblock_transactions(); |
590 | 590 | ||
591 | suspend_nvs_restore(); | 591 | suspend_nvs_restore(); |
592 | 592 | ||
@@ -784,7 +784,7 @@ static void acpi_hibernation_leave(void) | |||
784 | /* Restore the NVS memory area */ | 784 | /* Restore the NVS memory area */ |
785 | suspend_nvs_restore(); | 785 | suspend_nvs_restore(); |
786 | /* Allow EC transactions to happen. */ | 786 | /* Allow EC transactions to happen. */ |
787 | acpi_ec_unblock_transactions_early(); | 787 | acpi_ec_unblock_transactions(); |
788 | } | 788 | } |
789 | 789 | ||
790 | static void acpi_pm_thaw(void) | 790 | static void acpi_pm_thaw(void) |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 358165e9f5b8..703c26e7022c 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -314,10 +314,14 @@ static struct kobject *tables_kobj; | |||
314 | static struct kobject *dynamic_tables_kobj; | 314 | static struct kobject *dynamic_tables_kobj; |
315 | static struct kobject *hotplug_kobj; | 315 | static struct kobject *hotplug_kobj; |
316 | 316 | ||
317 | #define ACPI_MAX_TABLE_INSTANCES 999 | ||
318 | #define ACPI_INST_SIZE 4 /* including trailing 0 */ | ||
319 | |||
317 | struct acpi_table_attr { | 320 | struct acpi_table_attr { |
318 | struct bin_attribute attr; | 321 | struct bin_attribute attr; |
319 | char name[8]; | 322 | char name[ACPI_NAME_SIZE]; |
320 | int instance; | 323 | int instance; |
324 | char filename[ACPI_NAME_SIZE+ACPI_INST_SIZE]; | ||
321 | struct list_head node; | 325 | struct list_head node; |
322 | }; | 326 | }; |
323 | 327 | ||
@@ -329,14 +333,9 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, | |||
329 | container_of(bin_attr, struct acpi_table_attr, attr); | 333 | container_of(bin_attr, struct acpi_table_attr, attr); |
330 | struct acpi_table_header *table_header = NULL; | 334 | struct acpi_table_header *table_header = NULL; |
331 | acpi_status status; | 335 | acpi_status status; |
332 | char name[ACPI_NAME_SIZE]; | ||
333 | |||
334 | if (strncmp(table_attr->name, "NULL", 4)) | ||
335 | memcpy(name, table_attr->name, ACPI_NAME_SIZE); | ||
336 | else | ||
337 | memcpy(name, "\0\0\0\0", 4); | ||
338 | 336 | ||
339 | status = acpi_get_table(name, table_attr->instance, &table_header); | 337 | status = acpi_get_table(table_attr->name, table_attr->instance, |
338 | &table_header); | ||
340 | if (ACPI_FAILURE(status)) | 339 | if (ACPI_FAILURE(status)) |
341 | return -ENODEV; | 340 | return -ENODEV; |
342 | 341 | ||
@@ -344,38 +343,45 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, | |||
344 | table_header, table_header->length); | 343 | table_header, table_header->length); |
345 | } | 344 | } |
346 | 345 | ||
347 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | 346 | static int acpi_table_attr_init(struct kobject *tables_obj, |
348 | struct acpi_table_header *table_header) | 347 | struct acpi_table_attr *table_attr, |
348 | struct acpi_table_header *table_header) | ||
349 | { | 349 | { |
350 | struct acpi_table_header *header = NULL; | 350 | struct acpi_table_header *header = NULL; |
351 | struct acpi_table_attr *attr = NULL; | 351 | struct acpi_table_attr *attr = NULL; |
352 | char instance_str[ACPI_INST_SIZE]; | ||
352 | 353 | ||
353 | sysfs_attr_init(&table_attr->attr.attr); | 354 | sysfs_attr_init(&table_attr->attr.attr); |
354 | if (table_header->signature[0] != '\0') | 355 | ACPI_MOVE_NAME(table_attr->name, table_header->signature); |
355 | memcpy(table_attr->name, table_header->signature, | ||
356 | ACPI_NAME_SIZE); | ||
357 | else | ||
358 | memcpy(table_attr->name, "NULL", 4); | ||
359 | 356 | ||
360 | list_for_each_entry(attr, &acpi_table_attr_list, node) { | 357 | list_for_each_entry(attr, &acpi_table_attr_list, node) { |
361 | if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE)) | 358 | if (ACPI_COMPARE_NAME(table_attr->name, attr->name)) |
362 | if (table_attr->instance < attr->instance) | 359 | if (table_attr->instance < attr->instance) |
363 | table_attr->instance = attr->instance; | 360 | table_attr->instance = attr->instance; |
364 | } | 361 | } |
365 | table_attr->instance++; | 362 | table_attr->instance++; |
363 | if (table_attr->instance > ACPI_MAX_TABLE_INSTANCES) { | ||
364 | pr_warn("%4.4s: too many table instances\n", | ||
365 | table_attr->name); | ||
366 | return -ERANGE; | ||
367 | } | ||
366 | 368 | ||
369 | ACPI_MOVE_NAME(table_attr->filename, table_header->signature); | ||
370 | table_attr->filename[ACPI_NAME_SIZE] = '\0'; | ||
367 | if (table_attr->instance > 1 || (table_attr->instance == 1 && | 371 | if (table_attr->instance > 1 || (table_attr->instance == 1 && |
368 | !acpi_get_table | 372 | !acpi_get_table |
369 | (table_header->signature, 2, &header))) | 373 | (table_header->signature, 2, &header))) { |
370 | sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", | 374 | snprintf(instance_str, sizeof(instance_str), "%u", |
371 | table_attr->instance); | 375 | table_attr->instance); |
376 | strcat(table_attr->filename, instance_str); | ||
377 | } | ||
372 | 378 | ||
373 | table_attr->attr.size = table_header->length; | 379 | table_attr->attr.size = table_header->length; |
374 | table_attr->attr.read = acpi_table_show; | 380 | table_attr->attr.read = acpi_table_show; |
375 | table_attr->attr.attr.name = table_attr->name; | 381 | table_attr->attr.attr.name = table_attr->filename; |
376 | table_attr->attr.attr.mode = 0400; | 382 | table_attr->attr.attr.mode = 0400; |
377 | 383 | ||
378 | return; | 384 | return sysfs_create_bin_file(tables_obj, &table_attr->attr); |
379 | } | 385 | } |
380 | 386 | ||
381 | acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context) | 387 | acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context) |
@@ -383,21 +389,22 @@ acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context) | |||
383 | struct acpi_table_attr *table_attr; | 389 | struct acpi_table_attr *table_attr; |
384 | 390 | ||
385 | switch (event) { | 391 | switch (event) { |
386 | case ACPI_TABLE_EVENT_LOAD: | 392 | case ACPI_TABLE_EVENT_INSTALL: |
387 | table_attr = | 393 | table_attr = |
388 | kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); | 394 | kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); |
389 | if (!table_attr) | 395 | if (!table_attr) |
390 | return AE_NO_MEMORY; | 396 | return AE_NO_MEMORY; |
391 | 397 | ||
392 | acpi_table_attr_init(table_attr, table); | 398 | if (acpi_table_attr_init(dynamic_tables_kobj, |
393 | if (sysfs_create_bin_file(dynamic_tables_kobj, | 399 | table_attr, table)) { |
394 | &table_attr->attr)) { | ||
395 | kfree(table_attr); | 400 | kfree(table_attr); |
396 | return AE_ERROR; | 401 | return AE_ERROR; |
397 | } else | 402 | } |
398 | list_add_tail(&table_attr->node, &acpi_table_attr_list); | 403 | list_add_tail(&table_attr->node, &acpi_table_attr_list); |
399 | break; | 404 | break; |
405 | case ACPI_TABLE_EVENT_LOAD: | ||
400 | case ACPI_TABLE_EVENT_UNLOAD: | 406 | case ACPI_TABLE_EVENT_UNLOAD: |
407 | case ACPI_TABLE_EVENT_UNINSTALL: | ||
401 | /* | 408 | /* |
402 | * we do not need to do anything right now | 409 | * we do not need to do anything right now |
403 | * because the table is not deleted from the | 410 | * because the table is not deleted from the |
@@ -435,13 +442,12 @@ static int acpi_tables_sysfs_init(void) | |||
435 | if (ACPI_FAILURE(status)) | 442 | if (ACPI_FAILURE(status)) |
436 | continue; | 443 | continue; |
437 | 444 | ||
438 | table_attr = NULL; | ||
439 | table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL); | 445 | table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL); |
440 | if (!table_attr) | 446 | if (!table_attr) |
441 | return -ENOMEM; | 447 | return -ENOMEM; |
442 | 448 | ||
443 | acpi_table_attr_init(table_attr, table_header); | 449 | ret = acpi_table_attr_init(tables_kobj, |
444 | ret = sysfs_create_bin_file(tables_kobj, &table_attr->attr); | 450 | table_attr, table_header); |
445 | if (ret) { | 451 | if (ret) { |
446 | kfree(table_attr); | 452 | kfree(table_attr); |
447 | return ret; | 453 | return ret; |
@@ -597,14 +603,27 @@ static ssize_t counter_show(struct kobject *kobj, | |||
597 | if (result) | 603 | if (result) |
598 | goto end; | 604 | goto end; |
599 | 605 | ||
606 | if (status & ACPI_EVENT_FLAG_ENABLE_SET) | ||
607 | size += sprintf(buf + size, " EN"); | ||
608 | else | ||
609 | size += sprintf(buf + size, " "); | ||
610 | if (status & ACPI_EVENT_FLAG_STATUS_SET) | ||
611 | size += sprintf(buf + size, " STS"); | ||
612 | else | ||
613 | size += sprintf(buf + size, " "); | ||
614 | |||
600 | if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER)) | 615 | if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER)) |
601 | size += sprintf(buf + size, " invalid"); | 616 | size += sprintf(buf + size, " invalid "); |
602 | else if (status & ACPI_EVENT_FLAG_ENABLED) | 617 | else if (status & ACPI_EVENT_FLAG_ENABLED) |
603 | size += sprintf(buf + size, " enabled"); | 618 | size += sprintf(buf + size, " enabled "); |
604 | else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) | 619 | else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) |
605 | size += sprintf(buf + size, " wake_enabled"); | 620 | size += sprintf(buf + size, " wake_enabled"); |
621 | else | ||
622 | size += sprintf(buf + size, " disabled "); | ||
623 | if (status & ACPI_EVENT_FLAG_MASKED) | ||
624 | size += sprintf(buf + size, " masked "); | ||
606 | else | 625 | else |
607 | size += sprintf(buf + size, " disabled"); | 626 | size += sprintf(buf + size, " unmasked"); |
608 | 627 | ||
609 | end: | 628 | end: |
610 | size += sprintf(buf + size, "\n"); | 629 | size += sprintf(buf + size, "\n"); |
@@ -655,8 +674,12 @@ static ssize_t counter_set(struct kobject *kobj, | |||
655 | !(status & ACPI_EVENT_FLAG_ENABLED)) | 674 | !(status & ACPI_EVENT_FLAG_ENABLED)) |
656 | result = acpi_enable_gpe(handle, index); | 675 | result = acpi_enable_gpe(handle, index); |
657 | else if (!strcmp(buf, "clear\n") && | 676 | else if (!strcmp(buf, "clear\n") && |
658 | (status & ACPI_EVENT_FLAG_SET)) | 677 | (status & ACPI_EVENT_FLAG_STATUS_SET)) |
659 | result = acpi_clear_gpe(handle, index); | 678 | result = acpi_clear_gpe(handle, index); |
679 | else if (!strcmp(buf, "mask\n")) | ||
680 | result = acpi_mask_gpe(handle, index, TRUE); | ||
681 | else if (!strcmp(buf, "unmask\n")) | ||
682 | result = acpi_mask_gpe(handle, index, FALSE); | ||
660 | else if (!kstrtoul(buf, 0, &tmp)) | 683 | else if (!kstrtoul(buf, 0, &tmp)) |
661 | all_counters[index].count = tmp; | 684 | all_counters[index].count = tmp; |
662 | else | 685 | else |
@@ -664,13 +687,13 @@ static ssize_t counter_set(struct kobject *kobj, | |||
664 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { | 687 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { |
665 | int event = index - num_gpes; | 688 | int event = index - num_gpes; |
666 | if (!strcmp(buf, "disable\n") && | 689 | if (!strcmp(buf, "disable\n") && |
667 | (status & ACPI_EVENT_FLAG_ENABLED)) | 690 | (status & ACPI_EVENT_FLAG_ENABLE_SET)) |
668 | result = acpi_disable_event(event, ACPI_NOT_ISR); | 691 | result = acpi_disable_event(event, ACPI_NOT_ISR); |
669 | else if (!strcmp(buf, "enable\n") && | 692 | else if (!strcmp(buf, "enable\n") && |
670 | !(status & ACPI_EVENT_FLAG_ENABLED)) | 693 | !(status & ACPI_EVENT_FLAG_ENABLE_SET)) |
671 | result = acpi_enable_event(event, ACPI_NOT_ISR); | 694 | result = acpi_enable_event(event, ACPI_NOT_ISR); |
672 | else if (!strcmp(buf, "clear\n") && | 695 | else if (!strcmp(buf, "clear\n") && |
673 | (status & ACPI_EVENT_FLAG_SET)) | 696 | (status & ACPI_EVENT_FLAG_STATUS_SET)) |
674 | result = acpi_clear_event(event); | 697 | result = acpi_clear_event(event); |
675 | else if (!kstrtoul(buf, 0, &tmp)) | 698 | else if (!kstrtoul(buf, 0, &tmp)) |
676 | all_counters[index].count = tmp; | 699 | all_counters[index].count = tmp; |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 9f0ad6ebb368..cdd56c4657e0 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/earlycpio.h> | 35 | #include <linux/earlycpio.h> |
36 | #include <linux/memblock.h> | 36 | #include <linux/memblock.h> |
37 | #include <linux/initrd.h> | 37 | #include <linux/initrd.h> |
38 | #include <linux/acpi.h> | ||
39 | #include "internal.h" | 38 | #include "internal.h" |
40 | 39 | ||
41 | #ifdef CONFIG_ACPI_CUSTOM_DSDT | 40 | #ifdef CONFIG_ACPI_CUSTOM_DSDT |
@@ -246,6 +245,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size, | |||
246 | struct acpi_subtable_header *entry; | 245 | struct acpi_subtable_header *entry; |
247 | unsigned long table_end; | 246 | unsigned long table_end; |
248 | int count = 0; | 247 | int count = 0; |
248 | int errs = 0; | ||
249 | int i; | 249 | int i; |
250 | 250 | ||
251 | if (acpi_disabled) | 251 | if (acpi_disabled) |
@@ -278,10 +278,12 @@ acpi_parse_entries_array(char *id, unsigned long table_size, | |||
278 | if (entry->type != proc[i].id) | 278 | if (entry->type != proc[i].id) |
279 | continue; | 279 | continue; |
280 | if (!proc[i].handler || | 280 | if (!proc[i].handler || |
281 | proc[i].handler(entry, table_end)) | 281 | (!errs && proc[i].handler(entry, table_end))) { |
282 | return -EINVAL; | 282 | errs++; |
283 | continue; | ||
284 | } | ||
283 | 285 | ||
284 | proc->count++; | 286 | proc[i].count++; |
285 | break; | 287 | break; |
286 | } | 288 | } |
287 | if (i != proc_num) | 289 | if (i != proc_num) |
@@ -301,11 +303,11 @@ acpi_parse_entries_array(char *id, unsigned long table_size, | |||
301 | } | 303 | } |
302 | 304 | ||
303 | if (max_entries && count > max_entries) { | 305 | if (max_entries && count > max_entries) { |
304 | pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", | 306 | pr_warn("[%4.4s:0x%02x] found the maximum %i entries\n", |
305 | id, proc->id, count - max_entries, count); | 307 | id, proc->id, count); |
306 | } | 308 | } |
307 | 309 | ||
308 | return count; | 310 | return errs ? -EINVAL : count; |
309 | } | 311 | } |
310 | 312 | ||
311 | int __init | 313 | int __init |