Subject: powerpc: Allow devices to register with numa topology From: Jeremy Kerr Change of_node_to_nid() to traverse the device tree, looking for a numa id. Cell uses this to assign ids to SPUs, which are children of the CPU node. Existing users of of_node_to_nid() are altered to use of_node_to_nid_single(), which doesn't do the traversal. Export an attach_sysdev_to_node() function, allowing system devices (eg. SPUs) to link themselves into the numa topology in sysfs. Signed-off-by: Arnd Bergmann --- Index: linus-2.6/arch/powerpc/mm/numa.c =================================================================== --- linus-2.6.orig/arch/powerpc/mm/numa.c +++ linus-2.6/arch/powerpc/mm/numa.c @@ -208,6 +208,28 @@ static int of_node_numa_domain(struct de return numa_domain; } +/* Walk the device tree upwards, looking for an associativity id */ +int of_node_to_nid(struct device_node *device) +{ + struct device_node *tmp; + int nid = -1; + + of_node_get(device); + while (device) { + nid = of_node_numa_domain(device); + if (nid != -1) + break; + + tmp = device; + device = of_get_parent(tmp); + of_node_put(tmp); + } + of_node_put(device); + + return nid; +} +EXPORT_SYMBOL_GPL(of_node_to_nid); + /* * In theory, the "ibm,associativity" property may contain multiple * associativity lists because a resource may be multiply connected Index: linus-2.6/include/asm-powerpc/topology.h =================================================================== --- linus-2.6.orig/include/asm-powerpc/topology.h +++ linus-2.6/include/asm-powerpc/topology.h @@ -4,6 +4,9 @@ #include +struct sys_device; +struct device_node; + #ifdef CONFIG_NUMA #include @@ -27,6 +30,8 @@ static inline int node_to_first_cpu(int return first_cpu(tmp); } +int of_node_to_nid(struct device_node *device); + #define pcibus_to_node(node) (-1) #define pcibus_to_cpumask(bus) (cpu_online_map) @@ -57,10 +62,29 @@ static inline int node_to_first_cpu(int extern void __init dump_numa_cpu_topology(void); +extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); +extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid); + #else +static inline int of_node_to_nid(struct device_node *device) +{ + return 0; +} + static inline void dump_numa_cpu_topology(void) {} +static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid) +{ + return 0; +} + +static inline void sysfs_remove_device_from_node(struct sys_device *dev, + int nid) +{ +} + + #include #endif /* CONFIG_NUMA */ Index: linus-2.6/arch/powerpc/kernel/sysfs.c =================================================================== --- linus-2.6.orig/arch/powerpc/kernel/sysfs.c +++ linus-2.6/arch/powerpc/kernel/sysfs.c @@ -322,13 +322,31 @@ static void register_nodes(void) } } } + +int sysfs_add_device_to_node(struct sys_device *dev, int nid) +{ + struct node *node = &node_devices[nid]; + return sysfs_create_link(&node->sysdev.kobj, &dev->kobj, + kobject_name(&dev->kobj)); +} + +void sysfs_remove_device_from_node(struct sys_device *dev, int nid) +{ + struct node *node = &node_devices[nid]; + sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj)); +} + #else static void register_nodes(void) { return; } + #endif +EXPORT_SYMBOL_GPL(sysfs_add_device_to_node); +EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node); + /* Only valid if CPU is present. */ static ssize_t show_physical_id(struct sys_device *dev, char *buf) {