Commit c4450655 authored by Patrick Mochel's avatar Patrick Mochel

driver model: get rid of global device list; minor cleanups.

Since the device subsystem contains a global list of registered objects,
we don't need to keep our own separate list, so we axe it. This also
results in a savings of sizeof(void *) x 2 in the size of each device.

drivers/base/power.c is updated to take the subsystem's rwsem and iterate
over that list of objects.

This leaves only the children list of struct device protected by the driver
model semaphore. This could be removed, but there is one user of it (EDD), 
so it can't happen yet.

This patch also removes the driver model spinlock, which isn't used anymore.
parent 6a3b0825
#undef DEBUG
#ifdef DEBUG
# define DBG(x...) printk(x)
#else
# define DBG(x...)
#endif
extern struct list_head global_device_list;
extern spinlock_t device_lock;
extern struct semaphore device_sem;
extern int bus_add_device(struct device * dev);
......
......@@ -18,15 +18,11 @@
#include "base.h"
LIST_HEAD(global_device_list);
int (*platform_notify)(struct device * dev) = NULL;
int (*platform_notify_remove)(struct device * dev) = NULL;
DECLARE_MUTEX(device_sem);
spinlock_t device_lock = SPIN_LOCK_UNLOCKED;
#define to_dev(obj) container_of(obj,struct device,kobj)
......@@ -146,11 +142,9 @@ void device_initialize(struct device *dev)
kobject_init(&dev->kobj);
INIT_LIST_HEAD(&dev->node);
INIT_LIST_HEAD(&dev->children);
INIT_LIST_HEAD(&dev->g_list);
INIT_LIST_HEAD(&dev->driver_list);
INIT_LIST_HEAD(&dev->bus_list);
INIT_LIST_HEAD(&dev->intf_list);
// spin_lock_init(&dev->lock);
}
/**
......@@ -188,13 +182,11 @@ int device_add(struct device *dev)
goto register_done;
/* now take care of our own registration */
down(&device_sem);
if (parent) {
list_add_tail(&dev->g_list,&dev->parent->g_list);
down(&device_sem);
list_add_tail(&dev->node,&parent->children);
} else
list_add_tail(&dev->g_list,&global_device_list);
up(&device_sem);
up(&device_sem);
}
bus_add_device(dev);
......@@ -276,10 +268,11 @@ void device_del(struct device * dev)
{
struct device * parent = dev->parent;
down(&device_sem);
list_del_init(&dev->node);
list_del_init(&dev->g_list);
up(&device_sem);
if (parent) {
down(&device_sem);
list_del_init(&dev->node);
up(&device_sem);
}
/* Notify the platform of the removal, in case they
* need to do anything...
......
......@@ -15,7 +15,9 @@
#include <asm/semaphore.h>
#include "base.h"
#define to_dev(node) container_of(node,struct device,g_list)
#define to_dev(node) container_of(node,struct device,kobj.entry)
extern struct subsystem device_subsys;
/**
* device_suspend - suspend/remove all devices on the device ree
......@@ -35,8 +37,8 @@ int device_suspend(u32 state, u32 level)
printk(KERN_EMERG "Suspending devices\n");
down(&device_sem);
list_for_each(node,&global_device_list) {
down_write(&device_subsys.rwsem);
list_for_each(node,&device_subsys.list) {
struct device * dev = to_dev(node);
if (dev->driver && dev->driver->suspend) {
pr_debug("suspending device %s\n",dev->name);
......@@ -45,7 +47,7 @@ int device_suspend(u32 state, u32 level)
printk(KERN_ERR "%s: suspend returned %d\n",dev->name,error);
}
}
up(&device_sem);
up_write(&device_subsys.rwsem);
return error;
}
......@@ -61,15 +63,15 @@ void device_resume(u32 level)
{
struct list_head * node;
down(&device_sem);
list_for_each_prev(node,&global_device_list) {
down_write(&device_subsys.rwsem);
list_for_each_prev(node,&device_subsys.list) {
struct device * dev = to_dev(node);
if (dev->driver && dev->driver->resume) {
pr_debug("resuming device %s\n",dev->name);
dev->driver->resume(dev,level);
}
}
up(&device_sem);
up_write(&device_subsys.rwsem);
printk(KERN_EMERG "Devices Resumed\n");
}
......@@ -83,15 +85,15 @@ void device_shutdown(void)
printk(KERN_EMERG "Shutting down devices\n");
down(&device_sem);
list_for_each(entry,&global_device_list) {
down_write(&device_subsys.rwsem);
list_for_each(entry,&device_subsys.list) {
struct device * dev = to_dev(entry);
if (dev->driver && dev->driver->shutdown) {
pr_debug("shutting down %s\n",dev->name);
dev->driver->shutdown(dev);
}
}
up(&device_sem);
up_write(&device_subsys.rwsem);
}
EXPORT_SYMBOL(device_suspend);
......
......@@ -250,7 +250,6 @@ extern int interface_add_data(struct intf_data *);
struct device {
struct list_head g_list; /* node in depth-first order list */
struct list_head node; /* node in sibling list */
struct list_head bus_list; /* node in bus's list */
struct list_head driver_list;
......@@ -290,12 +289,6 @@ list_to_dev(struct list_head *node)
return list_entry(node, struct device, node);
}
static inline struct device *
g_list_to_dev(struct list_head *g_list)
{
return list_entry(g_list, struct device, g_list);
}
static inline void *
dev_get_drvdata (struct device *dev)
{
......
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