diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-05 13:08:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-05 13:08:27 -0400 |
commit | f4fe74cc909bf811cd9cc7fd84f5a7514e06a7e1 (patch) | |
tree | 858648091006b4b4795170560132ff6073759af6 | |
parent | 3c89adb0d11117f64d5b501730be7fb2bf53a479 (diff) | |
parent | 2448d1399bac5b49c2664f96e223e42d2b88c022 (diff) |
Merge tag 'acpi-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI updates from Rafael Wysocki:
"These update the ACPICA code in the kernel to the 20180508 upstream
revision and make it support the RT patch, add CPPC v3 support to the
ACPI CPPC library, add a WDAT-based watchdog quirk to prevent clashes
with the RTC, add quirks to the ACPI AC and battery drivers, and
update the ACPI SoC drivers.
Specifics:
- Update the ACPICA code in the kernel to the 20180508 upstream
revision including:
* iASL -tc option enhancement (Bob Moore).
* Debugger improvements (Bob Moore).
* Support for tables larger than 1 MB in acpidump/acpixtract (Bob
Moore).
* Minor fixes and cleanups (Colin Ian King, Toomas Soome).
- Make the ACPICA code in the kernel support the RT patch (Sebastian
Andrzej Siewior, Steven Rostedt).
- Add a kmemleak annotation to the ACPICA code (Larry Finger).
- Add CPPC v3 support to the ACPI CPPC library and fix two issues
related to CPPC (Prashanth Prakash, Al Stone).
- Add an ACPI WDAT-based watchdog quirk to prefer iTCO_wdt on systems
where WDAT clashes with the RTC SRAM (Mika Westerberg).
- Add some quirks to the ACPI AC and battery drivers (Carlo Caione,
Hans de Goede).
- Update the ACPI SoC drivers for Intel (LPSS) and AMD (APD)
platforms (Akshu Agrawal, Hans de Goede).
- Fix up some assorted minor issues (Al Stone, Laszlo Toth, Mathieu
Malaterre)"
* tag 'acpi-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (32 commits)
ACPICA: Mark acpi_ut_create_internal_object_dbg() memory allocations as non-leaks
ACPI / watchdog: Prefer iTCO_wdt always when WDAT table uses RTC SRAM
mailbox: PCC: erroneous error message when parsing ACPI PCCT
ACPICA: Update version to 20180508
ACPICA: acpidump/acpixtract: Support for tables larger than 1MB
ACPI: APD: Add AMD misc clock handler support
clk: x86: Add ST oscout platform clock
ACPICA: Update version to 20180427
ACPICA: Debugger: Removed direct support for EC address space in "Test Objects"
ACPICA: Debugger: Add Package support for "test objects" command
ACPICA: Improve error messages for the namespace root node
ACPICA: Fix potential infinite loop in acpi_rs_dump_byte_list
ACPICA: vsnprintf: this statement may fall through
ACPICA: Tables: Fix spelling mistake in comment
ACPICA: iASL: Enhance the -tc option (create AML hex file in C)
ACPI: Add missing prototype_for arch_post_acpi_subsys_init()
ACPI / tables: improve comments regarding acpi_parse_entries_array()
ACPICA: Convert acpi_gbl_hardware lock back to an acpi_raw_spinlock
ACPICA: provide abstraction for raw_spinlock_t
ACPI / CPPC: Fix invalid PCC channel status errors
...
36 files changed, 751 insertions, 194 deletions
diff --git a/Documentation/acpi/cppc_sysfs.txt b/Documentation/acpi/cppc_sysfs.txt new file mode 100644 index 000000000000..f20fb445135d --- /dev/null +++ b/Documentation/acpi/cppc_sysfs.txt | |||
@@ -0,0 +1,69 @@ | |||
1 | |||
2 | Collaborative Processor Performance Control (CPPC) | ||
3 | |||
4 | CPPC defined in the ACPI spec describes a mechanism for the OS to manage the | ||
5 | performance of a logical processor on a contigious and abstract performance | ||
6 | scale. CPPC exposes a set of registers to describe abstract performance scale, | ||
7 | to request performance levels and to measure per-cpu delivered performance. | ||
8 | |||
9 | For more details on CPPC please refer to the ACPI specification at: | ||
10 | |||
11 | http://uefi.org/specifications | ||
12 | |||
13 | Some of the CPPC registers are exposed via sysfs under: | ||
14 | |||
15 | /sys/devices/system/cpu/cpuX/acpi_cppc/ | ||
16 | |||
17 | for each cpu X | ||
18 | |||
19 | -------------------------------------------------------------------------------- | ||
20 | |||
21 | $ ls -lR /sys/devices/system/cpu/cpu0/acpi_cppc/ | ||
22 | /sys/devices/system/cpu/cpu0/acpi_cppc/: | ||
23 | total 0 | ||
24 | -r--r--r-- 1 root root 65536 Mar 5 19:38 feedback_ctrs | ||
25 | -r--r--r-- 1 root root 65536 Mar 5 19:38 highest_perf | ||
26 | -r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_freq | ||
27 | -r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_nonlinear_perf | ||
28 | -r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_perf | ||
29 | -r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_freq | ||
30 | -r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_perf | ||
31 | -r--r--r-- 1 root root 65536 Mar 5 19:38 reference_perf | ||
32 | -r--r--r-- 1 root root 65536 Mar 5 19:38 wraparound_time | ||
33 | |||
34 | -------------------------------------------------------------------------------- | ||
35 | |||
36 | * highest_perf : Highest performance of this processor (abstract scale). | ||
37 | * nominal_perf : Highest sustained performance of this processor (abstract scale). | ||
38 | * lowest_nonlinear_perf : Lowest performance of this processor with nonlinear | ||
39 | power savings (abstract scale). | ||
40 | * lowest_perf : Lowest performance of this processor (abstract scale). | ||
41 | |||
42 | * lowest_freq : CPU frequency corresponding to lowest_perf (in MHz). | ||
43 | * nominal_freq : CPU frequency corresponding to nominal_perf (in MHz). | ||
44 | The above frequencies should only be used to report processor performance in | ||
45 | freqency instead of abstract scale. These values should not be used for any | ||
46 | functional decisions. | ||
47 | |||
48 | * feedback_ctrs : Includes both Reference and delivered performance counter. | ||
49 | Reference counter ticks up proportional to processor's reference performance. | ||
50 | Delivered counter ticks up proportional to processor's delivered performance. | ||
51 | * wraparound_time: Minimum time for the feedback counters to wraparound (seconds). | ||
52 | * reference_perf : Performance level at which reference performance counter | ||
53 | accumulates (abstract scale). | ||
54 | |||
55 | -------------------------------------------------------------------------------- | ||
56 | |||
57 | Computing Average Delivered Performance | ||
58 | |||
59 | Below describes the steps to compute the average performance delivered by taking | ||
60 | two different snapshots of feedback counters at time T1 and T2. | ||
61 | |||
62 | T1: Read feedback_ctrs as fbc_t1 | ||
63 | Wait or run some workload | ||
64 | T2: Read feedback_ctrs as fbc_t2 | ||
65 | |||
66 | delivered_counter_delta = fbc_t2[del] - fbc_t1[del] | ||
67 | reference_counter_delta = fbc_t2[ref] - fbc_t1[ref] | ||
68 | |||
69 | delivered_perf = (refernce_perf x delivered_counter_delta) / reference_counter_delta | ||
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 84fdfa70920a..cdd3136829f1 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -86,6 +86,7 @@ extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); | |||
86 | 86 | ||
87 | 87 | ||
88 | static int ac_sleep_before_get_state_ms; | 88 | static int ac_sleep_before_get_state_ms; |
89 | static int ac_check_pmic = 1; | ||
89 | 90 | ||
90 | static struct acpi_driver acpi_ac_driver = { | 91 | static struct acpi_driver acpi_ac_driver = { |
91 | .name = "ac", | 92 | .name = "ac", |
@@ -293,21 +294,43 @@ static int acpi_ac_battery_notify(struct notifier_block *nb, | |||
293 | return NOTIFY_OK; | 294 | return NOTIFY_OK; |
294 | } | 295 | } |
295 | 296 | ||
296 | static int thinkpad_e530_quirk(const struct dmi_system_id *d) | 297 | static int __init thinkpad_e530_quirk(const struct dmi_system_id *d) |
297 | { | 298 | { |
298 | ac_sleep_before_get_state_ms = 1000; | 299 | ac_sleep_before_get_state_ms = 1000; |
299 | return 0; | 300 | return 0; |
300 | } | 301 | } |
301 | 302 | ||
302 | static const struct dmi_system_id ac_dmi_table[] = { | 303 | static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d) |
304 | { | ||
305 | ac_check_pmic = 0; | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static const struct dmi_system_id ac_dmi_table[] __initconst = { | ||
303 | { | 310 | { |
311 | /* Thinkpad e530 */ | ||
304 | .callback = thinkpad_e530_quirk, | 312 | .callback = thinkpad_e530_quirk, |
305 | .ident = "thinkpad e530", | ||
306 | .matches = { | 313 | .matches = { |
307 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 314 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
308 | DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"), | 315 | DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"), |
309 | }, | 316 | }, |
310 | }, | 317 | }, |
318 | { | ||
319 | /* ECS EF20EA */ | ||
320 | .callback = ac_do_not_check_pmic_quirk, | ||
321 | .matches = { | ||
322 | DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), | ||
323 | }, | ||
324 | }, | ||
325 | { | ||
326 | /* Lenovo Ideapad Miix 320 */ | ||
327 | .callback = ac_do_not_check_pmic_quirk, | ||
328 | .matches = { | ||
329 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
330 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"), | ||
331 | DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), | ||
332 | }, | ||
333 | }, | ||
311 | {}, | 334 | {}, |
312 | }; | 335 | }; |
313 | 336 | ||
@@ -367,7 +390,6 @@ end: | |||
367 | kfree(ac); | 390 | kfree(ac); |
368 | } | 391 | } |
369 | 392 | ||
370 | dmi_check_system(ac_dmi_table); | ||
371 | return result; | 393 | return result; |
372 | } | 394 | } |
373 | 395 | ||
@@ -425,13 +447,17 @@ static int __init acpi_ac_init(void) | |||
425 | if (acpi_disabled) | 447 | if (acpi_disabled) |
426 | return -ENODEV; | 448 | return -ENODEV; |
427 | 449 | ||
428 | for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++) | 450 | dmi_check_system(ac_dmi_table); |
429 | if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1", | 451 | |
430 | acpi_ac_blacklist[i].hrv)) { | 452 | if (ac_check_pmic) { |
431 | pr_info(PREFIX "AC: found native %s PMIC, not loading\n", | 453 | for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++) |
432 | acpi_ac_blacklist[i].hid); | 454 | if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1", |
433 | return -ENODEV; | 455 | acpi_ac_blacklist[i].hrv)) { |
434 | } | 456 | pr_info(PREFIX "AC: found native %s PMIC, not loading\n", |
457 | acpi_ac_blacklist[i].hid); | ||
458 | return -ENODEV; | ||
459 | } | ||
460 | } | ||
435 | 461 | ||
436 | #ifdef CONFIG_ACPI_PROCFS_POWER | 462 | #ifdef CONFIG_ACPI_PROCFS_POWER |
437 | acpi_ac_dir = acpi_lock_ac_dir(); | 463 | acpi_ac_dir = acpi_lock_ac_dir(); |
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index d553b0087947..2664452fa112 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
14 | #include <linux/platform_data/clk-st.h> | ||
14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
15 | #include <linux/pm_domain.h> | 16 | #include <linux/pm_domain.h> |
16 | #include <linux/clkdev.h> | 17 | #include <linux/clkdev.h> |
@@ -72,6 +73,47 @@ static int acpi_apd_setup(struct apd_private_data *pdata) | |||
72 | } | 73 | } |
73 | 74 | ||
74 | #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE | 75 | #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE |
76 | |||
77 | static int misc_check_res(struct acpi_resource *ares, void *data) | ||
78 | { | ||
79 | struct resource res; | ||
80 | |||
81 | return !acpi_dev_resource_memory(ares, &res); | ||
82 | } | ||
83 | |||
84 | static int st_misc_setup(struct apd_private_data *pdata) | ||
85 | { | ||
86 | struct acpi_device *adev = pdata->adev; | ||
87 | struct platform_device *clkdev; | ||
88 | struct st_clk_data *clk_data; | ||
89 | struct resource_entry *rentry; | ||
90 | struct list_head resource_list; | ||
91 | int ret; | ||
92 | |||
93 | clk_data = devm_kzalloc(&adev->dev, sizeof(*clk_data), GFP_KERNEL); | ||
94 | if (!clk_data) | ||
95 | return -ENOMEM; | ||
96 | |||
97 | INIT_LIST_HEAD(&resource_list); | ||
98 | ret = acpi_dev_get_resources(adev, &resource_list, misc_check_res, | ||
99 | NULL); | ||
100 | if (ret < 0) | ||
101 | return -ENOENT; | ||
102 | |||
103 | list_for_each_entry(rentry, &resource_list, node) { | ||
104 | clk_data->base = devm_ioremap(&adev->dev, rentry->res->start, | ||
105 | resource_size(rentry->res)); | ||
106 | break; | ||
107 | } | ||
108 | |||
109 | acpi_dev_free_resource_list(&resource_list); | ||
110 | |||
111 | clkdev = platform_device_register_data(&adev->dev, "clk-st", | ||
112 | PLATFORM_DEVID_NONE, clk_data, | ||
113 | sizeof(*clk_data)); | ||
114 | return PTR_ERR_OR_ZERO(clkdev); | ||
115 | } | ||
116 | |||
75 | static const struct apd_device_desc cz_i2c_desc = { | 117 | static const struct apd_device_desc cz_i2c_desc = { |
76 | .setup = acpi_apd_setup, | 118 | .setup = acpi_apd_setup, |
77 | .fixed_clk_rate = 133000000, | 119 | .fixed_clk_rate = 133000000, |
@@ -94,6 +136,10 @@ static const struct apd_device_desc cz_uart_desc = { | |||
94 | .fixed_clk_rate = 48000000, | 136 | .fixed_clk_rate = 48000000, |
95 | .properties = uart_properties, | 137 | .properties = uart_properties, |
96 | }; | 138 | }; |
139 | |||
140 | static const struct apd_device_desc st_misc_desc = { | ||
141 | .setup = st_misc_setup, | ||
142 | }; | ||
97 | #endif | 143 | #endif |
98 | 144 | ||
99 | #ifdef CONFIG_ARM64 | 145 | #ifdef CONFIG_ARM64 |
@@ -179,6 +225,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { | |||
179 | { "AMD0020", APD_ADDR(cz_uart_desc) }, | 225 | { "AMD0020", APD_ADDR(cz_uart_desc) }, |
180 | { "AMDI0020", APD_ADDR(cz_uart_desc) }, | 226 | { "AMDI0020", APD_ADDR(cz_uart_desc) }, |
181 | { "AMD0030", }, | 227 | { "AMD0030", }, |
228 | { "AMD0040", APD_ADDR(st_misc_desc)}, | ||
182 | #endif | 229 | #endif |
183 | #ifdef CONFIG_ARM64 | 230 | #ifdef CONFIG_ARM64 |
184 | { "APMC0D0F", APD_ADDR(xgene_i2c_desc) }, | 231 | { "APMC0D0F", APD_ADDR(xgene_i2c_desc) }, |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 2bcffec8dbf0..cb6ac5c65c2e 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -69,6 +69,10 @@ ACPI_MODULE_NAME("acpi_lpss"); | |||
69 | #define LPSS_SAVE_CTX BIT(4) | 69 | #define LPSS_SAVE_CTX BIT(4) |
70 | #define LPSS_NO_D3_DELAY BIT(5) | 70 | #define LPSS_NO_D3_DELAY BIT(5) |
71 | 71 | ||
72 | /* Crystal Cove PMIC shares same ACPI ID between different platforms */ | ||
73 | #define BYT_CRC_HRV 2 | ||
74 | #define CHT_CRC_HRV 3 | ||
75 | |||
72 | struct lpss_private_data; | 76 | struct lpss_private_data; |
73 | 77 | ||
74 | struct lpss_device_desc { | 78 | struct lpss_device_desc { |
@@ -162,7 +166,7 @@ static void byt_pwm_setup(struct lpss_private_data *pdata) | |||
162 | if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1")) | 166 | if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1")) |
163 | return; | 167 | return; |
164 | 168 | ||
165 | if (!acpi_dev_present("INT33FD", NULL, -1)) | 169 | if (!acpi_dev_present("INT33FD", NULL, BYT_CRC_HRV)) |
166 | pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup)); | 170 | pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup)); |
167 | } | 171 | } |
168 | 172 | ||
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 4bde16fb97d8..95600309ce42 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c | |||
@@ -12,35 +12,51 @@ | |||
12 | #define pr_fmt(fmt) "ACPI: watchdog: " fmt | 12 | #define pr_fmt(fmt) "ACPI: watchdog: " fmt |
13 | 13 | ||
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/dmi.h> | ||
16 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
17 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
18 | 17 | ||
19 | #include "internal.h" | 18 | #include "internal.h" |
20 | 19 | ||
21 | static const struct dmi_system_id acpi_watchdog_skip[] = { | 20 | #ifdef CONFIG_RTC_MC146818_LIB |
22 | { | 21 | #include <linux/mc146818rtc.h> |
23 | /* | 22 | |
24 | * On Lenovo Z50-70 there are two issues with the WDAT | 23 | /* |
25 | * table. First some of the instructions use RTC SRAM | 24 | * There are several systems where the WDAT table is accessing RTC SRAM to |
26 | * to store persistent information. This does not work well | 25 | * store persistent information. This does not work well with the Linux RTC |
27 | * with Linux RTC driver. Second, more important thing is | 26 | * driver so on those systems we skip WDAT driver and prefer iTCO_wdt |
28 | * that the instructions do not actually reset the system. | 27 | * instead. |
29 | * | 28 | * |
30 | * On this particular system iTCO_wdt seems to work just | 29 | * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. |
31 | * fine so we prefer that over WDAT for now. | 30 | */ |
32 | * | 31 | static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) |
33 | * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. | 32 | { |
34 | */ | 33 | const struct acpi_wdat_entry *entries; |
35 | .ident = "Lenovo Z50-70", | 34 | int i; |
36 | .matches = { | 35 | |
37 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 36 | entries = (struct acpi_wdat_entry *)(wdat + 1); |
38 | DMI_MATCH(DMI_PRODUCT_NAME, "20354"), | 37 | for (i = 0; i < wdat->entries; i++) { |
39 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"), | 38 | const struct acpi_generic_address *gas; |
40 | }, | 39 | |
41 | }, | 40 | gas = &entries[i].register_region; |
42 | {} | 41 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
43 | }; | 42 | switch (gas->address) { |
43 | case RTC_PORT(0): | ||
44 | case RTC_PORT(1): | ||
45 | case RTC_PORT(2): | ||
46 | case RTC_PORT(3): | ||
47 | return true; | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | |||
52 | return false; | ||
53 | } | ||
54 | #else | ||
55 | static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) | ||
56 | { | ||
57 | return false; | ||
58 | } | ||
59 | #endif | ||
44 | 60 | ||
45 | static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) | 61 | static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) |
46 | { | 62 | { |
@@ -50,9 +66,6 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) | |||
50 | if (acpi_disabled) | 66 | if (acpi_disabled) |
51 | return NULL; | 67 | return NULL; |
52 | 68 | ||
53 | if (dmi_check_system(acpi_watchdog_skip)) | ||
54 | return NULL; | ||
55 | |||
56 | status = acpi_get_table(ACPI_SIG_WDAT, 0, | 69 | status = acpi_get_table(ACPI_SIG_WDAT, 0, |
57 | (struct acpi_table_header **)&wdat); | 70 | (struct acpi_table_header **)&wdat); |
58 | if (ACPI_FAILURE(status)) { | 71 | if (ACPI_FAILURE(status)) { |
@@ -60,6 +73,11 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) | |||
60 | return NULL; | 73 | return NULL; |
61 | } | 74 | } |
62 | 75 | ||
76 | if (acpi_watchdog_uses_rtc(wdat)) { | ||
77 | pr_info("Skipping WDAT on this system because it uses RTC SRAM\n"); | ||
78 | return NULL; | ||
79 | } | ||
80 | |||
63 | return wdat; | 81 | return wdat; |
64 | } | 82 | } |
65 | 83 | ||
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index a2a85122fafe..5a9c2febc0fb 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h | |||
@@ -143,6 +143,8 @@ acpi_status | |||
143 | fl_split_input_pathname(char *input_path, | 143 | fl_split_input_pathname(char *input_path, |
144 | char **out_directory_path, char **out_filename); | 144 | char **out_directory_path, char **out_filename); |
145 | 145 | ||
146 | char *fl_get_file_basename(char *file_pathname); | ||
147 | |||
146 | char *ad_generate_filename(char *prefix, char *table_id); | 148 | char *ad_generate_filename(char *prefix, char *table_id); |
147 | 149 | ||
148 | void | 150 | void |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 0bc550072a21..1e6204518496 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -82,7 +82,7 @@ ACPI_GLOBAL(u8, acpi_gbl_global_lock_pending); | |||
82 | * interrupt level | 82 | * interrupt level |
83 | */ | 83 | */ |
84 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */ | 84 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */ |
85 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ | 85 | ACPI_GLOBAL(acpi_raw_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ |
86 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock); | 86 | ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock); |
87 | 87 | ||
88 | /* Mutex for _OSI support */ | 88 | /* Mutex for _OSI support */ |
diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c index 170802c62179..dc94de91033e 100644 --- a/drivers/acpi/acpica/dbnames.c +++ b/drivers/acpi/acpica/dbnames.c | |||
@@ -189,9 +189,15 @@ void acpi_db_dump_namespace(char *start_arg, char *depth_arg) | |||
189 | } | 189 | } |
190 | 190 | ||
191 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); | 191 | acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); |
192 | acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n", | 192 | |
193 | ((struct acpi_namespace_node *)subtree_entry)->name. | 193 | if (((struct acpi_namespace_node *)subtree_entry)->parent) { |
194 | ascii, subtree_entry); | 194 | acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n", |
195 | ((struct acpi_namespace_node *)subtree_entry)-> | ||
196 | name.ascii, subtree_entry); | ||
197 | } else { | ||
198 | acpi_os_printf("ACPI Namespace (from %s):\n", | ||
199 | ACPI_NAMESPACE_ROOT); | ||
200 | } | ||
195 | 201 | ||
196 | /* Display the subtree */ | 202 | /* Display the subtree */ |
197 | 203 | ||
diff --git a/drivers/acpi/acpica/dbtest.c b/drivers/acpi/acpica/dbtest.c index 3892680a5258..8a5462439a97 100644 --- a/drivers/acpi/acpica/dbtest.c +++ b/drivers/acpi/acpica/dbtest.c | |||
@@ -30,6 +30,8 @@ acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length); | |||
30 | static acpi_status | 30 | static acpi_status |
31 | acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length); | 31 | acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length); |
32 | 32 | ||
33 | static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node); | ||
34 | |||
33 | static acpi_status | 35 | static acpi_status |
34 | acpi_db_read_from_object(struct acpi_namespace_node *node, | 36 | acpi_db_read_from_object(struct acpi_namespace_node *node, |
35 | acpi_object_type expected_type, | 37 | acpi_object_type expected_type, |
@@ -273,6 +275,11 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
273 | bit_length = byte_length * 8; | 275 | bit_length = byte_length * 8; |
274 | break; | 276 | break; |
275 | 277 | ||
278 | case ACPI_TYPE_PACKAGE: | ||
279 | |||
280 | local_type = ACPI_TYPE_PACKAGE; | ||
281 | break; | ||
282 | |||
276 | case ACPI_TYPE_FIELD_UNIT: | 283 | case ACPI_TYPE_FIELD_UNIT: |
277 | case ACPI_TYPE_BUFFER_FIELD: | 284 | case ACPI_TYPE_BUFFER_FIELD: |
278 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 285 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
@@ -305,6 +312,7 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
305 | 312 | ||
306 | acpi_os_printf("%14s: %4.4s", | 313 | acpi_os_printf("%14s: %4.4s", |
307 | acpi_ut_get_type_name(node->type), node->name.ascii); | 314 | acpi_ut_get_type_name(node->type), node->name.ascii); |
315 | |||
308 | if (!obj_desc) { | 316 | if (!obj_desc) { |
309 | acpi_os_printf(" Ignoring, no attached object\n"); | 317 | acpi_os_printf(" Ignoring, no attached object\n"); |
310 | return (AE_OK); | 318 | return (AE_OK); |
@@ -322,14 +330,13 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
322 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 330 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
323 | case ACPI_ADR_SPACE_SYSTEM_IO: | 331 | case ACPI_ADR_SPACE_SYSTEM_IO: |
324 | case ACPI_ADR_SPACE_PCI_CONFIG: | 332 | case ACPI_ADR_SPACE_PCI_CONFIG: |
325 | case ACPI_ADR_SPACE_EC: | ||
326 | 333 | ||
327 | break; | 334 | break; |
328 | 335 | ||
329 | default: | 336 | default: |
330 | 337 | ||
331 | acpi_os_printf | 338 | acpi_os_printf |
332 | (" %s space is not supported [%4.4s]\n", | 339 | (" %s space is not supported in this command [%4.4s]\n", |
333 | acpi_ut_get_region_name(region_obj->region. | 340 | acpi_ut_get_region_name(region_obj->region. |
334 | space_id), | 341 | space_id), |
335 | region_obj->region.node->name.ascii); | 342 | region_obj->region.node->name.ascii); |
@@ -359,6 +366,11 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
359 | status = acpi_db_test_buffer_type(node, bit_length); | 366 | status = acpi_db_test_buffer_type(node, bit_length); |
360 | break; | 367 | break; |
361 | 368 | ||
369 | case ACPI_TYPE_PACKAGE: | ||
370 | |||
371 | status = acpi_db_test_package_type(node); | ||
372 | break; | ||
373 | |||
362 | default: | 374 | default: |
363 | 375 | ||
364 | acpi_os_printf(" Ignoring, type not implemented (%2.2X)", | 376 | acpi_os_printf(" Ignoring, type not implemented (%2.2X)", |
@@ -366,6 +378,13 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
366 | break; | 378 | break; |
367 | } | 379 | } |
368 | 380 | ||
381 | /* Exit on error, but don't abort the namespace walk */ | ||
382 | |||
383 | if (ACPI_FAILURE(status)) { | ||
384 | status = AE_OK; | ||
385 | goto exit; | ||
386 | } | ||
387 | |||
369 | switch (node->type) { | 388 | switch (node->type) { |
370 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 389 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
371 | 390 | ||
@@ -373,12 +392,14 @@ acpi_db_test_one_object(acpi_handle obj_handle, | |||
373 | acpi_os_printf(" (%s)", | 392 | acpi_os_printf(" (%s)", |
374 | acpi_ut_get_region_name(region_obj->region. | 393 | acpi_ut_get_region_name(region_obj->region. |
375 | space_id)); | 394 | space_id)); |
395 | |||
376 | break; | 396 | break; |
377 | 397 | ||
378 | default: | 398 | default: |
379 | break; | 399 | break; |
380 | } | 400 | } |
381 | 401 | ||
402 | exit: | ||
382 | acpi_os_printf("\n"); | 403 | acpi_os_printf("\n"); |
383 | return (status); | 404 | return (status); |
384 | } | 405 | } |
@@ -431,7 +452,6 @@ acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length) | |||
431 | if (temp1->integer.value == value_to_write) { | 452 | if (temp1->integer.value == value_to_write) { |
432 | value_to_write = 0; | 453 | value_to_write = 0; |
433 | } | 454 | } |
434 | |||
435 | /* Write a new value */ | 455 | /* Write a new value */ |
436 | 456 | ||
437 | write_value.type = ACPI_TYPE_INTEGER; | 457 | write_value.type = ACPI_TYPE_INTEGER; |
@@ -708,6 +728,35 @@ exit: | |||
708 | 728 | ||
709 | /******************************************************************************* | 729 | /******************************************************************************* |
710 | * | 730 | * |
731 | * FUNCTION: acpi_db_test_package_type | ||
732 | * | ||
733 | * PARAMETERS: node - Parent NS node for the object | ||
734 | * | ||
735 | * RETURN: Status | ||
736 | * | ||
737 | * DESCRIPTION: Test read for a Package object. | ||
738 | * | ||
739 | ******************************************************************************/ | ||
740 | |||
741 | static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node) | ||
742 | { | ||
743 | union acpi_object *temp1 = NULL; | ||
744 | acpi_status status; | ||
745 | |||
746 | /* Read the original value */ | ||
747 | |||
748 | status = acpi_db_read_from_object(node, ACPI_TYPE_PACKAGE, &temp1); | ||
749 | if (ACPI_FAILURE(status)) { | ||
750 | return (status); | ||
751 | } | ||
752 | |||
753 | acpi_os_printf(" %8.8X Elements", temp1->package.count); | ||
754 | acpi_os_free(temp1); | ||
755 | return (status); | ||
756 | } | ||
757 | |||
758 | /******************************************************************************* | ||
759 | * | ||
711 | * FUNCTION: acpi_db_read_from_object | 760 | * FUNCTION: acpi_db_read_from_object |
712 | * | 761 | * |
713 | * PARAMETERS: node - Parent NS node for the object | 762 | * PARAMETERS: node - Parent NS node for the object |
@@ -746,8 +795,8 @@ acpi_db_read_from_object(struct acpi_namespace_node *node, | |||
746 | acpi_gbl_method_executing = TRUE; | 795 | acpi_gbl_method_executing = TRUE; |
747 | status = acpi_evaluate_object(read_handle, NULL, | 796 | status = acpi_evaluate_object(read_handle, NULL, |
748 | ¶m_objects, &return_obj); | 797 | ¶m_objects, &return_obj); |
749 | acpi_gbl_method_executing = FALSE; | ||
750 | 798 | ||
799 | acpi_gbl_method_executing = FALSE; | ||
751 | if (ACPI_FAILURE(status)) { | 800 | if (ACPI_FAILURE(status)) { |
752 | acpi_os_printf("Could not read from object, %s", | 801 | acpi_os_printf("Could not read from object, %s", |
753 | acpi_format_exception(status)); | 802 | acpi_format_exception(status)); |
@@ -760,6 +809,7 @@ acpi_db_read_from_object(struct acpi_namespace_node *node, | |||
760 | case ACPI_TYPE_INTEGER: | 809 | case ACPI_TYPE_INTEGER: |
761 | case ACPI_TYPE_BUFFER: | 810 | case ACPI_TYPE_BUFFER: |
762 | case ACPI_TYPE_STRING: | 811 | case ACPI_TYPE_STRING: |
812 | case ACPI_TYPE_PACKAGE: | ||
763 | /* | 813 | /* |
764 | * Did we receive the type we wanted? Most important for the | 814 | * Did we receive the type we wanted? Most important for the |
765 | * Integer/Buffer case (when a field is larger than an Integer, | 815 | * Integer/Buffer case (when a field is larger than an Integer, |
@@ -771,6 +821,7 @@ acpi_db_read_from_object(struct acpi_namespace_node *node, | |||
771 | acpi_ut_get_type_name(expected_type), | 821 | acpi_ut_get_type_name(expected_type), |
772 | acpi_ut_get_type_name(ret_value->type)); | 822 | acpi_ut_get_type_name(ret_value->type)); |
773 | 823 | ||
824 | acpi_os_free(return_obj.pointer); | ||
774 | return (AE_TYPE); | 825 | return (AE_TYPE); |
775 | } | 826 | } |
776 | 827 | ||
diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index d1422f984f6e..7592176a8fa2 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c | |||
@@ -115,7 +115,7 @@ acpi_ds_scope_stack_push(struct acpi_namespace_node *node, | |||
115 | acpi_ut_get_type_name(old_scope_info-> | 115 | acpi_ut_get_type_name(old_scope_info-> |
116 | common.value))); | 116 | common.value))); |
117 | } else { | 117 | } else { |
118 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[\\___] (%s)", "ROOT")); | 118 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, ACPI_NAMESPACE_ROOT)); |
119 | } | 119 | } |
120 | 120 | ||
121 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, | 121 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, |
@@ -166,14 +166,14 @@ acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state) | |||
166 | 166 | ||
167 | new_scope_info = walk_state->scope_info; | 167 | new_scope_info = walk_state->scope_info; |
168 | if (new_scope_info) { | 168 | if (new_scope_info) { |
169 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, | 169 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[%4.4s] (%s)\n", |
170 | "[%4.4s] (%s)\n", | ||
171 | acpi_ut_get_node_name(new_scope_info-> | 170 | acpi_ut_get_node_name(new_scope_info-> |
172 | scope.node), | 171 | scope.node), |
173 | acpi_ut_get_type_name(new_scope_info-> | 172 | acpi_ut_get_type_name(new_scope_info-> |
174 | common.value))); | 173 | common.value))); |
175 | } else { | 174 | } else { |
176 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[\\___] (ROOT)\n")); | 175 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "%s\n", |
176 | ACPI_NAMESPACE_ROOT)); | ||
177 | } | 177 | } |
178 | 178 | ||
179 | acpi_ut_delete_generic_state(scope_info); | 179 | acpi_ut_delete_generic_state(scope_info); |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 27a86ad55b58..3de794bcf8fa 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -390,14 +390,14 @@ acpi_status acpi_hw_clear_acpi_status(void) | |||
390 | ACPI_BITMASK_ALL_FIXED_STATUS, | 390 | ACPI_BITMASK_ALL_FIXED_STATUS, |
391 | ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); | 391 | ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); |
392 | 392 | ||
393 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 393 | lock_flags = acpi_os_acquire_raw_lock(acpi_gbl_hardware_lock); |
394 | 394 | ||
395 | /* Clear the fixed events in PM1 A/B */ | 395 | /* Clear the fixed events in PM1 A/B */ |
396 | 396 | ||
397 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, | 397 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, |
398 | ACPI_BITMASK_ALL_FIXED_STATUS); | 398 | ACPI_BITMASK_ALL_FIXED_STATUS); |
399 | 399 | ||
400 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | 400 | acpi_os_release_raw_lock(acpi_gbl_hardware_lock, lock_flags); |
401 | 401 | ||
402 | if (ACPI_FAILURE(status)) { | 402 | if (ACPI_FAILURE(status)) { |
403 | goto exit; | 403 | goto exit; |
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 5d1396870bd0..6e39a771a56e 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -227,7 +227,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) | |||
227 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 227 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
228 | } | 228 | } |
229 | 229 | ||
230 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 230 | lock_flags = acpi_os_acquire_raw_lock(acpi_gbl_hardware_lock); |
231 | 231 | ||
232 | /* | 232 | /* |
233 | * At this point, we know that the parent register is one of the | 233 | * At this point, we know that the parent register is one of the |
@@ -288,7 +288,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) | |||
288 | 288 | ||
289 | unlock_and_exit: | 289 | unlock_and_exit: |
290 | 290 | ||
291 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | 291 | acpi_os_release_raw_lock(acpi_gbl_hardware_lock, lock_flags); |
292 | return_ACPI_STATUS(status); | 292 | return_ACPI_STATUS(status); |
293 | } | 293 | } |
294 | 294 | ||
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index b12a0b1cd9ce..6601e71b45e3 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c | |||
@@ -539,7 +539,7 @@ static void acpi_rs_out_title(const char *title) | |||
539 | 539 | ||
540 | static void acpi_rs_dump_byte_list(u16 length, u8 * data) | 540 | static void acpi_rs_dump_byte_list(u16 length, u8 * data) |
541 | { | 541 | { |
542 | u8 i; | 542 | u16 i; |
543 | 543 | ||
544 | for (i = 0; i < length; i++) { | 544 | for (i = 0; i < length; i++) { |
545 | acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]); | 545 | acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]); |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index c5085b7ae8c9..5f8e7b561c90 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -88,7 +88,7 @@ acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, | |||
88 | * DESCRIPTION: This function is called to verify and install an ACPI table. | 88 | * DESCRIPTION: This function is called to verify and install an ACPI table. |
89 | * When this function is called by "Load" or "LoadTable" opcodes, | 89 | * When this function is called by "Load" or "LoadTable" opcodes, |
90 | * or by acpi_load_table() API, the "Reload" parameter is set. | 90 | * or by acpi_load_table() API, the "Reload" parameter is set. |
91 | * After sucessfully returning from this function, table is | 91 | * After successfully returning from this function, table is |
92 | * "INSTALLED" but not "VALIDATED". | 92 | * "INSTALLED" but not "VALIDATED". |
93 | * | 93 | * |
94 | ******************************************************************************/ | 94 | ******************************************************************************/ |
diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c index 148aeb84e561..fffa6f5ae59e 100644 --- a/drivers/acpi/acpica/utbuffer.c +++ b/drivers/acpi/acpica/utbuffer.c | |||
@@ -53,7 +53,7 @@ void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset) | |||
53 | 53 | ||
54 | /* Print current offset */ | 54 | /* Print current offset */ |
55 | 55 | ||
56 | acpi_os_printf("%6.4X: ", (base_offset + i)); | 56 | acpi_os_printf("%8.4X: ", (base_offset + i)); |
57 | 57 | ||
58 | /* Print 16 hex chars */ | 58 | /* Print 16 hex chars */ |
59 | 59 | ||
@@ -219,7 +219,7 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file, | |||
219 | 219 | ||
220 | /* Print current offset */ | 220 | /* Print current offset */ |
221 | 221 | ||
222 | fprintf(file, "%6.4X: ", (base_offset + i)); | 222 | fprintf(file, "%8.4X: ", (base_offset + i)); |
223 | 223 | ||
224 | /* Print 16 hex chars */ | 224 | /* Print 16 hex chars */ |
225 | 225 | ||
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index d2d93e388f40..2e465e6a0ab6 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -52,7 +52,7 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
52 | return_ACPI_STATUS (status); | 52 | return_ACPI_STATUS (status); |
53 | } | 53 | } |
54 | 54 | ||
55 | status = acpi_os_create_lock (&acpi_gbl_hardware_lock); | 55 | status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock); |
56 | if (ACPI_FAILURE (status)) { | 56 | if (ACPI_FAILURE (status)) { |
57 | return_ACPI_STATUS (status); | 57 | return_ACPI_STATUS (status); |
58 | } | 58 | } |
@@ -109,7 +109,7 @@ void acpi_ut_mutex_terminate(void) | |||
109 | /* Delete the spinlocks */ | 109 | /* Delete the spinlocks */ |
110 | 110 | ||
111 | acpi_os_delete_lock(acpi_gbl_gpe_lock); | 111 | acpi_os_delete_lock(acpi_gbl_gpe_lock); |
112 | acpi_os_delete_lock(acpi_gbl_hardware_lock); | 112 | acpi_os_delete_raw_lock(acpi_gbl_hardware_lock); |
113 | acpi_os_delete_lock(acpi_gbl_reference_count_lock); | 113 | acpi_os_delete_lock(acpi_gbl_reference_count_lock); |
114 | 114 | ||
115 | /* Delete the reader/writer lock */ | 115 | /* Delete the reader/writer lock */ |
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index 5b78fe08d7d7..ae6d8cc18cec 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c | |||
@@ -8,6 +8,7 @@ | |||
8 | *****************************************************************************/ | 8 | *****************************************************************************/ |
9 | 9 | ||
10 | #include <acpi/acpi.h> | 10 | #include <acpi/acpi.h> |
11 | #include <linux/kmemleak.h> | ||
11 | #include "accommon.h" | 12 | #include "accommon.h" |
12 | #include "acnamesp.h" | 13 | #include "acnamesp.h" |
13 | 14 | ||
@@ -70,6 +71,7 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char | |||
70 | if (!object) { | 71 | if (!object) { |
71 | return_PTR(NULL); | 72 | return_PTR(NULL); |
72 | } | 73 | } |
74 | kmemleak_not_leak(object); | ||
73 | 75 | ||
74 | switch (type) { | 76 | switch (type) { |
75 | case ACPI_TYPE_REGION: | 77 | case ACPI_TYPE_REGION: |
diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index 35ffd8d51c65..a98c334c3bb7 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c | |||
@@ -470,6 +470,7 @@ int vsnprintf(char *string, acpi_size size, const char *format, va_list args) | |||
470 | case 'X': | 470 | case 'X': |
471 | 471 | ||
472 | type |= ACPI_FORMAT_UPPER; | 472 | type |= ACPI_FORMAT_UPPER; |
473 | /* FALLTHROUGH */ | ||
473 | 474 | ||
474 | case 'x': | 475 | case 'x': |
475 | 476 | ||
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index bd57a77bbcb2..5bef0b059406 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c | |||
@@ -141,7 +141,7 @@ void acpi_ut_repair_name(char *name) | |||
141 | * Special case for the root node. This can happen if we get an | 141 | * Special case for the root node. This can happen if we get an |
142 | * error during the execution of module-level code. | 142 | * error during the execution of module-level code. |
143 | */ | 143 | */ |
144 | if (ACPI_COMPARE_NAME(name, "\\___")) { | 144 | if (ACPI_COMPARE_NAME(name, ACPI_ROOT_PATHNAME)) { |
145 | return; | 145 | return; |
146 | } | 146 | } |
147 | 147 | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 76550689ce10..b0113a5802a3 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -74,6 +74,8 @@ static async_cookie_t async_cookie; | |||
74 | static bool battery_driver_registered; | 74 | static bool battery_driver_registered; |
75 | static int battery_bix_broken_package; | 75 | static int battery_bix_broken_package; |
76 | static int battery_notification_delay_ms; | 76 | static int battery_notification_delay_ms; |
77 | static int battery_ac_is_broken; | ||
78 | static int battery_check_pmic = 1; | ||
77 | static unsigned int cache_time = 1000; | 79 | static unsigned int cache_time = 1000; |
78 | module_param(cache_time, uint, 0644); | 80 | module_param(cache_time, uint, 0644); |
79 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); | 81 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
@@ -207,6 +209,20 @@ static bool acpi_battery_is_degraded(struct acpi_battery *battery) | |||
207 | battery->full_charge_capacity < battery->design_capacity; | 209 | battery->full_charge_capacity < battery->design_capacity; |
208 | } | 210 | } |
209 | 211 | ||
212 | static int acpi_battery_handle_discharging(struct acpi_battery *battery) | ||
213 | { | ||
214 | /* | ||
215 | * Some devices wrongly report discharging if the battery's charge level | ||
216 | * was above the device's start charging threshold atm the AC adapter | ||
217 | * was plugged in and the device thus did not start a new charge cycle. | ||
218 | */ | ||
219 | if ((battery_ac_is_broken || power_supply_is_system_supplied()) && | ||
220 | battery->rate_now == 0) | ||
221 | return POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
222 | |||
223 | return POWER_SUPPLY_STATUS_DISCHARGING; | ||
224 | } | ||
225 | |||
210 | static int acpi_battery_get_property(struct power_supply *psy, | 226 | static int acpi_battery_get_property(struct power_supply *psy, |
211 | enum power_supply_property psp, | 227 | enum power_supply_property psp, |
212 | union power_supply_propval *val) | 228 | union power_supply_propval *val) |
@@ -222,7 +238,7 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
222 | switch (psp) { | 238 | switch (psp) { |
223 | case POWER_SUPPLY_PROP_STATUS: | 239 | case POWER_SUPPLY_PROP_STATUS: |
224 | if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) | 240 | if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) |
225 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 241 | val->intval = acpi_battery_handle_discharging(battery); |
226 | else if (battery->state & ACPI_BATTERY_STATE_CHARGING) | 242 | else if (battery->state & ACPI_BATTERY_STATE_CHARGING) |
227 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 243 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
228 | else if (acpi_battery_is_charged(battery)) | 244 | else if (acpi_battery_is_charged(battery)) |
@@ -1263,23 +1279,64 @@ battery_notification_delay_quirk(const struct dmi_system_id *d) | |||
1263 | return 0; | 1279 | return 0; |
1264 | } | 1280 | } |
1265 | 1281 | ||
1282 | static int __init | ||
1283 | battery_ac_is_broken_quirk(const struct dmi_system_id *d) | ||
1284 | { | ||
1285 | battery_ac_is_broken = 1; | ||
1286 | return 0; | ||
1287 | } | ||
1288 | |||
1289 | static int __init | ||
1290 | battery_do_not_check_pmic_quirk(const struct dmi_system_id *d) | ||
1291 | { | ||
1292 | battery_check_pmic = 0; | ||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1266 | static const struct dmi_system_id bat_dmi_table[] __initconst = { | 1296 | static const struct dmi_system_id bat_dmi_table[] __initconst = { |
1267 | { | 1297 | { |
1298 | /* NEC LZ750/LS */ | ||
1268 | .callback = battery_bix_broken_package_quirk, | 1299 | .callback = battery_bix_broken_package_quirk, |
1269 | .ident = "NEC LZ750/LS", | ||
1270 | .matches = { | 1300 | .matches = { |
1271 | DMI_MATCH(DMI_SYS_VENDOR, "NEC"), | 1301 | DMI_MATCH(DMI_SYS_VENDOR, "NEC"), |
1272 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"), | 1302 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"), |
1273 | }, | 1303 | }, |
1274 | }, | 1304 | }, |
1275 | { | 1305 | { |
1306 | /* Acer Aspire V5-573G */ | ||
1276 | .callback = battery_notification_delay_quirk, | 1307 | .callback = battery_notification_delay_quirk, |
1277 | .ident = "Acer Aspire V5-573G", | ||
1278 | .matches = { | 1308 | .matches = { |
1279 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 1309 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
1280 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"), | 1310 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"), |
1281 | }, | 1311 | }, |
1282 | }, | 1312 | }, |
1313 | { | ||
1314 | /* Point of View mobii wintab p800w */ | ||
1315 | .callback = battery_ac_is_broken_quirk, | ||
1316 | .matches = { | ||
1317 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | ||
1318 | DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), | ||
1319 | DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"), | ||
1320 | /* Above matches are too generic, add bios-date match */ | ||
1321 | DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"), | ||
1322 | }, | ||
1323 | }, | ||
1324 | { | ||
1325 | /* ECS EF20EA */ | ||
1326 | .callback = battery_do_not_check_pmic_quirk, | ||
1327 | .matches = { | ||
1328 | DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), | ||
1329 | }, | ||
1330 | }, | ||
1331 | { | ||
1332 | /* Lenovo Ideapad Miix 320 */ | ||
1333 | .callback = battery_do_not_check_pmic_quirk, | ||
1334 | .matches = { | ||
1335 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1336 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"), | ||
1337 | DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), | ||
1338 | }, | ||
1339 | }, | ||
1283 | {}, | 1340 | {}, |
1284 | }; | 1341 | }; |
1285 | 1342 | ||
@@ -1419,16 +1476,18 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) | |||
1419 | unsigned int i; | 1476 | unsigned int i; |
1420 | int result; | 1477 | int result; |
1421 | 1478 | ||
1422 | for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++) | ||
1423 | if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) { | ||
1424 | pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME | ||
1425 | ": found native %s PMIC, not loading\n", | ||
1426 | acpi_battery_blacklist[i]); | ||
1427 | return; | ||
1428 | } | ||
1429 | |||
1430 | dmi_check_system(bat_dmi_table); | 1479 | dmi_check_system(bat_dmi_table); |
1431 | 1480 | ||
1481 | if (battery_check_pmic) { | ||
1482 | for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++) | ||
1483 | if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) { | ||
1484 | pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME | ||
1485 | ": found native %s PMIC, not loading\n", | ||
1486 | acpi_battery_blacklist[i]); | ||
1487 | return; | ||
1488 | } | ||
1489 | } | ||
1490 | |||
1432 | #ifdef CONFIG_ACPI_PROCFS_POWER | 1491 | #ifdef CONFIG_ACPI_PROCFS_POWER |
1433 | acpi_battery_dir = acpi_lock_battery_dir(); | 1492 | acpi_battery_dir = acpi_lock_battery_dir(); |
1434 | if (!acpi_battery_dir) | 1493 | if (!acpi_battery_dir) |
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 735c74a4cbdb..d9ce4b162e2c 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c | |||
@@ -39,6 +39,7 @@ | |||
39 | 39 | ||
40 | #include <linux/cpufreq.h> | 40 | #include <linux/cpufreq.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/iopoll.h> | ||
42 | #include <linux/ktime.h> | 43 | #include <linux/ktime.h> |
43 | #include <linux/rwsem.h> | 44 | #include <linux/rwsem.h> |
44 | #include <linux/wait.h> | 45 | #include <linux/wait.h> |
@@ -49,7 +50,7 @@ struct cppc_pcc_data { | |||
49 | struct mbox_chan *pcc_channel; | 50 | struct mbox_chan *pcc_channel; |
50 | void __iomem *pcc_comm_addr; | 51 | void __iomem *pcc_comm_addr; |
51 | bool pcc_channel_acquired; | 52 | bool pcc_channel_acquired; |
52 | ktime_t deadline; | 53 | unsigned int deadline_us; |
53 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; | 54 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; |
54 | 55 | ||
55 | bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ | 56 | bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ |
@@ -156,6 +157,9 @@ show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, highest_perf); | |||
156 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf); | 157 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf); |
157 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf); | 158 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf); |
158 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf); | 159 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf); |
160 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_freq); | ||
161 | show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_freq); | ||
162 | |||
159 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf); | 163 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf); |
160 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); | 164 | show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); |
161 | 165 | ||
@@ -183,6 +187,8 @@ static struct attribute *cppc_attrs[] = { | |||
183 | &lowest_perf.attr, | 187 | &lowest_perf.attr, |
184 | &lowest_nonlinear_perf.attr, | 188 | &lowest_nonlinear_perf.attr, |
185 | &nominal_perf.attr, | 189 | &nominal_perf.attr, |
190 | &nominal_freq.attr, | ||
191 | &lowest_freq.attr, | ||
186 | NULL | 192 | NULL |
187 | }; | 193 | }; |
188 | 194 | ||
@@ -193,42 +199,31 @@ static struct kobj_type cppc_ktype = { | |||
193 | 199 | ||
194 | static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) | 200 | static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) |
195 | { | 201 | { |
196 | int ret = -EIO, status = 0; | 202 | int ret, status; |
197 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | 203 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; |
198 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = | 204 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = |
199 | pcc_ss_data->pcc_comm_addr; | 205 | pcc_ss_data->pcc_comm_addr; |
200 | ktime_t next_deadline = ktime_add(ktime_get(), | ||
201 | pcc_ss_data->deadline); | ||
202 | 206 | ||
203 | if (!pcc_ss_data->platform_owns_pcc) | 207 | if (!pcc_ss_data->platform_owns_pcc) |
204 | return 0; | 208 | return 0; |
205 | 209 | ||
206 | /* Retry in case the remote processor was too slow to catch up. */ | 210 | /* |
207 | while (!ktime_after(ktime_get(), next_deadline)) { | 211 | * Poll PCC status register every 3us(delay_us) for maximum of |
208 | /* | 212 | * deadline_us(timeout_us) until PCC command complete bit is set(cond) |
209 | * Per spec, prior to boot the PCC space wil be initialized by | 213 | */ |
210 | * platform and should have set the command completion bit when | 214 | ret = readw_relaxed_poll_timeout(&generic_comm_base->status, status, |
211 | * PCC can be used by OSPM | 215 | status & PCC_CMD_COMPLETE_MASK, 3, |
212 | */ | 216 | pcc_ss_data->deadline_us); |
213 | status = readw_relaxed(&generic_comm_base->status); | ||
214 | if (status & PCC_CMD_COMPLETE_MASK) { | ||
215 | ret = 0; | ||
216 | if (chk_err_bit && (status & PCC_ERROR_MASK)) | ||
217 | ret = -EIO; | ||
218 | break; | ||
219 | } | ||
220 | /* | ||
221 | * Reducing the bus traffic in case this loop takes longer than | ||
222 | * a few retries. | ||
223 | */ | ||
224 | udelay(3); | ||
225 | } | ||
226 | 217 | ||
227 | if (likely(!ret)) | 218 | if (likely(!ret)) { |
228 | pcc_ss_data->platform_owns_pcc = false; | 219 | pcc_ss_data->platform_owns_pcc = false; |
229 | else | 220 | if (chk_err_bit && (status & PCC_ERROR_MASK)) |
230 | pr_err("PCC check channel failed for ss: %d. Status=%x\n", | 221 | ret = -EIO; |
231 | pcc_ss_id, status); | 222 | } |
223 | |||
224 | if (unlikely(ret)) | ||
225 | pr_err("PCC check channel failed for ss: %d. ret=%d\n", | ||
226 | pcc_ss_id, ret); | ||
232 | 227 | ||
233 | return ret; | 228 | return ret; |
234 | } | 229 | } |
@@ -580,7 +575,7 @@ static int register_pcc_channel(int pcc_ss_idx) | |||
580 | * So add an arbitrary amount of wait on top of Nominal. | 575 | * So add an arbitrary amount of wait on top of Nominal. |
581 | */ | 576 | */ |
582 | usecs_lat = NUM_RETRIES * cppc_ss->latency; | 577 | usecs_lat = NUM_RETRIES * cppc_ss->latency; |
583 | pcc_data[pcc_ss_idx]->deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); | 578 | pcc_data[pcc_ss_idx]->deadline_us = usecs_lat; |
584 | pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; | 579 | pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; |
585 | pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; | 580 | pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; |
586 | pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; | 581 | pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; |
@@ -613,7 +608,6 @@ bool __weak cpc_ffh_supported(void) | |||
613 | return false; | 608 | return false; |
614 | } | 609 | } |
615 | 610 | ||
616 | |||
617 | /** | 611 | /** |
618 | * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace | 612 | * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace |
619 | * | 613 | * |
@@ -641,6 +635,34 @@ int pcc_data_alloc(int pcc_ss_id) | |||
641 | 635 | ||
642 | return 0; | 636 | return 0; |
643 | } | 637 | } |
638 | |||
639 | /* Check if CPPC revision + num_ent combination is supported */ | ||
640 | static bool is_cppc_supported(int revision, int num_ent) | ||
641 | { | ||
642 | int expected_num_ent; | ||
643 | |||
644 | switch (revision) { | ||
645 | case CPPC_V2_REV: | ||
646 | expected_num_ent = CPPC_V2_NUM_ENT; | ||
647 | break; | ||
648 | case CPPC_V3_REV: | ||
649 | expected_num_ent = CPPC_V3_NUM_ENT; | ||
650 | break; | ||
651 | default: | ||
652 | pr_debug("Firmware exports unsupported CPPC revision: %d\n", | ||
653 | revision); | ||
654 | return false; | ||
655 | } | ||
656 | |||
657 | if (expected_num_ent != num_ent) { | ||
658 | pr_debug("Firmware exports %d entries. Expected: %d for CPPC rev:%d\n", | ||
659 | num_ent, expected_num_ent, revision); | ||
660 | return false; | ||
661 | } | ||
662 | |||
663 | return true; | ||
664 | } | ||
665 | |||
644 | /* | 666 | /* |
645 | * An example CPC table looks like the following. | 667 | * An example CPC table looks like the following. |
646 | * | 668 | * |
@@ -731,14 +753,6 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
731 | cpc_obj->type); | 753 | cpc_obj->type); |
732 | goto out_free; | 754 | goto out_free; |
733 | } | 755 | } |
734 | |||
735 | /* Only support CPPCv2. Bail otherwise. */ | ||
736 | if (num_ent != CPPC_NUM_ENT) { | ||
737 | pr_debug("Firmware exports %d entries. Expected: %d\n", | ||
738 | num_ent, CPPC_NUM_ENT); | ||
739 | goto out_free; | ||
740 | } | ||
741 | |||
742 | cpc_ptr->num_entries = num_ent; | 756 | cpc_ptr->num_entries = num_ent; |
743 | 757 | ||
744 | /* Second entry should be revision. */ | 758 | /* Second entry should be revision. */ |
@@ -750,12 +764,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
750 | cpc_obj->type); | 764 | cpc_obj->type); |
751 | goto out_free; | 765 | goto out_free; |
752 | } | 766 | } |
767 | cpc_ptr->version = cpc_rev; | ||
753 | 768 | ||
754 | if (cpc_rev != CPPC_REV) { | 769 | if (!is_cppc_supported(cpc_rev, num_ent)) |
755 | pr_debug("Firmware exports revision:%d. Expected:%d\n", | ||
756 | cpc_rev, CPPC_REV); | ||
757 | goto out_free; | 770 | goto out_free; |
758 | } | ||
759 | 771 | ||
760 | /* Iterate through remaining entries in _CPC */ | 772 | /* Iterate through remaining entries in _CPC */ |
761 | for (i = 2; i < num_ent; i++) { | 773 | for (i = 2; i < num_ent; i++) { |
@@ -808,6 +820,18 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
808 | } | 820 | } |
809 | } | 821 | } |
810 | per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id; | 822 | per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id; |
823 | |||
824 | /* | ||
825 | * Initialize the remaining cpc_regs as unsupported. | ||
826 | * Example: In case FW exposes CPPC v2, the below loop will initialize | ||
827 | * LOWEST_FREQ and NOMINAL_FREQ regs as unsupported | ||
828 | */ | ||
829 | for (i = num_ent - 2; i < MAX_CPC_REG_ENT; i++) { | ||
830 | cpc_ptr->cpc_regs[i].type = ACPI_TYPE_INTEGER; | ||
831 | cpc_ptr->cpc_regs[i].cpc_entry.int_value = 0; | ||
832 | } | ||
833 | |||
834 | |||
811 | /* Store CPU Logical ID */ | 835 | /* Store CPU Logical ID */ |
812 | cpc_ptr->cpu_id = pr->id; | 836 | cpc_ptr->cpu_id = pr->id; |
813 | 837 | ||
@@ -1037,26 +1061,34 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
1037 | { | 1061 | { |
1038 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); | 1062 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); |
1039 | struct cpc_register_resource *highest_reg, *lowest_reg, | 1063 | struct cpc_register_resource *highest_reg, *lowest_reg, |
1040 | *lowest_non_linear_reg, *nominal_reg; | 1064 | *lowest_non_linear_reg, *nominal_reg, |
1041 | u64 high, low, nom, min_nonlinear; | 1065 | *low_freq_reg = NULL, *nom_freq_reg = NULL; |
1066 | u64 high, low, nom, min_nonlinear, low_f = 0, nom_f = 0; | ||
1042 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); | 1067 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); |
1043 | struct cppc_pcc_data *pcc_ss_data; | 1068 | struct cppc_pcc_data *pcc_ss_data = NULL; |
1044 | int ret = 0, regs_in_pcc = 0; | 1069 | int ret = 0, regs_in_pcc = 0; |
1045 | 1070 | ||
1046 | if (!cpc_desc || pcc_ss_id < 0) { | 1071 | if (!cpc_desc) { |
1047 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | 1072 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); |
1048 | return -ENODEV; | 1073 | return -ENODEV; |
1049 | } | 1074 | } |
1050 | 1075 | ||
1051 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1052 | highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; | 1076 | highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; |
1053 | lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; | 1077 | lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; |
1054 | lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF]; | 1078 | lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF]; |
1055 | nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; | 1079 | nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; |
1080 | low_freq_reg = &cpc_desc->cpc_regs[LOWEST_FREQ]; | ||
1081 | nom_freq_reg = &cpc_desc->cpc_regs[NOMINAL_FREQ]; | ||
1056 | 1082 | ||
1057 | /* Are any of the regs PCC ?*/ | 1083 | /* Are any of the regs PCC ?*/ |
1058 | if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || | 1084 | if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || |
1059 | CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg)) { | 1085 | CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) || |
1086 | CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) { | ||
1087 | if (pcc_ss_id < 0) { | ||
1088 | pr_debug("Invalid pcc_ss_id\n"); | ||
1089 | return -ENODEV; | ||
1090 | } | ||
1091 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1060 | regs_in_pcc = 1; | 1092 | regs_in_pcc = 1; |
1061 | down_write(&pcc_ss_data->pcc_lock); | 1093 | down_write(&pcc_ss_data->pcc_lock); |
1062 | /* Ring doorbell once to update PCC subspace */ | 1094 | /* Ring doorbell once to update PCC subspace */ |
@@ -1081,6 +1113,17 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
1081 | if (!high || !low || !nom || !min_nonlinear) | 1113 | if (!high || !low || !nom || !min_nonlinear) |
1082 | ret = -EFAULT; | 1114 | ret = -EFAULT; |
1083 | 1115 | ||
1116 | /* Read optional lowest and nominal frequencies if present */ | ||
1117 | if (CPC_SUPPORTED(low_freq_reg)) | ||
1118 | cpc_read(cpunum, low_freq_reg, &low_f); | ||
1119 | |||
1120 | if (CPC_SUPPORTED(nom_freq_reg)) | ||
1121 | cpc_read(cpunum, nom_freq_reg, &nom_f); | ||
1122 | |||
1123 | perf_caps->lowest_freq = low_f; | ||
1124 | perf_caps->nominal_freq = nom_f; | ||
1125 | |||
1126 | |||
1084 | out_err: | 1127 | out_err: |
1085 | if (regs_in_pcc) | 1128 | if (regs_in_pcc) |
1086 | up_write(&pcc_ss_data->pcc_lock); | 1129 | up_write(&pcc_ss_data->pcc_lock); |
@@ -1101,16 +1144,15 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
1101 | struct cpc_register_resource *delivered_reg, *reference_reg, | 1144 | struct cpc_register_resource *delivered_reg, *reference_reg, |
1102 | *ref_perf_reg, *ctr_wrap_reg; | 1145 | *ref_perf_reg, *ctr_wrap_reg; |
1103 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); | 1146 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); |
1104 | struct cppc_pcc_data *pcc_ss_data; | 1147 | struct cppc_pcc_data *pcc_ss_data = NULL; |
1105 | u64 delivered, reference, ref_perf, ctr_wrap_time; | 1148 | u64 delivered, reference, ref_perf, ctr_wrap_time; |
1106 | int ret = 0, regs_in_pcc = 0; | 1149 | int ret = 0, regs_in_pcc = 0; |
1107 | 1150 | ||
1108 | if (!cpc_desc || pcc_ss_id < 0) { | 1151 | if (!cpc_desc) { |
1109 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); | 1152 | pr_debug("No CPC descriptor for CPU:%d\n", cpunum); |
1110 | return -ENODEV; | 1153 | return -ENODEV; |
1111 | } | 1154 | } |
1112 | 1155 | ||
1113 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1114 | delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; | 1156 | delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; |
1115 | reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; | 1157 | reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; |
1116 | ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; | 1158 | ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; |
@@ -1126,6 +1168,11 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
1126 | /* Are any of the regs PCC ?*/ | 1168 | /* Are any of the regs PCC ?*/ |
1127 | if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || | 1169 | if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || |
1128 | CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { | 1170 | CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { |
1171 | if (pcc_ss_id < 0) { | ||
1172 | pr_debug("Invalid pcc_ss_id\n"); | ||
1173 | return -ENODEV; | ||
1174 | } | ||
1175 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1129 | down_write(&pcc_ss_data->pcc_lock); | 1176 | down_write(&pcc_ss_data->pcc_lock); |
1130 | regs_in_pcc = 1; | 1177 | regs_in_pcc = 1; |
1131 | /* Ring doorbell once to update PCC subspace */ | 1178 | /* Ring doorbell once to update PCC subspace */ |
@@ -1176,15 +1223,14 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
1176 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); | 1223 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); |
1177 | struct cpc_register_resource *desired_reg; | 1224 | struct cpc_register_resource *desired_reg; |
1178 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); | 1225 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); |
1179 | struct cppc_pcc_data *pcc_ss_data; | 1226 | struct cppc_pcc_data *pcc_ss_data = NULL; |
1180 | int ret = 0; | 1227 | int ret = 0; |
1181 | 1228 | ||
1182 | if (!cpc_desc || pcc_ss_id < 0) { | 1229 | if (!cpc_desc) { |
1183 | pr_debug("No CPC descriptor for CPU:%d\n", cpu); | 1230 | pr_debug("No CPC descriptor for CPU:%d\n", cpu); |
1184 | return -ENODEV; | 1231 | return -ENODEV; |
1185 | } | 1232 | } |
1186 | 1233 | ||
1187 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1188 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; | 1234 | desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; |
1189 | 1235 | ||
1190 | /* | 1236 | /* |
@@ -1195,6 +1241,11 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
1195 | * achieve that goal here | 1241 | * achieve that goal here |
1196 | */ | 1242 | */ |
1197 | if (CPC_IN_PCC(desired_reg)) { | 1243 | if (CPC_IN_PCC(desired_reg)) { |
1244 | if (pcc_ss_id < 0) { | ||
1245 | pr_debug("Invalid pcc_ss_id\n"); | ||
1246 | return -ENODEV; | ||
1247 | } | ||
1248 | pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1198 | down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */ | 1249 | down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */ |
1199 | if (pcc_ss_data->platform_owns_pcc) { | 1250 | if (pcc_ss_data->platform_owns_pcc) { |
1200 | ret = check_pcc_chan(pcc_ss_id, false); | 1251 | ret = check_pcc_chan(pcc_ss_id, false); |
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index 71769fd687b2..6fa9c2a4cfe9 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c | |||
@@ -8,8 +8,8 @@ void acpi_reboot(void) | |||
8 | { | 8 | { |
9 | struct acpi_generic_address *rr; | 9 | struct acpi_generic_address *rr; |
10 | struct pci_bus *bus0; | 10 | struct pci_bus *bus0; |
11 | u8 reset_value; | ||
12 | unsigned int devfn; | 11 | unsigned int devfn; |
12 | u8 reset_value; | ||
13 | 13 | ||
14 | if (acpi_disabled) | 14 | if (acpi_disabled) |
15 | return; | 15 | return; |
@@ -40,7 +40,7 @@ void acpi_reboot(void) | |||
40 | /* Form PCI device/function pair. */ | 40 | /* Form PCI device/function pair. */ |
41 | devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, | 41 | devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, |
42 | (rr->address >> 16) & 0xffff); | 42 | (rr->address >> 16) & 0xffff); |
43 | printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG."); | 43 | printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG.\n"); |
44 | /* Write the value that resets us. */ | 44 | /* Write the value that resets us. */ |
45 | pci_bus_write_config_byte(bus0, devfn, | 45 | pci_bus_write_config_byte(bus0, devfn, |
46 | (rr->address & 0xffff), reset_value); | 46 | (rr->address & 0xffff), reset_value); |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 849c4fb19b03..4a3410aa6540 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -222,7 +222,7 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) | |||
222 | * acpi_parse_entries_array - for each proc_num find a suitable subtable | 222 | * acpi_parse_entries_array - for each proc_num find a suitable subtable |
223 | * | 223 | * |
224 | * @id: table id (for debugging purposes) | 224 | * @id: table id (for debugging purposes) |
225 | * @table_size: single entry size | 225 | * @table_size: size of the root table |
226 | * @table_header: where does the table start? | 226 | * @table_header: where does the table start? |
227 | * @proc: array of acpi_subtable_proc struct containing entry id | 227 | * @proc: array of acpi_subtable_proc struct containing entry id |
228 | * and associated handler with it | 228 | * and associated handler with it |
@@ -233,6 +233,11 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) | |||
233 | * on it. Assumption is that there's only single handler for particular | 233 | * on it. Assumption is that there's only single handler for particular |
234 | * entry id. | 234 | * entry id. |
235 | * | 235 | * |
236 | * The table_size is not the size of the complete ACPI table (the length | ||
237 | * field in the header struct), but only the size of the root table; i.e., | ||
238 | * the offset from the very first byte of the complete ACPI table, to the | ||
239 | * first byte of the very first subtable. | ||
240 | * | ||
236 | * On success returns sum of all matching entries for all proc handlers. | 241 | * On success returns sum of all matching entries for all proc handlers. |
237 | * Otherwise, -ENODEV or -EINVAL is returned. | 242 | * Otherwise, -ENODEV or -EINVAL is returned. |
238 | */ | 243 | */ |
@@ -400,7 +405,7 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler) | |||
400 | return -ENODEV; | 405 | return -ENODEV; |
401 | } | 406 | } |
402 | 407 | ||
403 | /* | 408 | /* |
404 | * The BIOS is supposed to supply a single APIC/MADT, | 409 | * The BIOS is supposed to supply a single APIC/MADT, |
405 | * but some report two. Provide a knob to use either. | 410 | * but some report two. Provide a knob to use either. |
406 | * (don't you wish instance 0 and 1 were not the same?) | 411 | * (don't you wish instance 0 and 1 were not the same?) |
diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile index 1367afb03858..00303bc05415 100644 --- a/drivers/clk/x86/Makefile +++ b/drivers/clk/x86/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o | ||
2 | obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE) += clk-st.o | ||
1 | clk-x86-lpss-objs := clk-lpt.o | 3 | clk-x86-lpss-objs := clk-lpt.o |
2 | obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o | 4 | obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o |
3 | obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o | ||
diff --git a/drivers/clk/x86/clk-st.c b/drivers/clk/x86/clk-st.c new file mode 100644 index 000000000000..fb62f3938008 --- /dev/null +++ b/drivers/clk/x86/clk-st.c | |||
@@ -0,0 +1,77 @@ | |||
1 | // SPDX-License-Identifier: MIT | ||
2 | /* | ||
3 | * clock framework for AMD Stoney based clocks | ||
4 | * | ||
5 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
6 | */ | ||
7 | |||
8 | #include <linux/clk.h> | ||
9 | #include <linux/clkdev.h> | ||
10 | #include <linux/clk-provider.h> | ||
11 | #include <linux/platform_data/clk-st.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | |||
14 | /* Clock Driving Strength 2 register */ | ||
15 | #define CLKDRVSTR2 0x28 | ||
16 | /* Clock Control 1 register */ | ||
17 | #define MISCCLKCNTL1 0x40 | ||
18 | /* Auxiliary clock1 enable bit */ | ||
19 | #define OSCCLKENB 2 | ||
20 | /* 25Mhz auxiliary output clock freq bit */ | ||
21 | #define OSCOUT1CLK25MHZ 16 | ||
22 | |||
23 | #define ST_CLK_48M 0 | ||
24 | #define ST_CLK_25M 1 | ||
25 | #define ST_CLK_MUX 2 | ||
26 | #define ST_CLK_GATE 3 | ||
27 | #define ST_MAX_CLKS 4 | ||
28 | |||
29 | static const char * const clk_oscout1_parents[] = { "clk48MHz", "clk25MHz" }; | ||
30 | static struct clk_hw *hws[ST_MAX_CLKS]; | ||
31 | |||
32 | static int st_clk_probe(struct platform_device *pdev) | ||
33 | { | ||
34 | struct st_clk_data *st_data; | ||
35 | |||
36 | st_data = dev_get_platdata(&pdev->dev); | ||
37 | if (!st_data || !st_data->base) | ||
38 | return -EINVAL; | ||
39 | |||
40 | hws[ST_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz", NULL, 0, | ||
41 | 48000000); | ||
42 | hws[ST_CLK_25M] = clk_hw_register_fixed_rate(NULL, "clk25MHz", NULL, 0, | ||
43 | 25000000); | ||
44 | |||
45 | hws[ST_CLK_MUX] = clk_hw_register_mux(NULL, "oscout1_mux", | ||
46 | clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents), | ||
47 | 0, st_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0, NULL); | ||
48 | |||
49 | clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_25M]->clk); | ||
50 | |||
51 | hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "oscout1_mux", | ||
52 | 0, st_data->base + MISCCLKCNTL1, OSCCLKENB, | ||
53 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
54 | |||
55 | clk_hw_register_clkdev(hws[ST_CLK_GATE], "oscout1", NULL); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int st_clk_remove(struct platform_device *pdev) | ||
61 | { | ||
62 | int i; | ||
63 | |||
64 | for (i = 0; i < ST_MAX_CLKS; i++) | ||
65 | clk_hw_unregister(hws[i]); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static struct platform_driver st_clk_driver = { | ||
70 | .driver = { | ||
71 | .name = "clk-st", | ||
72 | .suppress_bind_attrs = true, | ||
73 | }, | ||
74 | .probe = st_clk_probe, | ||
75 | .remove = st_clk_remove, | ||
76 | }; | ||
77 | builtin_platform_driver(st_clk_driver); | ||
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index b15115a48775..3464580ac3ca 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c | |||
@@ -42,9 +42,6 @@ | |||
42 | */ | 42 | */ |
43 | static struct cppc_cpudata **all_cpu_data; | 43 | static struct cppc_cpudata **all_cpu_data; |
44 | 44 | ||
45 | /* Capture the max KHz from DMI */ | ||
46 | static u64 cppc_dmi_max_khz; | ||
47 | |||
48 | /* Callback function used to retrieve the max frequency from DMI */ | 45 | /* Callback function used to retrieve the max frequency from DMI */ |
49 | static void cppc_find_dmi_mhz(const struct dmi_header *dm, void *private) | 46 | static void cppc_find_dmi_mhz(const struct dmi_header *dm, void *private) |
50 | { | 47 | { |
@@ -75,6 +72,64 @@ static u64 cppc_get_dmi_max_khz(void) | |||
75 | return (1000 * mhz); | 72 | return (1000 * mhz); |
76 | } | 73 | } |
77 | 74 | ||
75 | /* | ||
76 | * If CPPC lowest_freq and nominal_freq registers are exposed then we can | ||
77 | * use them to convert perf to freq and vice versa | ||
78 | * | ||
79 | * If the perf/freq point lies between Nominal and Lowest, we can treat | ||
80 | * (Low perf, Low freq) and (Nom Perf, Nom freq) as 2D co-ordinates of a line | ||
81 | * and extrapolate the rest | ||
82 | * For perf/freq > Nominal, we use the ratio perf:freq at Nominal for conversion | ||
83 | */ | ||
84 | static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu, | ||
85 | unsigned int perf) | ||
86 | { | ||
87 | static u64 max_khz; | ||
88 | struct cppc_perf_caps *caps = &cpu->perf_caps; | ||
89 | u64 mul, div; | ||
90 | |||
91 | if (caps->lowest_freq && caps->nominal_freq) { | ||
92 | if (perf >= caps->nominal_perf) { | ||
93 | mul = caps->nominal_freq; | ||
94 | div = caps->nominal_perf; | ||
95 | } else { | ||
96 | mul = caps->nominal_freq - caps->lowest_freq; | ||
97 | div = caps->nominal_perf - caps->lowest_perf; | ||
98 | } | ||
99 | } else { | ||
100 | if (!max_khz) | ||
101 | max_khz = cppc_get_dmi_max_khz(); | ||
102 | mul = max_khz; | ||
103 | div = cpu->perf_caps.highest_perf; | ||
104 | } | ||
105 | return (u64)perf * mul / div; | ||
106 | } | ||
107 | |||
108 | static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu, | ||
109 | unsigned int freq) | ||
110 | { | ||
111 | static u64 max_khz; | ||
112 | struct cppc_perf_caps *caps = &cpu->perf_caps; | ||
113 | u64 mul, div; | ||
114 | |||
115 | if (caps->lowest_freq && caps->nominal_freq) { | ||
116 | if (freq >= caps->nominal_freq) { | ||
117 | mul = caps->nominal_perf; | ||
118 | div = caps->nominal_freq; | ||
119 | } else { | ||
120 | mul = caps->lowest_perf; | ||
121 | div = caps->lowest_freq; | ||
122 | } | ||
123 | } else { | ||
124 | if (!max_khz) | ||
125 | max_khz = cppc_get_dmi_max_khz(); | ||
126 | mul = cpu->perf_caps.highest_perf; | ||
127 | div = max_khz; | ||
128 | } | ||
129 | |||
130 | return (u64)freq * mul / div; | ||
131 | } | ||
132 | |||
78 | static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, | 133 | static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, |
79 | unsigned int target_freq, | 134 | unsigned int target_freq, |
80 | unsigned int relation) | 135 | unsigned int relation) |
@@ -86,7 +141,7 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy, | |||
86 | 141 | ||
87 | cpu = all_cpu_data[policy->cpu]; | 142 | cpu = all_cpu_data[policy->cpu]; |
88 | 143 | ||
89 | desired_perf = (u64)target_freq * cpu->perf_caps.highest_perf / cppc_dmi_max_khz; | 144 | desired_perf = cppc_cpufreq_khz_to_perf(cpu, target_freq); |
90 | /* Return if it is exactly the same perf */ | 145 | /* Return if it is exactly the same perf */ |
91 | if (desired_perf == cpu->perf_ctrls.desired_perf) | 146 | if (desired_perf == cpu->perf_ctrls.desired_perf) |
92 | return ret; | 147 | return ret; |
@@ -186,24 +241,24 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
186 | return ret; | 241 | return ret; |
187 | } | 242 | } |
188 | 243 | ||
189 | cppc_dmi_max_khz = cppc_get_dmi_max_khz(); | 244 | /* Convert the lowest and nominal freq from MHz to KHz */ |
245 | cpu->perf_caps.lowest_freq *= 1000; | ||
246 | cpu->perf_caps.nominal_freq *= 1000; | ||
190 | 247 | ||
191 | /* | 248 | /* |
192 | * Set min to lowest nonlinear perf to avoid any efficiency penalty (see | 249 | * Set min to lowest nonlinear perf to avoid any efficiency penalty (see |
193 | * Section 8.4.7.1.1.5 of ACPI 6.1 spec) | 250 | * Section 8.4.7.1.1.5 of ACPI 6.1 spec) |
194 | */ | 251 | */ |
195 | policy->min = cpu->perf_caps.lowest_nonlinear_perf * cppc_dmi_max_khz / | 252 | policy->min = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_nonlinear_perf); |
196 | cpu->perf_caps.highest_perf; | 253 | policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf); |
197 | policy->max = cppc_dmi_max_khz; | ||
198 | 254 | ||
199 | /* | 255 | /* |
200 | * Set cpuinfo.min_freq to Lowest to make the full range of performance | 256 | * Set cpuinfo.min_freq to Lowest to make the full range of performance |
201 | * available if userspace wants to use any perf between lowest & lowest | 257 | * available if userspace wants to use any perf between lowest & lowest |
202 | * nonlinear perf | 258 | * nonlinear perf |
203 | */ | 259 | */ |
204 | policy->cpuinfo.min_freq = cpu->perf_caps.lowest_perf * cppc_dmi_max_khz / | 260 | policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_perf); |
205 | cpu->perf_caps.highest_perf; | 261 | policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf); |
206 | policy->cpuinfo.max_freq = cppc_dmi_max_khz; | ||
207 | 262 | ||
208 | policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num); | 263 | policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num); |
209 | policy->shared_type = cpu->shared_type; | 264 | policy->shared_type = cpu->shared_type; |
@@ -229,7 +284,8 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
229 | cpu->cur_policy = policy; | 284 | cpu->cur_policy = policy; |
230 | 285 | ||
231 | /* Set policy->cur to max now. The governors will adjust later. */ | 286 | /* Set policy->cur to max now. The governors will adjust later. */ |
232 | policy->cur = cppc_dmi_max_khz; | 287 | policy->cur = cppc_cpufreq_perf_to_khz(cpu, |
288 | cpu->perf_caps.highest_perf); | ||
233 | cpu->perf_ctrls.desired_perf = cpu->perf_caps.highest_perf; | 289 | cpu->perf_ctrls.desired_perf = cpu->perf_caps.highest_perf; |
234 | 290 | ||
235 | ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls); | 291 | ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls); |
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 3ef7f036ceea..fc3c237daef2 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c | |||
@@ -373,33 +373,24 @@ static const struct mbox_chan_ops pcc_chan_ops = { | |||
373 | }; | 373 | }; |
374 | 374 | ||
375 | /** | 375 | /** |
376 | * parse_pcc_subspace - Parse the PCC table and verify PCC subspace | 376 | * parse_pcc_subspaces -- Count PCC subspaces defined |
377 | * entries. There should be one entry per PCC client. | ||
378 | * @header: Pointer to the ACPI subtable header under the PCCT. | 377 | * @header: Pointer to the ACPI subtable header under the PCCT. |
379 | * @end: End of subtable entry. | 378 | * @end: End of subtable entry. |
380 | * | 379 | * |
381 | * Return: 0 for Success, else errno. | 380 | * Return: If we find a PCC subspace entry of a valid type, return 0. |
381 | * Otherwise, return -EINVAL. | ||
382 | * | 382 | * |
383 | * This gets called for each entry in the PCC table. | 383 | * This gets called for each entry in the PCC table. |
384 | */ | 384 | */ |
385 | static int parse_pcc_subspace(struct acpi_subtable_header *header, | 385 | static int parse_pcc_subspace(struct acpi_subtable_header *header, |
386 | const unsigned long end) | 386 | const unsigned long end) |
387 | { | 387 | { |
388 | struct acpi_pcct_hw_reduced *pcct_ss; | 388 | struct acpi_pcct_subspace *ss = (struct acpi_pcct_subspace *) header; |
389 | |||
390 | if (pcc_mbox_ctrl.num_chans <= MAX_PCC_SUBSPACES) { | ||
391 | pcct_ss = (struct acpi_pcct_hw_reduced *) header; | ||
392 | 389 | ||
393 | if ((pcct_ss->header.type != | 390 | if (ss->header.type < ACPI_PCCT_TYPE_RESERVED) |
394 | ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) | 391 | return 0; |
395 | && (pcct_ss->header.type != | ||
396 | ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) { | ||
397 | pr_err("Incorrect PCC Subspace type detected\n"); | ||
398 | return -EINVAL; | ||
399 | } | ||
400 | } | ||
401 | 392 | ||
402 | return 0; | 393 | return -EINVAL; |
403 | } | 394 | } |
404 | 395 | ||
405 | /** | 396 | /** |
@@ -449,8 +440,8 @@ static int __init acpi_pcc_probe(void) | |||
449 | struct acpi_table_header *pcct_tbl; | 440 | struct acpi_table_header *pcct_tbl; |
450 | struct acpi_subtable_header *pcct_entry; | 441 | struct acpi_subtable_header *pcct_entry; |
451 | struct acpi_table_pcct *acpi_pcct_tbl; | 442 | struct acpi_table_pcct *acpi_pcct_tbl; |
443 | struct acpi_subtable_proc proc[ACPI_PCCT_TYPE_RESERVED]; | ||
452 | int count, i, rc; | 444 | int count, i, rc; |
453 | int sum = 0; | ||
454 | acpi_status status = AE_OK; | 445 | acpi_status status = AE_OK; |
455 | 446 | ||
456 | /* Search for PCCT */ | 447 | /* Search for PCCT */ |
@@ -459,43 +450,41 @@ static int __init acpi_pcc_probe(void) | |||
459 | if (ACPI_FAILURE(status) || !pcct_tbl) | 450 | if (ACPI_FAILURE(status) || !pcct_tbl) |
460 | return -ENODEV; | 451 | return -ENODEV; |
461 | 452 | ||
462 | count = acpi_table_parse_entries(ACPI_SIG_PCCT, | 453 | /* Set up the subtable handlers */ |
463 | sizeof(struct acpi_table_pcct), | 454 | for (i = ACPI_PCCT_TYPE_GENERIC_SUBSPACE; |
464 | ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE, | 455 | i < ACPI_PCCT_TYPE_RESERVED; i++) { |
465 | parse_pcc_subspace, MAX_PCC_SUBSPACES); | 456 | proc[i].id = i; |
466 | sum += (count > 0) ? count : 0; | 457 | proc[i].count = 0; |
467 | 458 | proc[i].handler = parse_pcc_subspace; | |
468 | count = acpi_table_parse_entries(ACPI_SIG_PCCT, | 459 | } |
469 | sizeof(struct acpi_table_pcct), | ||
470 | ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2, | ||
471 | parse_pcc_subspace, MAX_PCC_SUBSPACES); | ||
472 | sum += (count > 0) ? count : 0; | ||
473 | 460 | ||
474 | if (sum == 0 || sum >= MAX_PCC_SUBSPACES) { | 461 | count = acpi_table_parse_entries_array(ACPI_SIG_PCCT, |
475 | pr_err("Error parsing PCC subspaces from PCCT\n"); | 462 | sizeof(struct acpi_table_pcct), proc, |
463 | ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES); | ||
464 | if (count == 0 || count > MAX_PCC_SUBSPACES) { | ||
465 | pr_warn("Invalid PCCT: %d PCC subspaces\n", count); | ||
476 | return -EINVAL; | 466 | return -EINVAL; |
477 | } | 467 | } |
478 | 468 | ||
479 | pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * | 469 | pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * count, GFP_KERNEL); |
480 | sum, GFP_KERNEL); | ||
481 | if (!pcc_mbox_channels) { | 470 | if (!pcc_mbox_channels) { |
482 | pr_err("Could not allocate space for PCC mbox channels\n"); | 471 | pr_err("Could not allocate space for PCC mbox channels\n"); |
483 | return -ENOMEM; | 472 | return -ENOMEM; |
484 | } | 473 | } |
485 | 474 | ||
486 | pcc_doorbell_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL); | 475 | pcc_doorbell_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL); |
487 | if (!pcc_doorbell_vaddr) { | 476 | if (!pcc_doorbell_vaddr) { |
488 | rc = -ENOMEM; | 477 | rc = -ENOMEM; |
489 | goto err_free_mbox; | 478 | goto err_free_mbox; |
490 | } | 479 | } |
491 | 480 | ||
492 | pcc_doorbell_ack_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL); | 481 | pcc_doorbell_ack_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL); |
493 | if (!pcc_doorbell_ack_vaddr) { | 482 | if (!pcc_doorbell_ack_vaddr) { |
494 | rc = -ENOMEM; | 483 | rc = -ENOMEM; |
495 | goto err_free_db_vaddr; | 484 | goto err_free_db_vaddr; |
496 | } | 485 | } |
497 | 486 | ||
498 | pcc_doorbell_irq = kcalloc(sum, sizeof(int), GFP_KERNEL); | 487 | pcc_doorbell_irq = kcalloc(count, sizeof(int), GFP_KERNEL); |
499 | if (!pcc_doorbell_irq) { | 488 | if (!pcc_doorbell_irq) { |
500 | rc = -ENOMEM; | 489 | rc = -ENOMEM; |
501 | goto err_free_db_ack_vaddr; | 490 | goto err_free_db_ack_vaddr; |
@@ -509,18 +498,24 @@ static int __init acpi_pcc_probe(void) | |||
509 | if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) | 498 | if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) |
510 | pcc_mbox_ctrl.txdone_irq = true; | 499 | pcc_mbox_ctrl.txdone_irq = true; |
511 | 500 | ||
512 | for (i = 0; i < sum; i++) { | 501 | for (i = 0; i < count; i++) { |
513 | struct acpi_generic_address *db_reg; | 502 | struct acpi_generic_address *db_reg; |
514 | struct acpi_pcct_hw_reduced *pcct_ss; | 503 | struct acpi_pcct_subspace *pcct_ss; |
515 | pcc_mbox_channels[i].con_priv = pcct_entry; | 504 | pcc_mbox_channels[i].con_priv = pcct_entry; |
516 | 505 | ||
517 | pcct_ss = (struct acpi_pcct_hw_reduced *) pcct_entry; | 506 | if (pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE || |
507 | pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) { | ||
508 | struct acpi_pcct_hw_reduced *pcct_hrss; | ||
509 | |||
510 | pcct_hrss = (struct acpi_pcct_hw_reduced *) pcct_entry; | ||
518 | 511 | ||
519 | if (pcc_mbox_ctrl.txdone_irq) { | 512 | if (pcc_mbox_ctrl.txdone_irq) { |
520 | rc = pcc_parse_subspace_irq(i, pcct_ss); | 513 | rc = pcc_parse_subspace_irq(i, pcct_hrss); |
521 | if (rc < 0) | 514 | if (rc < 0) |
522 | goto err; | 515 | goto err; |
516 | } | ||
523 | } | 517 | } |
518 | pcct_ss = (struct acpi_pcct_subspace *) pcct_entry; | ||
524 | 519 | ||
525 | /* If doorbell is in system memory cache the virt address */ | 520 | /* If doorbell is in system memory cache the virt address */ |
526 | db_reg = &pcct_ss->doorbell_register; | 521 | db_reg = &pcct_ss->doorbell_register; |
@@ -531,7 +526,7 @@ static int __init acpi_pcc_probe(void) | |||
531 | ((unsigned long) pcct_entry + pcct_entry->length); | 526 | ((unsigned long) pcct_entry + pcct_entry->length); |
532 | } | 527 | } |
533 | 528 | ||
534 | pcc_mbox_ctrl.num_chans = sum; | 529 | pcc_mbox_ctrl.num_chans = count; |
535 | 530 | ||
536 | pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans); | 531 | pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans); |
537 | 532 | ||
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 7b289dd00a30..6f69a4f638f8 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h | |||
@@ -49,11 +49,14 @@ | |||
49 | /* Definitions of the predefined namespace names */ | 49 | /* Definitions of the predefined namespace names */ |
50 | 50 | ||
51 | #define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */ | 51 | #define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */ |
52 | #define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */ | ||
53 | |||
54 | #define ACPI_PREFIX_MIXED (u32) 0x69706341 /* "Acpi" */ | 52 | #define ACPI_PREFIX_MIXED (u32) 0x69706341 /* "Acpi" */ |
55 | #define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */ | 53 | #define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */ |
56 | 54 | ||
55 | /* Root name stuff */ | ||
56 | |||
57 | #define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */ | ||
58 | #define ACPI_ROOT_PATHNAME "\\___" | ||
59 | #define ACPI_NAMESPACE_ROOT "Namespace Root" | ||
57 | #define ACPI_NS_ROOT_PATH "\\" | 60 | #define ACPI_NS_ROOT_PATH "\\" |
58 | 61 | ||
59 | #endif /* __ACNAMES_H__ */ | 62 | #endif /* __ACNAMES_H__ */ |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 540d35f06ad6..eb1f21af7556 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -98,6 +98,27 @@ void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags); | |||
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | /* | 100 | /* |
101 | * RAW spinlock primitives. If the OS does not provide them, fallback to | ||
102 | * spinlock primitives | ||
103 | */ | ||
104 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_raw_lock | ||
105 | # define acpi_os_create_raw_lock(out_handle) acpi_os_create_lock(out_handle) | ||
106 | #endif | ||
107 | |||
108 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_delete_raw_lock | ||
109 | # define acpi_os_delete_raw_lock(handle) acpi_os_delete_lock(handle) | ||
110 | #endif | ||
111 | |||
112 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_raw_lock | ||
113 | # define acpi_os_acquire_raw_lock(handle) acpi_os_acquire_lock(handle) | ||
114 | #endif | ||
115 | |||
116 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_release_raw_lock | ||
117 | # define acpi_os_release_raw_lock(handle, flags) \ | ||
118 | acpi_os_release_lock(handle, flags) | ||
119 | #endif | ||
120 | |||
121 | /* | ||
101 | * Semaphore primitives | 122 | * Semaphore primitives |
102 | */ | 123 | */ |
103 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_semaphore | 124 | #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_semaphore |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c01d790c17c2..77d71bd1be39 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 13 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
14 | 14 | ||
15 | #define ACPI_CA_VERSION 0x20180313 | 15 | #define ACPI_CA_VERSION 0x20180508 |
16 | 16 | ||
17 | #include <acpi/acconfig.h> | 17 | #include <acpi/acconfig.h> |
18 | #include <acpi/actypes.h> | 18 | #include <acpi/actypes.h> |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 1c530f95dc34..2b1bafa197c0 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -245,6 +245,10 @@ typedef u64 acpi_physical_address; | |||
245 | #define acpi_spinlock void * | 245 | #define acpi_spinlock void * |
246 | #endif | 246 | #endif |
247 | 247 | ||
248 | #ifndef acpi_raw_spinlock | ||
249 | #define acpi_raw_spinlock acpi_spinlock | ||
250 | #endif | ||
251 | |||
248 | #ifndef acpi_semaphore | 252 | #ifndef acpi_semaphore |
249 | #define acpi_semaphore void * | 253 | #define acpi_semaphore void * |
250 | #endif | 254 | #endif |
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 2010c0516f27..8e0b8250a139 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h | |||
@@ -20,14 +20,16 @@ | |||
20 | #include <acpi/pcc.h> | 20 | #include <acpi/pcc.h> |
21 | #include <acpi/processor.h> | 21 | #include <acpi/processor.h> |
22 | 22 | ||
23 | /* Only support CPPCv2 for now. */ | 23 | /* Support CPPCv2 and CPPCv3 */ |
24 | #define CPPC_NUM_ENT 21 | 24 | #define CPPC_V2_REV 2 |
25 | #define CPPC_REV 2 | 25 | #define CPPC_V3_REV 3 |
26 | #define CPPC_V2_NUM_ENT 21 | ||
27 | #define CPPC_V3_NUM_ENT 23 | ||
26 | 28 | ||
27 | #define PCC_CMD_COMPLETE_MASK (1 << 0) | 29 | #define PCC_CMD_COMPLETE_MASK (1 << 0) |
28 | #define PCC_ERROR_MASK (1 << 2) | 30 | #define PCC_ERROR_MASK (1 << 2) |
29 | 31 | ||
30 | #define MAX_CPC_REG_ENT 19 | 32 | #define MAX_CPC_REG_ENT 21 |
31 | 33 | ||
32 | /* CPPC specific PCC commands. */ | 34 | /* CPPC specific PCC commands. */ |
33 | #define CMD_READ 0 | 35 | #define CMD_READ 0 |
@@ -91,6 +93,8 @@ enum cppc_regs { | |||
91 | AUTO_ACT_WINDOW, | 93 | AUTO_ACT_WINDOW, |
92 | ENERGY_PERF, | 94 | ENERGY_PERF, |
93 | REFERENCE_PERF, | 95 | REFERENCE_PERF, |
96 | LOWEST_FREQ, | ||
97 | NOMINAL_FREQ, | ||
94 | }; | 98 | }; |
95 | 99 | ||
96 | /* | 100 | /* |
@@ -104,6 +108,8 @@ struct cppc_perf_caps { | |||
104 | u32 nominal_perf; | 108 | u32 nominal_perf; |
105 | u32 lowest_perf; | 109 | u32 lowest_perf; |
106 | u32 lowest_nonlinear_perf; | 110 | u32 lowest_nonlinear_perf; |
111 | u32 lowest_freq; | ||
112 | u32 nominal_freq; | ||
107 | }; | 113 | }; |
108 | 114 | ||
109 | struct cppc_perf_ctrls { | 115 | struct cppc_perf_ctrls { |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index a0b232703302..7451b3bca83a 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -102,6 +102,7 @@ | |||
102 | 102 | ||
103 | #define acpi_cache_t struct kmem_cache | 103 | #define acpi_cache_t struct kmem_cache |
104 | #define acpi_spinlock spinlock_t * | 104 | #define acpi_spinlock spinlock_t * |
105 | #define acpi_raw_spinlock raw_spinlock_t * | ||
105 | #define acpi_cpu_flags unsigned long | 106 | #define acpi_cpu_flags unsigned long |
106 | 107 | ||
107 | /* Use native linux version of acpi_os_allocate_zeroed */ | 108 | /* Use native linux version of acpi_os_allocate_zeroed */ |
@@ -119,6 +120,10 @@ | |||
119 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object | 120 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object |
120 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id | 121 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id |
121 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock | 122 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock |
123 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_raw_lock | ||
124 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_delete_raw_lock | ||
125 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_raw_lock | ||
126 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_release_raw_lock | ||
122 | 127 | ||
123 | /* | 128 | /* |
124 | * OSL interfaces used by debugger/disassembler | 129 | * OSL interfaces used by debugger/disassembler |
diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h index 7e81475fe034..d754a1b12721 100644 --- a/include/acpi/platform/aclinuxex.h +++ b/include/acpi/platform/aclinuxex.h | |||
@@ -90,6 +90,36 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) | |||
90 | lock ? AE_OK : AE_NO_MEMORY; \ | 90 | lock ? AE_OK : AE_NO_MEMORY; \ |
91 | }) | 91 | }) |
92 | 92 | ||
93 | |||
94 | #define acpi_os_create_raw_lock(__handle) \ | ||
95 | ({ \ | ||
96 | raw_spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ | ||
97 | if (lock) { \ | ||
98 | *(__handle) = lock; \ | ||
99 | raw_spin_lock_init(*(__handle)); \ | ||
100 | } \ | ||
101 | lock ? AE_OK : AE_NO_MEMORY; \ | ||
102 | }) | ||
103 | |||
104 | static inline acpi_cpu_flags acpi_os_acquire_raw_lock(acpi_raw_spinlock lockp) | ||
105 | { | ||
106 | acpi_cpu_flags flags; | ||
107 | |||
108 | raw_spin_lock_irqsave(lockp, flags); | ||
109 | return flags; | ||
110 | } | ||
111 | |||
112 | static inline void acpi_os_release_raw_lock(acpi_raw_spinlock lockp, | ||
113 | acpi_cpu_flags flags) | ||
114 | { | ||
115 | raw_spin_unlock_irqrestore(lockp, flags); | ||
116 | } | ||
117 | |||
118 | static inline void acpi_os_delete_raw_lock(acpi_raw_spinlock handle) | ||
119 | { | ||
120 | ACPI_FREE(handle); | ||
121 | } | ||
122 | |||
93 | static inline u8 acpi_os_readable(void *pointer, acpi_size length) | 123 | static inline u8 acpi_os_readable(void *pointer, acpi_size length) |
94 | { | 124 | { |
95 | return TRUE; | 125 | return TRUE; |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index c01675b3d93f..fd0ea6af9e36 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -578,6 +578,7 @@ int acpi_match_platform_list(const struct acpi_platform_list *plat); | |||
578 | 578 | ||
579 | extern void acpi_early_init(void); | 579 | extern void acpi_early_init(void); |
580 | extern void acpi_subsystem_init(void); | 580 | extern void acpi_subsystem_init(void); |
581 | extern void arch_post_acpi_subsys_init(void); | ||
581 | 582 | ||
582 | extern int acpi_nvs_register(__u64 start, __u64 size); | 583 | extern int acpi_nvs_register(__u64 start, __u64 size); |
583 | 584 | ||
diff --git a/include/linux/platform_data/clk-st.h b/include/linux/platform_data/clk-st.h new file mode 100644 index 000000000000..7cdb6a402b35 --- /dev/null +++ b/include/linux/platform_data/clk-st.h | |||
@@ -0,0 +1,17 @@ | |||
1 | /* SPDX-License-Identifier: MIT */ | ||
2 | /* | ||
3 | * clock framework for AMD Stoney based clock | ||
4 | * | ||
5 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
6 | */ | ||
7 | |||
8 | #ifndef __CLK_ST_H | ||
9 | #define __CLK_ST_H | ||
10 | |||
11 | #include <linux/compiler.h> | ||
12 | |||
13 | struct st_clk_data { | ||
14 | void __iomem *base; | ||
15 | }; | ||
16 | |||
17 | #endif /* __CLK_ST_H */ | ||