diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/bus.c | 2 | ||||
-rw-r--r-- | drivers/acpi/device_sysfs.c | 8 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 2 | ||||
-rw-r--r-- | drivers/acpi/pptt.c | 93 |
4 files changed, 60 insertions, 45 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 0c05ccde1f7a..9531dd0fef50 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1014,7 +1014,7 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv) && !acpi_match_device_ids(acpi_dev, acpi_drv->ids); } -static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) +static int acpi_device_uevent(const struct device *dev, struct kobj_uevent_env *env) { return __acpi_device_uevent_modalias(to_acpi_device(dev), env); } diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index c3aa15571f16..0fbfbaa8d8e3 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -133,7 +133,7 @@ static void acpi_hide_nondev_subnodes(struct acpi_device_data *data) * -EINVAL: output error * -ENOMEM: output is truncated */ -static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias, +static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalias, int size) { int len; @@ -191,7 +191,7 @@ static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias, * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of * ACPI/PNP IDs. */ -static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, +static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias, int size) { struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; @@ -239,7 +239,7 @@ static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, return len; } -int __acpi_device_uevent_modalias(struct acpi_device *adev, +int __acpi_device_uevent_modalias(const struct acpi_device *adev, struct kobj_uevent_env *env) { int len; @@ -277,7 +277,7 @@ int __acpi_device_uevent_modalias(struct acpi_device *adev, * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001". */ -int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) +int acpi_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env) { return __acpi_device_uevent_modalias(acpi_companion_match(dev), env); } diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index ec584442fb29..06ad497067ac 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -120,7 +120,7 @@ int acpi_bus_register_early_device(int type); Device Matching and Notification -------------------------------------------------------------------------- */ struct acpi_device *acpi_companion_match(const struct device *dev); -int __acpi_device_uevent_modalias(struct acpi_device *adev, +int __acpi_device_uevent_modalias(const struct acpi_device *adev, struct kobj_uevent_env *env); /* -------------------------------------------------------------------------- diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index c91342dcbcd6..10975bb603fb 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -81,6 +81,7 @@ static inline bool acpi_pptt_match_type(int table_type, int type) * acpi_pptt_walk_cache() - Attempt to find the requested acpi_pptt_cache * @table_hdr: Pointer to the head of the PPTT table * @local_level: passed res reflects this cache level + * @split_levels: Number of split cache levels (data/instruction). * @res: cache resource in the PPTT we want to walk * @found: returns a pointer to the requested level if found * @level: the requested cache level @@ -100,6 +101,7 @@ static inline bool acpi_pptt_match_type(int table_type, int type) */ static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr, unsigned int local_level, + unsigned int *split_levels, struct acpi_subtable_header *res, struct acpi_pptt_cache **found, unsigned int level, int type) @@ -113,8 +115,17 @@ static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr, while (cache) { local_level++; + if (!(cache->flags & ACPI_PPTT_CACHE_TYPE_VALID)) { + cache = fetch_pptt_cache(table_hdr, cache->next_level_of_cache); + continue; + } + + if (split_levels && + (acpi_pptt_match_type(cache->attributes, ACPI_PPTT_CACHE_TYPE_DATA) || + acpi_pptt_match_type(cache->attributes, ACPI_PPTT_CACHE_TYPE_INSTR))) + *split_levels = local_level; + if (local_level == level && - cache->flags & ACPI_PPTT_CACHE_TYPE_VALID && acpi_pptt_match_type(cache->attributes, type)) { if (*found != NULL && cache != *found) pr_warn("Found duplicate cache level/type unable to determine uniqueness\n"); @@ -135,8 +146,8 @@ static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr, static struct acpi_pptt_cache * acpi_find_cache_level(struct acpi_table_header *table_hdr, struct acpi_pptt_processor *cpu_node, - unsigned int *starting_level, unsigned int level, - int type) + unsigned int *starting_level, unsigned int *split_levels, + unsigned int level, int type) { struct acpi_subtable_header *res; unsigned int number_of_levels = *starting_level; @@ -149,7 +160,8 @@ acpi_find_cache_level(struct acpi_table_header *table_hdr, resource++; local_level = acpi_pptt_walk_cache(table_hdr, *starting_level, - res, &ret, level, type); + split_levels, res, &ret, + level, type); /* * we are looking for the max depth. Since its potentially * possible for a given node to have resources with differing @@ -165,29 +177,29 @@ acpi_find_cache_level(struct acpi_table_header *table_hdr, } /** - * acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches + * acpi_count_levels() - Given a PPTT table, and a CPU node, count the cache + * levels and split cache levels (data/instruction). * @table_hdr: Pointer to the head of the PPTT table * @cpu_node: processor node we wish to count caches for + * @levels: Number of levels if success. + * @split_levels: Number of split cache levels (data/instruction) if + * success. Can by NULL. * * Given a processor node containing a processing unit, walk into it and count * how many levels exist solely for it, and then walk up each level until we hit * the root node (ignore the package level because it may be possible to have - * caches that exist across packages). Count the number of cache levels that - * exist at each level on the way up. - * - * Return: Total number of levels found. + * caches that exist across packages). Count the number of cache levels and + * split cache levels (data/instruction) that exist at each level on the way + * up. */ -static int acpi_count_levels(struct acpi_table_header *table_hdr, - struct acpi_pptt_processor *cpu_node) +static void acpi_count_levels(struct acpi_table_header *table_hdr, + struct acpi_pptt_processor *cpu_node, + unsigned int *levels, unsigned int *split_levels) { - int total_levels = 0; - do { - acpi_find_cache_level(table_hdr, cpu_node, &total_levels, 0, 0); + acpi_find_cache_level(table_hdr, cpu_node, levels, split_levels, 0, 0); cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent); } while (cpu_node); - - return total_levels; } /** @@ -281,19 +293,6 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct acpi_table_he return NULL; } -static int acpi_find_cache_levels(struct acpi_table_header *table_hdr, - u32 acpi_cpu_id) -{ - int number_of_levels = 0; - struct acpi_pptt_processor *cpu; - - cpu = acpi_find_processor_node(table_hdr, acpi_cpu_id); - if (cpu) - number_of_levels = acpi_count_levels(table_hdr, cpu); - - return number_of_levels; -} - static u8 acpi_cache_type(enum cache_type type) { switch (type) { @@ -334,7 +333,7 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta while (cpu_node && !found) { found = acpi_find_cache_level(table_hdr, cpu_node, - &total_levels, level, acpi_type); + &total_levels, NULL, level, acpi_type); *node = cpu_node; cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent); } @@ -602,32 +601,48 @@ static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag) } /** - * acpi_find_last_cache_level() - Determines the number of cache levels for a PE + * acpi_get_cache_info() - Determine the number of cache levels and + * split cache levels (data/instruction) and for a PE. * @cpu: Kernel logical CPU number + * @levels: Number of levels if success. + * @split_levels: Number of levels being split (i.e. data/instruction) + * if success. Can by NULL. * * Given a logical CPU number, returns the number of levels of cache represented * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0 * indicating we didn't find any cache levels. * - * Return: Cache levels visible to this core. + * Return: -ENOENT if no PPTT table or no PPTT processor struct found. + * 0 on success. */ -int acpi_find_last_cache_level(unsigned int cpu) +int acpi_get_cache_info(unsigned int cpu, unsigned int *levels, + unsigned int *split_levels) { - u32 acpi_cpu_id; + struct acpi_pptt_processor *cpu_node; struct acpi_table_header *table; - int number_of_levels = 0; + u32 acpi_cpu_id; + + *levels = 0; + if (split_levels) + *split_levels = 0; table = acpi_get_pptt(); if (!table) return -ENOENT; - pr_debug("Cache Setup find last level CPU=%d\n", cpu); + pr_debug("Cache Setup: find cache levels for CPU=%d\n", cpu); acpi_cpu_id = get_acpi_id_for_cpu(cpu); - number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id); - pr_debug("Cache Setup find last level level=%d\n", number_of_levels); + cpu_node = acpi_find_processor_node(table, acpi_cpu_id); + if (!cpu_node) + return -ENOENT; + + acpi_count_levels(table, cpu_node, levels, split_levels); - return number_of_levels; + pr_debug("Cache Setup: last_level=%d split_levels=%d\n", + *levels, split_levels ? *split_levels : -1); + + return 0; } /** |