Commit aeb14ea3 authored by Patrick Mochel's avatar Patrick Mochel

driver model: add support for multi-board systems.

- device struct sys_root for describing the individual boards of a multi-board
  system.

- allow for registration of alternate device roots.

- check if struct sys_device::root is set on registration, and add it as a child of
  an alternative root, if it's set. 
parent 2a833213
...@@ -23,6 +23,63 @@ static struct device system_bus = { ...@@ -23,6 +23,63 @@ static struct device system_bus = {
.bus_id = "sys", .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 * sys_device_register - add a system device to the tree
* @sysdev: device in question * @sysdev: device in question
...@@ -46,8 +103,12 @@ int sys_device_register(struct sys_device * sysdev) ...@@ -46,8 +103,12 @@ int sys_device_register(struct sys_device * sysdev)
if (!sysdev) if (!sysdev)
return -EINVAL; return -EINVAL;
if (!sysdev->dev.parent) if (!sysdev->dev.parent) {
sysdev->dev.parent = &system_bus; if (sysdev->root)
sysdev->dev.parent = &sysdev->root->sysdev;
else
sysdev->dev.parent = &system_bus;
}
/* make sure bus type is set */ /* make sure bus type is set */
if (!sysdev->dev.bus) if (!sysdev->dev.bus)
......
...@@ -379,6 +379,16 @@ extern void put_device(struct device * dev); ...@@ -379,6 +379,16 @@ extern void put_device(struct device * dev);
/* drivers/base/sys.c */ /* 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 { struct sys_device {
char * name; char * name;
u32 id; u32 id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment