2 * drivers/base/core.c - core driver model code (device registration, etc)
4 * Copyright (c) 2002 Patrick Mochel
5 * 2002 Open Source Development Lab
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>
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
[];
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
);
50 ret
= dev_attr
->show(dev
,buf
,count
,off
);
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
);
63 ret
= dev_attr
->store(dev
,buf
,count
,off
);
67 static struct sysfs_ops dev_sysfs_ops
= {
68 .show
= dev_attr_show
,
69 .store
= dev_attr_store
,
72 struct subsystem device_subsys
= {
76 .sysfs_ops
= &dev_sysfs_ops
,
77 .default_attrs
= dev_default_attrs
,
81 int device_create_file(struct device
* dev
, struct device_attribute
* attr
)
84 if (get_device(dev
)) {
85 error
= sysfs_create_file(&dev
->kobj
,&attr
->attr
);
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
);
99 int device_add(struct device
*dev
)
103 if (!dev
|| !strlen(dev
->bus_id
))
107 dev
->state
= DEVICE_REGISTERED
;
109 list_add_tail(&dev
->g_list
,&dev
->parent
->g_list
);
110 list_add_tail(&dev
->node
,&dev
->parent
->children
);
112 list_add_tail(&dev
->g_list
,&global_device_list
);
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
);
120 dev
->kobj
.parent
= &dev
->parent
->kobj
;
121 dev
->kobj
.subsys
= &device_subsys
;
122 if ((error
= kobject_register(&dev
->kobj
)))
127 /* notify platform of device entry */
129 platform_notify(dev
);
131 /* notify userspace of device entry */
132 dev_hotplug(dev
, "add");
134 devclass_add_device(dev
);
138 list_del_init(&dev
->g_list
);
139 list_del_init(&dev
->node
);
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
;
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
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
)
176 if (!dev
|| !strlen(dev
->bus_id
))
179 device_initialize(dev
);
181 get_device(dev
->parent
);
182 error
= device_add(dev
);
183 if (error
&& dev
->parent
)
184 put_device(dev
->parent
);
188 struct device
* get_device(struct device
* dev
)
190 struct device
* ret
= dev
;
192 if (device_present(dev
) && atomic_read(&dev
->refcount
) > 0)
193 atomic_inc(&dev
->refcount
);
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
)
207 if (!atomic_dec_and_test(&dev
->refcount
)) {
211 list_del_init(&dev
->node
);
212 list_del_init(&dev
->g_list
);
215 WARN_ON(dev
->state
== DEVICE_REGISTERED
);
217 if (dev
->state
== DEVICE_GONE
)
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
);
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
)
255 dev
->state
= DEVICE_GONE
;
258 pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n",
259 dev
->bus_id
,dev
->name
);
260 kobject_unregister(&dev
->kobj
);
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
);