From 2bd00bcd73e5edd5769e2a5f24c59a517582d862 Mon Sep 17 00:00:00 2001 From: Jeremy Linton Date: Fri, 11 May 2018 18:58:00 -0500 Subject: ACPI/PPTT: Add Processor Properties Topology Table parsing ACPI 6.2 adds a new table, which describes how processing units are related to each other in tree like fashion. Caches are also sprinkled throughout the tree and describe the properties of the caches in relation to other caches and processing units. Add the code to parse the cache hierarchy and report the total number of levels of cache for a given core using acpi_find_last_cache_level() as well as fill out the individual cores cache information with cache_setup_acpi() once the cpu_cacheinfo structure has been populated by the arch specific code. An additional patch later in the set adds the ability to report peers in the topology using find_acpi_cpu_topology() to report a unique ID for each processing unit at a given level in the tree. These unique id's can then be used to match related processing units which exist as threads, within a given package, etc. Tested-by: Ard Biesheuvel Tested-by: Vijaya Kumar K Tested-by: Xiongfeng Wang Tested-by: Tomasz Nowicki Acked-by: Sudeep Holla Acked-by: Ard Biesheuvel Acked-by: Rafael J. Wysocki Signed-off-by: Jeremy Linton Signed-off-by: Catalin Marinas --- include/linux/acpi.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 15bfb15c2fa5..032e12a2fdc2 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1297,4 +1297,8 @@ static inline int lpit_read_residency_count_address(u64 *address) } #endif +int find_acpi_cpu_topology(unsigned int cpu, int level); +int find_acpi_cpu_topology_package(unsigned int cpu); +int find_acpi_cpu_cache_topology(unsigned int cpu, int level); + #endif /*_LINUX_ACPI_H*/ -- cgit v1.3-8-gc7d7 From 2520e627dbeecf7ccccc50c969504b59e1a3294b Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 5 Jun 2018 15:35:03 +0100 Subject: ACPI / PPTT: fix build when CONFIG_ACPI_PPTT is not enabled Though CONFIG_ACPI_PPTT is selected by platforms and nor user visible, it may be useful to support the build with CONFIG_ACPI_PPTT disabled. This patch adds the missing dummy/boiler plate implementation to fix the build. Acked-by: "Rafael J. Wysocki" Signed-off-by: Sudeep Holla Signed-off-by: Catalin Marinas --- include/linux/acpi.h | 15 +++++++++++++++ include/linux/cacheinfo.h | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'include/linux/acpi.h') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 032e12a2fdc2..d2639cd2eafc 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1297,8 +1297,23 @@ static inline int lpit_read_residency_count_address(u64 *address) } #endif +#ifdef CONFIG_ACPI_PPTT int find_acpi_cpu_topology(unsigned int cpu, int level); int find_acpi_cpu_topology_package(unsigned int cpu); int find_acpi_cpu_cache_topology(unsigned int cpu, int level); +#else +static inline int find_acpi_cpu_topology(unsigned int cpu, int level) +{ + return -EINVAL; +} +static inline int find_acpi_cpu_topology_package(unsigned int cpu) +{ + return -EINVAL; +} +static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level) +{ + return -EINVAL; +} +#endif #endif /*_LINUX_ACPI_H*/ diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h index 89397e30e269..70e19bc6cc9f 100644 --- a/include/linux/cacheinfo.h +++ b/include/linux/cacheinfo.h @@ -98,7 +98,7 @@ struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu); int init_cache_level(unsigned int cpu); int populate_cache_leaves(unsigned int cpu); int cache_setup_acpi(unsigned int cpu); -#ifndef CONFIG_ACPI +#ifndef CONFIG_ACPI_PPTT /* * acpi_find_last_cache_level is only called on ACPI enabled * platforms using the PPTT for topology. This means that if -- cgit v1.3-8-gc7d7 From d2d2e3c46be5d6dd8001d0eebdf7cafb9bc7006b Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Thu, 21 Jun 2018 16:43:17 +0300 Subject: acpi: Add helper for deactivating memory region Sometimes memory resource may be overlapping with SystemMemory Operation Region by design, for example if the memory region is used as a mailbox for communication with a firmware in the system. One occasion of such mailboxes is USB Type-C Connector System Software Interface (UCSI). With regions like that, it is important that the driver is able to map the memory with the requirements it has. For example, the driver should be allowed to map the memory as non-cached memory. However, if the operation region has been accessed before the driver has mapped the memory, the memory has been marked as write-back by the time the driver is loaded. That means the driver will fail to map the memory if it expects non-cached memory. To work around the problem, introducing helper that the drivers can use to temporarily deactivate (unmap) SystemMemory Operation Regions that overlap with their IO memory. Fixes: 8243edf44152 ("usb: typec: ucsi: Add ACPI driver") Cc: stable@vger.kernel.org Reviewed-by: Rafael J. Wysocki Signed-off-by: Heikki Krogerus Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/osl.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 3 +++ 2 files changed, 75 insertions(+) (limited to 'include/linux/acpi.h') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 7ca41bf023c9..8df9abfa947b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -45,6 +45,8 @@ #include #include +#include "acpica/accommon.h" +#include "acpica/acnamesp.h" #include "internal.h" #define _COMPONENT ACPI_OS_SERVICES @@ -1490,6 +1492,76 @@ int acpi_check_region(resource_size_t start, resource_size_t n, } EXPORT_SYMBOL(acpi_check_region); +static acpi_status acpi_deactivate_mem_region(acpi_handle handle, u32 level, + void *_res, void **return_value) +{ + struct acpi_mem_space_context **mem_ctx; + union acpi_operand_object *handler_obj; + union acpi_operand_object *region_obj2; + union acpi_operand_object *region_obj; + struct resource *res = _res; + acpi_status status; + + region_obj = acpi_ns_get_attached_object(handle); + if (!region_obj) + return AE_OK; + + handler_obj = region_obj->region.handler; + if (!handler_obj) + return AE_OK; + + if (region_obj->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) + return AE_OK; + + if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) + return AE_OK; + + region_obj2 = acpi_ns_get_secondary_object(region_obj); + if (!region_obj2) + return AE_OK; + + mem_ctx = (void *)®ion_obj2->extra.region_context; + + if (!(mem_ctx[0]->address >= res->start && + mem_ctx[0]->address < res->end)) + return AE_OK; + + status = handler_obj->address_space.setup(region_obj, + ACPI_REGION_DEACTIVATE, + NULL, (void **)mem_ctx); + if (ACPI_SUCCESS(status)) + region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE); + + return status; +} + +/** + * acpi_release_memory - Release any mappings done to a memory region + * @handle: Handle to namespace node + * @res: Memory resource + * @level: A level that terminates the search + * + * Walks through @handle and unmaps all SystemMemory Operation Regions that + * overlap with @res and that have already been activated (mapped). + * + * This is a helper that allows drivers to place special requirements on memory + * region that may overlap with operation regions, primarily allowing them to + * safely map the region as non-cached memory. + * + * The unmapped Operation Regions will be automatically remapped next time they + * are called, so the drivers do not need to do anything else. + */ +acpi_status acpi_release_memory(acpi_handle handle, struct resource *res, + u32 level) +{ + if (!(res->flags & IORESOURCE_MEM)) + return AE_TYPE; + + return acpi_walk_namespace(ACPI_TYPE_REGION, handle, level, + acpi_deactivate_mem_region, NULL, res, NULL); +} +EXPORT_SYMBOL_GPL(acpi_release_memory); + /* * Let drivers know whether the resource checks are effective */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 4b35a66383f9..e54f40974eb0 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -443,6 +443,9 @@ int acpi_check_resource_conflict(const struct resource *res); int acpi_check_region(resource_size_t start, resource_size_t n, const char *name); +acpi_status acpi_release_memory(acpi_handle handle, struct resource *res, + u32 level); + int acpi_resources_are_enforced(void); #ifdef CONFIG_HIBERNATION -- cgit v1.3-8-gc7d7