Blame view

drivers/base/core.c 46.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
  /*
   * drivers/base/core.c - core driver model code (device registration, etc)
   *
   * Copyright (c) 2002-3 Patrick Mochel
   * Copyright (c) 2002-3 Open Source Development Labs
64bb5d2c1   Greg Kroah-Hartman   Driver core: allo...
6
7
   * Copyright (c) 2006 Greg Kroah-Hartman <gregkh@suse.de>
   * Copyright (c) 2006 Novell, Inc.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
   *
   * This file is released under the GPLv2
   *
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
17
  #include <linux/device.h>
  #include <linux/err.h>
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/string.h>
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
18
  #include <linux/kdev_t.h>
116af3782   Benjamin Herrenschmidt   Driver core: add ...
19
  #include <linux/notifier.h>
da231fd5d   Kay Sievers   Driver core: fix ...
20
  #include <linux/genhd.h>
815d2d50d   Andrew Morton   driver core: debu...
21
  #include <linux/kallsyms.h>
f75b1c60f   Dave Young   class: change int...
22
  #include <linux/mutex.h>
401097ea4   Shaohua Li   driver core: sync...
23
  #include <linux/async.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
25
26
  
  #include "base.h"
  #include "power/power.h"
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
27
28
  int (*platform_notify)(struct device *dev) = NULL;
  int (*platform_notify_remove)(struct device *dev) = NULL;
e105b8bfc   Dan Williams   sysfs: add /sys/d...
29
30
31
  static struct kobject *dev_kobj;
  struct kobject *sysfs_dev_char_kobj;
  struct kobject *sysfs_dev_block_kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32

4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
33
34
35
36
37
38
39
40
41
42
43
  #ifdef CONFIG_BLOCK
  static inline int device_is_not_partition(struct device *dev)
  {
  	return !(dev->type == &part_type);
  }
  #else
  static inline int device_is_not_partition(struct device *dev)
  {
  	return 1;
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

3e95637a4   Alan Stern   [PATCH] Driver Co...
45
46
47
48
49
50
51
52
53
  /**
   * dev_driver_string - Return a device's driver name, if at all possible
   * @dev: struct device to get the name of
   *
   * Will return the device's driver's name if it is bound to a device.  If
   * the device is not bound to a device, it will return the name of the bus
   * it is attached to.  If it is not attached to a bus either, an empty
   * string will be returned.
   */
bf9ca69fc   Jean Delvare   dev_printk(): con...
54
  const char *dev_driver_string(const struct device *dev)
3e95637a4   Alan Stern   [PATCH] Driver Co...
55
  {
3589972e5   Alan Stern   Driver core: fix ...
56
57
58
59
60
61
62
63
  	struct device_driver *drv;
  
  	/* dev->driver can change to NULL underneath us because of unbinding,
  	 * so be careful about accessing it.  dev->bus and dev->class should
  	 * never change once they are set, so they don't need special care.
  	 */
  	drv = ACCESS_ONCE(dev->driver);
  	return drv ? drv->name :
a456b7023   Jean Delvare   dev_printk and ne...
64
65
  			(dev->bus ? dev->bus->name :
  			(dev->class ? dev->class->name : ""));
3e95637a4   Alan Stern   [PATCH] Driver Co...
66
  }
310a922d4   Matthew Wilcox   Fix dev_printk() ...
67
  EXPORT_SYMBOL(dev_driver_string);
3e95637a4   Alan Stern   [PATCH] Driver Co...
68

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
  #define to_dev(obj) container_of(obj, struct device, kobj)
  #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
