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