summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/base/sys.c65
-rw-r--r--include/linux/device.h10
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;