Merge with Linux 2.5.48.
[linux-2.6/linux-mips.git] / drivers / base / core.c
blobdd04ea679f02bdc68a75aaf4c0d13b6b8a11694f
1 /*
2 * drivers/base/core.c - core driver model code (device registration, etc)
3 *
4 * Copyright (c) 2002 Patrick Mochel
5 * 2002 Open Source Development Lab
6 */
8 #define DEBUG 0
10 #include <linux/device.h>
11 #include <linux/err.h>
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/string.h>
17 #include <asm/semaphore.h>
19 #include "base.h"
21 LIST_HEAD(global_device_list);
23 int (*platform_notify)(struct device * dev) = NULL;
24 int (*platform_notify_remove)(struct device * dev) = NULL;
26 DECLARE_MUTEX(device_sem);
28 spinlock_t device_lock = SPIN_LOCK_UNLOCKED;
30 #define to_dev(obj) container_of(obj,struct device,kobj)
34 * sysfs bindings for devices.
37 #define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
39 extern struct attribute * dev_default_attrs[];
41 static ssize_t
42 dev_attr_show(struct kobject * kobj, struct attribute * attr,
43 char * buf, size_t count, loff_t off)
45 struct device_attribute * dev_attr = to_dev_attr(attr);
46 struct device * dev = to_dev(kobj);
47 ssize_t ret = 0;
49 if (dev_attr->show)
50 ret = dev_attr->show(dev,buf,count,off);
51 return ret;
54 static ssize_t
55 dev_attr_store(struct kobject * kobj, struct attribute * attr,
56 const char * buf, size_t count, loff_t off)
58 struct device_attribute * dev_attr = to_dev_attr(attr);
59 struct device * dev = to_dev(kobj);
60 ssize_t ret = 0;
62 if (dev_attr->store)
63 ret = dev_attr->store(dev,buf,count,off);
64 return ret;
67 static struct sysfs_ops dev_sysfs_ops = {
68 .show = dev_attr_show,
69 .store = dev_attr_store,
72 struct subsystem device_subsys = {
73 .kobj = {
74 .name = "devices",
76 .sysfs_ops = &dev_sysfs_ops,
77 .default_attrs = dev_default_attrs,
81 int device_create_file(struct device * dev, struct device_attribute * attr)
83 int error = 0;
84 if (get_device(dev)) {
85 error = sysfs_create_file(&dev->kobj,&attr->attr);
86 put_device(dev);
88 return error;
91 void device_remove_file(struct device * dev, struct device_attribute * attr)
93 if (get_device(dev)) {
94 sysfs_remove_file(&dev->kobj,&attr->attr);
95 put_device(dev);
99 int device_add(struct device *dev)
101 int error;
103 if (!dev || !strlen(dev->bus_id))
104 return -EINVAL;
106 down(&device_sem);
107 dev->state = DEVICE_REGISTERED;
108 if (dev->parent) {
109 list_add_tail(&dev->g_list,&dev->parent->g_list);
110 list_add_tail(&dev->node,&dev->parent->children);
111 } else
112 list_add_tail(&dev->g_list,&global_device_list);
113 up(&device_sem);
115 pr_debug("DEV: registering device: ID = '%s', name = %s\n",
116 dev->bus_id, dev->name);
118 strncpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN);
119 if (dev->parent)
120 dev->kobj.parent = &dev->parent->kobj;
121 dev->kobj.subsys = &device_subsys;
122 if ((error = kobject_register(&dev->kobj)))
123 goto register_done;
125 bus_add_device(dev);
127 /* notify platform of device entry */
128 if (platform_notify)
129 platform_notify(dev);
131 /* notify userspace of device entry */
132 dev_hotplug(dev, "add");
134 devclass_add_device(dev);
135 register_done:
136 if (error) {
137 up(&device_sem);
138 list_del_init(&dev->g_list);
139 list_del_init(&dev->node);
140 up(&device_sem);
142 return error;
145 void device_initialize(struct device *dev)
147 kobject_init(&dev->kobj);
148 INIT_LIST_HEAD(&dev->node);
149 INIT_LIST_HEAD(&dev->children);
150 INIT_LIST_HEAD(&dev->g_list);
151 INIT_LIST_HEAD(&dev->driver_list);
152 INIT_LIST_HEAD(&dev->bus_list);
153 INIT_LIST_HEAD(&dev->intf_list);
154 spin_lock_init(&dev->lock);
155 atomic_set(&dev->refcount,1);
156 dev->state = DEVICE_INITIALIZED;
157 if (dev->parent)
158 get_device(dev->parent);
162 * device_register - register a device
163 * @dev: pointer to the device structure
165 * First, make sure that the device has a parent, create
166 * a directory for it, then add it to the parent's list of
167 * children.
169 * Maintains a global list of all devices, in depth-first ordering.
170 * The head for that list is device_root.g_list.
172 int device_register(struct device *dev)
174 int error;
176 if (!dev || !strlen(dev->bus_id))
177 return -EINVAL;
179 device_initialize(dev);
180 if (dev->parent)
181 get_device(dev->parent);
182 error = device_add(dev);
183 if (error && dev->parent)
184 put_device(dev->parent);
185 return error;
188 struct device * get_device(struct device * dev)
190 struct device * ret = dev;
191 down(&device_sem);
192 if (device_present(dev) && atomic_read(&dev->refcount) > 0)
193 atomic_inc(&dev->refcount);
194 else
195 ret = NULL;
196 up(&device_sem);
197 return ret;
201 * put_device - decrement reference count, and clean up when it hits 0
202 * @dev: device in question
204 void put_device(struct device * dev)
206 down(&device_sem);
207 if (!atomic_dec_and_test(&dev->refcount)) {
208 up(&device_sem);
209 return;
211 list_del_init(&dev->node);
212 list_del_init(&dev->g_list);
213 up(&device_sem);
215 WARN_ON(dev->state == DEVICE_REGISTERED);
217 if (dev->state == DEVICE_GONE)
218 device_del(dev);
221 void device_del(struct device * dev)
223 struct device * parent = dev->parent;
225 /* Notify the platform of the removal, in case they
226 * need to do anything...
228 if (platform_notify_remove)
229 platform_notify_remove(dev);
231 /* notify userspace that this device is about to disappear */
232 dev_hotplug (dev, "remove");
234 bus_remove_device(dev);
236 if (dev->release)
237 dev->release(dev);
239 if (parent)
240 put_device(parent);
244 * device_unregister - unlink device
245 * @dev: device going away
247 * The device has been removed from the system, so we disavow knowledge
248 * of it. It might not be the final reference to the device, so we mark
249 * it as !present, so no more references to it can be acquired.
250 * In the end, we decrement the final reference count for it.
252 void device_unregister(struct device * dev)
254 down(&device_sem);
255 dev->state = DEVICE_GONE;
256 up(&device_sem);
258 pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n",
259 dev->bus_id,dev->name);
260 kobject_unregister(&dev->kobj);
261 put_device(dev);
264 static int __init device_subsys_init(void)
266 return subsystem_register(&device_subsys);
269 core_initcall(device_subsys_init);
271 EXPORT_SYMBOL(device_register);
272 EXPORT_SYMBOL(device_unregister);
273 EXPORT_SYMBOL(get_device);
274 EXPORT_SYMBOL(put_device);
276 EXPORT_SYMBOL(device_create_file);
277 EXPORT_SYMBOL(device_remove_file);