static void cache_setup_acpi_cpu(struct acpi_table_header *table, unsigned int cpu) { struct acpi_pptt_cache *found_cache; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu); struct cacheinfo *this_leaf; unsigned int index = 0; struct acpi_pptt_processor *cpu_node = NULL; while (index < get_cpu_cacheinfo(cpu)->num_leaves) { this_leaf = this_cpu_ci->info_list + index; found_cache = acpi_find_cache_node(table, acpi_cpu_id, this_leaf->type, this_leaf->level, &cpu_node); pr_debug("found = %p %p\n", found_cache, cpu_node); if (found_cache) update_cache_properties(this_leaf, found_cache, cpu_node); index++; } }
static int __init_cache_level(unsigned int cpu) { unsigned int ctype, level, leaves, of_level; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) { ctype = get_cache_type(level); if (ctype == CACHE_TYPE_NOCACHE) { level--; break; } /* Separate instruction and data caches */ leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1; } of_level = of_find_last_cache_level(cpu); if (level < of_level) { /* * some external caches not specified in CLIDR_EL1 * the information may be available in the device tree * only unified external caches are considered here */ leaves += (of_level - level); level = of_level; } this_cpu_ci->num_levels = level; this_cpu_ci->num_leaves = leaves; return 0; }
static int __populate_cache_leaves(unsigned int cpu) { unsigned int level, idx; enum cache_type type; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); struct cacheinfo *this_leaf = this_cpu_ci->info_list; for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && idx < this_cpu_ci->num_leaves; idx++, level++) { type = get_cache_type(level); if (type == CACHE_TYPE_SEPARATE) { ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); } else { ci_leaf_init(this_leaf++, type, level); } } return 0; }
static int cache_setup_of_node(unsigned int cpu) { struct device_node *np; struct cacheinfo *this_leaf; struct device *cpu_dev = get_cpu_device(cpu); struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); unsigned int index = 0; /* skip if of_node is already populated */ if (this_cpu_ci->info_list->of_node) return 0; if (!cpu_dev) { pr_err("No cpu device for CPU %d\n", cpu); return -ENODEV; } np = cpu_dev->of_node; if (!np) { pr_err("Failed to find cpu%d device node\n", cpu); return -ENOENT; } while (index < cache_leaves(cpu)) { this_leaf = this_cpu_ci->info_list + index; if (this_leaf->level != 1) np = of_find_next_cache_node(np); else np = of_node_get(np);/* cpu node itself */ if (!np) break; this_leaf->of_node = np; index++; } if (index != cache_leaves(cpu)) /* not all OF nodes populated */ return -ENOENT; return 0; }