18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * driver/base/topology.c - Populate sysfs with cpu topology information 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Written by: Zhang Yanmin, Intel Corporation 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (C) 2006, Intel Corp. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * All rights reserved. 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#include <linux/mm.h> 128c2ecf20Sopenharmony_ci#include <linux/cpu.h> 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/hardirq.h> 158c2ecf20Sopenharmony_ci#include <linux/topology.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define define_id_show_func(name) \ 188c2ecf20Sopenharmony_cistatic ssize_t name##_show(struct device *dev, \ 198c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) \ 208c2ecf20Sopenharmony_ci{ \ 218c2ecf20Sopenharmony_ci return sysfs_emit(buf, "%d\n", topology_##name(dev->id)); \ 228c2ecf20Sopenharmony_ci} 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define define_siblings_show_map(name, mask) \ 258c2ecf20Sopenharmony_cistatic ssize_t name##_show(struct device *dev, \ 268c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) \ 278c2ecf20Sopenharmony_ci{ \ 288c2ecf20Sopenharmony_ci return cpumap_print_to_pagebuf(false, buf, topology_##mask(dev->id));\ 298c2ecf20Sopenharmony_ci} 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define define_siblings_show_list(name, mask) \ 328c2ecf20Sopenharmony_cistatic ssize_t name##_list_show(struct device *dev, \ 338c2ecf20Sopenharmony_ci struct device_attribute *attr, \ 348c2ecf20Sopenharmony_ci char *buf) \ 358c2ecf20Sopenharmony_ci{ \ 368c2ecf20Sopenharmony_ci return cpumap_print_to_pagebuf(true, buf, topology_##mask(dev->id));\ 378c2ecf20Sopenharmony_ci} 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define define_siblings_show_func(name, mask) \ 408c2ecf20Sopenharmony_ci define_siblings_show_map(name, mask); \ 418c2ecf20Sopenharmony_ci define_siblings_show_list(name, mask) 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cidefine_id_show_func(physical_package_id); 448c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(physical_package_id); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cidefine_id_show_func(die_id); 478c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(die_id); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cidefine_id_show_func(core_id); 508c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(core_id); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cidefine_siblings_show_func(thread_siblings, sibling_cpumask); 538c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(thread_siblings); 548c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(thread_siblings_list); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cidefine_siblings_show_func(core_cpus, sibling_cpumask); 578c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(core_cpus); 588c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(core_cpus_list); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cidefine_siblings_show_func(core_siblings, core_cpumask); 618c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(core_siblings); 628c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(core_siblings_list); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cidefine_siblings_show_func(die_cpus, die_cpumask); 658c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(die_cpus); 668c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(die_cpus_list); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cidefine_siblings_show_func(package_cpus, core_cpumask); 698c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(package_cpus); 708c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(package_cpus_list); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#ifdef CONFIG_SCHED_BOOK 738c2ecf20Sopenharmony_cidefine_id_show_func(book_id); 748c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(book_id); 758c2ecf20Sopenharmony_cidefine_siblings_show_func(book_siblings, book_cpumask); 768c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(book_siblings); 778c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(book_siblings_list); 788c2ecf20Sopenharmony_ci#endif 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#ifdef CONFIG_SCHED_DRAWER 818c2ecf20Sopenharmony_cidefine_id_show_func(drawer_id); 828c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(drawer_id); 838c2ecf20Sopenharmony_cidefine_siblings_show_func(drawer_siblings, drawer_cpumask); 848c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(drawer_siblings); 858c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(drawer_siblings_list); 868c2ecf20Sopenharmony_ci#endif 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic struct attribute *default_attrs[] = { 898c2ecf20Sopenharmony_ci &dev_attr_physical_package_id.attr, 908c2ecf20Sopenharmony_ci &dev_attr_die_id.attr, 918c2ecf20Sopenharmony_ci &dev_attr_core_id.attr, 928c2ecf20Sopenharmony_ci &dev_attr_thread_siblings.attr, 938c2ecf20Sopenharmony_ci &dev_attr_thread_siblings_list.attr, 948c2ecf20Sopenharmony_ci &dev_attr_core_cpus.attr, 958c2ecf20Sopenharmony_ci &dev_attr_core_cpus_list.attr, 968c2ecf20Sopenharmony_ci &dev_attr_core_siblings.attr, 978c2ecf20Sopenharmony_ci &dev_attr_core_siblings_list.attr, 988c2ecf20Sopenharmony_ci &dev_attr_die_cpus.attr, 998c2ecf20Sopenharmony_ci &dev_attr_die_cpus_list.attr, 1008c2ecf20Sopenharmony_ci &dev_attr_package_cpus.attr, 1018c2ecf20Sopenharmony_ci &dev_attr_package_cpus_list.attr, 1028c2ecf20Sopenharmony_ci#ifdef CONFIG_SCHED_BOOK 1038c2ecf20Sopenharmony_ci &dev_attr_book_id.attr, 1048c2ecf20Sopenharmony_ci &dev_attr_book_siblings.attr, 1058c2ecf20Sopenharmony_ci &dev_attr_book_siblings_list.attr, 1068c2ecf20Sopenharmony_ci#endif 1078c2ecf20Sopenharmony_ci#ifdef CONFIG_SCHED_DRAWER 1088c2ecf20Sopenharmony_ci &dev_attr_drawer_id.attr, 1098c2ecf20Sopenharmony_ci &dev_attr_drawer_siblings.attr, 1108c2ecf20Sopenharmony_ci &dev_attr_drawer_siblings_list.attr, 1118c2ecf20Sopenharmony_ci#endif 1128c2ecf20Sopenharmony_ci NULL 1138c2ecf20Sopenharmony_ci}; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistatic const struct attribute_group topology_attr_group = { 1168c2ecf20Sopenharmony_ci .attrs = default_attrs, 1178c2ecf20Sopenharmony_ci .name = "topology" 1188c2ecf20Sopenharmony_ci}; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/* Add/Remove cpu_topology interface for CPU device */ 1218c2ecf20Sopenharmony_cistatic int topology_add_dev(unsigned int cpu) 1228c2ecf20Sopenharmony_ci{ 1238c2ecf20Sopenharmony_ci struct device *dev = get_cpu_device(cpu); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci return sysfs_create_group(&dev->kobj, &topology_attr_group); 1268c2ecf20Sopenharmony_ci} 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cistatic int topology_remove_dev(unsigned int cpu) 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci struct device *dev = get_cpu_device(cpu); 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci sysfs_remove_group(&dev->kobj, &topology_attr_group); 1338c2ecf20Sopenharmony_ci return 0; 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic int __init topology_sysfs_init(void) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci return cpuhp_setup_state(CPUHP_TOPOLOGY_PREPARE, 1398c2ecf20Sopenharmony_ci "base/topology:prepare", topology_add_dev, 1408c2ecf20Sopenharmony_ci topology_remove_dev); 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cidevice_initcall(topology_sysfs_init); 144