diff options
| -rw-r--r-- | drivers/base/sys.c | 65 | ||||
| -rw-r--r-- | include/linux/device.h | 10 |
2 files changed, 73 insertions, 2 deletions
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 8dfa5b7bfb2b..a61fea973d36 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -23,6 +23,63 @@ static struct device system_bus = { .bus_id = "sys", }; + +/** + * sys_register_root - add a subordinate system root + * @root: new root + * + * This is for NUMA-like systems so they can accurately + * represent the topology of the entire system. + * As boards are discovered, a new struct sys_root should + * be allocated and registered. + * The discovery mechanism should initialize the id field + * of the struture, as well as much of the embedded device + * structure as possible, inlcuding the name, the bus_id + * and parent fields. + * + * This simply calls device_register on the embedded device. + * On success, it will use the struct @root->sysdev + * device to create a pseudo-parent for system devices + * on that board. + * + * The platform code can then use @root to specifiy the + * controlling board when discovering and registering + * system devices. + */ +int sys_register_root(struct sys_root * root) +{ + int error = 0; + + if (!root) + return -EINVAL; + + pr_debug("Registering system board %d\n",root->id); + + error = device_register(&root->dev); + if (!error) { + strncpy(root->sysdev.bus_id,"sys",BUS_ID_SIZE); + strncpy(root->sysdev.name,"System Bus",DEVICE_NAME_SIZE); + root->sysdev.parent = &root->dev; + error = device_register(&root->sysdev); + }; + + return error; +} + +/** + * sys_unregister_root - remove subordinate root from tree + * @root: subordinate root in question. + * + * We only decrement the reference count on @root->sysdev + * and @root->dev. + * If both are 0, they will be cleaned up by the core. + */ +void sys_unegister_root(struct sys_root * root) +{ + put_device(&root->sysdev); + put_device(&root->dev); +} + /** * sys_device_register - add a system device to the tree * @sysdev: device in question @@ -46,8 +103,12 @@ int sys_device_register(struct sys_device * sysdev) if (!sysdev) return -EINVAL; - if (!sysdev->dev.parent) - sysdev->dev.parent = &system_bus; + if (!sysdev->dev.parent) { + if (sysdev->root) + sysdev->dev.parent = &sysdev->root->sysdev; + else + sysdev->dev.parent = &system_bus; + } /* make sure bus type is set */ if (!sysdev->dev.bus) diff --git a/include/linux/device.h b/include/linux/device.h index 7abeead7bfe1..53a71f85ae59 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -379,6 +379,16 @@ extern void put_device(struct device * dev); /* drivers/base/sys.c */ +struct sys_root { + u32 id; + struct device dev; + struct device sysdev; +}; + +extern int sys_register_root(struct sys_root *); +extern void sys_unregister_root(struct sys_root *); + + struct sys_device { char * name; u32 id; |
