diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-14 11:42:04 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-14 11:42:04 -0700 |
commit | cf1d2b44f6c701ffff58606b5b8a8996190d6e7d (patch) | |
tree | a1306bfa0cb2e58f21954ab1ef9b6c8da558f59e /drivers/acpi | |
parent | 0b8417c14181595997091145342954332fa016cd (diff) | |
parent | 8be2362d10e8b0ea9844706d8c388480d37226d2 (diff) | |
download | linux-cf1d2b44f6c701ffff58606b5b8a8996190d6e7d.tar.bz2 |
Merge tag 'acpi-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI updates from Rafael Wysocki:
"These add support for generic initiator-only proximity domains to the
ACPI NUMA code and the architectures using it, clean up some
non-ACPICA code referring to debug facilities from ACPICA, reduce the
overhead related to accessing GPE registers, add a new DPTF (Dynamic
Power and Thermal Framework) participant driver, update the ACPICA
code in the kernel to upstream revision 20200925, add a new ACPI
backlight whitelist entry, fix a few assorted issues and clean up some
code.
Specifics:
- Add support for generic initiator-only proximity domains to the
ACPI NUMA code and the architectures using it (Jonathan Cameron)
- Clean up some non-ACPICA code referring to debug facilities from
ACPICA that are not actually used in there (Hanjun Guo)
- Add new DPTF driver for the PCH FIVR participant (Srinivas
Pandruvada)
- Reduce overhead related to accessing GPE registers in ACPICA and
the OS interface layer and make it possible to access GPE registers
using logical addresses if they are memory-mapped (Rafael Wysocki)
- Update the ACPICA code in the kernel to upstream revision 20200925
including changes as follows:
+ Add predefined names from the SMBus sepcification (Bob Moore)
+ Update acpi_help UUID list (Bob Moore)
+ Return exceptions for string-to-integer conversions in iASL (Bob
Moore)
+ Add a new "ALL <NameSeg>" debugger command (Bob Moore)
+ Add support for 64 bit risc-v compilation (Colin Ian King)
+ Do assorted cleanups (Bob Moore, Colin Ian King, Randy Dunlap)
- Add new ACPI backlight whitelist entry for HP 635 Notebook (Alex
Hung)
- Move TPS68470 OpRegion driver to drivers/acpi/pmic/ and split out
Kconfig and Makefile specific for ACPI PMIC (Andy Shevchenko)
- Clean up the ACPI SoC driver for AMD SoCs (Hanjun Guo)
- Add missing config_item_put() to fix refcount leak (Hanjun Guo)
- Drop lefrover field from struct acpi_memory_device (Hanjun Guo)
- Make the ACPI extlog driver check for RDMSR failures (Ben
Hutchings)
- Fix handling of lid state changes in the ACPI button driver when
input device is closed (Dmitry Torokhov)
- Fix several assorted build issues (Barnabás Pőcze, John Garry,
Nathan Chancellor, Tian Tao)
- Drop unused inline functions and reduce code duplication by using
kobj_to_dev() in the NFIT parsing code (YueHaibing, Wang Qing)
- Serialize tools/power/acpi Makefile (Thomas Renninger)"
* tag 'acpi-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (64 commits)
ACPICA: Update version to 20200925 Version 20200925
ACPICA: Remove unnecessary semicolon
ACPICA: Debugger: Add a new command: "ALL <NameSeg>"
ACPICA: iASL: Return exceptions for string-to-integer conversions
ACPICA: acpi_help: Update UUID list
ACPICA: Add predefined names found in the SMBus sepcification
ACPICA: Tree-wide: fix various typos and spelling mistakes
ACPICA: Drop the repeated word "an" in a comment
ACPICA: Add support for 64 bit risc-v compilation
ACPI: button: fix handling lid state changes when input device closed
tools/power/acpi: Serialize Makefile
ACPI: scan: Replace ACPI_DEBUG_PRINT() with pr_debug()
ACPI: memhotplug: Remove 'state' from struct acpi_memory_device
ACPI / extlog: Check for RDMSR failure
ACPI: Make acpi_evaluate_dsm() prototype consistent
docs: mm: numaperf.rst Add brief description for access class 1.
node: Add access1 class to represent CPU to memory characteristics
ACPI: HMAT: Fix handling of changes from ACPI 6.2 to ACPI 6.3
ACPI: Let ACPI know we support Generic Initiator Affinity Structures
x86: Support Generic Initiator only proximity domains
...
Diffstat (limited to 'drivers/acpi')
56 files changed, 855 insertions, 298 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 7540a5179a47..edf1558c1105 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -504,55 +504,6 @@ config ACPI_EXTLOG config ACPI_ADXL bool -menuconfig PMIC_OPREGION - bool "PMIC (Power Management Integrated Circuit) operation region support" - help - Select this option to enable support for ACPI operation - region of the PMIC chip. The operation region can be used - to control power rails and sensor reading/writing on the - PMIC chip. - -if PMIC_OPREGION -config BYTCRC_PMIC_OPREGION - bool "ACPI operation region support for Bay Trail Crystal Cove PMIC" - depends on INTEL_SOC_PMIC - help - This config adds ACPI operation region support for the Bay Trail - version of the Crystal Cove PMIC. - -config CHTCRC_PMIC_OPREGION - bool "ACPI operation region support for Cherry Trail Crystal Cove PMIC" - depends on INTEL_SOC_PMIC - help - This config adds ACPI operation region support for the Cherry Trail - version of the Crystal Cove PMIC. - -config XPOWER_PMIC_OPREGION - bool "ACPI operation region support for XPower AXP288 PMIC" - depends on MFD_AXP20X_I2C && IOSF_MBI=y - help - This config adds ACPI operation region support for XPower AXP288 PMIC. - -config BXT_WC_PMIC_OPREGION - bool "ACPI operation region support for BXT WhiskeyCove PMIC" - depends on INTEL_SOC_PMIC_BXTWC - help - This config adds ACPI operation region support for BXT WhiskeyCove PMIC. - -config CHT_WC_PMIC_OPREGION - bool "ACPI operation region support for CHT Whiskey Cove PMIC" - depends on INTEL_SOC_PMIC_CHTWC - help - This config adds ACPI operation region support for CHT Whiskey Cove PMIC. - -config CHT_DC_TI_PMIC_OPREGION - bool "ACPI operation region support for Dollar Cove TI PMIC" - depends on INTEL_SOC_PMIC_CHTDC_TI - help - This config adds ACPI operation region support for Dollar Cove TI PMIC. - -endif - config ACPI_CONFIGFS tristate "ACPI configfs support" select CONFIGFS_FS @@ -568,21 +519,7 @@ config ACPI_PPTT bool endif -config TPS68470_PMIC_OPREGION - bool "ACPI operation region support for TPS68470 PMIC" - depends on MFD_TPS68470 - help - This config adds ACPI operation region support for TI TPS68470 PMIC. - TPS68470 device is an advanced power management unit that powers - a Compact Camera Module (CCM), generates clocks for image sensors, - drives a dual LED for flash and incorporates two LED drivers for - general purpose indicators. - This driver enables ACPI operation region support control voltage - regulators and clocks. - - This option is a bool as it provides an ACPI operation - region, which must be available before any of the devices - using this, are probed. +source "drivers/acpi/pmic/Kconfig" endif # ACPI diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 9a957544e357..44e412506317 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -107,17 +107,9 @@ obj-$(CONFIG_ACPI_APEI) += apei/ obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o -obj-$(CONFIG_PMIC_OPREGION) += pmic/intel_pmic.o -obj-$(CONFIG_BYTCRC_PMIC_OPREGION) += pmic/intel_pmic_bytcrc.o -obj-$(CONFIG_CHTCRC_PMIC_OPREGION) += pmic/intel_pmic_chtcrc.o -obj-$(CONFIG_XPOWER_PMIC_OPREGION) += pmic/intel_pmic_xpower.o -obj-$(CONFIG_BXT_WC_PMIC_OPREGION) += pmic/intel_pmic_bxtwc.o -obj-$(CONFIG_CHT_WC_PMIC_OPREGION) += pmic/intel_pmic_chtwc.o -obj-$(CONFIG_CHT_DC_TI_PMIC_OPREGION) += pmic/intel_pmic_chtdc_ti.o - obj-$(CONFIG_ACPI_CONFIGFS) += acpi_configfs.o -obj-$(CONFIG_TPS68470_PMIC_OPREGION) += pmic/tps68470_pmic.o +obj-y += pmic/ video-objs += acpi_video.o video_detect.o obj-y += dptf/ diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index 806b8ce05624..39359ce0eb2c 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -7,39 +7,28 @@ * Wu, Jeff <Jeff.Wu@amd.com> */ -#include <linux/clk-provider.h> -#include <linux/platform_data/clk-fch.h> -#include <linux/platform_device.h> -#include <linux/pm_domain.h> -#include <linux/clkdev.h> #include <linux/acpi.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> #include <linux/err.h> #include <linux/io.h> -#include <linux/pm.h> +#include <linux/platform_data/clk-fch.h> +#include <linux/platform_device.h> #include "internal.h" -ACPI_MODULE_NAME("acpi_apd"); struct apd_private_data; /** - * ACPI_APD_SYSFS : add device attributes in sysfs - * ACPI_APD_PM : attach power domain to device - */ -#define ACPI_APD_SYSFS BIT(0) -#define ACPI_APD_PM BIT(1) - -/** * struct apd_device_desc - a descriptor for apd device - * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM * @fixed_clk_rate: fixed rate input clock source for acpi device; * 0 means no fixed rate input clock source + * @properties: build-in properties of the device such as UART * @setup: a hook routine to set device resource during create platform device * * Device description defined as acpi_device_id.driver_data */ struct apd_device_desc { - unsigned int flags; unsigned int fixed_clk_rate; struct property_entry *properties; int (*setup)(struct apd_private_data *pdata); @@ -71,7 +60,6 @@ static int acpi_apd_setup(struct apd_private_data *pdata) } #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE - static int misc_check_res(struct acpi_resource *ares, void *data) { struct resource res; @@ -142,7 +130,7 @@ static const struct apd_device_desc cz_uart_desc = { static const struct apd_device_desc fch_misc_desc = { .setup = fch_misc_setup, }; -#endif +#endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */ #ifdef CONFIG_ARM64 static const struct apd_device_desc xgene_i2c_desc = { @@ -184,13 +172,9 @@ static const struct apd_device_desc hip08_spi_desc = { .setup = acpi_apd_setup, .fixed_clk_rate = 250000000, }; -#endif +#endif /* CONFIG_ARM64 */ -#else - -#define APD_ADDR(desc) (0UL) - -#endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */ +#endif /** * Create platform device during acpi scan attach handle. diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c index 33ac6cb428fe..67f1d33d15c4 100644 --- a/drivers/acpi/acpi_cmos_rtc.c +++ b/drivers/acpi/acpi_cmos_rtc.c @@ -15,8 +15,6 @@ #include "internal.h" -ACPI_MODULE_NAME("cmos rtc"); - static const struct acpi_device_id acpi_cmos_rtc_ids[] = { { "PNP0B00" }, { "PNP0B01" }, diff --git a/drivers/acpi/acpi_configfs.c b/drivers/acpi/acpi_configfs.c index 88c8af455ea3..cf91f49101ea 100644 --- a/drivers/acpi/acpi_configfs.c +++ b/drivers/acpi/acpi_configfs.c @@ -228,6 +228,7 @@ static void acpi_table_drop_item(struct config_group *group, ACPI_INFO(("Host-directed Dynamic ACPI Table Unload")); acpi_unload_table(table->index); + config_item_put(cfg); } static struct configfs_group_operations acpi_table_group_ops = { diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index f138e12b7b82..72f1fb77abcd 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c @@ -222,9 +222,9 @@ static int __init extlog_init(void) u64 cap; int rc; - rdmsrl(MSR_IA32_MCG_CAP, cap); - - if (!(cap & MCG_ELOG_P) || !extlog_get_l1addr()) + if (rdmsrl_safe(MSR_IA32_MCG_CAP, &cap) || + !(cap & MCG_ELOG_P) || + !extlog_get_l1addr()) return -ENODEV; rc = -EINVAL; diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 5e2bfbcf526f..46e307ea0f78 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -26,8 +26,6 @@ #include "internal.h" -ACPI_MODULE_NAME("acpi_lpss"); - #ifdef CONFIG_X86_INTEL_LPSS #include <asm/cpu_device_id.h> diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index e294f44a7850..ad6e90fbc813 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -22,13 +22,6 @@ #define ACPI_MEMORY_DEVICE_HID "PNP0C80" #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" -#define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT - -#undef PREFIX -#define PREFIX "ACPI:memory_hp:" - -ACPI_MODULE_NAME("acpi_memhotplug"); - static const struct acpi_device_id memory_device_ids[] = { {ACPI_MEMORY_DEVICE_HID, 0}, {"", 0}, @@ -36,11 +29,6 @@ static const struct acpi_device_id memory_device_ids[] = { #ifdef CONFIG_ACPI_HOTPLUG_MEMORY -/* Memory Device States */ -#define MEMORY_INVALID_STATE 0 -#define MEMORY_POWER_ON_STATE 1 -#define MEMORY_POWER_OFF_STATE 2 - static int acpi_memory_device_add(struct acpi_device *device, const struct acpi_device_id *not_used); static void acpi_memory_device_remove(struct acpi_device *device); @@ -64,8 +52,7 @@ struct acpi_memory_info { }; struct acpi_memory_device { - struct acpi_device * device; - unsigned int state; /* State of the memory device */ + struct acpi_device *device; struct list_head res_list; }; @@ -233,7 +220,6 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) } if (!num_enabled) { dev_err(&mem_device->device->dev, "add_memory failed\n"); - mem_device->state = MEMORY_INVALID_STATE; return -EINVAL; } /* @@ -304,9 +290,6 @@ static int acpi_memory_device_add(struct acpi_device *device, return result; } - /* Set the device state */ - mem_device->state = MEMORY_POWER_ON_STATE; - result = acpi_memory_check_device(mem_device); if (result) { acpi_memory_device_free(mem_device); diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index c05050f474cd..78d621290a35 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -19,8 +19,6 @@ #include "internal.h" -ACPI_MODULE_NAME("platform"); - static const struct acpi_device_id forbidden_id_list[] = { {"PNP0000", 0}, /* PIC */ {"PNP0100", 0}, /* Timer */ diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index a676daaa2da5..f8a3abdfe250 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -37,12 +37,14 @@ struct acpi_db_argument_info { struct acpi_db_execute_walk { u32 count; u32 max_count; + char name_seg[ACPI_NAMESEG_SIZE + 1]; }; #define PARAM_LIST(pl) pl #define EX_NO_SINGLE_STEP 1 #define EX_SINGLE_STEP 2 +#define EX_ALL 4 /* * dbxface - external debugger interfaces @@ -124,6 +126,8 @@ void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op); void acpi_db_evaluate_predefined_names(void); +void acpi_db_evaluate_all(char *name_seg); + /* * dbnames - namespace commands */ diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 1030a0ce1599..2fee91f57b21 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -42,6 +42,12 @@ ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1a_enable); ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1b_status); ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1b_enable); +#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES +ACPI_GLOBAL(unsigned long, acpi_gbl_xgpe0_block_logical_address); +ACPI_GLOBAL(unsigned long, acpi_gbl_xgpe1_block_logical_address); + +#endif /* ACPI_GPE_USE_LOGICAL_ADDRESSES */ + /* * Handle both ACPI 1.0 and ACPI 2.0+ Integer widths. The integer width is * determined by the revision of the DSDT: If the DSDT revision is less than diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index ebf6453d0e21..6ab92e28330d 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -73,9 +73,15 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width); acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width); +acpi_status acpi_hw_validate_io_block(u64 address, u32 bit_width, u32 count); + /* * hwgpe - GPE support */ +acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg); + +acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg); + u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info); acpi_status diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index af58cd2dc9d3..f83b98fa13ac 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -454,11 +454,18 @@ struct acpi_gpe_event_info { u8 disable_for_dispatch; /* Masked during dispatching */ }; +/* GPE register address */ + +struct acpi_gpe_address { + u8 space_id; /* Address space where the register exists */ + u64 address; /* 64-bit address of the register */ +}; + /* Information about a GPE register pair, one per each status/enable pair in an array */ struct acpi_gpe_register_info { - struct acpi_generic_address status_address; /* Address of status reg */ - struct acpi_generic_address enable_address; /* Address of enable reg */ + struct acpi_gpe_address status_address; /* Address of status reg */ + struct acpi_gpe_address enable_address; /* Address of enable reg */ u16 base_gpe_number; /* Base GPE number for this register */ u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ u8 enable_for_run; /* GPEs to keep enabled when running */ diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 2cbb56652f1c..57ea2276790f 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -101,7 +101,7 @@ enum acpi_return_package_types { /* Support macros for users of the predefined info table */ -#define METHOD_PREDEF_ARGS_MAX 4 +#define METHOD_PREDEF_ARGS_MAX 5 #define METHOD_ARG_BIT_WIDTH 3 #define METHOD_ARG_MASK 0x0007 #define ARG_COUNT_IS_MINIMUM 0x8000 @@ -117,6 +117,7 @@ enum acpi_return_package_types { #define METHOD_2ARGS(a1,a2) (2 | (a1 << 3) | (a2 << 6)) #define METHOD_3ARGS(a1,a2,a3) (3 | (a1 << 3) | (a2 << 6) | (a3 << 9)) #define METHOD_4ARGS(a1,a2,a3,a4) (4 | (a1 << 3) | (a2 << 6) | (a3 << 9) | (a4 << 12)) +#define METHOD_5ARGS(a1,a2,a3,a4,a5) (5 | (a1 << 3) | (a2 << 6) | (a3 << 9) | (a4 << 12) | (a5 << 15)) #define METHOD_RETURNS(type) (type) #define METHOD_NO_RETURN_VALUE 0 @@ -902,9 +903,39 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { {{"_S4W", METHOD_0ARGS, METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, + {{"_SBA", METHOD_0ARGS, + METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (4 Int) */ + PACKAGE_INFO(ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0), + + {{"_SBI", METHOD_0ARGS, + METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (1 Int, 1 Buf) */ + PACKAGE_INFO(ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 1, + ACPI_RTYPE_BUFFER, 1, 0), + + {{"_SBR", + METHOD_3ARGS(ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, + ACPI_TYPE_INTEGER), + METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (2 Int) */ + PACKAGE_INFO(ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, + ACPI_RTYPE_BUFFER | ACPI_RTYPE_INTEGER, 1, 0), + {{"_SBS", METHOD_0ARGS, METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, + {{"_SBT", + METHOD_4ARGS(ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, + ACPI_TYPE_ANY), + METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Fixed-length (2 Int, 1 Buf | Int) */ + PACKAGE_INFO(ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, + ACPI_RTYPE_BUFFER | ACPI_RTYPE_INTEGER, 1, 0), + + {{"_SBW", + METHOD_5ARGS(ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, + ACPI_TYPE_INTEGER, ACPI_TYPE_ANY), + METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, + PACKAGE_INFO(ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER | ACPI_RTYPE_INTEGER, + 1, 0, 0, 0), + {{"_SCP", METHOD_1ARGS(ACPI_TYPE_INTEGER) | ARG_COUNT_IS_MINIMUM, METHOD_NO_RETURN_VALUE}}, /* Acpi 1.0 allowed 1 integer arg. Acpi 3.0 expanded to 3 args. Allow both. */ diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c index 4027eaab18a4..d3a9521e2dc8 100644 --- a/drivers/acpi/acpica/dbexec.c +++ b/drivers/acpi/acpica/dbexec.c @@ -86,7 +86,8 @@ void acpi_db_delete_objects(u32 count, union acpi_object *objects) * * RETURN: Status * - * DESCRIPTION: Execute a control method. + * DESCRIPTION: Execute a control method. Used to evaluate objects via the + * "EXECUTE" or "EVALUATE" commands. * ******************************************************************************/ @@ -314,11 +315,12 @@ acpi_db_execution_walk(acpi_handle obj_handle, status = acpi_evaluate_object(node, NULL, NULL, &return_obj); + acpi_gbl_method_executing = FALSE; + acpi_os_printf("Evaluation of [%4.4s] returned %s\n", acpi_ut_get_node_name(node), acpi_format_exception(status)); - acpi_gbl_method_executing = FALSE; return (AE_OK); } @@ -334,7 +336,8 @@ acpi_db_execution_walk(acpi_handle obj_handle, * RETURN: None * * DESCRIPTION: Execute a control method. Name is relative to the current - * scope. + * scope. Function used for the "EXECUTE", "EVALUATE", and + * "ALL" commands * ******************************************************************************/ @@ -372,6 +375,12 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags) return; } + if ((flags & EX_ALL) && (strlen(name) > 4)) { + acpi_os_printf("Input name (%s) must be a 4-char NameSeg\n", + name); + return; + } + name_string = ACPI_ALLOCATE(strlen(name) + 1); if (!name_string) { return; @@ -389,13 +398,24 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags) return; } - acpi_gbl_db_method_info.name = name_string; - acpi_gbl_db_method_info.args = args; - acpi_gbl_db_method_info.types = types; - acpi_gbl_db_method_info.flags = flags; + /* Command (ALL <nameseg>) to execute all methods of a particular name */ - return_obj.pointer = NULL; - return_obj.length = ACPI_ALLOCATE_BUFFER; + else if (flags & EX_ALL) { + acpi_gbl_db_method_info.name = name_string; + return_obj.pointer = NULL; + return_obj.length = ACPI_ALLOCATE_BUFFER; + acpi_db_evaluate_all(name_string); + ACPI_FREE(name_string); + return; + } else { + acpi_gbl_db_method_info.name = name_string; + acpi_gbl_db_method_info.args = args; + acpi_gbl_db_method_info.types = types; + acpi_gbl_db_method_info.flags = flags; + + return_obj.pointer = NULL; + return_obj.length = ACPI_ALLOCATE_BUFFER; + } status = acpi_db_execute_setup(&acpi_gbl_db_method_info); if (ACPI_FAILURE(status)) { @@ -450,6 +470,7 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags) (u32)return_obj.length); acpi_db_dump_external_object(return_obj.pointer, 1); + acpi_os_printf("\n"); /* Dump a _PLD buffer if present */ diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c index ee6a1b77af3f..2952856b8a67 100644 --- a/drivers/acpi/acpica/dbinput.c +++ b/drivers/acpi/acpica/dbinput.c @@ -37,6 +37,7 @@ acpi_db_match_command_help(const char *command, enum acpi_ex_debugger_commands { CMD_NOT_FOUND = 0, CMD_NULL, + CMD_ALL, CMD_ALLOCATIONS, CMD_ARGS, CMD_ARGUMENTS, @@ -115,6 +116,7 @@ enum acpi_ex_debugger_commands { static const struct acpi_db_command_info acpi_gbl_db_commands[] = { {"<NOT FOUND>", 0}, {"<NULL>", 0}, + {"ALL", 1}, {"ALLOCATIONS", 0}, {"ARGS", 0}, {"ARGUMENTS", 0}, @@ -222,6 +224,7 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = { {1, " Type <Object>", "Display object type\n"}, {0, "\nControl Method Execution:", "\n"}, + {1, " All <NameSeg>", "Evaluate all objects named NameSeg\n"}, {1, " Evaluate <Namepath> [Arguments]", "Evaluate object or control method\n"}, {1, " Execute <Namepath> [Arguments]", "Synonym for Evaluate\n"}, @@ -436,7 +439,7 @@ static void acpi_db_display_help(char *command) acpi_os_printf("\n"); } else { - /* Display help for all commands that match the subtring */ + /* Display help for all commands that match the substring */ acpi_db_display_command_info(command, TRUE); } @@ -740,6 +743,15 @@ acpi_db_command_dispatch(char *input_buffer, } break; + case CMD_ALL: + + acpi_os_printf("Executing all objects with NameSeg: %s\n", + acpi_gbl_db_args[1]); + acpi_db_execute(acpi_gbl_db_args[1], &acpi_gbl_db_args[2], + &acpi_gbl_db_arg_types[2], + EX_NO_SINGLE_STEP | EX_ALL); + break; + case CMD_ALLOCATIONS: #ifdef ACPI_DBG_TRACK_ALLOCATIONS diff --git a/drivers/acpi/acpica/dbmethod.c b/drivers/acpi/acpica/dbmethod.c index 4e48a7de7413..889d13828e49 100644 --- a/drivers/acpi/acpica/dbmethod.c +++ b/drivers/acpi/acpica/dbmethod.c @@ -21,6 +21,8 @@ static acpi_status acpi_db_walk_for_execute(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value); +static acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node); + /******************************************************************************* * * FUNCTION: acpi_db_set_method_breakpoint @@ -346,42 +348,26 @@ acpi_status acpi_db_disassemble_method(char *name) /******************************************************************************* * - * FUNCTION: acpi_db_walk_for_execute + * FUNCTION: acpi_db_evaluate_object * - * PARAMETERS: Callback from walk_namespace + * PARAMETERS: node - Namespace node for the object * * RETURN: Status * - * DESCRIPTION: Batch execution module. Currently only executes predefined - * ACPI names. + * DESCRIPTION: Main execution function for the Evaluate/Execute/All debugger + * commands. * ******************************************************************************/ -static acpi_status -acpi_db_walk_for_execute(acpi_handle obj_handle, - u32 nesting_level, void *context, void **return_value) +static acpi_status acpi_db_evaluate_object(struct acpi_namespace_node *node) { - struct acpi_namespace_node *node = - (struct acpi_namespace_node *)obj_handle; - struct acpi_db_execute_walk *info = - (struct acpi_db_execute_walk *)context; - struct acpi_buffer return_obj; - acpi_status status; char *pathname; u32 i; struct acpi_device_info *obj_info; struct acpi_object_list param_objects; union acpi_object params[ACPI_METHOD_NUM_ARGS]; - const union acpi_predefined_info *predefined; - - predefined = acpi_ut_match_predefined_method(node->name.ascii); - if (!predefined) { - return (AE_OK); - } - - if (node->type == ACPI_TYPE_LOCAL_SCOPE) { - return (AE_OK); - } + struct acpi_buffer return_obj; + acpi_status status; pathname = acpi_ns_get_external_pathname(node); if (!pathname) { @@ -390,7 +376,7 @@ acpi_db_walk_for_execute(acpi_handle obj_handle, /* Get the object info for number of method parameters */ - status = acpi_get_object_info(obj_handle, &obj_info); + status = acpi_get_object_info(node, &obj_info); if (ACPI_FAILURE(status)) { ACPI_FREE(pathname); return (status); @@ -421,14 +407,67 @@ acpi_db_walk_for_execute(acpi_handle obj_handle, acpi_gbl_method_executing = TRUE; status = acpi_evaluate_object(node, NULL, ¶m_objects, &return_obj); + acpi_gbl_method_executing = FALSE; acpi_os_printf("%-32s returned %s\n", pathname, acpi_format_exception(status)); - acpi_gbl_method_executing = FALSE; + if (return_obj.length) { + acpi_os_printf("Evaluation of %s returned object %p, " + "external buffer length %X\n", + pathname, return_obj.pointer, + (u32)return_obj.length); + + acpi_db_dump_external_object(return_obj.pointer, 1); + acpi_os_printf("\n"); + } + ACPI_FREE(pathname); /* Ignore status from method execution */ + return (AE_OK); + + /* Update count, check if we have executed enough methods */ + +} + +/******************************************************************************* + * + * FUNCTION: acpi_db_walk_for_execute + * + * PARAMETERS: Callback from walk_namespace + * + * RETURN: Status + * + * DESCRIPTION: Batch execution function. Evaluates all "predefined" objects -- + * the nameseg begins with an underscore. + * + ******************************************************************************/ + +static acpi_status +acpi_db_walk_for_execute(acpi_handle obj_handle, + u32 nesting_level, void *context, void **return_value) +{ + struct acpi_namespace_node *node = + (struct acpi_namespace_node *)obj_handle; + struct acpi_db_execute_walk *info = + (struct acpi_db_execute_walk *)context; + acpi_status status; + const union acpi_predefined_info *predefined; + + predefined = acpi_ut_match_predefined_method(node->name.ascii); + if (!predefined) { + return (AE_OK); + } + + if (node->type == ACPI_TYPE_LOCAL_SCOPE) { + return (AE_OK); + } + + acpi_db_evaluate_object(node); + + /* Ignore status from object evaluation */ + status = AE_OK; /* Update count, check if we have executed enough methods */ @@ -443,6 +482,52 @@ acpi_db_walk_for_execute(acpi_handle obj_handle, /******************************************************************************* * + * FUNCTION: acpi_db_walk_for_execute_all + * + * PARAMETERS: Callback from walk_namespace + * + * RETURN: Status + * + * DESCRIPTION: Batch execution function. Evaluates all objects whose path ends + * with the nameseg "Info->NameSeg". Used for the "ALL" command. + * + ******************************************************************************/ + +static acpi_status +acpi_db_walk_for_execute_all(acpi_handle obj_handle, + u32 nesting_level, + void *context, void **return_value) +{ + struct acpi_namespace_node *node = + (struct acpi_namespace_node *)obj_handle; + struct acpi_db_execute_walk *info = + (struct acpi_db_execute_walk *)context; + acpi_status status; + + if (!ACPI_COMPARE_NAMESEG(node->name.ascii, info->name_seg)) { + return (AE_OK); + } + + if (node->type == ACPI_TYPE_LOCAL_SCOPE) { + return (AE_OK); + } + + /* Now evaluate the input object (node) */ + + acpi_db_evaluate_object(node); + + /* Ignore status from method execution */ + + status = AE_OK; + + /* Update count of executed methods/objects */ + + info->count++; + return (status); +} + +/******************************************************************************* + * * FUNCTION: acpi_db_evaluate_predefined_names * * PARAMETERS: None @@ -470,3 +555,35 @@ void acpi_db_evaluate_predefined_names(void) acpi_os_printf("Evaluated %u predefined names in the namespace\n", info.count); } + +/******************************************************************************* + * + * FUNCTION: acpi_db_evaluate_all + * + * PARAMETERS: none_acpi_gbl_db_method_info + * + * RETURN: None + * + * DESCRIPTION: Namespace batch execution. Implements the "ALL" command. + * Execute all namepaths whose final nameseg matches the + * input nameseg. + * + ******************************************************************************/ + +void acpi_db_evaluate_all(char *name_seg) +{ + struct acpi_db_execute_walk info; + + info.count = 0; + info.max_count = ACPI_UINT32_MAX; + ACPI_COPY_NAMESEG(info.name_seg, name_seg); + info.name_seg[ACPI_NAMESEG_SIZE] = 0; + + /* Search all nodes in namespace */ + + (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, acpi_db_walk_for_execute_all, + NULL, (void *)&info, NULL); + + acpi_os_printf("Evaluated %u names in the namespace\n", info.count); +} diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 3e39907fedd9..06b9c8dd11c9 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -656,14 +656,14 @@ acpi_ev_detect_gpe(struct acpi_namespace_node *gpe_device, /* GPE currently enabled (enable bit == 1)? */ - status = acpi_hw_read(&enable_reg, &gpe_register_info->enable_address); + status = acpi_hw_gpe_read(&enable_reg, &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { goto error_exit; } /* GPE currently active (status bit == 1)? */ - status = acpi_hw_read(&status_reg, &gpe_register_info->status_address); + status = acpi_hw_gpe_read(&status_reg, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { goto error_exit; } diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 132adff1e131..f5298be4273a 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -233,12 +233,6 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) this_register->status_address.space_id = gpe_block->space_id; this_register->enable_address.space_id = gpe_block->space_id; - this_register->status_address.bit_width = - ACPI_GPE_REGISTER_WIDTH; - this_register->enable_address.bit_width = - ACPI_GPE_REGISTER_WIDTH; - this_register->status_address.bit_offset = 0; - this_register->enable_address.bit_offset = 0; /* Init the event_info for each GPE within this register */ @@ -251,14 +245,14 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) /* Disable all GPEs within this register */ - status = acpi_hw_write(0x00, &this_register->enable_address); + status = acpi_hw_gpe_write(0x00, &this_register->enable_address); if (ACPI_FAILURE(status)) { goto error_exit; } /* Clear any pending GPE events within this register */ - status = acpi_hw_write(0xFF, &this_register->status_address); + status = acpi_hw_gpe_write(0xFF, &this_register->status_address); if (ACPI_FAILURE(status)) { goto error_exit; } @@ -317,6 +311,23 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, return_ACPI_STATUS(AE_OK); } + /* Validate the space_ID */ + + if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && + (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { + ACPI_ERROR((AE_INFO, + "Unsupported address space: 0x%X", space_id)); + return_ACPI_STATUS(AE_SUPPORT); + } + + if (space_id == ACPI_ADR_SPACE_SYSTEM_IO) { + status = acpi_hw_validate_io_block(address, + ACPI_GPE_REGISTER_WIDTH, + register_count); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + } + /* Allocate a new GPE block */ gpe_block = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_block_info)); diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 6effd8076dcc..6d82d30d8f7b 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -32,6 +32,16 @@ ACPI_MODULE_NAME("evgpeinit") * kernel boot time as well. */ +#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES +#define ACPI_FADT_GPE_BLOCK_ADDRESS(N) \ + acpi_gbl_FADT.xgpe##N##_block.space_id == \ + ACPI_ADR_SPACE_SYSTEM_MEMORY ? \ + (u64)acpi_gbl_xgpe##N##_block_logical_address : \ + acpi_gbl_FADT.xgpe##N##_block.address +#else +#define ACPI_FADT_GPE_BLOCK_ADDRESS(N) acpi_gbl_FADT.xgpe##N##_block.address +#endif /* ACPI_GPE_USE_LOGICAL_ADDRESSES */ + /******************************************************************************* * * FUNCTION: acpi_ev_gpe_initialize @@ -49,6 +59,7 @@ acpi_status acpi_ev_gpe_initialize(void) u32 register_count1 = 0; u32 gpe_number_max = 0; acpi_status status; + u64 address; ACPI_FUNCTION_TRACE(ev_gpe_initialize); @@ -85,8 +96,9 @@ acpi_status acpi_ev_gpe_initialize(void) * If EITHER the register length OR the block address are zero, then that * particular block is not supported. */ - if (acpi_gbl_FADT.gpe0_block_length && - acpi_gbl_FADT.xgpe0_block.address) { + address = ACPI_FADT_GPE_BLOCK_ADDRESS(0); + + if (acpi_gbl_FADT.gpe0_block_length && address) { /* GPE block 0 exists (has both length and address > 0) */ @@ -97,7 +109,6 @@ acpi_status acpi_ev_gpe_initialize(void) /* Install GPE Block 0 */ status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, - acpi_gbl_FADT.xgpe0_block. address, acpi_gbl_FADT.xgpe0_block. space_id, register_count0, 0, @@ -110,8 +121,9 @@ acpi_status acpi_ev_gpe_initialize(void) } } - if (acpi_gbl_FADT.gpe1_block_length && - acpi_gbl_FADT.xgpe1_block.address) { + address = ACPI_FADT_GPE_BLOCK_ADDRESS(1); + + if (acpi_gbl_FADT.gpe1_block_length && address) { /* GPE block 1 exists (has both length and address > 0) */ @@ -137,7 +149,6 @@ acpi_status acpi_ev_gpe_initialize(void) status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, - acpi_gbl_FADT.xgpe1_block. address, acpi_gbl_FADT.xgpe1_block. space_id, register_count1, diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 49c46d4dd070..37bb67ef3232 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -26,6 +26,76 @@ acpi_hw_gpe_enable_write(u8 enable_mask, /****************************************************************************** * + * FUNCTION: acpi_hw_gpe_read + * + * PARAMETERS: value - Where the value is returned + * reg - GPE register structure + * + * RETURN: Status + * + * DESCRIPTION: Read from a GPE register in either memory or IO space. + * + * LIMITATIONS: <These limitations also apply to acpi_hw_gpe_write> + * space_ID must be system_memory or system_IO. + * + ******************************************************************************/ + +acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg) +{ + acpi_status status; + u32 value32; + + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { +#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES + *value = (u64)ACPI_GET8(reg->address); + return_ACPI_STATUS(AE_OK); +#else + return acpi_os_read_memory((acpi_physical_address)reg->address, + value, ACPI_GPE_REGISTER_WIDTH); +#endif + } + + status = acpi_os_read_port((acpi_io_address)reg->address, + &value32, ACPI_GPE_REGISTER_WIDTH); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + + *value = (u64)value32; + + return_ACPI_STATUS(AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_hw_gpe_write + * + * PARAMETERS: value - Value to be written + * reg - GPE register structure + * + * RETURN: Status + * + * DESCRIPTION: Write to a GPE register in either memory or IO space. + * + ******************************************************************************/ + +acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg) +{ + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { +#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES + ACPI_SET8(reg->address, value); + return_ACPI_STATUS(AE_OK); +#else + return acpi_os_write_memory((acpi_physical_address)reg->address, + value, ACPI_GPE_REGISTER_WIDTH); +#endif + } + + return acpi_os_write_port((acpi_io_address)reg->address, (u32)value, + ACPI_GPE_REGISTER_WIDTH); +} + +/****************************************************************************** + * * FUNCTION: acpi_hw_get_gpe_register_bit * * PARAMETERS: gpe_event_info - Info block for the GPE @@ -79,7 +149,8 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) /* Get current value of the enable register that contains this GPE */ - status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address); + status = acpi_hw_gpe_read(&enable_mask, + &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -118,9 +189,8 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) /* Write the updated enable mask */ - status = - acpi_hw_write(enable_mask, - &gpe_register_info->enable_address); + status = acpi_hw_gpe_write(enable_mask, + &gpe_register_info->enable_address); } return (status); } @@ -158,8 +228,8 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info) */ register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); - status = - acpi_hw_write(register_bit, &gpe_register_info->status_address); + status = acpi_hw_gpe_write(register_bit, + &gpe_register_info->status_address); return (status); } @@ -227,7 +297,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, /* GPE currently enabled (enable bit == 1)? */ - status = acpi_hw_read(&in_byte, &gpe_register_info->enable_address); + status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -238,7 +308,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, /* GPE currently active (status bit == 1)? */ - status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); + status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { return (status); } @@ -274,7 +344,8 @@ acpi_hw_gpe_enable_write(u8 enable_mask, gpe_register_info->enable_mask = enable_mask; - status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); + status = acpi_hw_gpe_write(enable_mask, + &gpe_register_info->enable_address); return (status); } @@ -341,9 +412,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /* Clear status on all GPEs in this register */ - status = - acpi_hw_write(0xFF, - &gpe_block->register_info[i].status_address); + status = acpi_hw_gpe_write(0xFF, + &gpe_block->register_info[i].status_address); if (ACPI_FAILURE(status)) { return (status); } @@ -481,14 +551,14 @@ acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info, for (i = 0; i < gpe_block->register_count; i++) { gpe_register_info = &gpe_block->register_info[i]; - status = acpi_hw_read(&in_enable, - &gpe_register_info->enable_address); + status = acpi_hw_gpe_read(&in_enable, + &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { continue; } - status = acpi_hw_read(&in_status, - &gpe_register_info->status_address); + status = acpi_hw_gpe_read(&in_status, + &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { continue; } diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index 4d94861e6093..b2ca7dfd3fc9 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -292,3 +292,33 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) return (AE_OK); } + +/****************************************************************************** + * + * FUNCTION: acpi_hw_validate_io_block + * + * PARAMETERS: Address Address of I/O port/register blobk + * bit_width Number of bits (8,16,32) in each register + * count Number of registers in the block + * + * RETURN: Status + * + * DESCRIPTION: Validates a block of I/O ports/registers. + * + ******************************************************************************/ + +acpi_status acpi_hw_validate_io_block(u64 address, u32 bit_width, u32 count) +{ + acpi_status status; + + while (count--) { + status = acpi_hw_validate_io_request((acpi_io_address)address, + bit_width); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + + address += ACPI_DIV_8(bit_width); + } + + return_ACPI_STATUS(AE_OK); +} diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index fe9b3639a87d..83d26abcf448 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -294,7 +294,7 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) node_to_delete = next_node; next_node = next_node->peer; acpi_ns_delete_node(node_to_delete); - }; + } /* Clear the parent's child pointer */ diff --git a/drivers/acpi/acpica/nsarguments.c b/drivers/acpi/acpica/nsarguments.c index d5e8405e9d8f..6bbc7d350a16 100644 --- a/drivers/acpi/acpica/nsarguments.c +++ b/drivers/acpi/acpica/nsarguments.c @@ -55,7 +55,9 @@ void acpi_ns_check_argument_types(struct acpi_evaluate_info *info) arg_type = METHOD_GET_NEXT_TYPE(arg_type_list); user_arg_type = info->parameters[i]->common.type; - if (user_arg_type != arg_type) { + /* No typechecking for ACPI_TYPE_ANY */ + + if ((user_arg_type != arg_type) && (arg_type != ACPI_TYPE_ANY)) { ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, ACPI_WARN_ALWAYS, "Argument #%u type mismatch - " diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index c022bef263e5..324269481160 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -24,7 +24,8 @@ ACPI_MODULE_NAME("nsxfobj") * * RETURN: Status * - * DESCRIPTION: This routine returns the type associatd with a particular handle + * DESCRIPTION: This routine returns the type associated with a particular + * handle * ******************************************************************************/ acpi_status acpi_get_type(acpi_handle handle, acpi_object_type *ret_type) diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index c780046bf294..bd3caf735be3 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -508,8 +508,8 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) } /* - * If the transfer to the new method method call worked - *, a new walk state was created -- get it + * If the transfer to the new method method call worked, + * a new walk state was created -- get it */ walk_state = acpi_ds_get_current_walk_state(thread); continue; diff --git a/drivers/acpi/acpica/utpredef.c b/drivers/acpi/acpica/utpredef.c index 05fe3470fb93..dd277f7e9f10 100644 --- a/drivers/acpi/acpica/utpredef.c +++ b/drivers/acpi/acpica/utpredef.c @@ -151,7 +151,7 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types); static const char *ut_external_type_names[] = /* Indexed by ACPI_TYPE_* */ { - ", UNSUPPORTED-TYPE", + ", Type_ANY", ", Integer", ", String", ", Buffer", @@ -311,8 +311,7 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types) for (i = 0; i < arg_count; i++) { this_argument_type = METHOD_GET_NEXT_TYPE(argument_types); - if (!this_argument_type - || (this_argument_type > METHOD_MAX_ARG_TYPE)) { + if (this_argument_type > METHOD_MAX_ARG_TYPE) { printf("**** Invalid argument type (%u) " "in predefined info structure\n", this_argument_type); diff --git a/drivers/acpi/acpica/utstrsuppt.c b/drivers/acpi/acpica/utstrsuppt.c index 05ff20049b87..2d91003fcf26 100644 --- a/drivers/acpi/acpica/utstrsuppt.c +++ b/drivers/acpi/acpica/utstrsuppt.c @@ -45,10 +45,15 @@ acpi_status acpi_ut_convert_octal_string(char *string, u64 *return_value_ptr) /* Convert each ASCII byte in the input string */ while (*string) { - - /* Character must be ASCII 0-7, otherwise terminate with no error */ - + /* + * Character must be ASCII 0-7, otherwise: + * 1) Runtime: terminate with no error, per the ACPI spec + * 2) Compiler: return an error + */ if (!(ACPI_IS_OCTAL_DIGIT(*string))) { +#ifdef ACPI_ASL_COMPILER + status = AE_BAD_OCTAL_CONSTANT; +#endif break; } @@ -94,10 +99,15 @@ acpi_status acpi_ut_convert_decimal_string(char *string, u64 *return_value_ptr) /* Convert each ASCII byte in the input string */ while (*string) { - - /* Character must be ASCII 0-9, otherwise terminate with no error */ - + /* + * Character must be ASCII 0-9, otherwise: + * 1) Runtime: terminate with no error, per the ACPI spec + * 2) Compiler: return an error + */ if (!isdigit(*string)) { +#ifdef ACPI_ASL_COMPILER + status = AE_BAD_DECIMAL_CONSTANT; +#endif break; } @@ -143,10 +153,15 @@ acpi_status acpi_ut_convert_hex_string(char *string, u64 *return_value_ptr) /* Convert each ASCII byte in the input string */ while (*string) { - - /* Must be ASCII A-F, a-f, or 0-9, otherwise terminate with no error */ - + /* + * Character must be ASCII A-F, a-f, or 0-9, otherwise: + * 1) Runtime: terminate with no error, per the ACPI spec + * 2) Compiler: return an error + */ if (!isxdigit(*string)) { +#ifdef ACPI_ASL_COMPILER + status = AE_BAD_HEX_CONSTANT; +#endif break; } diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index e358d0046494..552fd9ffaca4 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -632,7 +632,11 @@ int apei_map_generic_address(struct acpi_generic_address *reg) rc = apei_check_gar(reg, &address, &access_bit_width); if (rc) return rc; - return acpi_os_map_generic_address(reg); + + if (!acpi_os_map_generic_address(reg)) + return -ENXIO; + + return 0; } EXPORT_SYMBOL_GPL(apei_map_generic_address); diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index e670785a6201..6f89c16f45f3 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -1329,7 +1329,7 @@ static int __init arm_smmu_v3_set_proximity(struct device *dev, smmu = (struct acpi_iort_smmu_v3 *)node->node_data; if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) { - int dev_node = acpi_map_pxm_to_node(smmu->pxm); + int dev_node = pxm_to_node(smmu->pxm); if (dev_node != NUMA_NO_NODE && !node_online(dev_node)) return -EINVAL; diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 54002670cb7a..113c661eb848 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -303,7 +303,11 @@ static void acpi_bus_osc_support(void) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT; capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT; +#ifdef CONFIG_ARM64 + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT; +#endif #ifdef CONFIG_X86 + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT; if (boot_cpu_has(X86_FEATURE_HWP)) { capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT; capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT; diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index a4eda7fe50d3..da4b125ab4c3 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -153,6 +153,7 @@ struct acpi_button { int last_state; ktime_t last_time; bool suspended; + bool lid_state_initialized; }; static struct acpi_device *lid_device; @@ -383,6 +384,8 @@ static int acpi_lid_update_state(struct acpi_device *device, static void acpi_lid_initialize_state(struct acpi_device *device) { + struct acpi_button *button = acpi_driver_data(device); + switch (lid_init_state) { case ACPI_BUTTON_LID_INIT_OPEN: (void)acpi_lid_notify_state(device, 1); @@ -394,13 +397,14 @@ static void acpi_lid_initialize_state(struct acpi_device *device) default: break; } + + button->lid_state_initialized = true; } static void acpi_button_notify(struct acpi_device *device, u32 event) { struct acpi_button *button = acpi_driver_data(device); struct input_dev *input; - int users; switch (event) { case ACPI_FIXED_HARDWARE_EVENT: @@ -409,10 +413,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) case ACPI_BUTTON_NOTIFY_STATUS: input = button->input; if (button->type == ACPI_BUTTON_TYPE_LID) { - mutex_lock(&button->input->mutex); - users = button->input->users; - mutex_unlock(&button->input->mutex); - if (users) + if (button->lid_state_initialized) acpi_lid_update_state(device, true); } else { int keycode; @@ -457,7 +458,7 @@ static int acpi_button_resume(struct device *dev) struct acpi_button *button = acpi_driver_data(device); button->suspended = false; - if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) { + if (button->type == ACPI_BUTTON_TYPE_LID) { button->last_state = !!acpi_lid_evaluate_state(device); button->last_time = ktime_get(); acpi_lid_initialize_state(device); diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 9ea5f55d97e3..ccaa647ac3d4 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -14,9 +14,6 @@ #include "internal.h" -#define _COMPONENT ACPI_CONTAINER_COMPONENT -ACPI_MODULE_NAME("container"); - static const struct acpi_device_id container_device_ids[] = { {"ACPI0004", 0}, {"PNP0A05", 0}, diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c index b097ef209313..7b54dc95d36b 100644 --- a/drivers/acpi/custom_method.c +++ b/drivers/acpi/custom_method.c @@ -13,8 +13,6 @@ #include "internal.h" -#define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("custom_method"); MODULE_LICENSE("GPL"); static struct dentry *cm_dentry; diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index d5ecea3715f8..074eb98d213e 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -10,9 +10,6 @@ #include "internal.h" -#define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("debugfs"); - struct dentry *acpi_debugfs_dir; EXPORT_SYMBOL_GPL(acpi_debugfs_dir); diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 9bd72c26ef46..45d4b7b69de8 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -20,8 +20,6 @@ #include "internal.h" -ACPI_MODULE_NAME("dock"); - static bool immediate_undock = 1; module_param(immediate_undock, bool, 0644); MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " diff --git a/drivers/acpi/dptf/Kconfig b/drivers/acpi/dptf/Kconfig index 90a2fd979282..51f06f36cafa 100644 --- a/drivers/acpi/dptf/Kconfig +++ b/drivers/acpi/dptf/Kconfig @@ -14,3 +14,17 @@ config DPTF_POWER To compile this driver as a module, choose M here: the module will be called dptf_power. + +config DPTF_PCH_FIVR + tristate "DPTF PCH FIVR Participant" + depends on X86 + help + This driver adds support for Dynamic Platform and Thermal Framework + (DPTF) PCH FIVR Participant device support. This driver allows to + switch PCH FIVR (Fully Integrated Voltage Regulator) frequency. + This participant is responsible for exposing: + freq_mhz_low_clock + freq_mhz_high_clock + + To compile this driver as a module, choose M here: + the module will be called dptf_pch_fivr. diff --git a/drivers/acpi/dptf/Makefile b/drivers/acpi/dptf/Makefile index 1a9b0a2b25bf..297340682f66 100644 --- a/drivers/acpi/dptf/Makefile +++ b/drivers/acpi/dptf/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_ACPI) += int340x_thermal.o obj-$(CONFIG_DPTF_POWER) += dptf_power.o +obj-$(CONFIG_DPTF_PCH_FIVR) += dptf_pch_fivr.o diff --git a/drivers/acpi/dptf/dptf_pch_fivr.c b/drivers/acpi/dptf/dptf_pch_fivr.c new file mode 100644 index 000000000000..4ab288827747 --- /dev/null +++ b/drivers/acpi/dptf/dptf_pch_fivr.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * dptf_pch_fivr: DPTF PCH FIVR Participant driver + * Copyright (c) 2020, Intel Corporation. + */ + +#include <linux/acpi.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +/* + * Presentation of attributes which are defined for INT1045 + * They are: + * freq_mhz_low_clock : Set PCH FIVR switching freq for + * FIVR clock 19.2MHz and 24MHz + * freq_mhz_high_clock : Set PCH FIVR switching freq for + * FIVR clock 38.4MHz + */ +#define PCH_FIVR_SHOW(name, method) \ +static ssize_t name##_show(struct device *dev,\ + struct device_attribute *attr,\ + char *buf)\ +{\ + struct acpi_device *acpi_dev = dev_get_drvdata(dev);\ + unsigned long long val;\ + acpi_status status;\ +\ + status = acpi_evaluate_integer(acpi_dev->handle, #method,\ + NULL, &val);\ + if (ACPI_SUCCESS(status))\ + return sprintf(buf, "%d\n", (int)val);\ + else\ + return -EINVAL;\ +} + +#define PCH_FIVR_STORE(name, method) \ +static ssize_t name##_store(struct device *dev,\ + struct device_attribute *attr,\ + const char *buf, size_t count)\ +{\ + struct acpi_device *acpi_dev = dev_get_drvdata(dev);\ + acpi_status status;\ + u32 val;\ +\ + if (kstrtouint(buf, 0, &val) < 0)\ + return -EINVAL;\ +\ + status = acpi_execute_simple_method(acpi_dev->handle, #method, val);\ + if (ACPI_SUCCESS(status))\ + return count;\ +\ + return -EINVAL;\ +} + +PCH_FIVR_SHOW(freq_mhz_low_clock, GFC0) +PCH_FIVR_SHOW(freq_mhz_high_clock, GFC1) +PCH_FIVR_STORE(freq_mhz_low_clock, RFC0) +PCH_FIVR_STORE(freq_mhz_high_clock, RFC1) + +static DEVICE_ATTR_RW(freq_mhz_low_clock); +static DEVICE_ATTR_RW(freq_mhz_high_clock); + +static struct attribute *fivr_attrs[] = { + &dev_attr_freq_mhz_low_clock.attr, + &dev_attr_freq_mhz_high_clock.attr, + NULL +}; + +static const struct attribute_group pch_fivr_attribute_group = { + .attrs = fivr_attrs, + .name = "pch_fivr_switch_frequency" +}; + +static int pch_fivr_add(struct platform_device *pdev) +{ + struct acpi_device *acpi_dev; + unsigned long long ptype; + acpi_status status; + int result; + + acpi_dev = ACPI_COMPANION(&(pdev->dev)); + if (!acpi_dev) + return -ENODEV; + + status = acpi_evaluate_integer(acpi_dev->handle, "PTYP", NULL, &ptype); + if (ACPI_FAILURE(status) || ptype != 0x05) + return -ENODEV; + + result = sysfs_create_group(&pdev->dev.kobj, + &pch_fivr_attribute_group); + if (result) + return result; + + platform_set_drvdata(pdev, acpi_dev); + + return 0; +} + +static int pch_fivr_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &pch_fivr_attribute_group); + + return 0; +} + +static const struct acpi_device_id pch_fivr_device_ids[] = { + {"INTC1045", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, pch_fivr_device_ids); + +static struct platform_driver pch_fivr_driver = { + .probe = pch_fivr_add, + .remove = pch_fivr_remove, + .driver = { + .name = "DPTF PCH FIVR", + .acpi_match_table = pch_fivr_device_ids, + }, +}; + +module_platform_driver(pch_fivr_driver); + +MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ACPI DPTF PCH FIVR driver"); diff --git a/drivers/acpi/dptf/int340x_thermal.c b/drivers/acpi/dptf/int340x_thermal.c index bc71a6a60334..8d420c7e7178 100644 --- a/drivers/acpi/dptf/int340x_thermal.c +++ b/drivers/acpi/dptf/int340x_thermal.c @@ -27,6 +27,7 @@ static const struct acpi_device_id int340x_thermal_device_ids[] = { {"INTC1040"}, {"INTC1043"}, {"INTC1044"}, + {"INTC1045"}, {"INTC1047"}, {""}, }; diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index 47f21599f2ab..170643927044 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -19,9 +19,6 @@ #include "internal.h" -#define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("event"); - /* ACPI notifier chain */ static BLOCKING_NOTIFIER_HEAD(acpi_chain_head); diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 26dd208a0d63..756227837b3b 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -1389,7 +1389,7 @@ static bool ars_supported(struct nvdimm_bus *nvdimm_bus) static umode_t nfit_visible(struct kobject *kobj, struct attribute *a, int n) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev); if (a == &dev_attr_scrub.attr) @@ -1679,7 +1679,7 @@ static struct attribute *acpi_nfit_dimm_attributes[] = { static umode_t acpi_nfit_dimm_attr_visible(struct kobject *kobj, struct attribute *a, int n) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct nvdimm *nvdimm = to_nvdimm(dev); struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); @@ -3006,10 +3006,8 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, ndr_desc->provider_data = nfit_spa; ndr_desc->attr_groups = acpi_nfit_region_attribute_groups; if (spa->flags & ACPI_NFIT_PROXIMITY_VALID) { - ndr_desc->numa_node = acpi_map_pxm_to_online_node( - spa->proximity_domain); - ndr_desc->target_node = acpi_map_pxm_to_node( - spa->proximity_domain); + ndr_desc->numa_node = pxm_to_online_node(spa->proximity_domain); + ndr_desc->target_node = pxm_to_node(spa->proximity_domain); } else { ndr_desc->numa_node = NUMA_NO_NODE; ndr_desc->target_node = NUMA_NO_NODE; diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 134bcb40b2af..cb73a5d6ea76 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -63,7 +63,7 @@ struct memory_target { unsigned int memory_pxm; unsigned int processor_pxm; struct resource memregions; - struct node_hmem_attrs hmem_attrs; + struct node_hmem_attrs hmem_attrs[2]; struct list_head caches; struct node_cache_attrs cache_attrs; bool registered; @@ -72,6 +72,7 @@ struct memory_target { struct memory_initiator { struct list_head node; unsigned int processor_pxm; + bool has_cpu; }; struct memory_locality { @@ -115,6 +116,7 @@ static __init void alloc_memory_initiator(unsigned int cpu_pxm) return; initiator->processor_pxm = cpu_pxm; + initiator->has_cpu = node_state(pxm_to_node(cpu_pxm), N_CPU); list_add_tail(&initiator->node, &initiators); } @@ -222,28 +224,28 @@ static u32 hmat_normalize(u16 entry, u64 base, u8 type) } static void hmat_update_target_access(struct memory_target *target, - u8 type, u32 value) + u8 type, u32 value, int access) { switch (type) { case ACPI_HMAT_ACCESS_LATENCY: - target->hmem_attrs.read_latency = value; - target->hmem_attrs.write_latency = value; + target->hmem_attrs[access].read_latency = value; + target->hmem_attrs[access].write_latency = value; break; case ACPI_HMAT_READ_LATENCY: - target->hmem_attrs.read_latency = value; + target->hmem_attrs[access].read_latency = value; break; case ACPI_HMAT_WRITE_LATENCY: - target->hmem_attrs.write_latency = value; + target->hmem_attrs[access].write_latency = value; break; case ACPI_HMAT_ACCESS_BANDWIDTH: - target->hmem_attrs.read_bandwidth = value; - target->hmem_attrs.write_bandwidth = value; + target->hmem_attrs[access].read_bandwidth = value; + target->hmem_attrs[access].write_bandwidth = value; break; case ACPI_HMAT_READ_BANDWIDTH: - target->hmem_attrs.read_bandwidth = value; + target->hmem_attrs[access].read_bandwidth = value; break; case ACPI_HMAT_WRITE_BANDWIDTH: - target->hmem_attrs.write_bandwidth = value; + target->hmem_attrs[access].write_bandwidth = value; break; default: break; @@ -336,8 +338,12 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header, if (mem_hier == ACPI_HMAT_MEMORY) { target = find_mem_target(targs[targ]); - if (target && target->processor_pxm == inits[init]) - hmat_update_target_access(target, type, value); + if (target && target->processor_pxm == inits[init]) { + hmat_update_target_access(target, type, value, 0); + /* If the node has a CPU, update access 1 */ + if (node_state(pxm_to_node(inits[init]), N_CPU)) + hmat_update_target_access(target, type, value, 1); + } } } } @@ -431,7 +437,8 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade pr_info("HMAT: Memory Flags:%04x Processor Domain:%u Memory Domain:%u\n", p->flags, p->processor_PD, p->memory_PD); - if (p->flags & ACPI_HMAT_MEMORY_PD_VALID && hmat_revision == 1) { + if ((hmat_revision == 1 && p->flags & ACPI_HMAT_MEMORY_PD_VALID) || + hmat_revision > 1) { target = find_mem_target(p->memory_PD); if (!target) { pr_debug("HMAT: Memory Domain missing from SRAT\n"); @@ -573,6 +580,7 @@ static void hmat_register_target_initiators(struct memory_target *target) unsigned int mem_nid, cpu_nid; struct memory_locality *loc = NULL; u32 best = 0; + bool access0done = false; int i; mem_nid = pxm_to_node(target->memory_pxm); @@ -584,7 +592,11 @@ static void hmat_register_target_initiators(struct memory_target *target) if (target->processor_pxm != PXM_INVAL) { cpu_nid = pxm_to_node(target->processor_pxm); register_memory_node_under_compute_node(mem_nid, cpu_nid, 0); - return; + access0done = true; + if (node_state(cpu_nid, N_CPU)) { + register_memory_node_under_compute_node(mem_nid, cpu_nid, 1); + return; + } } if (list_empty(&localities)) @@ -598,6 +610,41 @@ static void hmat_register_target_initiators(struct memory_target *target) */ bitmap_zero(p_nodes, MAX_NUMNODES); list_sort(p_nodes, &initiators, initiator_cmp); + if (!access0done) { + for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { + loc = localities_types[i]; + if (!loc) + continue; + + best = 0; + list_for_each_entry(initiator, &initiators, node) { + u32 value; + + if (!test_bit(initiator->processor_pxm, p_nodes)) + continue; + + value = hmat_initiator_perf(target, initiator, + loc->hmat_loc); + if (hmat_update_best(loc->hmat_loc->data_type, value, &best)) + bitmap_clear(p_nodes, 0, initiator->processor_pxm); + if (value != best) + clear_bit(initiator->processor_pxm, p_nodes); + } + if (best) + hmat_update_target_access(target, loc->hmat_loc->data_type, + best, 0); + } + + for_each_set_bit(i, p_nodes, MAX_NUMNODES) { + cpu_nid = pxm_to_node(i); + register_memory_node_under_compute_node(mem_nid, cpu_nid, 0); + } + } + + /* Access 1 ignores Generic Initiators */ + bitmap_zero(p_nodes, MAX_NUMNODES); + list_sort(p_nodes, &initiators, initiator_cmp); + best = 0; for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { loc = localities_types[i]; if (!loc) @@ -607,6 +654,10 @@ static void hmat_register_target_initiators(struct memory_target *target) list_for_each_entry(initiator, &initiators, node) { u32 value; + if (!initiator->has_cpu) { + clear_bit(initiator->processor_pxm, p_nodes); + continue; + } if (!test_bit(initiator->processor_pxm, p_nodes)) continue; @@ -617,12 +668,11 @@ static void hmat_register_target_initiators(struct memory_target *target) clear_bit(initiator->processor_pxm, p_nodes); } if (best) - hmat_update_target_access(target, loc->hmat_loc->data_type, best); + hmat_update_target_access(target, loc->hmat_loc->data_type, best, 1); } - for_each_set_bit(i, p_nodes, MAX_NUMNODES) { cpu_nid = pxm_to_node(i); - register_memory_node_under_compute_node(mem_nid, cpu_nid, 0); + register_memory_node_under_compute_node(mem_nid, cpu_nid, 1); } } @@ -635,10 +685,10 @@ static void hmat_register_target_cache(struct memory_target *target) node_add_cache(mem_nid, &tcache->cache_attrs); } -static void hmat_register_target_perf(struct memory_target *target) +static void hmat_register_target_perf(struct memory_target *target, int access) { unsigned mem_nid = pxm_to_node(target->memory_pxm); - node_set_perf_attrs(mem_nid, &target->hmem_attrs, 0); + node_set_perf_attrs(mem_nid, &target->hmem_attrs[access], access); } static void hmat_register_target_devices(struct memory_target *target) @@ -653,7 +703,7 @@ static void hmat_register_target_devices(struct memory_target *target) return; for (res = target->memregions.child; res; res = res->sibling) { - int target_nid = acpi_map_pxm_to_node(target->memory_pxm); + int target_nid = pxm_to_node(target->memory_pxm); hmem_register_device(target_nid, res); } @@ -683,7 +733,8 @@ static void hmat_register_target(struct memory_target *target) if (!target->registered) { hmat_register_target_initiators(target); hmat_register_target_cache(target); - hmat_register_target_perf(target); + hmat_register_target_perf(target, 0); + hmat_register_target_perf(target, 1); target->registered = true; } mutex_unlock(&target_lock); diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c index 1b0ae0a1959b..6021a1013442 100644 --- a/drivers/acpi/numa/srat.c +++ b/drivers/acpi/numa/srat.c @@ -36,7 +36,7 @@ void __init disable_srat(void) int pxm_to_node(int pxm) { - if (pxm < 0) + if (pxm < 0 || pxm >= MAX_PXM_DOMAINS || numa_off) return NUMA_NO_NODE; return pxm_to_node_map[pxm]; } @@ -135,6 +135,36 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) } break; + case ACPI_SRAT_TYPE_GENERIC_AFFINITY: + { + struct acpi_srat_generic_affinity *p = + (struct acpi_srat_generic_affinity *)header; + + if (p->device_handle_type == 0) { + /* + * For pci devices this may be the only place they + * are assigned a proximity domain + */ + pr_debug("SRAT Generic Initiator(Seg:%u BDF:%u) in proximity domain %d %s\n", + *(u16 *)(&p->device_handle[0]), + *(u16 *)(&p->device_handle[2]), + p->proximity_domain, + (p->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED) ? + "enabled" : "disabled"); + } else { + /* + * In this case we can rely on the device having a + * proximity domain reference + */ + pr_debug("SRAT Generic Initiator(HID=%.8s UID=%.4s) in proximity domain %d %s\n", + (char *)(&p->device_handle[0]), + (char *)(&p->device_handle[8]), + p->proximity_domain, + (p->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED) ? + "enabled" : "disabled"); + } + } + break; default: pr_warn("Found unsupported SRAT entry (type = 0x%x)\n", header->type); @@ -337,6 +367,41 @@ acpi_parse_gicc_affinity(union acpi_subtable_headers *header, return 0; } +#if defined(CONFIG_X86) || defined(CONFIG_ARM64) +static int __init +acpi_parse_gi_affinity(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_srat_generic_affinity *gi_affinity; + int node; + + gi_affinity = (struct acpi_srat_generic_affinity *)header; + if (!gi_affinity) + return -EINVAL; + acpi_table_print_srat_entry(&header->common); + + if (!(gi_affinity->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED)) + return -EINVAL; + + node = acpi_map_pxm_to_node(gi_affinity->proximity_domain); + if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) { + pr_err("SRAT: Too many proximity domains.\n"); + return -EINVAL; + } + node_set(node, numa_nodes_parsed); + node_set_state(node, N_GENERIC_INITIATOR); + + return 0; +} +#else +static int __init +acpi_parse_gi_affinity(union acpi_subtable_headers *header, + const unsigned long end) +{ + return 0; +} +#endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */ + static int __initdata parsed_numa_memblks; static int __init @@ -390,7 +455,7 @@ int __init acpi_numa_init(void) /* SRAT: System Resource Affinity Table */ if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { - struct acpi_subtable_proc srat_proc[3]; + struct acpi_subtable_proc srat_proc[4]; memset(srat_proc, 0, sizeof(srat_proc)); srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY; @@ -399,6 +464,8 @@ int __init acpi_numa_init(void) srat_proc[1].handler = acpi_parse_x2apic_affinity; srat_proc[2].id = ACPI_SRAT_TYPE_GICC_AFFINITY; srat_proc[2].handler = acpi_parse_gicc_affinity; + srat_proc[3].id = ACPI_SRAT_TYPE_GENERIC_AFFINITY; + srat_proc[3].handler = acpi_parse_gi_affinity; acpi_table_parse_entries_array(ACPI_SIG_SRAT, sizeof(struct acpi_table_srat), @@ -441,6 +508,6 @@ int acpi_get_node(acpi_handle handle) pxm = acpi_get_pxm(handle); - return acpi_map_pxm_to_node(pxm); + return pxm_to_node(pxm); } EXPORT_SYMBOL(acpi_get_node); diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 4a0b07792233..0418febc5cf2 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -447,24 +447,19 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size) } EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); -int acpi_os_map_generic_address(struct acpi_generic_address *gas) +void __iomem *acpi_os_map_generic_address(struct acpi_generic_address *gas) { u64 addr; - void __iomem *virt; if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) - return 0; + return NULL; /* Handle possible alignment issues */ memcpy(&addr, &gas->address, sizeof(addr)); if (!addr || !gas->bit_width) - return -EINVAL; - - virt = acpi_os_map_iomem(addr, gas->bit_width / 8); - if (!virt) - return -EIO; + return NULL; - return 0; + return acpi_os_map_iomem(addr, gas->bit_width / 8); } EXPORT_SYMBOL(acpi_os_map_generic_address); @@ -1749,17 +1744,22 @@ acpi_status __init acpi_os_initialize(void) { acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block); acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block); - acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block); - acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block); + + acpi_gbl_xgpe0_block_logical_address = + (unsigned long)acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block); + acpi_gbl_xgpe1_block_logical_address = + (unsigned long)acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block); + if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) { /* * Use acpi_os_map_generic_address to pre-map the reset * register if it's in system memory. */ - int rv; + void *rv; rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register); - pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv); + pr_debug(PREFIX "%s: map reset_reg %s\n", __func__, + rv ? "successful" : "failed"); } acpi_os_initialized = true; @@ -1787,8 +1787,12 @@ acpi_status acpi_os_terminate(void) acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block); acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block); + acpi_gbl_xgpe0_block_logical_address = 0UL; + acpi_gbl_xgpe1_block_logical_address = 0UL; + acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block); acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block); + if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) acpi_os_unmap_generic_address(&acpi_gbl_FADT.reset_register); diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index f90e841c59f5..c12b5fb3e8fb 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -24,8 +24,6 @@ #include "internal.h" -#define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME("pci_root"); #define ACPI_PCI_ROOT_CLASS "pci_bridge" #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" static int acpi_pci_root_add(struct acpi_device *device, @@ -62,7 +60,7 @@ static DEFINE_MUTEX(osc_lock); /** * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge - * @handle - the ACPI CA node in question. + * @handle: the ACPI CA node in question. * * Note: we could make this API take a struct acpi_device * instead, but * for now, it's more convenient to operate on an acpi_handle. diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index ca2461d1bf14..d6cb2c27a23b 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -28,9 +28,6 @@ static int check_sta_before_sun; -#define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME("pci_slot"); - #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ struct acpi_pci_slot { diff --git a/drivers/acpi/pmic/Kconfig b/drivers/acpi/pmic/Kconfig new file mode 100644 index 000000000000..56bbcb2ce61b --- /dev/null +++ b/drivers/acpi/pmic/Kconfig @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: GPL-2.0 + +menuconfig PMIC_OPREGION + bool "PMIC (Power Management Integrated Circuit) operation region support" + help + Select this option to enable support for ACPI operation + region of the PMIC chip. The operation region can be used + to control power rails and sensor reading/writing on the + PMIC chip. + +if PMIC_OPREGION + +config BYTCRC_PMIC_OPREGION + bool "ACPI operation region support for Bay Trail Crystal Cove PMIC" + depends on INTEL_SOC_PMIC + help + This config adds ACPI operation region support for the Bay Trail + version of the Crystal Cove PMIC. + +config CHTCRC_PMIC_OPREGION + bool "ACPI operation region support for Cherry Trail Crystal Cove PMIC" + depends on INTEL_SOC_PMIC + help + This config adds ACPI operation region support for the Cherry Trail + version of the Crystal Cove PMIC. + +config XPOWER_PMIC_OPREGION + bool "ACPI operation region support for XPower AXP288 PMIC" + depends on MFD_AXP20X_I2C && IOSF_MBI=y + help + This config adds ACPI operation region support for XPower AXP288 PMIC. + +config BXT_WC_PMIC_OPREGION + bool "ACPI operation region support for BXT WhiskeyCove PMIC" + depends on INTEL_SOC_PMIC_BXTWC + help + This config adds ACPI operation region support for BXT WhiskeyCove PMIC. + +config CHT_WC_PMIC_OPREGION + bool "ACPI operation region support for CHT Whiskey Cove PMIC" + depends on INTEL_SOC_PMIC_CHTWC + help + This config adds ACPI operation region support for CHT Whiskey Cove PMIC. + +config CHT_DC_TI_PMIC_OPREGION + bool "ACPI operation region support for Dollar Cove TI PMIC" + depends on INTEL_SOC_PMIC_CHTDC_TI + help + This config adds ACPI operation region support for Dollar Cove TI PMIC. + +endif # PMIC_OPREGION + +config TPS68470_PMIC_OPREGION + bool "ACPI operation region support for TPS68470 PMIC" + depends on MFD_TPS68470 + help + This config adds ACPI operation region support for TI TPS68470 PMIC. + TPS68470 device is an advanced power management unit that powers + a Compact Camera Module (CCM), generates clocks for image sensors, + drives a dual LED for flash and incorporates two LED drivers for + general purpose indicators. + This driver enables ACPI operation region support control voltage + regulators and clocks. + + This option is a bool as it provides an ACPI operation + region, which must be available before any of the devices + using this, are probed. diff --git a/drivers/acpi/pmic/Makefile b/drivers/acpi/pmic/Makefile new file mode 100644 index 000000000000..cd072c64920c --- /dev/null +++ b/drivers/acpi/pmic/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_PMIC_OPREGION) += intel_pmic.o +obj-$(CONFIG_BYTCRC_PMIC_OPREGION) += intel_pmic_bytcrc.o +obj-$(CONFIG_CHTCRC_PMIC_OPREGION) += intel_pmic_chtcrc.o +obj-$(CONFIG_XPOWER_PMIC_OPREGION) += intel_pmic_xpower.o +obj-$(CONFIG_BXT_WC_PMIC_OPREGION) += intel_pmic_bxtwc.o +obj-$(CONFIG_CHT_WC_PMIC_OPREGION) += intel_pmic_chtwc.o +obj-$(CONFIG_CHT_DC_TI_PMIC_OPREGION) += intel_pmic_chtdc_ti.o +obj-$(CONFIG_TPS68470_PMIC_OPREGION) += tps68470_pmic.o diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 7892980b3ce4..0cca7991f186 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c @@ -10,15 +10,11 @@ #include "sleep.h" #include "internal.h" -#define _COMPONENT ACPI_SYSTEM_COMPONENT - /* * this file provides support for: * /proc/acpi/wakeup */ -ACPI_MODULE_NAME("sleep") - static int acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) { diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index f32beb7d7882..2ac48cda5b20 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -14,9 +14,6 @@ #include <linux/acpi.h> #include <acpi/processor.h> -#define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_core"); - static struct acpi_table_madt *get_madt_table(void) { static struct acpi_table_madt *madt; diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 41feb88ee92d..6c7d05b37c98 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -20,8 +20,6 @@ #define PREFIX "ACPI: " #define ACPI_PROCESSOR_CLASS "processor" -#define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_thermal"); #ifdef CONFIG_CPU_FREQ diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 2142f1554761..684c726828e1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -898,8 +898,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) */ err = acpi_device_sleep_wake(device, 0, 0, 0); if (err) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "error in _DSW or _PSW evaluation\n")); + pr_debug("error in _DSW or _PSW evaluation\n"); } static void acpi_bus_init_power_state(struct acpi_device *device, int state) diff --git a/drivers/acpi/tiny-power-button.c b/drivers/acpi/tiny-power-button.c index 6273d73c0b59..420e61b8eaae 100644 --- a/drivers/acpi/tiny-power-button.c +++ b/drivers/acpi/tiny-power-button.c @@ -4,7 +4,6 @@ #include <linux/acpi.h> #include <acpi/button.h> -ACPI_MODULE_NAME("tiny-power-button"); MODULE_AUTHOR("Josh Triplett"); MODULE_DESCRIPTION("ACPI Tiny Power Button Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 2499d7e3c710..3a032afd9d05 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -35,9 +35,6 @@ #include <linux/workqueue.h> #include <acpi/video.h> -ACPI_MODULE_NAME("video"); -#define _COMPONENT ACPI_VIDEO_COMPONENT - void acpi_video_unregister_backlight(void); static bool backlight_notifier_registered; @@ -282,6 +279,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"), }, }, + /* https://bugs.launchpad.net/bugs/1894667 */ + { + .callback = video_detect_force_video, + .ident = "HP 635 Notebook", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"), + }, + }, /* Non win8 machines which need native backlight nevertheless */ { diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 0b2e42530adf..f89dd9a99e6e 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -26,8 +26,6 @@ static DEFINE_MUTEX(acpi_wakeup_handler_mutex); * suspend/resume and isn't really required as this is called in S-state. At * that time, there is no device hotplug **/ -#define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("wakeup_devices") /** * acpi_enable_wakeup_devices - Enable wake-up device GPEs. |