71
72
  static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
  			     char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  {
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
74
75
  	struct device_attribute *dev_attr = to_dev_attr(attr);
  	struct device *dev = to_dev(kobj);
4a0c20bf8   Dmitry Torokhov   [PATCH] sysfs: (d...
76
  	ssize_t ret = -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
  
  	if (dev_attr->show)
54b6f35c9   Yani Ioannou   [PATCH] Driver co...
79
  		ret = dev_attr->show(dev, dev_attr, buf);
815d2d50d   Andrew Morton   driver core: debu...
80
81
82
83
84
  	if (ret >= (ssize_t)PAGE_SIZE) {
  		print_symbol("dev_attr_show: %s returned bad count
  ",
  				(unsigned long)dev_attr->show);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
86
  	return ret;
  }
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
87
88
  static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr,
  			      const char *buf, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
  {
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
90
91
  	struct device_attribute *dev_attr = to_dev_attr(attr);
  	struct device *dev = to_dev(kobj);
4a0c20bf8   Dmitry Torokhov   [PATCH] sysfs: (d...
92
  	ssize_t ret = -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
  
  	if (dev_attr->store)
54b6f35c9   Yani Ioannou   [PATCH] Driver co...
95
  		ret = dev_attr->store(dev, dev_attr, buf, count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
  	return ret;
  }
52cf25d0a   Emese Revfy   Driver core: Cons...
98
  static const struct sysfs_ops dev_sysfs_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
101
102
103
104
105
106
107
108
109
110
111
  	.show	= dev_attr_show,
  	.store	= dev_attr_store,
  };
  
  
  /**
   *	device_release - free device structure.
   *	@kobj:	device's kobject.
   *
   *	This is called once the reference count for the object
   *	reaches 0. We forward the call to the device's release
   *	method, which should handle actually freeing the structure.
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
112
  static void device_release(struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
  {
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
114
  	struct device *dev = to_dev(kobj);
fb069a5d1   Greg Kroah-Hartman   driver core: crea...
115
  	struct device_private *p = dev->p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
  
  	if (dev->release)
  		dev->release(dev);
f9f852df2   Kay Sievers   Driver core: add ...
119
120
  	else if (dev->type && dev->type->release)
  		dev->type->release(dev);
2620efef7   Greg Kroah-Hartman   Driver core: add ...
121
122
  	else if (dev->class && dev->class->dev_release)
  		dev->class->dev_release(dev);
f810a5cf2   Arjan van de Ven   Use WARN() in dri...
123
124
  	else
  		WARN(1, KERN_ERR "Device '%s' does not have a release() "
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
125
126
  			"function, it is broken and must be fixed.
  ",
1e0b2cf93   Kay Sievers   driver core: stru...
127
  			dev_name(dev));
fb069a5d1   Greg Kroah-Hartman   driver core: crea...
128
  	kfree(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  }
bc451f205   Eric W. Biederman   kobj: Add basic i...
130
131
132
133
134
135
136
137
138
139
  static const void *device_namespace(struct kobject *kobj)
  {
  	struct device *dev = to_dev(kobj);
  	const void *ns = NULL;
  
  	if (dev->class && dev->class->ns_type)
  		ns = dev->class->namespace(dev);
  
  	return ns;
  }
8f4afc410   Greg Kroah-Hartman   Driver core: rena...
140
  static struct kobj_type device_ktype = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
  	.release	= device_release,
  	.sysfs_ops	= &dev_sysfs_ops,
bc451f205   Eric W. Biederman   kobj: Add basic i...
143
  	.namespace	= device_namespace,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
  };
312c004d3   Kay Sievers   [PATCH] driver co...
145
  static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
147
  {
  	struct kobj_type *ktype = get_ktype(kobj);
8f4afc410   Greg Kroah-Hartman   Driver core: rena...
148
  	if (ktype == &device_ktype) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
  		struct device *dev = to_dev(kobj);
  		if (dev->bus)
  			return 1;
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
152
153
  		if (dev->class)
  			return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
  	}
  	return 0;
  }
312c004d3   Kay Sievers   [PATCH] driver co...
157
  static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
159
  {
  	struct device *dev = to_dev(kobj);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
160
161
162
163
164
  	if (dev->bus)
  		return dev->bus->name;
  	if (dev->class)
  		return dev->class->name;
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
  }
7eff2e7a8   Kay Sievers   Driver core: chan...
166
167
  static int dev_uevent(struct kset *kset, struct kobject *kobj,
  		      struct kobj_uevent_env *env)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
  {
  	struct device *dev = to_dev(kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
  	int retval = 0;
6fcf53acc   Kay Sievers   Driver Core: add ...
171
  	/* add device node properties if present */
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
172
  	if (MAJOR(dev->devt)) {
6fcf53acc   Kay Sievers   Driver Core: add ...
173
174
  		const char *tmp;
  		const char *name;
e454cea20   Kay Sievers   Driver-Core: exte...
175
  		mode_t mode = 0;
6fcf53acc   Kay Sievers   Driver Core: add ...
176

7eff2e7a8   Kay Sievers   Driver core: chan...
177
178
  		add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
  		add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
e454cea20   Kay Sievers   Driver-Core: exte...
179
  		name = device_get_devnode(dev, &mode, &tmp);
6fcf53acc   Kay Sievers   Driver Core: add ...
180
181
182
  		if (name) {
  			add_uevent_var(env, "DEVNAME=%s", name);
  			kfree(tmp);
e454cea20   Kay Sievers   Driver-Core: exte...
183
184
  			if (mode)
  				add_uevent_var(env, "DEVMODE=%#o", mode & 0777);
6fcf53acc   Kay Sievers   Driver Core: add ...
185
  		}
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
186
  	}
414264f95   Kay Sievers   Driver core: add ...
187
  	if (dev->type && dev->type->name)
7eff2e7a8   Kay Sievers   Driver core: chan...
188
  		add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
414264f95   Kay Sievers   Driver core: add ...
189

239378f16   Kay Sievers   Driver core: add ...
190
  	if (dev->driver)
7eff2e7a8   Kay Sievers   Driver core: chan...
191
  		add_uevent_var(env, "DRIVER=%s", dev->driver->name);
239378f16   Kay Sievers   Driver core: add ...
192

a87cb2ac4   Kay Sievers   CONFIG_SYSFS_DEPR...
193
  #ifdef CONFIG_SYSFS_DEPRECATED
239378f16   Kay Sievers   Driver core: add ...
194
195
196
197
198
199
200
201
202
203
  	if (dev->class) {
  		struct device *parent = dev->parent;
  
  		/* find first bus device in parent chain */
  		while (parent && !parent->bus)
  			parent = parent->parent;
  		if (parent && parent->bus) {
  			const char *path;
  
  			path = kobject_get_path(&parent->kobj, GFP_KERNEL);
2c7afd125   Kay Sievers   Driver core: keep...
204
  			if (path) {
7eff2e7a8   Kay Sievers   Driver core: chan...
205
  				add_uevent_var(env, "PHYSDEVPATH=%s", path);
2c7afd125   Kay Sievers   Driver core: keep...
206
207
  				kfree(path);
  			}
239378f16   Kay Sievers   Driver core: add ...
208

7eff2e7a8   Kay Sievers   Driver core: chan...
209
  			add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name);
239378f16   Kay Sievers   Driver core: add ...
210
211
  
  			if (parent->driver)
7eff2e7a8   Kay Sievers   Driver core: chan...
212
213
  				add_uevent_var(env, "PHYSDEVDRIVER=%s",
  					       parent->driver->name);
239378f16   Kay Sievers   Driver core: add ...
214
215
  		}
  	} else if (dev->bus) {
7eff2e7a8   Kay Sievers   Driver core: chan...
216
  		add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
239378f16   Kay Sievers   Driver core: add ...
217
218
  
  		if (dev->driver)
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
219
220
  			add_uevent_var(env, "PHYSDEVDRIVER=%s",
  				       dev->driver->name);
d81d9d6b9   Kay Sievers   deprecate PHYSDEV...
221
  	}
239378f16   Kay Sievers   Driver core: add ...
222
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223

7eff2e7a8   Kay Sievers   Driver core: chan...
224
  	/* have the bus specific function add its stuff */
312c004d3   Kay Sievers   [PATCH] driver co...
225
  	if (dev->bus && dev->bus->uevent) {
7eff2e7a8   Kay Sievers   Driver core: chan...
226
  		retval = dev->bus->uevent(dev, env);
f9f852df2   Kay Sievers   Driver core: add ...
227
  		if (retval)
7dc72b284   Greg Kroah-Hartman   Driver core: clea...
228
229
  			pr_debug("device: '%s': %s: bus uevent() returned %d
  ",
1e0b2cf93   Kay Sievers   driver core: stru...
230
  				 dev_name(dev), __func__, retval);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
  	}
7eff2e7a8   Kay Sievers   Driver core: chan...
232
  	/* have the class specific function add its stuff */
2620efef7   Greg Kroah-Hartman   Driver core: add ...
233
  	if (dev->class && dev->class->dev_uevent) {
7eff2e7a8   Kay Sievers   Driver core: chan...
234
  		retval = dev->class->dev_uevent(dev, env);
f9f852df2   Kay Sievers   Driver core: add ...
235
  		if (retval)
7dc72b284   Greg Kroah-Hartman   Driver core: clea...
236
  			pr_debug("device: '%s': %s: class uevent() "
1e0b2cf93   Kay Sievers   driver core: stru...
237
238
  				 "returned %d
  ", dev_name(dev),
2b3a302a0   Harvey Harrison   driver core: repl...
239
  				 __func__, retval);
f9f852df2   Kay Sievers   Driver core: add ...
240
  	}
eef35c2d4   Stefan Weil   Fix spelling fuct...
241
  	/* have the device type specific function add its stuff */
f9f852df2   Kay Sievers   Driver core: add ...
242
  	if (dev->type && dev->type->uevent) {
7eff2e7a8   Kay Sievers   Driver core: chan...
243
  		retval = dev->type->uevent(dev, env);
f9f852df2   Kay Sievers   Driver core: add ...
244
  		if (retval)
7dc72b284   Greg Kroah-Hartman   Driver core: clea...
245
  			pr_debug("device: '%s': %s: dev_type uevent() "
1e0b2cf93   Kay Sievers   driver core: stru...
246
247
  				 "returned %d
  ", dev_name(dev),
2b3a302a0   Harvey Harrison   driver core: repl...
248
  				 __func__, retval);
2620efef7   Greg Kroah-Hartman   Driver core: add ...
249
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
251
  	return retval;
  }
9cd43611c   Emese Revfy   kobject: Constify...
252
  static const struct kset_uevent_ops device_uevent_ops = {
312c004d3   Kay Sievers   [PATCH] driver co...
253
254
255
  	.filter =	dev_uevent_filter,
  	.name =		dev_uevent_name,
  	.uevent =	dev_uevent,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  };
16574dccd   Kay Sievers   Driver core: make...
257
258
259
260
261
  static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
  			   char *buf)
  {
  	struct kobject *top_kobj;
  	struct kset *kset;
7eff2e7a8   Kay Sievers   Driver core: chan...
262
  	struct kobj_uevent_env *env = NULL;
16574dccd   Kay Sievers   Driver core: make...
263
264
265
266
267
268
  	int i;
  	size_t count = 0;
  	int retval;
  
  	/* search the kset, the device belongs to */
  	top_kobj = &dev->kobj;
5c5daf657   Kay Sievers   Driver core: excl...
269
270
  	while (!top_kobj->kset && top_kobj->parent)
  		top_kobj = top_kobj->parent;
16574dccd   Kay Sievers   Driver core: make...
271
272
  	if (!top_kobj->kset)
  		goto out;
5c5daf657   Kay Sievers   Driver core: excl...
273

16574dccd   Kay Sievers   Driver core: make...
274
275
276
277
278
279
280
281
  	kset = top_kobj->kset;
  	if (!kset->uevent_ops || !kset->uevent_ops->uevent)
  		goto out;
  
  	/* respect filter */
  	if (kset->uevent_ops && kset->uevent_ops->filter)
  		if (!kset->uevent_ops->filter(kset, &dev->kobj))
  			goto out;
7eff2e7a8   Kay Sievers   Driver core: chan...
282
283
  	env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
  	if (!env)
c7308c81a   Greg Kroah-Hartman   Driver core: fix ...
284
  		return -ENOMEM;
16574dccd   Kay Sievers   Driver core: make...
285
  	/* let the kset specific function add its keys */
7eff2e7a8   Kay Sievers   Driver core: chan...
286
  	retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
16574dccd   Kay Sievers   Driver core: make...
287
288
289
290
  	if (retval)
  		goto out;
  
  	/* copy keys to file */
7eff2e7a8   Kay Sievers   Driver core: chan...
291
292
293
  	for (i = 0; i < env->envp_idx; i++)
  		count += sprintf(&buf[count], "%s
  ", env->envp[i]);
16574dccd   Kay Sievers   Driver core: make...
294
  out:
7eff2e7a8   Kay Sievers   Driver core: chan...
295
  	kfree(env);
16574dccd   Kay Sievers   Driver core: make...
296
297
  	return count;
  }
a7fd67062   Kay Sievers   [PATCH] add sysfs...
298
299
300
  static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
  			    const char *buf, size_t count)
  {
60a96a595   Kay Sievers   Driver core: acce...
301
  	enum kobject_action action;
3f5468c9a   Kay Sievers   Driver-Core: requ...
302
  	if (kobject_action_type(buf, count, &action) == 0)
60a96a595   Kay Sievers   Driver core: acce...
303
  		kobject_uevent(&dev->kobj, action);
3f5468c9a   Kay Sievers   Driver-Core: requ...
304
305
306
  	else
  		dev_err(dev, "uevent: unknown action-string
  ");
a7fd67062   Kay Sievers   [PATCH] add sysfs...
307
308
  	return count;
  }
ad6a1e1c6   Tejun Heo   driver-core: make...
309
310
  static struct device_attribute uevent_attr =
  	__ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
621a1672f   Dmitry Torokhov   driver core: Use ...
311
312
  static int device_add_attributes(struct device *dev,
  				 struct device_attribute *attrs)
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
313
  {
621a1672f   Dmitry Torokhov   driver core: Use ...
314
  	int error = 0;
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
315
  	int i;
621a1672f   Dmitry Torokhov   driver core: Use ...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  
  	if (attrs) {
  		for (i = 0; attr_name(attrs[i]); i++) {
  			error = device_create_file(dev, &attrs[i]);
  			if (error)
  				break;
  		}
  		if (error)
  			while (--i >= 0)
  				device_remove_file(dev, &attrs[i]);
  	}
  	return error;
  }
  
  static void device_remove_attributes(struct device *dev,
  				     struct device_attribute *attrs)
  {
  	int i;
  
  	if (attrs)
  		for (i = 0; attr_name(attrs[i]); i++)
  			device_remove_file(dev, &attrs[i]);
  }
  
  static int device_add_groups(struct device *dev,
a4dbd6740   David Brownell   driver model: con...
341
  			     const struct attribute_group **groups)
621a1672f   Dmitry Torokhov   driver core: Use ...
342
  {
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
343
  	int error = 0;
621a1672f   Dmitry Torokhov   driver core: Use ...
344
  	int i;
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
345

621a1672f   Dmitry Torokhov   driver core: Use ...
346
347
348
  	if (groups) {
  		for (i = 0; groups[i]; i++) {
  			error = sysfs_create_group(&dev->kobj, groups[i]);
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
349
350
  			if (error) {
  				while (--i >= 0)
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
351
352
  					sysfs_remove_group(&dev->kobj,
  							   groups[i]);
621a1672f   Dmitry Torokhov   driver core: Use ...
353
  				break;
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
354
355
356
  			}
  		}
  	}
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
357
358
  	return error;
  }
621a1672f   Dmitry Torokhov   driver core: Use ...
359
  static void device_remove_groups(struct device *dev,
a4dbd6740   David Brownell   driver model: con...
360
  				 const struct attribute_group **groups)
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
361
362
  {
  	int i;
621a1672f   Dmitry Torokhov   driver core: Use ...
363
364
365
366
  
  	if (groups)
  		for (i = 0; groups[i]; i++)
  			sysfs_remove_group(&dev->kobj, groups[i]);
de0ff00d7   Greg Kroah-Hartman   Driver core: add ...
367
  }
2620efef7   Greg Kroah-Hartman   Driver core: add ...
368
369
370
  static int device_add_attrs(struct device *dev)
  {
  	struct class *class = dev->class;
f9f852df2   Kay Sievers   Driver core: add ...
371
  	struct device_type *type = dev->type;
621a1672f   Dmitry Torokhov   driver core: Use ...
372
  	int error;
2620efef7   Greg Kroah-Hartman   Driver core: add ...
373

621a1672f   Dmitry Torokhov   driver core: Use ...
374
375
  	if (class) {
  		error = device_add_attributes(dev, class->dev_attrs);
f9f852df2   Kay Sievers   Driver core: add ...
376
  		if (error)
621a1672f   Dmitry Torokhov   driver core: Use ...
377
  			return error;
2620efef7   Greg Kroah-Hartman   Driver core: add ...
378
  	}
f9f852df2   Kay Sievers   Driver core: add ...
379

621a1672f   Dmitry Torokhov   driver core: Use ...
380
381
  	if (type) {
  		error = device_add_groups(dev, type->groups);
f9f852df2   Kay Sievers   Driver core: add ...
382
  		if (error)
621a1672f   Dmitry Torokhov   driver core: Use ...
383
  			goto err_remove_class_attrs;
f9f852df2   Kay Sievers   Driver core: add ...
384
  	}
621a1672f   Dmitry Torokhov   driver core: Use ...
385
386
387
388
389
390
391
392
393
394
395
396
  	error = device_add_groups(dev, dev->groups);
  	if (error)
  		goto err_remove_type_groups;
  
  	return 0;
  
   err_remove_type_groups:
  	if (type)
  		device_remove_groups(dev, type->groups);
   err_remove_class_attrs:
  	if (class)
  		device_remove_attributes(dev, class->dev_attrs);
2620efef7   Greg Kroah-Hartman   Driver core: add ...
397
398
399
400
401
402
  	return error;
  }
  
  static void device_remove_attrs(struct device *dev)
  {
  	struct class *class = dev->class;
f9f852df2   Kay Sievers   Driver core: add ...
403
  	struct device_type *type = dev->type;
2620efef7   Greg Kroah-Hartman   Driver core: add ...
404

621a1672f   Dmitry Torokhov   driver core: Use ...
405
  	device_remove_groups(dev, dev->groups);
f9f852df2   Kay Sievers   Driver core: add ...
406

621a1672f   Dmitry Torokhov   driver core: Use ...
407
408
409
410
411
  	if (type)
  		device_remove_groups(dev, type->groups);
  
  	if (class)
  		device_remove_attributes(dev, class->dev_attrs);
2620efef7   Greg Kroah-Hartman   Driver core: add ...
412
  }
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
413
414
415
416
417
  static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
  			char *buf)
  {
  	return print_dev_t(buf, dev->devt);
  }
ad6a1e1c6   Tejun Heo   driver-core: make...
418
419
  static struct device_attribute devt_attr =
  	__ATTR(dev, S_IRUGO, show_dev, NULL);
881c6cfd7   Greg Kroah-Hartman   kset: convert /sy...
420
421
  /* kset to create /sys/devices/  */
  struct kset *devices_kset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
424
425
426
   * device_create_file - create sysfs attribute file for device.
   * @dev: device.
   * @attr: device attribute descriptor.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
   */
26579ab70   Phil Carmody   Driver core: devi...
428
429
  int device_create_file(struct device *dev,
  		       const struct device_attribute *attr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
431
  {
  	int error = 0;
0c98b19fe   Cornelia Huck   Driver core: Remo...
432
  	if (dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
  		error = sysfs_create_file(&dev->kobj, &attr->attr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
435
436
437
  	return error;
  }
  
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
438
439
440
   * device_remove_file - remove sysfs attribute file.
   * @dev: device.
   * @attr: device attribute descriptor.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
   */
26579ab70   Phil Carmody   Driver core: devi...
442
443
  void device_remove_file(struct device *dev,
  			const struct device_attribute *attr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
  {
0c98b19fe   Cornelia Huck   Driver core: Remo...
445
  	if (dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  		sysfs_remove_file(&dev->kobj, &attr->attr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
  }
2589f1887   Greg Kroah-Hartman   Driver core: add ...
448
449
450
451
452
  /**
   * device_create_bin_file - create sysfs binary attribute file for device.
   * @dev: device.
   * @attr: device binary attribute descriptor.
   */
66ecb92be   Phil Carmody   Driver core: bin_...
453
454
  int device_create_bin_file(struct device *dev,
  			   const struct bin_attribute *attr)
2589f1887   Greg Kroah-Hartman   Driver core: add ...
455
456
457
458
459
460
461
462
463
464
465
466
467
  {
  	int error = -EINVAL;
  	if (dev)
  		error = sysfs_create_bin_file(&dev->kobj, attr);
  	return error;
  }
  EXPORT_SYMBOL_GPL(device_create_bin_file);
  
  /**
   * device_remove_bin_file - remove sysfs binary attribute file
   * @dev: device.
   * @attr: device binary attribute descriptor.
   */
66ecb92be   Phil Carmody   Driver core: bin_...
468
469
  void device_remove_bin_file(struct device *dev,
  			    const struct bin_attribute *attr)
2589f1887   Greg Kroah-Hartman   Driver core: add ...
470
471
472
473
474
  {
  	if (dev)
  		sysfs_remove_bin_file(&dev->kobj, attr);
  }
  EXPORT_SYMBOL_GPL(device_remove_bin_file);
d9a9cdfb0   Alan Stern   [PATCH] sysfs and...
475
  /**
523ded71d   Alan Stern   device_schedule_c...
476
   * device_schedule_callback_owner - helper to schedule a callback for a device
d9a9cdfb0   Alan Stern   [PATCH] sysfs and...
477
478
   * @dev: device.
   * @func: callback function to invoke later.
523ded71d   Alan Stern   device_schedule_c...
479
   * @owner: module owning the callback routine
d9a9cdfb0   Alan Stern   [PATCH] sysfs and...
480
481
482
483
484
485
486
487
488
489
   *
   * Attribute methods must not unregister themselves or their parent device
   * (which would amount to the same thing).  Attempts to do so will deadlock,
   * since unregistration is mutually exclusive with driver callbacks.
   *
   * Instead methods can call this routine, which will attempt to allocate
   * and schedule a workqueue request to call back @func with @dev as its
   * argument in the workqueue's process context.  @dev will be pinned until
   * @func returns.
   *
523ded71d   Alan Stern   device_schedule_c...
490
491
492
   * This routine is usually called via the inline device_schedule_callback(),
   * which automatically sets @owner to THIS_MODULE.
   *
d9a9cdfb0   Alan Stern   [PATCH] sysfs and...
493
   * Returns 0 if the request was submitted, -ENOMEM if storage could not
523ded71d   Alan Stern   device_schedule_c...
494
   * be allocated, -ENODEV if a reference to @owner isn't available.
d9a9cdfb0   Alan Stern   [PATCH] sysfs and...
495
496
497
498
499
   *
   * NOTE: This routine won't work if CONFIG_SYSFS isn't set!  It uses an
   * underlying sysfs routine (since it is intended for use by attribute
   * methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
   */
523ded71d   Alan Stern   device_schedule_c...
500
501
  int device_schedule_callback_owner(struct device *dev,
  		void (*func)(struct device *), struct module *owner)
d9a9cdfb0   Alan Stern   [PATCH] sysfs and...
502
503
  {
  	return sysfs_schedule_callback(&dev->kobj,
523ded71d   Alan Stern   device_schedule_c...
504
  			(void (*)(void *)) func, dev, owner);
d9a9cdfb0   Alan Stern   [PATCH] sysfs and...
505
  }
523ded71d   Alan Stern   device_schedule_c...
506
  EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
d9a9cdfb0   Alan Stern   [PATCH] sysfs and...
507

34bb61f9d   James Bottomley   [PATCH] fix klist...
508
509
  static void klist_children_get(struct klist_node *n)
  {
f791b8c83   Greg Kroah-Hartman   driver core: move...
510
511
  	struct device_private *p = to_device_private_parent(n);
  	struct device *dev = p->device;
34bb61f9d   James Bottomley   [PATCH] fix klist...
512
513
514
515
516
517
  
  	get_device(dev);
  }
  
  static void klist_children_put(struct klist_node *n)
  {
f791b8c83   Greg Kroah-Hartman   driver core: move...
518
519
  	struct device_private *p = to_device_private_parent(n);
  	struct device *dev = p->device;
34bb61f9d   James Bottomley   [PATCH] fix klist...
520
521
522
  
  	put_device(dev);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
524
525
   * device_initialize - init device structure.
   * @dev: device.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
   *
5739411ac   Cornelia Huck   Driver core: Clar...
527
528
   * This prepares the device for use by other layers by initializing
   * its fields.
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
529
   * It is the first half of device_register(), if called by
5739411ac   Cornelia Huck   Driver core: Clar...
530
531
532
533
534
535
536
   * that function, though it can also be called separately, so one
   * may use @dev's fields. In particular, get_device()/put_device()
   * may be used for reference counting of @dev after calling this
   * function.
   *
   * NOTE: Use put_device() to give up your reference instead of freeing
   * @dev directly once you have called this function.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
539
  void device_initialize(struct device *dev)
  {
881c6cfd7   Greg Kroah-Hartman   kset: convert /sy...
540
  	dev->kobj.kset = devices_kset;
f9cb074bf   Greg Kroah-Hartman   Kobject: rename k...
541
  	kobject_init(&dev->kobj, &device_ktype);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
  	INIT_LIST_HEAD(&dev->dma_pools);
3142788b7   Thomas Gleixner   drivers/base: Con...
543
  	mutex_init(&dev->mutex);
1704f47b5   Peter Zijlstra   lockdep: Add nova...
544
  	lockdep_set_novalidate_class(&dev->mutex);
9ac7849e3   Tejun Heo   devres: device re...
545
546
  	spin_lock_init(&dev->devres_lock);
  	INIT_LIST_HEAD(&dev->devres_head);
3b98aeaf3   Alan Stern   PM: don't skip de...
547
  	device_pm_init(dev);
873481367   Christoph Hellwig   [PATCH] add numa ...
548
  	set_dev_node(dev, -1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
549
  }
40fa54226   Greg Kroah-Hartman   Driver core: make...
550
  #ifdef CONFIG_SYSFS_DEPRECATED
da231fd5d   Kay Sievers   Driver core: fix ...
551
552
  static struct kobject *get_device_parent(struct device *dev,
  					 struct device *parent)
40fa54226   Greg Kroah-Hartman   Driver core: make...
553
  {
da231fd5d   Kay Sievers   Driver core: fix ...
554
  	/* class devices without a parent live in /sys/class/<classname>/ */
3eb215de2   Dmitry Torokhov   Driver core: fix ...
555
  	if (dev->class && (!parent || parent->class != dev->class))
1fbfee6c6   Greg Kroah-Hartman   class: rename "su...
556
  		return &dev->class->p->class_subsys.kobj;
da231fd5d   Kay Sievers   Driver core: fix ...
557
  	/* all other devices keep their parent */
40fa54226   Greg Kroah-Hartman   Driver core: make...
558
  	else if (parent)
c744aeae9   Cornelia Huck   driver core: Allo...
559
  		return &parent->kobj;
40fa54226   Greg Kroah-Hartman   Driver core: make...
560

c744aeae9   Cornelia Huck   driver core: Allo...
561
  	return NULL;
40fa54226   Greg Kroah-Hartman   Driver core: make...
562
  }
da231fd5d   Kay Sievers   Driver core: fix ...
563
564
  
  static inline void cleanup_device_parent(struct device *dev) {}
63b6971a0   Cornelia Huck   Driver core: Clea...
565
566
  static inline void cleanup_glue_dir(struct device *dev,
  				    struct kobject *glue_dir) {}
40fa54226   Greg Kroah-Hartman   Driver core: make...
567
  #else
864062457   Kay Sievers   driver core: fix ...
568
  static struct kobject *virtual_device_parent(struct device *dev)
f0ee61a6c   Greg Kroah-Hartman   Driver Core: Move...
569
  {
864062457   Kay Sievers   driver core: fix ...
570
  	static struct kobject *virtual_dir = NULL;
f0ee61a6c   Greg Kroah-Hartman   Driver Core: Move...
571

864062457   Kay Sievers   driver core: fix ...
572
  	if (!virtual_dir)
4ff6abff8   Greg Kroah-Hartman   kobject: get rid ...
573
  		virtual_dir = kobject_create_and_add("virtual",
881c6cfd7   Greg Kroah-Hartman   kset: convert /sy...
574
  						     &devices_kset->kobj);
f0ee61a6c   Greg Kroah-Hartman   Driver Core: Move...
575

864062457   Kay Sievers   driver core: fix ...
576
  	return virtual_dir;
f0ee61a6c   Greg Kroah-Hartman   Driver Core: Move...
577
  }
bc451f205   Eric W. Biederman   kobj: Add basic i...
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
  struct class_dir {
  	struct kobject kobj;
  	struct class *class;
  };
  
  #define to_class_dir(obj) container_of(obj, struct class_dir, kobj)
  
  static void class_dir_release(struct kobject *kobj)
  {
  	struct class_dir *dir = to_class_dir(kobj);
  	kfree(dir);
  }
  
  static const
  struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj)
40fa54226   Greg Kroah-Hartman   Driver core: make...
593
  {
bc451f205   Eric W. Biederman   kobj: Add basic i...
594
595
596
597
598
599
600
601
602
603
604
605
606
607
  	struct class_dir *dir = to_class_dir(kobj);
  	return dir->class->ns_type;
  }
  
  static struct kobj_type class_dir_ktype = {
  	.release	= class_dir_release,
  	.sysfs_ops	= &kobj_sysfs_ops,
  	.child_ns_type	= class_dir_child_ns_type
  };
  
  static struct kobject *
  class_dir_create_and_add(struct class *class, struct kobject *parent_kobj)
  {
  	struct class_dir *dir;
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
608
  	int retval;
bc451f205   Eric W. Biederman   kobj: Add basic i...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
  	dir = kzalloc(sizeof(*dir), GFP_KERNEL);
  	if (!dir)
  		return NULL;
  
  	dir->class = class;
  	kobject_init(&dir->kobj, &class_dir_ktype);
  
  	dir->kobj.kset = &class->p->class_dirs;
  
  	retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
  	if (retval < 0) {
  		kobject_put(&dir->kobj);
  		return NULL;
  	}
  	return &dir->kobj;
  }
  
  
  static struct kobject *get_device_parent(struct device *dev,
  					 struct device *parent)
  {
864062457   Kay Sievers   driver core: fix ...
630
  	if (dev->class) {
77d3d7c1d   Tejun Heo   driver-core: fix ...
631
  		static DEFINE_MUTEX(gdp_mutex);
864062457   Kay Sievers   driver core: fix ...
632
633
634
635
636
637
  		struct kobject *kobj = NULL;
  		struct kobject *parent_kobj;
  		struct kobject *k;
  
  		/*
  		 * If we have no parent, we live in "virtual".
0f4dafc05   Kay Sievers   Kobject: auto-cle...
638
639
  		 * Class-devices with a non class-device as parent, live
  		 * in a "glue" directory to prevent namespace collisions.
864062457   Kay Sievers   driver core: fix ...
640
641
642
  		 */
  		if (parent == NULL)
  			parent_kobj = virtual_device_parent(dev);
24b1442d0   Eric W. Biederman   Driver-core: Alwa...
643
  		else if (parent->class && !dev->class->ns_type)
864062457   Kay Sievers   driver core: fix ...
644
645
646
  			return &parent->kobj;
  		else
  			parent_kobj = &parent->kobj;
77d3d7c1d   Tejun Heo   driver-core: fix ...
647
  		mutex_lock(&gdp_mutex);
864062457   Kay Sievers   driver core: fix ...
648
  		/* find our class-directory at the parent and reference it */
7c71448b8   Greg Kroah-Hartman   class: move drive...
649
650
  		spin_lock(&dev->class->p->class_dirs.list_lock);
  		list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)
864062457   Kay Sievers   driver core: fix ...
651
652
653
654
  			if (k->parent == parent_kobj) {
  				kobj = kobject_get(k);
  				break;
  			}
7c71448b8   Greg Kroah-Hartman   class: move drive...
655
  		spin_unlock(&dev->class->p->class_dirs.list_lock);
77d3d7c1d   Tejun Heo   driver-core: fix ...
656
657
  		if (kobj) {
  			mutex_unlock(&gdp_mutex);
864062457   Kay Sievers   driver core: fix ...
658
  			return kobj;
77d3d7c1d   Tejun Heo   driver-core: fix ...
659
  		}
864062457   Kay Sievers   driver core: fix ...
660
661
  
  		/* or create a new class-directory at the parent device */
bc451f205   Eric W. Biederman   kobj: Add basic i...
662
  		k = class_dir_create_and_add(dev->class, parent_kobj);
0f4dafc05   Kay Sievers   Kobject: auto-cle...
663
  		/* do not emit an uevent for this simple "glue" directory */
77d3d7c1d   Tejun Heo   driver-core: fix ...
664
  		mutex_unlock(&gdp_mutex);
43968d2f1   Greg Kroah-Hartman   kobject: get rid ...
665
  		return k;
864062457   Kay Sievers   driver core: fix ...
666
667
668
  	}
  
  	if (parent)
c744aeae9   Cornelia Huck   driver core: Allo...
669
670
671
  		return &parent->kobj;
  	return NULL;
  }
da231fd5d   Kay Sievers   Driver core: fix ...
672

63b6971a0   Cornelia Huck   Driver core: Clea...
673
  static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
da231fd5d   Kay Sievers   Driver core: fix ...
674
  {
0f4dafc05   Kay Sievers   Kobject: auto-cle...
675
  	/* see if we live in a "glue" directory */
c1fe539a7   Cornelia Huck   Driver core: Fix ...
676
  	if (!glue_dir || !dev->class ||
7c71448b8   Greg Kroah-Hartman   class: move drive...
677
  	    glue_dir->kset != &dev->class->p->class_dirs)
da231fd5d   Kay Sievers   Driver core: fix ...
678
  		return;
0f4dafc05   Kay Sievers   Kobject: auto-cle...
679
  	kobject_put(glue_dir);
da231fd5d   Kay Sievers   Driver core: fix ...
680
  }
63b6971a0   Cornelia Huck   Driver core: Clea...
681
682
683
684
685
  
  static void cleanup_device_parent(struct device *dev)
  {
  	cleanup_glue_dir(dev, dev->kobj.parent);
  }
c744aeae9   Cornelia Huck   driver core: Allo...
686
  #endif
864062457   Kay Sievers   driver core: fix ...
687

63b6971a0   Cornelia Huck   Driver core: Clea...
688
  static void setup_parent(struct device *dev, struct device *parent)
c744aeae9   Cornelia Huck   driver core: Allo...
689
690
691
  {
  	struct kobject *kobj;
  	kobj = get_device_parent(dev, parent);
c744aeae9   Cornelia Huck   driver core: Allo...
692
693
  	if (kobj)
  		dev->kobj.parent = kobj;
40fa54226   Greg Kroah-Hartman   Driver core: make...
694
  }
40fa54226   Greg Kroah-Hartman   Driver core: make...
695

2ee97caf0   Cornelia Huck   Driver core: chec...
696
697
698
699
700
701
  static int device_add_class_symlinks(struct device *dev)
  {
  	int error;
  
  	if (!dev->class)
  		return 0;
da231fd5d   Kay Sievers   Driver core: fix ...
702

1fbfee6c6   Greg Kroah-Hartman   class: rename "su...
703
704
  	error = sysfs_create_link(&dev->kobj,
  				  &dev->class->p->class_subsys.kobj,
2ee97caf0   Cornelia Huck   Driver core: chec...
705
706
707
  				  "subsystem");
  	if (error)
  		goto out;
da231fd5d   Kay Sievers   Driver core: fix ...
708
709
710
  
  #ifdef CONFIG_SYSFS_DEPRECATED
  	/* stacked class devices need a symlink in the class directory */
1fbfee6c6   Greg Kroah-Hartman   class: rename "su...
711
  	if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
712
  	    device_is_not_partition(dev)) {
1fbfee6c6   Greg Kroah-Hartman   class: rename "su...
713
  		error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
1e0b2cf93   Kay Sievers   driver core: stru...
714
  					  &dev->kobj, dev_name(dev));
2ee97caf0   Cornelia Huck   Driver core: chec...
715
716
717
  		if (error)
  			goto out_subsys;
  	}
da231fd5d   Kay Sievers   Driver core: fix ...
718

4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
719
  	if (dev->parent && device_is_not_partition(dev)) {
da231fd5d   Kay Sievers   Driver core: fix ...
720
721
  		struct device *parent = dev->parent;
  		char *class_name;
4f01a757e   Dmitry Torokhov   Driver core: fix ...
722

da231fd5d   Kay Sievers   Driver core: fix ...
723
724
725
726
727
728
729
730
731
  		/*
  		 * stacked class devices have the 'device' link
  		 * pointing to the bus device instead of the parent
  		 */
  		while (parent->class && !parent->bus && parent->parent)
  			parent = parent->parent;
  
  		error = sysfs_create_link(&dev->kobj,
  					  &parent->kobj,
4f01a757e   Dmitry Torokhov   Driver core: fix ...
732
733
734
  					  "device");
  		if (error)
  			goto out_busid;
da231fd5d   Kay Sievers   Driver core: fix ...
735
736
737
738
739
740
741
742
743
  
  		class_name = make_class_name(dev->class->name,
  						&dev->kobj);
  		if (class_name)
  			error = sysfs_create_link(&dev->parent->kobj,
  						&dev->kobj, class_name);
  		kfree(class_name);
  		if (error)
  			goto out_device;
2ee97caf0   Cornelia Huck   Driver core: chec...
744
745
  	}
  	return 0;
2ee97caf0   Cornelia Huck   Driver core: chec...
746
  out_device:
4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
747
  	if (dev->parent && device_is_not_partition(dev))
2ee97caf0   Cornelia Huck   Driver core: chec...
748
  		sysfs_remove_link(&dev->kobj, "device");
2ee97caf0   Cornelia Huck   Driver core: chec...
749
  out_busid:
1fbfee6c6   Greg Kroah-Hartman   class: rename "su...
750
  	if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
751
  	    device_is_not_partition(dev))
f349cf347   Eric W. Biederman   driver core: Impl...
752
  		sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
1e0b2cf93   Kay Sievers   driver core: stru...
753
  				  dev_name(dev));
da231fd5d   Kay Sievers   Driver core: fix ...
754
755
  #else
  	/* link in the class directory pointing to the device */
1fbfee6c6   Greg Kroah-Hartman   class: rename "su...
756
  	error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
1e0b2cf93   Kay Sievers   driver core: stru...
757
  				  &dev->kobj, dev_name(dev));
da231fd5d   Kay Sievers   Driver core: fix ...
758
759
  	if (error)
  		goto out_subsys;
4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
760
  	if (dev->parent && device_is_not_partition(dev)) {
da231fd5d   Kay Sievers   Driver core: fix ...
761
762
763
764
765
766
767
768
  		error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
  					  "device");
  		if (error)
  			goto out_busid;
  	}
  	return 0;
  
  out_busid:
f349cf347   Eric W. Biederman   driver core: Impl...
769
  	sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
da231fd5d   Kay Sievers   Driver core: fix ...
770
  #endif
2ee97caf0   Cornelia Huck   Driver core: chec...
771
772
773
774
775
776
777
778
779
780
  out_subsys:
  	sysfs_remove_link(&dev->kobj, "subsystem");
  out:
  	return error;
  }
  
  static void device_remove_class_symlinks(struct device *dev)
  {
  	if (!dev->class)
  		return;
da231fd5d   Kay Sievers   Driver core: fix ...
781

2ee97caf0   Cornelia Huck   Driver core: chec...
782
  #ifdef CONFIG_SYSFS_DEPRECATED
4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
783
  	if (dev->parent && device_is_not_partition(dev)) {
2ee97caf0   Cornelia Huck   Driver core: chec...
784
785
786
787
788
789
790
  		char *class_name;
  
  		class_name = make_class_name(dev->class->name, &dev->kobj);
  		if (class_name) {
  			sysfs_remove_link(&dev->parent->kobj, class_name);
  			kfree(class_name);
  		}
2ee97caf0   Cornelia Huck   Driver core: chec...
791
792
  		sysfs_remove_link(&dev->kobj, "device");
  	}
da231fd5d   Kay Sievers   Driver core: fix ...
793

1fbfee6c6   Greg Kroah-Hartman   class: rename "su...
794
  	if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
795
  	    device_is_not_partition(dev))
f349cf347   Eric W. Biederman   driver core: Impl...
796
  		sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
1e0b2cf93   Kay Sievers   driver core: stru...
797
  				  dev_name(dev));
