diff options
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 */ | ||
