# define DBG(x...)
#endif
-static struct iobus device_root = {
- bus_id: "root",
- name: "Logical System Root",
-};
+static struct device * device_root;
int (*platform_notify)(struct device * dev) = NULL;
int (*platform_notify_remove)(struct device * dev) = NULL;
extern int device_make_dir(struct device * dev);
extern void device_remove_dir(struct device * dev);
-extern int iobus_make_dir(struct iobus * iobus);
-extern void iobus_remove_dir(struct iobus * iobus);
-
static spinlock_t device_lock;
/**
if (!dev || !strlen(dev->bus_id))
return -EINVAL;
- BUG_ON(!dev->parent);
spin_lock(&device_lock);
INIT_LIST_HEAD(&dev->node);
+ INIT_LIST_HEAD(&dev->children);
spin_lock_init(&dev->lock);
atomic_set(&dev->refcount,2);
- get_iobus(dev->parent);
- list_add_tail(&dev->node,&dev->parent->devices);
+ if (dev != device_root) {
+ if (!dev->parent)
+ dev->parent = device_root;
+ get_device(dev->parent);
+ list_add_tail(&dev->node,&dev->parent->children);
+ }
spin_unlock(&device_lock);
- DBG("DEV: registering device: ID = '%s', name = %s, parent = %s\n",
- dev->bus_id, dev->name, parent->bus_id);
+ DBG("DEV: registering device: ID = '%s', name = %s\n",
+ dev->bus_id, dev->name);
if ((error = device_make_dir(dev)))
goto register_done;
register_done:
put_device(dev);
- if (error)
- put_iobus(dev->parent);
+ if (error && dev->parent)
+ put_device(dev->parent);
return error;
}
/* remove the driverfs directory */
device_remove_dir(dev);
- if (dev->subordinate)
- iobus_remove_dir(dev->subordinate);
-
/* Notify the platform of the removal, in case they
* need to do anything...
*/
if (dev->driver && dev->driver->remove)
dev->driver->remove(dev,REMOVE_FREE_RESOURCES);
- put_iobus(dev->parent);
-}
-
-int iobus_register(struct iobus *bus)
-{
- int error;
-
- if (!bus || !strlen(bus->bus_id))
- return -EINVAL;
-
- spin_lock(&device_lock);
- atomic_set(&bus->refcount,2);
- spin_lock_init(&bus->lock);
- INIT_LIST_HEAD(&bus->node);
- INIT_LIST_HEAD(&bus->devices);
- INIT_LIST_HEAD(&bus->children);
-
- if (bus != &device_root) {
- if (!bus->parent)
- bus->parent = &device_root;
- get_iobus(bus->parent);
- list_add_tail(&bus->node,&bus->parent->children);
- }
- spin_unlock(&device_lock);
-
- DBG("DEV: registering bus. ID = '%s' name = '%s' parent = %p\n",
- bus->bus_id,bus->name,bus->parent);
-
- error = iobus_make_dir(bus);
-
- put_iobus(bus);
- if (error && bus->parent)
- put_iobus(bus->parent);
- return error;
-}
-
-/**
- * iobus_unregister - remove bus and children from device tree
- * @bus: pointer to bus structure
- *
- * Remove device from parent's list of children and decrement
- * reference count on controlling device. That should take care of
- * the rest of the cleanup.
- */
-void put_iobus(struct iobus * iobus)
-{
- if (!atomic_dec_and_lock(&iobus->refcount,&device_lock))
- return;
- list_del_init(&iobus->node);
- spin_unlock(&device_lock);
-
- if (!list_empty(&iobus->devices) ||
- !list_empty(&iobus->children))
- BUG();
-
- put_iobus(iobus->parent);
- /* unregister itself */
- put_device(iobus->self);
+ put_device(dev->parent);
}
static int __init device_init_root(void)
{
- /* initialize parent bus lists */
- return iobus_register(&device_root);
+ device_root = kmalloc(sizeof(*device_root),GFP_KERNEL);
+ if (!device_root)
+ return -ENOMEM;
+ memset(device_root,0,sizeof(*device_root));
+ strcpy(device_root->bus_id,"root");
+ strcpy(device_root->name,"System Root");
+ return device_register(device_root);
}
static int __init device_driver_init(void)
EXPORT_SYMBOL(device_register);
EXPORT_SYMBOL(put_device);
-EXPORT_SYMBOL(iobus_register);
-EXPORT_SYMBOL(put_iobus);
child->parent = parent;
child->ops = parent->ops;
child->sysdata = parent->sysdata;
-
- /* init generic fields */
- child->iobus.self = &dev->dev;
- child->iobus.parent = &parent->iobus;
- dev->dev.subordinate = &child->iobus;
-
- strcpy(child->iobus.name,dev->dev.name);
+ child->dev = &dev->dev;
/*
* Set up the primary, secondary and subordinate
DBG("Scanning bus %02x\n", bus->number);
max = bus->secondary;
- /* we should know for sure what the bus number is, so set the bus ID
- * for the bus and make sure it's registered in the device tree */
- sprintf(bus->iobus.bus_id,"pci%d",bus->number);
- iobus_register(&bus->iobus);
-
/* Create a device template */
memset(&dev0, 0, sizeof(dev0));
dev0.bus = bus;
dev0.sysdata = bus->sysdata;
- dev0.dev.parent = &bus->iobus;
+ dev0.dev.parent = bus->dev;
dev0.dev.driver = &pci_device_driver;
/* Go find them, Rover! */
return NULL;
list_add_tail(&b->node, &pci_root_buses);
- sprintf(b->iobus.bus_id,"pci%d",bus);
- strcpy(b->iobus.name,"Host/PCI Bridge");
- iobus_register(&b->iobus);
+ b->dev = kmalloc(sizeof(*(b->dev)),GFP_KERNEL);
+ memset(b->dev,0,sizeof(*(b->dev)));
+ sprintf(b->dev->bus_id,"pci%d",bus);
+ strcpy(b->dev->name,"Host/PCI Bridge");
+ device_register(b->dev);
b->number = b->secondary = bus;
b->resource[0] = &ioport_resource;
struct device {
struct list_head node; /* node in sibling list */
- struct iobus *parent; /* parent bus */
-
- struct iobus *subordinate; /* only valid if this device is a
- bridge device */
+ struct list_head children;
+ struct device * parent;
char name[DEVICE_NAME_SIZE]; /* descriptive ascii string */
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
int (*add_device) (struct iobus*, char*);
};
-struct iobus {
- spinlock_t lock; /* lock for bus */
- atomic_t refcount;
-
- struct list_head node; /* node in sibling list */
- struct iobus *parent; /* parent bus */
- struct list_head children; /* children buses */
- struct list_head devices; /* children devices */
-
- struct device *self; /* pointer to controlling device */
- struct driver_dir_entry dir; /* driverfs directory */
-
- char name[DEVICE_NAME_SIZE];
- char bus_id[BUS_ID_SIZE];
-
- struct iobus_driver *driver; /* bus operations */
-};
-
static inline struct device *
list_to_dev(struct list_head *node)
{
return list_entry(node, struct device, node);
}
-static inline struct iobus *
-list_to_iobus(const struct list_head *node)
-{
- return list_entry(node, struct iobus, node);
-}
-
/*
* High level routines for use by the bus drivers
*/
extern void put_device(struct device * dev);
-static inline void lock_iobus(struct iobus * iobus)
-{
- spin_lock(&iobus->lock);
-}
-
-static inline void unlock_iobus(struct iobus * iobus)
-{
- spin_unlock(&iobus->lock);
-}
-
-static inline void get_iobus(struct iobus * iobus)
-{
- BUG_ON(!atomic_read(&iobus->refcount));
- atomic_inc(&iobus->refcount);
-}
-
-extern void put_iobus(struct iobus * iobus);
-
#endif /* _DEVICE_H_ */