da231fd5d   Kay Sievers   Driver core: fix ...
798
  #else
4e886c296   Greg Kroah-Hartman   Driver core: Fix ...
799
  	if (dev->parent && device_is_not_partition(dev))
da231fd5d   Kay Sievers   Driver core: fix ...
800
  		sysfs_remove_link(&dev->kobj, "device");
f349cf347   Eric W. Biederman   driver core: Impl...
801
  	sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
da231fd5d   Kay Sievers   Driver core: fix ...
802
  #endif
2ee97caf0   Cornelia Huck   Driver core: chec...
803
804
  	sysfs_remove_link(&dev->kobj, "subsystem");
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
  /**
413c239fa   Stephen Rothwell   driver-core: prep...
806
807
   * dev_set_name - set a device name
   * @dev: device
462323661   Randy Dunlap   dev_set_name: fix...
808
   * @fmt: format string for the device's name
413c239fa   Stephen Rothwell   driver-core: prep...
809
810
811
812
   */
  int dev_set_name(struct device *dev, const char *fmt, ...)
  {
  	va_list vargs;
1fa5ae857   Kay Sievers   driver core: get ...
813
  	int err;
413c239fa   Stephen Rothwell   driver-core: prep...
814
815
  
  	va_start(vargs, fmt);
1fa5ae857   Kay Sievers   driver core: get ...
816
  	err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
413c239fa   Stephen Rothwell   driver-core: prep...
817
  	va_end(vargs);
1fa5ae857   Kay Sievers   driver core: get ...
818
  	return err;
413c239fa   Stephen Rothwell   driver-core: prep...
819
820
821
822
  }
  EXPORT_SYMBOL_GPL(dev_set_name);
  
  /**
e105b8bfc   Dan Williams   sysfs: add /sys/d...
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
   * device_to_dev_kobj - select a /sys/dev/ directory for the device
   * @dev: device
   *
   * By default we select char/ for new entries.  Setting class->dev_obj
   * to NULL prevents an entry from being created.  class->dev_kobj must
   * be set (or cleared) before any devices are registered to the class
   * otherwise device_create_sys_dev_entry() and
   * device_remove_sys_dev_entry() will disagree about the the presence
   * of the link.
   */
  static struct kobject *device_to_dev_kobj(struct device *dev)
  {
  	struct kobject *kobj;
  
  	if (dev->class)
  		kobj = dev->class->dev_kobj;
  	else
  		kobj = sysfs_dev_char_kobj;
  
  	return kobj;
  }
  
  static int device_create_sys_dev_entry(struct device *dev)
  {
  	struct kobject *kobj = device_to_dev_kobj(dev);
  	int error = 0;
  	char devt_str[15];
  
  	if (kobj) {
  		format_dev_t(devt_str, dev->devt);
  		error = sysfs_create_link(kobj, &dev->kobj, devt_str);
  	}
  
  	return error;
  }
  
  static void device_remove_sys_dev_entry(struct device *dev)
  {
  	struct kobject *kobj = device_to_dev_kobj(dev);
  	char devt_str[15];
  
  	if (kobj) {
  		format_dev_t(devt_str, dev->devt);
  		sysfs_remove_link(kobj, devt_str);
  	}
  }
b40284378   Greg Kroah-Hartman   Driver core: move...
869
870
871
872
873
874
875
876
877
878
  int device_private_init(struct device *dev)
  {
  	dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
  	if (!dev->p)
  		return -ENOMEM;
  	dev->p->device = dev;
  	klist_init(&dev->p->klist_children, klist_children_get,
  		   klist_children_put);
  	return 0;
  }
e105b8bfc   Dan Williams   sysfs: add /sys/d...
879
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
880
881
   * device_add - add device to device hierarchy.
   * @dev: device.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
883
884
   * This is part 2 of device_register(), though may be called
   * separately _iff_ device_initialize() has been called separately.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
   *
5739411ac   Cornelia Huck   Driver core: Clar...
886
   * This adds @dev to the kobject hierarchy via kobject_add(), adds it
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
887
888
   * to the global and sibling lists for the device, then
   * adds it to the other relevant subsystems of the driver model.
5739411ac   Cornelia Huck   Driver core: Clar...
889
890
891
892
   *
   * NOTE: _Never_ directly free @dev after calling this function, even
   * if it returned an error! Always use put_device() to give up your
   * reference instead.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
893
894
895
896
   */
  int device_add(struct device *dev)
  {
  	struct device *parent = NULL;
c47ed219b   Greg Kroah-Hartman   Class: add suppor...
897
  	struct class_interface *class_intf;
c906a48ad   Greg Kroah-Hartman   driver core: add ...
898
  	int error = -EINVAL;
775b64d2b   Rafael J. Wysocki   PM: Acquire devic...
899

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
900
  	dev = get_device(dev);
c906a48ad   Greg Kroah-Hartman   driver core: add ...
901
902
  	if (!dev)
  		goto done;
fb069a5d1   Greg Kroah-Hartman   driver core: crea...
903
  	if (!dev->p) {
b40284378   Greg Kroah-Hartman   Driver core: move...
904
905
906
  		error = device_private_init(dev);
  		if (error)
  			goto done;
fb069a5d1   Greg Kroah-Hartman   driver core: crea...
907
  	}
fb069a5d1   Greg Kroah-Hartman   driver core: crea...
908

1fa5ae857   Kay Sievers   driver core: get ...
909
910
911
912
913
914
  	/*
  	 * for statically allocated devices, which should all be converted
  	 * some day, we need to initialize the name. We prevent reading back
  	 * the name, and force the use of dev_name()
  	 */
  	if (dev->init_name) {
acc0e90fb   Greg Kroah-Hartman   driver core: fix ...
915
  		dev_set_name(dev, "%s", dev->init_name);
1fa5ae857   Kay Sievers   driver core: get ...
916
917
  		dev->init_name = NULL;
  	}
c906a48ad   Greg Kroah-Hartman   driver core: add ...
918

e6309e756   Thomas Gleixner   Driver-core: Fix ...
919
920
  	if (!dev_name(dev)) {
  		error = -EINVAL;
5c8563d77   Kay Sievers   Driver Core: do n...
921
  		goto name_error;
e6309e756   Thomas Gleixner   Driver-core: Fix ...
922
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
923

1e0b2cf93   Kay Sievers   driver core: stru...
924
925
  	pr_debug("device: '%s': %s
  ", dev_name(dev), __func__);
c205ef488   Greg Kroah-Hartman   Driver core: crea...
926

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
  	parent = get_device(dev->parent);
63b6971a0   Cornelia Huck   Driver core: Clea...
928
  	setup_parent(dev, parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929

0d358f22f   Yinghai Lu   driver core: try ...
930
931
932
  	/* use parent numa_node */
  	if (parent)
  		set_dev_node(dev, dev_to_node(parent));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
933
  	/* first, register with generic layer. */
8a577ffc7   Kay Sievers   driver: dont upda...
934
935
  	/* we require the name to be set before, and pass NULL */
  	error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
40fa54226   Greg Kroah-Hartman   Driver core: make...
936
  	if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
  		goto Error;
a7fd67062   Kay Sievers   [PATCH] add sysfs...
938

370226449   Brian Walsh   drivers/base: Pla...
939
940
941
  	/* notify platform of device entry */
  	if (platform_notify)
  		platform_notify(dev);
ad6a1e1c6   Tejun Heo   driver-core: make...
942
  	error = device_create_file(dev, &uevent_attr);
a306eea40   Cornelia Huck   driver core fixes...
943
944
  	if (error)
  		goto attrError;
a7fd67062   Kay Sievers   [PATCH] add sysfs...
945

23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
946
  	if (MAJOR(dev->devt)) {
ad6a1e1c6   Tejun Heo   driver-core: make...
947
948
  		error = device_create_file(dev, &devt_attr);
  		if (error)
a306eea40   Cornelia Huck   driver core fixes...
949
  			goto ueventattrError;
e105b8bfc   Dan Williams   sysfs: add /sys/d...
950
951
952
953
  
  		error = device_create_sys_dev_entry(dev);
  		if (error)
  			goto devtattrError;
2b2af54a5   Kay Sievers   Driver Core: devt...
954
955
  
  		devtmpfs_create_node(dev);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
956
  	}
2ee97caf0   Cornelia Huck   Driver core: chec...
957
958
959
  	error = device_add_class_symlinks(dev);
  	if (error)
  		goto SymlinkError;
dc0afa838   Cornelia Huck   Driver core: codi...
960
961
  	error = device_add_attrs(dev);
  	if (error)
2620efef7   Greg Kroah-Hartman   Driver core: add ...
962
  		goto AttrsError;
dc0afa838   Cornelia Huck   Driver core: codi...
963
964
  	error = bus_add_device(dev);
  	if (error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
965
  		goto BusError;
3b98aeaf3   Alan Stern   PM: don't skip de...
966
  	error = dpm_sysfs_add(dev);
57eee3d23   Rafael J. Wysocki   Driver core: Call...
967
  	if (error)
3b98aeaf3   Alan Stern   PM: don't skip de...
968
969
  		goto DPMError;
  	device_pm_add(dev);
ec0676ee2   Alan Stern   Driver core: move...
970
971
972
973
974
975
976
  
  	/* Notify clients of device addition.  This call must come
  	 * after dpm_sysf_add() and before kobject_uevent().
  	 */
  	if (dev->bus)
  		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
  					     BUS_NOTIFY_ADD_DEVICE, dev);
83b5fb4cc   Cornelia Huck   Driver core: supp...
977
  	kobject_uevent(&dev->kobj, KOBJ_ADD);
2023c610d   Alan Stern   Driver core: add ...
978
  	bus_probe_device(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979
  	if (parent)
f791b8c83   Greg Kroah-Hartman   driver core: move...
980
981
  		klist_add_tail(&dev->p->knode_parent,
  			       &parent->p->klist_children);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
982

5d9fd169c   Greg Kroah-Hartman   [PATCH] Driver co...
983
  	if (dev->class) {
f75b1c60f   Dave Young   class: change int...
984
  		mutex_lock(&dev->class->p->class_mutex);
c47ed219b   Greg Kroah-Hartman   Class: add suppor...
985
  		/* tie the class to the device */
5a3ceb861   Tejun Heo   driver-core: use ...
986
987
  		klist_add_tail(&dev->knode_class,
  			       &dev->class->p->class_devices);
c47ed219b   Greg Kroah-Hartman   Class: add suppor...
988
989
  
  		/* notify any interfaces that the device is here */
184f1f779   Greg Kroah-Hartman   class: rename "in...
990
991
  		list_for_each_entry(class_intf,
  				    &dev->class->p->class_interfaces, node)
c47ed219b   Greg Kroah-Hartman   Class: add suppor...
992
993
  			if (class_intf->add_dev)
  				class_intf->add_dev(dev, class_intf);
f75b1c60f   Dave Young   class: change int...
994
  		mutex_unlock(&dev->class->p->class_mutex);
5d9fd169c   Greg Kroah-Hartman   [PATCH] Driver co...
995
  	}
c906a48ad   Greg Kroah-Hartman   driver core: add ...
996
  done:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
998
  	put_device(dev);
  	return error;
3b98aeaf3   Alan Stern   PM: don't skip de...
999
   DPMError:
57eee3d23   Rafael J. Wysocki   Driver core: Call...
1000
1001
  	bus_remove_device(dev);
   BusError:
82f0cf9b7   James Simmons   Driver core: fix ...
1002
  	device_remove_attrs(dev);
2620efef7   Greg Kroah-Hartman   Driver core: add ...
1003
   AttrsError:
2ee97caf0   Cornelia Huck   Driver core: chec...
1004
1005
  	device_remove_class_symlinks(dev);
   SymlinkError:
ad6a1e1c6   Tejun Heo   driver-core: make...
1006
  	if (MAJOR(dev->devt))
ad72956df   Kay Sievers   Driver Core: devt...
1007
1008
  		devtmpfs_delete_node(dev);
  	if (MAJOR(dev->devt))
e105b8bfc   Dan Williams   sysfs: add /sys/d...
1009
1010
1011
  		device_remove_sys_dev_entry(dev);
   devtattrError:
  	if (MAJOR(dev->devt))
ad6a1e1c6   Tejun Heo   driver-core: make...
1012
  		device_remove_file(dev, &devt_attr);
a306eea40   Cornelia Huck   driver core fixes...
1013
   ueventattrError:
ad6a1e1c6   Tejun Heo   driver-core: make...
1014
  	device_remove_file(dev, &uevent_attr);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1015
   attrError:
312c004d3   Kay Sievers   [PATCH] driver co...
1016
  	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
1018
  	kobject_del(&dev->kobj);
   Error:
63b6971a0   Cornelia Huck   Driver core: Clea...
1019
  	cleanup_device_parent(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1020
1021
  	if (parent)
  		put_device(parent);
5c8563d77   Kay Sievers   Driver Core: do n...
1022
1023
1024
  name_error:
  	kfree(dev->p);
  	dev->p = NULL;
c906a48ad   Greg Kroah-Hartman   driver core: add ...
1025
  	goto done;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1027
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1028
1029
   * device_register - register a device with the system.
   * @dev: pointer to the device structure
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1030
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1031
1032
1033
1034
1035
1036
   * This happens in two clean steps - initialize the device
   * and add it to the system. The two steps can be called
   * separately, but this is the easiest and most common.
   * I.e. you should only call the two helpers separately if
   * have a clearly defined need to use and refcount the device
   * before it is added to the hierarchy.
5739411ac   Cornelia Huck   Driver core: Clar...
1037
1038
1039
1040
   *
   * NOTE: _Never_ directly free @dev after calling this function, even
   * if it returned an error! Always use put_device() to give up the
   * reference initialized in this function instead.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1042
1043
1044
1045
1046
  int device_register(struct device *dev)
  {
  	device_initialize(dev);
  	return device_add(dev);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1047
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1048
1049
   * get_device - increment reference count for device.
   * @dev: device.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1050
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1051
1052
1053
   * This simply forwards the call to kobject_get(), though
   * we do take care to provide for the case that we get a NULL
   * pointer passed in.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1054
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1055
  struct device *get_device(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1056
1057
1058
  {
  	return dev ? to_dev(kobject_get(&dev->kobj)) : NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1059
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1060
1061
   * put_device - decrement reference count.
   * @dev: device in question.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1062
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1063
  void put_device(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064
  {
edfaa7c36   Kay Sievers   Driver core: conv...
1065
  	/* might_sleep(); */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1066
1067
1068
  	if (dev)
  		kobject_put(&dev->kobj);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1069
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1070
1071
   * device_del - delete device from system.
   * @dev: device.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1072
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1073
1074
1075
1076
1077
   * This is the first part of the device unregistration
   * sequence. This removes the device from the lists we control
   * from here, has it removed from the other driver model
   * subsystems it was added to in device_add(), and removes it
   * from the kobject hierarchy.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1078
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1079
1080
   * NOTE: this should be called manually _iff_ device_add() was
   * also called manually.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1081
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1082
  void device_del(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1083
  {
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1084
  	struct device *parent = dev->parent;
c47ed219b   Greg Kroah-Hartman   Class: add suppor...
1085
  	struct class_interface *class_intf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1086

ec0676ee2   Alan Stern   Driver core: move...
1087
1088
1089
1090
1091
1092
  	/* Notify clients of device removal.  This call must come
  	 * before dpm_sysfs_remove().
  	 */
  	if (dev->bus)
  		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
  					     BUS_NOTIFY_DEL_DEVICE, dev);
775b64d2b   Rafael J. Wysocki   PM: Acquire devic...
1093
  	device_pm_remove(dev);
3b98aeaf3   Alan Stern   PM: don't skip de...
1094
  	dpm_sysfs_remove(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1095
  	if (parent)
f791b8c83   Greg Kroah-Hartman   driver core: move...
1096
  		klist_del(&dev->p->knode_parent);
e105b8bfc   Dan Williams   sysfs: add /sys/d...
1097
  	if (MAJOR(dev->devt)) {
2b2af54a5   Kay Sievers   Driver Core: devt...
1098
  		devtmpfs_delete_node(dev);
e105b8bfc   Dan Williams   sysfs: add /sys/d...
1099
  		device_remove_sys_dev_entry(dev);
ad6a1e1c6   Tejun Heo   driver-core: make...
1100
  		device_remove_file(dev, &devt_attr);
e105b8bfc   Dan Williams   sysfs: add /sys/d...
1101
  	}
b9d9c82b4   Kay Sievers   [PATCH] Driver co...
1102
  	if (dev->class) {
da231fd5d   Kay Sievers   Driver core: fix ...
1103
  		device_remove_class_symlinks(dev);
99ef3ef8d   Kay Sievers   CONFIG_SYSFS_DEPR...
1104

f75b1c60f   Dave Young   class: change int...
1105
  		mutex_lock(&dev->class->p->class_mutex);
c47ed219b   Greg Kroah-Hartman   Class: add suppor...
1106
  		/* notify any interfaces that the device is now gone */
184f1f779   Greg Kroah-Hartman   class: rename "in...
1107
1108
  		list_for_each_entry(class_intf,
  				    &dev->class->p->class_interfaces, node)
c47ed219b   Greg Kroah-Hartman   Class: add suppor...
1109
1110
1111
  			if (class_intf->remove_dev)
  				class_intf->remove_dev(dev, class_intf);
  		/* remove the device from the class list */
5a3ceb861   Tejun Heo   driver-core: use ...
1112
  		klist_del(&dev->knode_class);
f75b1c60f   Dave Young   class: change int...
1113
  		mutex_unlock(&dev->class->p->class_mutex);
b9d9c82b4   Kay Sievers   [PATCH] Driver co...
1114
  	}
ad6a1e1c6   Tejun Heo   driver-core: make...
1115
  	device_remove_file(dev, &uevent_attr);
2620efef7   Greg Kroah-Hartman   Driver core: add ...
1116
  	device_remove_attrs(dev);
289535334   Benjamin Herrenschmidt   Driver core: Call...
1117
  	bus_remove_device(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1118

2f8d16a99   Tejun Heo   devres: release r...
1119
1120
1121
1122
1123
1124
  	/*
  	 * Some platform devices are driven without driver attached
  	 * and managed resources may have been acquired.  Make sure
  	 * all resources are released.
  	 */
  	devres_release_all(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1125
1126
1127
1128
1129
  	/* Notify the platform of the removal, in case they
  	 * need to do anything...
  	 */
  	if (platform_notify_remove)
  		platform_notify_remove(dev);
312c004d3   Kay Sievers   [PATCH] driver co...
1130
  	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
da231fd5d   Kay Sievers   Driver core: fix ...
1131
  	cleanup_device_parent(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1132
  	kobject_del(&dev->kobj);
da231fd5d   Kay Sievers   Driver core: fix ...
1133
  	put_device(parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1134
1135
1136
  }
  
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1137
1138
   * device_unregister - unregister device from system.
   * @dev: device going away.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1139
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1140
1141
1142
1143
1144
1145
   * We do this in two parts, like we do device_register(). First,
   * we remove it from all the subsystems with device_del(), then
   * we decrement the reference count via put_device(). If that
   * is the final reference count, the device will be cleaned up
   * via device_release() above. Otherwise, the structure will
   * stick around until the final reference to the device is dropped.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1146
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1147
  void device_unregister(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1148
  {
1e0b2cf93   Kay Sievers   driver core: stru...
1149
1150
  	pr_debug("device: '%s': %s
  ", dev_name(dev), __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151
1152
1153
  	device_del(dev);
  	put_device(dev);
  }
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1154
  static struct device *next_device(struct klist_iter *i)
36239577c   Patrick Mochel   [PATCH] Use a kli...
1155
  {
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1156
  	struct klist_node *n = klist_next(i);
f791b8c83   Greg Kroah-Hartman   driver core: move...
1157
1158
1159
1160
1161
1162
1163
1164
  	struct device *dev = NULL;
  	struct device_private *p;
  
  	if (n) {
  		p = to_device_private_parent(n);
  		dev = p->device;
  	}
  	return dev;
36239577c   Patrick Mochel   [PATCH] Use a kli...
1165
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1166
  /**
e454cea20   Kay Sievers   Driver-Core: exte...
1167
   * device_get_devnode - path of device node file
6fcf53acc   Kay Sievers   Driver Core: add ...
1168
   * @dev: device
e454cea20   Kay Sievers   Driver-Core: exte...
1169
   * @mode: returned file access mode
6fcf53acc   Kay Sievers   Driver Core: add ...
1170
1171
1172
1173
1174
1175
1176
   * @tmp: possibly allocated string
   *
   * Return the relative path of a possible device node.
   * Non-default names may need to allocate a memory to compose
   * a name. This memory is returned in tmp and needs to be
   * freed by the caller.
   */
e454cea20   Kay Sievers   Driver-Core: exte...
1177
1178
  const char *device_get_devnode(struct device *dev,
  			       mode_t *mode, const char **tmp)
6fcf53acc   Kay Sievers   Driver Core: add ...
1179
1180
1181
1182
1183
1184
  {
  	char *s;
  
  	*tmp = NULL;
  
  	/* the device type may provide a specific name */
e454cea20   Kay Sievers   Driver-Core: exte...
1185
1186
  	if (dev->type && dev->type->devnode)
  		*tmp = dev->type->devnode(dev, mode);
6fcf53acc   Kay Sievers   Driver Core: add ...
1187
1188
1189
1190
  	if (*tmp)
  		return *tmp;
  
  	/* the class may provide a specific name */
e454cea20   Kay Sievers   Driver-Core: exte...
1191
1192
  	if (dev->class && dev->class->devnode)
  		*tmp = dev->class->devnode(dev, mode);
6fcf53acc   Kay Sievers   Driver Core: add ...
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
  	if (*tmp)
  		return *tmp;
  
  	/* return name without allocation, tmp == NULL */
  	if (strchr(dev_name(dev), '!') == NULL)
  		return dev_name(dev);
  
  	/* replace '!' in the name with '/' */
  	*tmp = kstrdup(dev_name(dev), GFP_KERNEL);
  	if (!*tmp)
  		return NULL;
  	while ((s = strchr(*tmp, '!')))
  		s[0] = '/';
  	return *tmp;
  }
  
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1210
1211
1212
1213
   * device_for_each_child - device child iterator.
   * @parent: parent struct device.
   * @data: data for the callback.
   * @fn: function to be called for each device.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1214
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1215
1216
   * Iterate over @parent's child devices, and call @fn for each,
   * passing it @data.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1217
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1218
1219
   * We check the return of @fn each time. If it returns anything
   * other than 0, we break out and return that value.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1220
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1221
1222
  int device_for_each_child(struct device *parent, void *data,
  			  int (*fn)(struct device *dev, void *data))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1223
  {
36239577c   Patrick Mochel   [PATCH] Use a kli...
1224
  	struct klist_iter i;
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1225
  	struct device *child;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1226
  	int error = 0;
014c90dbb   Greg Kroah-Hartman   driver core: prev...
1227
1228
  	if (!parent->p)
  		return 0;
f791b8c83   Greg Kroah-Hartman   driver core: move...
1229
  	klist_iter_init(&parent->p->klist_children, &i);
36239577c   Patrick Mochel   [PATCH] Use a kli...
1230
1231
1232
  	while ((child = next_device(&i)) && !error)
  		error = fn(child, data);
  	klist_iter_exit(&i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1233
1234
  	return error;
  }
5ab699810   Cornelia Huck   driver core: Intr...
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
  /**
   * device_find_child - device iterator for locating a particular device.
   * @parent: parent struct device
   * @data: Data to pass to match function
   * @match: Callback function to check device
   *
   * This is similar to the device_for_each_child() function above, but it
   * returns a reference to a device that is 'found' for later use, as
   * determined by the @match callback.
   *
   * The callback should return 0 if the device doesn't match and non-zero
   * if it does.  If the callback returns non-zero and a reference to the
   * current device can be obtained, this function will return to the caller
   * and not iterate over any more devices.
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1250
1251
  struct device *device_find_child(struct device *parent, void *data,
  				 int (*match)(struct device *dev, void *data))
5ab699810   Cornelia Huck   driver core: Intr...
1252
1253
1254
1255
1256
1257
  {
  	struct klist_iter i;
  	struct device *child;
  
  	if (!parent)
  		return NULL;
f791b8c83   Greg Kroah-Hartman   driver core: move...
1258
  	klist_iter_init(&parent->p->klist_children, &i);
5ab699810   Cornelia Huck   driver core: Intr...
1259
1260
1261
1262
1263
1264
  	while ((child = next_device(&i)))
  		if (match(child, data) && get_device(child))
  			break;
  	klist_iter_exit(&i);
  	return child;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1265
1266
  int __init devices_init(void)
  {
881c6cfd7   Greg Kroah-Hartman   kset: convert /sy...
1267
1268
1269
  	devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
  	if (!devices_kset)
  		return -ENOMEM;
e105b8bfc   Dan Williams   sysfs: add /sys/d...
1270
1271
1272
1273
1274
1275
1276
1277
1278
  	dev_kobj = kobject_create_and_add("dev", NULL);
  	if (!dev_kobj)
  		goto dev_kobj_err;
  	sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
  	if (!sysfs_dev_block_kobj)
  		goto block_kobj_err;
  	sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
  	if (!sysfs_dev_char_kobj)
  		goto char_kobj_err;
881c6cfd7   Greg Kroah-Hartman   kset: convert /sy...
1279
  	return 0;
e105b8bfc   Dan Williams   sysfs: add /sys/d...
1280
1281
1282
1283
1284
1285
1286
1287
  
   char_kobj_err:
  	kobject_put(sysfs_dev_block_kobj);
   block_kobj_err:
  	kobject_put(dev_kobj);
   dev_kobj_err:
  	kset_unregister(devices_kset);
  	return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1288
1289
1290
  }
  
  EXPORT_SYMBOL_GPL(device_for_each_child);
5ab699810   Cornelia Huck   driver core: Intr...
1291
  EXPORT_SYMBOL_GPL(device_find_child);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1292
1293
1294
1295
1296
1297
1298
1299
1300
  
  EXPORT_SYMBOL_GPL(device_initialize);
  EXPORT_SYMBOL_GPL(device_add);
  EXPORT_SYMBOL_GPL(device_register);
  
  EXPORT_SYMBOL_GPL(device_del);
  EXPORT_SYMBOL_GPL(device_unregister);
  EXPORT_SYMBOL_GPL(get_device);
  EXPORT_SYMBOL_GPL(put_device);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1301
1302
1303
  
  EXPORT_SYMBOL_GPL(device_create_file);
  EXPORT_SYMBOL_GPL(device_remove_file);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1304

0aa0dc41b   Mark McLoughlin   driver core: add ...
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
  struct root_device
  {
  	struct device dev;
  	struct module *owner;
  };
  
  #define to_root_device(dev) container_of(dev, struct root_device, dev)
  
  static void root_device_release(struct device *dev)
  {
  	kfree(to_root_device(dev));
  }
  
  /**
   * __root_device_register - allocate and register a root device
   * @name: root device name
   * @owner: owner module of the root device, usually THIS_MODULE
   *
   * This function allocates a root device and registers it
   * using device_register(). In order to free the returned
   * device, use root_device_unregister().
   *
   * Root devices are dummy devices which allow other devices
   * to be grouped under /sys/devices. Use this function to
   * allocate a root device and then use it as the parent of
   * any device which should appear under /sys/devices/{name}
   *
   * The /sys/devices/{name} directory will also contain a
   * 'module' symlink which points to the @owner directory
   * in sysfs.
   *
f0eae0ed3   Jani Nikula   driver-core: docu...
1336
1337
   * Returns &struct device pointer on success, or ERR_PTR() on error.
   *
0aa0dc41b   Mark McLoughlin   driver core: add ...
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
   * Note: You probably want to use root_device_register().
   */
  struct device *__root_device_register(const char *name, struct module *owner)
  {
  	struct root_device *root;
  	int err = -ENOMEM;
  
  	root = kzalloc(sizeof(struct root_device), GFP_KERNEL);
  	if (!root)
  		return ERR_PTR(err);
acc0e90fb   Greg Kroah-Hartman   driver core: fix ...
1348
  	err = dev_set_name(&root->dev, "%s", name);
0aa0dc41b   Mark McLoughlin   driver core: add ...
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
  	if (err) {
  		kfree(root);
  		return ERR_PTR(err);
  	}
  
  	root->dev.release = root_device_release;
  
  	err = device_register(&root->dev);
  	if (err) {
  		put_device(&root->dev);
  		return ERR_PTR(err);
  	}
1d9e882ba   Christoph Egger   driver-core: fix ...
1361
  #ifdef CONFIG_MODULES	/* gotta find a "cleaner" way to do this */
0aa0dc41b   Mark McLoughlin   driver core: add ...
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
  	if (owner) {
  		struct module_kobject *mk = &owner->mkobj;
  
  		err = sysfs_create_link(&root->dev.kobj, &mk->kobj, "module");
  		if (err) {
  			device_unregister(&root->dev);
  			return ERR_PTR(err);
  		}
  		root->owner = owner;
  	}
  #endif
  
  	return &root->dev;
  }
  EXPORT_SYMBOL_GPL(__root_device_register);
  
  /**
   * root_device_unregister - unregister and free a root device
7cbcf2254   Randy Dunlap   driver-core: fix ...
1380
   * @dev: device going away
0aa0dc41b   Mark McLoughlin   driver core: add ...
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
   *
   * This function unregisters and cleans up a device that was created by
   * root_device_register().
   */
  void root_device_unregister(struct device *dev)
  {
  	struct root_device *root = to_root_device(dev);
  
  	if (root->owner)
  		sysfs_remove_link(&root->dev.kobj, "module");
  
  	device_unregister(dev);
  }
  EXPORT_SYMBOL_GPL(root_device_unregister);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1395
1396
1397
  
  static void device_create_release(struct device *dev)
  {
1e0b2cf93   Kay Sievers   driver core: stru...
1398
1399
  	pr_debug("device: '%s': %s
  ", dev_name(dev), __func__);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1400
1401
1402
1403
  	kfree(dev);
  }
  
  /**
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1404
   * device_create_vargs - creates a device and registers it with sysfs
42734dafa   Henrik Kretzschmar   [PATCH] Driver co...
1405
1406
1407
   * @class: pointer to the struct class that this device should be registered to
   * @parent: pointer to the parent struct device of this new device, if any
   * @devt: the dev_t for the char device to be added
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1408
   * @drvdata: the data to be added to the device for callbacks
42734dafa   Henrik Kretzschmar   [PATCH] Driver co...
1409
   * @fmt: string for the device's name
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1410
   * @args: va_list for the device's name
42734dafa   Henrik Kretzschmar   [PATCH] Driver co...
1411
1412
1413
   *
   * This function can be used by char device classes.  A struct device
   * will be created in sysfs, registered to the specified class.
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1414
   *
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1415
1416
   * A "dev" file will be created, showing the dev_t for the device, if
   * the dev_t is not 0,0.
42734dafa   Henrik Kretzschmar   [PATCH] Driver co...
1417
1418
1419
1420
   * If a pointer to a parent struct device is passed in, the newly created
   * struct device will be a child of that device in sysfs.
   * The pointer to the struct device will be returned from the call.
   * Any further sysfs files that might be required can be created using this
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1421
1422
   * pointer.
   *
f0eae0ed3   Jani Nikula   driver-core: docu...
1423
1424
   * Returns &struct device pointer on success, or ERR_PTR() on error.
   *
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1425
1426
1427
   * Note: the struct class passed to this function must have previously
   * been created with a call to class_create().
   */
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1428
1429
1430
  struct device *device_create_vargs(struct class *class, struct device *parent,
  				   dev_t devt, void *drvdata, const char *fmt,
  				   va_list args)
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1431
  {
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1432
1433
1434
1435
1436
  	struct device *dev = NULL;
  	int retval = -ENODEV;
  
  	if (class == NULL || IS_ERR(class))
  		goto error;
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
  
  	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  	if (!dev) {
  		retval = -ENOMEM;
  		goto error;
  	}
  
  	dev->devt = devt;
  	dev->class = class;
  	dev->parent = parent;
  	dev->release = device_create_release;
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1448
  	dev_set_drvdata(dev, drvdata);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1449

1fa5ae857   Kay Sievers   driver core: get ...
1450
1451
1452
  	retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
  	if (retval)
  		goto error;
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1453
1454
1455
  	retval = device_register(dev);
  	if (retval)
  		goto error;
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1456
1457
1458
  	return dev;
  
  error:
286661b37   Cornelia Huck   Driver core: Fix ...
1459
  	put_device(dev);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1460
1461
  	return ERR_PTR(retval);
  }
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1462
1463
1464
  EXPORT_SYMBOL_GPL(device_create_vargs);
  
  /**
4e1067394   Greg Kroah-Hartman   device create: co...
1465
   * device_create - creates a device and registers it with sysfs
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
   * @class: pointer to the struct class that this device should be registered to
   * @parent: pointer to the parent struct device of this new device, if any
   * @devt: the dev_t for the char device to be added
   * @drvdata: the data to be added to the device for callbacks
   * @fmt: string for the device's name
   *
   * This function can be used by char device classes.  A struct device
   * will be created in sysfs, registered to the specified class.
   *
   * A "dev" file will be created, showing the dev_t for the device, if
   * the dev_t is not 0,0.
   * If a pointer to a parent struct device is passed in, the newly created
   * struct device will be a child of that device in sysfs.
   * The pointer to the struct device will be returned from the call.
   * Any further sysfs files that might be required can be created using this
   * pointer.
   *
f0eae0ed3   Jani Nikula   driver-core: docu...
1483
1484
   * Returns &struct device pointer on success, or ERR_PTR() on error.
   *
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1485
1486
1487
   * Note: the struct class passed to this function must have previously
   * been created with a call to class_create().
   */
4e1067394   Greg Kroah-Hartman   device create: co...
1488
1489
  struct device *device_create(struct class *class, struct device *parent,
  			     dev_t devt, void *drvdata, const char *fmt, ...)
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1490
1491
1492
1493
1494
1495
1496
1497
1498
  {
  	va_list vargs;
  	struct device *dev;
  
  	va_start(vargs, fmt);
  	dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
  	va_end(vargs);
  	return dev;
  }
4e1067394   Greg Kroah-Hartman   device create: co...
1499
  EXPORT_SYMBOL_GPL(device_create);
8882b3942   Greg Kroah-Hartman   Driver core: add ...
1500

cd35449b9   Dave Young   driver core: conv...
1501
  static int __match_devt(struct device *dev, void *data)
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1502
  {
cd35449b9   Dave Young   driver core: conv...
1503
  	dev_t *devt = data;
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1504

cd35449b9   Dave Young   driver core: conv...
1505
  	return dev->devt == *devt;
775b64d2b   Rafael J. Wysocki   PM: Acquire devic...
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
  }
  
  /**
   * device_destroy - removes a device that was created with device_create()
   * @class: pointer to the struct class that this device was registered with
   * @devt: the dev_t of the device that was previously registered
   *
   * This call unregisters and cleans up a device that was created with a
   * call to device_create().
   */
  void device_destroy(struct class *class, dev_t devt)
  {
  	struct device *dev;
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1519

695794ae0   Greg Kroah-Hartman   Driver Core: add ...
1520
  	dev = class_find_device(class, NULL, &devt, __match_devt);
cd35449b9   Dave Young   driver core: conv...
1521
1522
  	if (dev) {
  		put_device(dev);
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1523
  		device_unregister(dev);
cd35449b9   Dave Young   driver core: conv...
1524
  	}
23681e479   Greg Kroah-Hartman   [PATCH] Driver co...
1525
1526
  }
  EXPORT_SYMBOL_GPL(device_destroy);
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1527
1528
1529
1530
1531
  
  /**
   * device_rename - renames a device
   * @dev: the pointer to the struct device to be renamed
   * @new_name: the new name of the device
030c1d2bf   Eric W. Biederman   kobject: Fix kobj...
1532
1533
1534
1535
1536
   *
   * It is the responsibility of the caller to provide mutual
   * exclusion between two different calls of device_rename
   * on the same device to ensure that new_name is valid and
   * won't conflict with other devices.
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1537
1538
1539
1540
1541
   */
  int device_rename(struct device *dev, char *new_name)
  {
  	char *old_class_name = NULL;
  	char *new_class_name = NULL;
2ee97caf0   Cornelia Huck   Driver core: chec...
1542
  	char *old_device_name = NULL;
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1543
1544
1545
1546
1547
  	int error;
  
  	dev = get_device(dev);
  	if (!dev)
  		return -EINVAL;
1e0b2cf93   Kay Sievers   driver core: stru...
1548
1549
  	pr_debug("device: '%s': %s: renaming to '%s'
  ", dev_name(dev),
2b3a302a0   Harvey Harrison   driver core: repl...
1550
  		 __func__, new_name);
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1551

99ef3ef8d   Kay Sievers   CONFIG_SYSFS_DEPR...
1552
  #ifdef CONFIG_SYSFS_DEPRECATED
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1553
1554
  	if ((dev->class) && (dev->parent))
  		old_class_name = make_class_name(dev->class->name, &dev->kobj);
99ef3ef8d   Kay Sievers   CONFIG_SYSFS_DEPR...
1555
  #endif
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1556

1fa5ae857   Kay Sievers   driver core: get ...
1557
  	old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
2ee97caf0   Cornelia Huck   Driver core: chec...
1558
1559
1560
  	if (!old_device_name) {
  		error = -ENOMEM;
  		goto out;
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1561
  	}
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1562

f349cf347   Eric W. Biederman   driver core: Impl...
1563
1564
1565
1566
1567
1568
1569
1570
  #ifndef CONFIG_SYSFS_DEPRECATED
  	if (dev->class) {
  		error = sysfs_rename_link(&dev->class->p->class_subsys.kobj,
  			&dev->kobj, old_device_name, new_name);
  		if (error)
  			goto out;
  	}
  #endif
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1571
  	error = kobject_rename(&dev->kobj, new_name);
1fa5ae857   Kay Sievers   driver core: get ...
1572
  	if (error)
2ee97caf0   Cornelia Huck   Driver core: chec...
1573
  		goto out;
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1574

99ef3ef8d   Kay Sievers   CONFIG_SYSFS_DEPR...
1575
  #ifdef CONFIG_SYSFS_DEPRECATED
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1576
1577
1578
  	if (old_class_name) {
  		new_class_name = make_class_name(dev->class->name, &dev->kobj);
  		if (new_class_name) {
2354dcc72   Eric W. Biederman   driver core: Use ...
1579
1580
1581
1582
  			error = sysfs_rename_link(&dev->parent->kobj,
  						  &dev->kobj,
  						  old_class_name,
  						  new_class_name);
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1583
1584
  		}
  	}
60b8cabd8   Kay Sievers   Driver Core: fix ...
1585
  #endif
2ee97caf0   Cornelia Huck   Driver core: chec...
1586
  out:
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1587
  	put_device(dev);
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1588
  	kfree(new_class_name);
952ab431c   Jesper Juhl   Driver core: Don'...
1589
  	kfree(old_class_name);
2ee97caf0   Cornelia Huck   Driver core: chec...
1590
  	kfree(old_device_name);
a2de48cac   Greg Kroah-Hartman   Driver core: add ...
1591
1592
1593
  
  	return error;
  }
a2807dbcb   Johannes Berg   driver core: expo...
1594
  EXPORT_SYMBOL_GPL(device_rename);
8a82472f8   Cornelia Huck   driver core: Intr...
1595
1596
1597
1598
1599
  
  static int device_move_class_links(struct device *dev,
  				   struct device *old_parent,
  				   struct device *new_parent)
  {
f7f3461d8   Greg Kroah-Hartman   Driver core: add ...
1600
  	int error = 0;
8a82472f8   Cornelia Huck   driver core: Intr...
1601
  #ifdef CONFIG_SYSFS_DEPRECATED
8a82472f8   Cornelia Huck   driver core: Intr...
1602
1603
1604
1605
  	char *class_name;
  
  	class_name = make_class_name(dev->class->name, &dev->kobj);
  	if (!class_name) {
cb360bbf6   Cornelia Huck   driver core fixes...
1606
  		error = -ENOMEM;
8a82472f8   Cornelia Huck   driver core: Intr...
1607
1608
1609
1610
1611
1612
  		goto out;
  	}
  	if (old_parent) {
  		sysfs_remove_link(&dev->kobj, "device");
  		sysfs_remove_link(&old_parent->kobj, class_name);
  	}
c744aeae9   Cornelia Huck   driver core: Allo...
1613
1614
1615
1616
1617
1618
1619
1620
1621
  	if (new_parent) {
  		error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
  					  "device");
  		if (error)
  			goto out;
  		error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
  					  class_name);
  		if (error)
  			sysfs_remove_link(&dev->kobj, "device");
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1622
  	} else
c744aeae9   Cornelia Huck   driver core: Allo...
1623
  		error = 0;
8a82472f8   Cornelia Huck   driver core: Intr...
1624
1625
1626
1627
  out:
  	kfree(class_name);
  	return error;
  #else
f7f3461d8   Greg Kroah-Hartman   Driver core: add ...
1628
1629
1630
1631
1632
1633
  	if (old_parent)
  		sysfs_remove_link(&dev->kobj, "device");
  	if (new_parent)
  		error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
  					  "device");
  	return error;
8a82472f8   Cornelia Huck   driver core: Intr...
1634
1635
1636
1637
1638
1639
  #endif
  }
  
  /**
   * device_move - moves a device to a new parent
   * @dev: the pointer to the struct device to be moved
c744aeae9   Cornelia Huck   driver core: Allo...
1640
   * @new_parent: the new parent of the device (can by NULL)
ffa6a7054   Cornelia Huck   Driver core: Fix ...
1641
   * @dpm_order: how to reorder the dpm_list
8a82472f8   Cornelia Huck   driver core: Intr...
1642
   */
ffa6a7054   Cornelia Huck   Driver core: Fix ...
1643
1644
  int device_move(struct device *dev, struct device *new_parent,
  		enum dpm_order dpm_order)
8a82472f8   Cornelia Huck   driver core: Intr...
1645
1646
1647
  {
  	int error;
  	struct device *old_parent;
c744aeae9   Cornelia Huck   driver core: Allo...
1648
  	struct kobject *new_parent_kobj;
8a82472f8   Cornelia Huck   driver core: Intr...
1649
1650
1651
1652
  
  	dev = get_device(dev);
  	if (!dev)
  		return -EINVAL;
ffa6a7054   Cornelia Huck   Driver core: Fix ...
1653
  	device_pm_lock();
8a82472f8   Cornelia Huck   driver core: Intr...
1654
  	new_parent = get_device(new_parent);
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
1655
  	new_parent_kobj = get_device_parent(dev, new_parent);
63b6971a0   Cornelia Huck   Driver core: Clea...
1656

1e0b2cf93   Kay Sievers   driver core: stru...
1657
1658
1659
  	pr_debug("device: '%s': %s: moving to '%s'
  ", dev_name(dev),
  		 __func__, new_parent ? dev_name(new_parent) : "<NULL>");
c744aeae9   Cornelia Huck   driver core: Allo...
1660
  	error = kobject_move(&dev->kobj, new_parent_kobj);
8a82472f8   Cornelia Huck   driver core: Intr...
1661
  	if (error) {
63b6971a0   Cornelia Huck   Driver core: Clea...
1662
  		cleanup_glue_dir(dev, new_parent_kobj);
8a82472f8   Cornelia Huck   driver core: Intr...
1663
1664
1665
1666
1667
1668
  		put_device(new_parent);
  		goto out;
  	}
  	old_parent = dev->parent;
  	dev->parent = new_parent;
  	if (old_parent)
f791b8c83   Greg Kroah-Hartman   driver core: move...
1669
  		klist_remove(&dev->p->knode_parent);
0d358f22f   Yinghai Lu   driver core: try ...
1670
  	if (new_parent) {
f791b8c83   Greg Kroah-Hartman   driver core: move...
1671
1672
  		klist_add_tail(&dev->p->knode_parent,
  			       &new_parent->p->klist_children);
0d358f22f   Yinghai Lu   driver core: try ...
1673
1674
  		set_dev_node(dev, dev_to_node(new_parent));
  	}
8a82472f8   Cornelia Huck   driver core: Intr...
1675
1676
1677
1678
1679
1680
1681
  	if (!dev->class)
  		goto out_put;
  	error = device_move_class_links(dev, old_parent, new_parent);
  	if (error) {
  		/* We ignore errors on cleanup since we're hosed anyway... */
  		device_move_class_links(dev, new_parent, old_parent);
  		if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
c744aeae9   Cornelia Huck   driver core: Allo...
1682
  			if (new_parent)
f791b8c83   Greg Kroah-Hartman   driver core: move...
1683
  				klist_remove(&dev->p->knode_parent);
0d358f22f   Yinghai Lu   driver core: try ...
1684
1685
  			dev->parent = old_parent;
  			if (old_parent) {
f791b8c83   Greg Kroah-Hartman   driver core: move...
1686
1687
  				klist_add_tail(&dev->p->knode_parent,
  					       &old_parent->p->klist_children);
0d358f22f   Yinghai Lu   driver core: try ...
1688
1689
  				set_dev_node(dev, dev_to_node(old_parent));
  			}
8a82472f8   Cornelia Huck   driver core: Intr...
1690
  		}
63b6971a0   Cornelia Huck   Driver core: Clea...
1691
  		cleanup_glue_dir(dev, new_parent_kobj);
8a82472f8   Cornelia Huck   driver core: Intr...
1692
1693
1694
  		put_device(new_parent);
  		goto out;
  	}
ffa6a7054   Cornelia Huck   Driver core: Fix ...
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
  	switch (dpm_order) {
  	case DPM_ORDER_NONE:
  		break;
  	case DPM_ORDER_DEV_AFTER_PARENT:
  		device_pm_move_after(dev, new_parent);
  		break;
  	case DPM_ORDER_PARENT_BEFORE_DEV:
  		device_pm_move_before(new_parent, dev);
  		break;
  	case DPM_ORDER_DEV_LAST:
  		device_pm_move_last(dev);
  		break;
  	}
8a82472f8   Cornelia Huck   driver core: Intr...
1708
1709
1710
  out_put:
  	put_device(old_parent);
  out:
ffa6a7054   Cornelia Huck   Driver core: Fix ...
1711
  	device_pm_unlock();
8a82472f8   Cornelia Huck   driver core: Intr...
1712
1713
1714
  	put_device(dev);
  	return error;
  }
8a82472f8   Cornelia Huck   driver core: Intr...
1715
  EXPORT_SYMBOL_GPL(device_move);
37b0c0203   Greg Kroah-Hartman   driver core: clea...
1716
1717
1718
1719
1720
1721
  
  /**
   * device_shutdown - call ->shutdown() on each device to shutdown.
   */
  void device_shutdown(void)
  {
6245838fe   Hugh Daschbach   Driver core: Prot...
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
  	struct device *dev;
  
  	spin_lock(&devices_kset->list_lock);
  	/*
  	 * Walk the devices list backward, shutting down each in turn.
  	 * Beware that device unplug events may also start pulling
  	 * devices offline, even as the system is shutting down.
  	 */
  	while (!list_empty(&devices_kset->list)) {
  		dev = list_entry(devices_kset->list.prev, struct device,
  				kobj.entry);
  		get_device(dev);
  		/*
  		 * Make sure the device is off the kset list, in the
  		 * event that dev->*->shutdown() doesn't remove it.
  		 */
  		list_del_init(&dev->kobj.entry);
  		spin_unlock(&devices_kset->list_lock);
37b0c0203   Greg Kroah-Hartman   driver core: clea...
1740

37b0c0203   Greg Kroah-Hartman   driver core: clea...
1741
1742
1743
1744
1745
1746
1747
1748
1749
  		if (dev->bus && dev->bus->shutdown) {
  			dev_dbg(dev, "shutdown
  ");
  			dev->bus->shutdown(dev);
  		} else if (dev->driver && dev->driver->shutdown) {
  			dev_dbg(dev, "shutdown
  ");
  			dev->driver->shutdown(dev);
  		}
6245838fe   Hugh Daschbach   Driver core: Prot...
1750
1751
1752
  		put_device(dev);
  
  		spin_lock(&devices_kset->list_lock);
37b0c0203   Greg Kroah-Hartman   driver core: clea...
1753
  	}
6245838fe   Hugh Daschbach   Driver core: Prot...
1754
  	spin_unlock(&devices_kset->list_lock);
401097ea4   Shaohua Li   driver core: sync...
1755
  	async_synchronize_full();
37b0c0203   Greg Kroah-Hartman   driver core: clea...
1756
  }
99bcf2171   Joe Perches   device.h drivers/...
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
  
  /*
   * Device logging functions
   */
  
  #ifdef CONFIG_PRINTK
  
  static int __dev_printk(const char *level, const struct device *dev,
  			struct va_format *vaf)
  {
  	if (!dev)
  		return printk("%s(NULL device *): %pV", level, vaf);
  
  	return printk("%s%s %s: %pV",
  		      level, dev_driver_string(dev), dev_name(dev), vaf);
  }
  
  int dev_printk(const char *level, const struct device *dev,
  	       const char *fmt, ...)
  {
  	struct va_format vaf;
  	va_list args;
  	int r;
  
  	va_start(args, fmt);
  
  	vaf.fmt = fmt;
  	vaf.va = &args;
  
  	r = __dev_printk(level, dev, &vaf);
  	va_end(args);
  
  	return r;
  }
  EXPORT_SYMBOL(dev_printk);
  
  #define define_dev_printk_level(func, kern_level)		\
  int func(const struct device *dev, const char *fmt, ...)	\
  {								\
  	struct va_format vaf;					\
  	va_list args;						\
  	int r;							\
  								\
  	va_start(args, fmt);					\
  								\
  	vaf.fmt = fmt;						\
  	vaf.va = &args;						\
  								\
  	r = __dev_printk(kern_level, dev, &vaf);		\
  	va_end(args);						\
  								\
  	return r;						\
  }								\
  EXPORT_SYMBOL(func);
  
  define_dev_printk_level(dev_emerg, KERN_EMERG);
  define_dev_printk_level(dev_alert, KERN_ALERT);
  define_dev_printk_level(dev_crit, KERN_CRIT);
  define_dev_printk_level(dev_err, KERN_ERR);
  define_dev_printk_level(dev_warn, KERN_WARNING);
  define_dev_printk_level(dev_notice, KERN_NOTICE);
  define_dev_printk_level(_dev_info, KERN_INFO);
  
  #endif