Blame view

drivers/base/dd.c 10.3 KB
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
1
  /*
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
2
   * drivers/base/dd.c - The core device/driver interactions.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
3
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
4
5
6
   * This file contains the (sometimes tricky) code that controls the
   * interactions between devices and drivers, which primarily includes
   * driver binding and unbinding.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
7
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
8
9
10
   * All of this code used to exist in drivers/base/bus.c, but was
   * relocated to here in the name of compartmentalization (since it wasn't
   * strictly code just for the 'struct bus_type'.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
11
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
12
13
   * Copyright (c) 2002-5 Patrick Mochel
   * Copyright (c) 2002-3 Open Source Development Labs
b40284378   Greg Kroah-Hartman   Driver core: move...
14
15
   * Copyright (c) 2007-2009 Greg Kroah-Hartman <gregkh@suse.de>
   * Copyright (c) 2007-2009 Novell Inc.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
16
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
17
   * This file is released under the GPLv2
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
18
19
20
   */
  
  #include <linux/device.h>
216773a78   Arjan van de Ven   Consolidate drive...
21
  #include <linux/delay.h>
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
22
  #include <linux/module.h>
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
23
  #include <linux/kthread.h>
735a7ffb7   Andrew Morton   [PATCH] drivers: ...
24
  #include <linux/wait.h>
216773a78   Arjan van de Ven   Consolidate drive...
25
  #include <linux/async.h>
5e928f77a   Rafael J. Wysocki   PM: Introduce cor...
26
  #include <linux/pm_runtime.h>
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
27
28
29
  
  #include "base.h"
  #include "power/power.h"
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
30

1901fb260   Kay Sievers   Driver core: fix ...
31
  static void driver_bound(struct device *dev)
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
32
  {
8940b4f31   Greg Kroah-Hartman   driver core: move...
33
  	if (klist_node_attached(&dev->p->knode_driver)) {
f86db396f   Andrew Morton   drivers/base: che...
34
35
  		printk(KERN_WARNING "%s: device %s already bound
  ",
2b3a302a0   Harvey Harrison   driver core: repl...
36
  			__func__, kobject_name(&dev->kobj));
1901fb260   Kay Sievers   Driver core: fix ...
37
  		return;
f86db396f   Andrew Morton   drivers/base: che...
38
  	}
4c898c7f2   Daniel Ritz   [PATCH] Driver Co...
39

1e0b2cf93   Kay Sievers   driver core: stru...
40
41
  	pr_debug("driver: '%s': %s: bound to device '%s'
  ", dev_name(dev),
2b3a302a0   Harvey Harrison   driver core: repl...
42
  		 __func__, dev->driver->name);
116af3782   Benjamin Herrenschmidt   Driver core: add ...
43

fbb88fadf   Stefani Seibold   driver-core: fix ...
44
  	klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
116af3782   Benjamin Herrenschmidt   Driver core: add ...
45
  	if (dev->bus)
c6f7e72a3   Greg Kroah-Hartman   driver core: remo...
46
  		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
116af3782   Benjamin Herrenschmidt   Driver core: add ...
47
  					     BUS_NOTIFY_BOUND_DRIVER, dev);
1901fb260   Kay Sievers   Driver core: fix ...
48
49
50
51
52
  }
  
  static int driver_sysfs_add(struct device *dev)
  {
  	int ret;
45daef0fd   Magnus Damm   Driver core: Add ...
53
54
55
  	if (dev->bus)
  		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
  					     BUS_NOTIFY_BIND_DRIVER, dev);
e5dd12784   Greg Kroah-Hartman   Driver core: move...
56
  	ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
57
  			  kobject_name(&dev->kobj));
f86db396f   Andrew Morton   drivers/base: che...
58
  	if (ret == 0) {
e5dd12784   Greg Kroah-Hartman   Driver core: move...
59
  		ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj,
f86db396f   Andrew Morton   drivers/base: che...
60
61
  					"driver");
  		if (ret)
e5dd12784   Greg Kroah-Hartman   Driver core: move...
62
  			sysfs_remove_link(&dev->driver->p->kobj,
f86db396f   Andrew Morton   drivers/base: che...
63
64
65
  					kobject_name(&dev->kobj));
  	}
  	return ret;
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
66
  }
1901fb260   Kay Sievers   Driver core: fix ...
67
68
69
70
71
  static void driver_sysfs_remove(struct device *dev)
  {
  	struct device_driver *drv = dev->driver;
  
  	if (drv) {
e5dd12784   Greg Kroah-Hartman   Driver core: move...
72
  		sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj));
1901fb260   Kay Sievers   Driver core: fix ...
73
74
75
76
77
  		sysfs_remove_link(&dev->kobj, "driver");
  	}
  }
  
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
78
79
   * device_bind_driver - bind a driver to one device.
   * @dev: device.
1901fb260   Kay Sievers   Driver core: fix ...
80
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
81
82
   * Allow manual attachment of a driver to a device.
   * Caller must have already set @dev->driver.
1901fb260   Kay Sievers   Driver core: fix ...
83
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
84
85
86
87
   * Note that this does not modify the bus reference count
   * nor take the bus's rwsem. Please verify those are accounted
   * for before calling this. (It is ok to call with no other effort
   * from a driver's probe() method.)
1901fb260   Kay Sievers   Driver core: fix ...
88
   *
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
89
   * This function must be called with the device lock held.
1901fb260   Kay Sievers   Driver core: fix ...
90
91
92
   */
  int device_bind_driver(struct device *dev)
  {
cb986b749   Cornelia Huck   driver core: Chan...
93
94
95
96
97
98
  	int ret;
  
  	ret = driver_sysfs_add(dev);
  	if (!ret)
  		driver_bound(dev);
  	return ret;
1901fb260   Kay Sievers   Driver core: fix ...
99
  }
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
100
  EXPORT_SYMBOL_GPL(device_bind_driver);
1901fb260   Kay Sievers   Driver core: fix ...
101

d779249ed   Greg Kroah-Hartman   Driver Core: add ...
102
  static atomic_t probe_count = ATOMIC_INIT(0);
735a7ffb7   Andrew Morton   [PATCH] drivers: ...
103
  static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
21c7f30b1   Cornelia Huck   driver core: per-...
104
  static int really_probe(struct device *dev, struct device_driver *drv)
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
105
  {
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
106
  	int ret = 0;
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
107

d779249ed   Greg Kroah-Hartman   Driver Core: add ...
108
  	atomic_inc(&probe_count);
7dc72b284   Greg Kroah-Hartman   Driver core: clea...
109
110
  	pr_debug("bus: '%s': %s: probing driver %s with device %s
  ",
1e0b2cf93   Kay Sievers   driver core: stru...
111
  		 drv->bus->name, __func__, drv->name, dev_name(dev));
9ac7849e3   Tejun Heo   devres: device re...
112
  	WARN_ON(!list_empty(&dev->devres_head));
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
113

07e4a3e27   Patrick Mochel   [PATCH] Move devi...
114
  	dev->driver = drv;
1901fb260   Kay Sievers   Driver core: fix ...
115
116
117
  	if (driver_sysfs_add(dev)) {
  		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed
  ",
1e0b2cf93   Kay Sievers   driver core: stru...
118
  			__func__, dev_name(dev));
1901fb260   Kay Sievers   Driver core: fix ...
119
120
  		goto probe_failed;
  	}
594c8281f   Russell King   [PATCH] Add bus_t...
121
122
  	if (dev->bus->probe) {
  		ret = dev->bus->probe(dev);
1901fb260   Kay Sievers   Driver core: fix ...
123
  		if (ret)
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
124
  			goto probe_failed;
594c8281f   Russell King   [PATCH] Add bus_t...
125
  	} else if (drv->probe) {
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
126
  		ret = drv->probe(dev);
1901fb260   Kay Sievers   Driver core: fix ...
127
  		if (ret)
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
128
  			goto probe_failed;
f86db396f   Andrew Morton   drivers/base: che...
129
  	}
1901fb260   Kay Sievers   Driver core: fix ...
130
131
  
  	driver_bound(dev);
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
132
  	ret = 1;
7dc72b284   Greg Kroah-Hartman   Driver core: clea...
133
134
  	pr_debug("bus: '%s': %s: bound device %s to driver %s
  ",
1e0b2cf93   Kay Sievers   driver core: stru...
135
  		 drv->bus->name, __func__, dev_name(dev), drv->name);
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
136
  	goto done;
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
137

d779249ed   Greg Kroah-Hartman   Driver Core: add ...
138
  probe_failed:
9ac7849e3   Tejun Heo   devres: device re...
139
  	devres_release_all(dev);
1901fb260   Kay Sievers   Driver core: fix ...
140
141
  	driver_sysfs_remove(dev);
  	dev->driver = NULL;
c578abbc2   Cornelia Huck   driver core: Don'...
142
  	if (ret != -ENODEV && ret != -ENXIO) {
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
143
144
145
146
  		/* driver matched but the probe failed */
  		printk(KERN_WARNING
  		       "%s: probe of %s failed with error %d
  ",
1e0b2cf93   Kay Sievers   driver core: stru...
147
  		       drv->name, dev_name(dev), ret);
bcbe4f94d   Wolfram Sang   drivers: base: pr...
148
149
150
151
  	} else {
  		pr_debug("%s: probe of %s rejects match %d
  ",
  		       drv->name, dev_name(dev), ret);
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
152
  	}
c578abbc2   Cornelia Huck   driver core: Don'...
153
154
155
156
157
  	/*
  	 * Ignore errors returned by ->probe so that the next driver can try
  	 * its luck.
  	 */
  	ret = 0;
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
158
  done:
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
159
  	atomic_dec(&probe_count);
735a7ffb7   Andrew Morton   [PATCH] drivers: ...
160
  	wake_up(&probe_waitqueue);
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
161
162
163
164
165
166
167
168
169
170
171
  	return ret;
  }
  
  /**
   * driver_probe_done
   * Determine if the probe sequence is finished or not.
   *
   * Should somehow figure out how to use a semaphore, not an atomic variable...
   */
  int driver_probe_done(void)
  {
2b3a302a0   Harvey Harrison   driver core: repl...
172
173
  	pr_debug("%s: probe_count = %d
  ", __func__,
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
174
175
176
177
178
179
180
  		 atomic_read(&probe_count));
  	if (atomic_read(&probe_count))
  		return -EBUSY;
  	return 0;
  }
  
  /**
216773a78   Arjan van de Ven   Consolidate drive...
181
182
   * wait_for_device_probe
   * Wait for device probing to be completed.
216773a78   Arjan van de Ven   Consolidate drive...
183
   */
b23530ebc   Ming Lei   driver core: remo...
184
  void wait_for_device_probe(void)
216773a78   Arjan van de Ven   Consolidate drive...
185
186
  {
  	/* wait for the known devices to complete their probing */
b23530ebc   Ming Lei   driver core: remo...
187
  	wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
216773a78   Arjan van de Ven   Consolidate drive...
188
  	async_synchronize_full();
216773a78   Arjan van de Ven   Consolidate drive...
189
  }
d4d5291c8   Arjan van de Ven   driver synchroniz...
190
  EXPORT_SYMBOL_GPL(wait_for_device_probe);
216773a78   Arjan van de Ven   Consolidate drive...
191
192
  
  /**
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
193
194
195
196
   * driver_probe_device - attempt to bind device & driver together
   * @drv: driver to bind a device to
   * @dev: device to try to bind to the driver
   *
49b420a13   Ming Lei   driver core: chec...
197
   * This function returns -ENODEV if the device is not registered,
af901ca18   André Goddard Rosa   tree-wide: fix as...
198
   * 1 if the device is bound successfully and 0 otherwise.
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
199
   *
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
200
201
   * This function must be called with @dev lock held.  When called for a
   * USB interface, @dev->parent lock must be held as well.
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
202
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
203
  int driver_probe_device(struct device_driver *drv, struct device *dev)
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
204
  {
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
205
  	int ret = 0;
f2eaae197   Alan Stern   Driver core: Fix ...
206
207
  	if (!device_is_registered(dev))
  		return -ENODEV;
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
208

7dc72b284   Greg Kroah-Hartman   Driver core: clea...
209
210
  	pr_debug("bus: '%s': %s: matched device %s with driver %s
  ",
1e0b2cf93   Kay Sievers   driver core: stru...
211
  		 drv->bus->name, __func__, dev_name(dev), drv->name);
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
212

5e928f77a   Rafael J. Wysocki   PM: Introduce cor...
213
214
  	pm_runtime_get_noresume(dev);
  	pm_runtime_barrier(dev);
21c7f30b1   Cornelia Huck   driver core: per-...
215
  	ret = really_probe(dev, drv);
5e928f77a   Rafael J. Wysocki   PM: Introduce cor...
216
  	pm_runtime_put_sync(dev);
d779249ed   Greg Kroah-Hartman   Driver Core: add ...
217

0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
218
  	return ret;
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
219
  }
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
220
  static int __device_attach(struct device_driver *drv, void *data)
2287c322b   Patrick Mochel   [PATCH] Use bus_f...
221
  {
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
222
  	struct device *dev = data;
49b420a13   Ming Lei   driver core: chec...
223
224
225
  
  	if (!driver_match_device(drv, dev))
  		return 0;
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
226
  	return driver_probe_device(drv, dev);
2287c322b   Patrick Mochel   [PATCH] Use bus_f...
227
  }
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
228
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
229
230
   * device_attach - try to attach device to a driver.
   * @dev: device.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
231
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
232
233
234
   * Walk the list of drivers that the bus has and call
   * driver_probe_device() for each pair. If a compatible
   * pair is found, break out and return.
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
235
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
236
   * Returns 1 if the device was bound to a driver;
59a3cd7f9   Dmitry Torokhov   Driver core: fix ...
237
   * 0 if no matching driver was found;
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
238
   * -ENODEV if the device is not registered.
bf74ad5bc   Alan Stern   [PATCH] Hold the ...
239
   *
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
240
   * When called for a USB interface, @dev->parent lock must be held.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
241
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
242
  int device_attach(struct device *dev)
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
243
  {
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
244
  	int ret = 0;
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
245
  	device_lock(dev);
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
246
  	if (dev->driver) {
8497d6a21   Sebastian Ott   driver-core: fix ...
247
248
249
250
  		if (klist_node_attached(&dev->p->knode_driver)) {
  			ret = 1;
  			goto out_unlock;
  		}
f86db396f   Andrew Morton   drivers/base: che...
251
252
253
  		ret = device_bind_driver(dev);
  		if (ret == 0)
  			ret = 1;
c6a46696f   Cornelia Huck   driver core: don'...
254
255
256
257
  		else {
  			dev->driver = NULL;
  			ret = 0;
  		}
21c7f30b1   Cornelia Huck   driver core: per-...
258
  	} else {
5e928f77a   Rafael J. Wysocki   PM: Introduce cor...
259
  		pm_runtime_get_noresume(dev);
5adc55da4   Adrian Bunk   PCI: remove the b...
260
  		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
5e928f77a   Rafael J. Wysocki   PM: Introduce cor...
261
  		pm_runtime_put_sync(dev);
21c7f30b1   Cornelia Huck   driver core: per-...
262
  	}
8497d6a21   Sebastian Ott   driver-core: fix ...
263
  out_unlock:
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
264
  	device_unlock(dev);
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
265
  	return ret;
2287c322b   Patrick Mochel   [PATCH] Use bus_f...
266
  }
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
267
  EXPORT_SYMBOL_GPL(device_attach);
2287c322b   Patrick Mochel   [PATCH] Use bus_f...
268

4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
269
  static int __driver_attach(struct device *dev, void *data)
2287c322b   Patrick Mochel   [PATCH] Use bus_f...
270
  {
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
271
  	struct device_driver *drv = data;
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
272
273
274
275
276
277
278
279
280
281
  
  	/*
  	 * Lock device and try to bind to it. We drop the error
  	 * here and always return 0, because we need to keep trying
  	 * to bind to devices and some drivers will return an error
  	 * simply if it didn't support the device.
  	 *
  	 * driver_probe_device() will spit a warning if there
  	 * is an error.
  	 */
49b420a13   Ming Lei   driver core: chec...
282
  	if (!driver_match_device(drv, dev))
6cd495860   Arjan van de Ven   device model: Do ...
283
  		return 0;
bf74ad5bc   Alan Stern   [PATCH] Hold the ...
284
  	if (dev->parent)	/* Needed for USB */
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
285
286
  		device_lock(dev->parent);
  	device_lock(dev);
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
287
288
  	if (!dev->driver)
  		driver_probe_device(drv, dev);
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
289
  	device_unlock(dev);
bf74ad5bc   Alan Stern   [PATCH] Hold the ...
290
  	if (dev->parent)
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
291
  		device_unlock(dev->parent);
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
292

07e4a3e27   Patrick Mochel   [PATCH] Move devi...
293
294
295
296
  	return 0;
  }
  
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
297
298
   * driver_attach - try to bind driver to devices.
   * @drv: driver.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
299
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
300
301
302
303
   * Walk the list of devices that the bus has on it and try to
   * match the driver with each one.  If driver_probe_device()
   * returns 0 and the @dev->driver is set, we've found a
   * compatible pair.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
304
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
305
  int driver_attach(struct device_driver *drv)
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
306
  {
f86db396f   Andrew Morton   drivers/base: che...
307
  	return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
308
  }
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
309
  EXPORT_SYMBOL_GPL(driver_attach);
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
310

ab71c6f07   Stefan Richter   driver core: fix ...
311
  /*
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
312
313
   * __device_release_driver() must be called with @dev lock held.
   * When called for a USB interface, @dev->parent lock must be held as well.
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
314
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
315
  static void __device_release_driver(struct device *dev)
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
316
  {
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
317
  	struct device_driver *drv;
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
318

ef2c51746   Alan Stern   Driver core: fix ...
319
  	drv = dev->driver;
c95a6b057   Alan Stern   [PATCH] driver co...
320
  	if (drv) {
e1866b33b   Rafael J. Wysocki   PM / Runtime: Rew...
321
  		pm_runtime_get_sync(dev);
5e928f77a   Rafael J. Wysocki   PM: Introduce cor...
322

1901fb260   Kay Sievers   Driver core: fix ...
323
  		driver_sysfs_remove(dev);
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
324

116af3782   Benjamin Herrenschmidt   Driver core: add ...
325
  		if (dev->bus)
c6f7e72a3   Greg Kroah-Hartman   driver core: remo...
326
  			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
116af3782   Benjamin Herrenschmidt   Driver core: add ...
327
328
  						     BUS_NOTIFY_UNBIND_DRIVER,
  						     dev);
e1866b33b   Rafael J. Wysocki   PM / Runtime: Rew...
329
  		pm_runtime_put_sync(dev);
0f836ca4c   Alan Stern   [PATCH] driver co...
330
  		if (dev->bus && dev->bus->remove)
594c8281f   Russell King   [PATCH] Add bus_t...
331
332
  			dev->bus->remove(dev);
  		else if (drv->remove)
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
333
  			drv->remove(dev);
9ac7849e3   Tejun Heo   devres: device re...
334
  		devres_release_all(dev);
0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
335
  		dev->driver = NULL;
8940b4f31   Greg Kroah-Hartman   driver core: move...
336
  		klist_remove(&dev->p->knode_driver);
309b7d60a   Joerg Roedel   driver core: add ...
337
338
339
340
  		if (dev->bus)
  			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
  						     BUS_NOTIFY_UNBOUND_DRIVER,
  						     dev);
5e928f77a   Rafael J. Wysocki   PM: Introduce cor...
341

0d3e5a2e3   Patrick Mochel   [PATCH] Driver Co...
342
  	}
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
343
  }
ab71c6f07   Stefan Richter   driver core: fix ...
344
  /**
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
345
346
   * device_release_driver - manually detach device from driver.
   * @dev: device.
ab71c6f07   Stefan Richter   driver core: fix ...
347
   *
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
348
   * Manually detach device from driver.
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
349
   * When called for a USB interface, @dev->parent lock must be held.
ab71c6f07   Stefan Richter   driver core: fix ...
350
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
351
  void device_release_driver(struct device *dev)
94e7b1c5f   Patrick Mochel   [PATCH] Add a kli...
352
  {
c95a6b057   Alan Stern   [PATCH] driver co...
353
354
355
356
357
  	/*
  	 * If anyone calls device_release_driver() recursively from
  	 * within their ->remove callback for the same device, they
  	 * will deadlock right here.
  	 */
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
358
  	device_lock(dev);
c95a6b057   Alan Stern   [PATCH] driver co...
359
  	__device_release_driver(dev);
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
360
  	device_unlock(dev);
94e7b1c5f   Patrick Mochel   [PATCH] Add a kli...
361
  }
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
362
  EXPORT_SYMBOL_GPL(device_release_driver);
c95a6b057   Alan Stern   [PATCH] driver co...
363

07e4a3e27   Patrick Mochel   [PATCH] Move devi...
364
365
366
367
  /**
   * driver_detach - detach driver from all devices it controls.
   * @drv: driver.
   */
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
368
  void driver_detach(struct device_driver *drv)
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
369
  {
8940b4f31   Greg Kroah-Hartman   driver core: move...
370
  	struct device_private *dev_prv;
4a3ad20cc   Greg Kroah-Hartman   Driver core: codi...
371
  	struct device *dev;
c95a6b057   Alan Stern   [PATCH] driver co...
372
373
  
  	for (;;) {
e5dd12784   Greg Kroah-Hartman   Driver core: move...
374
375
376
  		spin_lock(&drv->p->klist_devices.k_lock);
  		if (list_empty(&drv->p->klist_devices.k_list)) {
  			spin_unlock(&drv->p->klist_devices.k_lock);
c95a6b057   Alan Stern   [PATCH] driver co...
377
378
  			break;
  		}
8940b4f31   Greg Kroah-Hartman   driver core: move...
379
380
381
382
  		dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
  				     struct device_private,
  				     knode_driver.n_node);
  		dev = dev_prv->device;
c95a6b057   Alan Stern   [PATCH] driver co...
383
  		get_device(dev);
e5dd12784   Greg Kroah-Hartman   Driver core: move...
384
  		spin_unlock(&drv->p->klist_devices.k_lock);
c95a6b057   Alan Stern   [PATCH] driver co...
385

bf74ad5bc   Alan Stern   [PATCH] Hold the ...
386
  		if (dev->parent)	/* Needed for USB */
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
387
388
  			device_lock(dev->parent);
  		device_lock(dev);
c95a6b057   Alan Stern   [PATCH] driver co...
389
390
  		if (dev->driver == drv)
  			__device_release_driver(dev);
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
391
  		device_unlock(dev);
bf74ad5bc   Alan Stern   [PATCH] Hold the ...
392
  		if (dev->parent)
8e9394ce2   Greg Kroah-Hartman   Driver core: crea...
393
  			device_unlock(dev->parent);
c95a6b057   Alan Stern   [PATCH] driver co...
394
395
  		put_device(dev);
  	}
07e4a3e27   Patrick Mochel   [PATCH] Move devi...
396
  }
b40284378   Greg Kroah-Hartman   Driver core: move...
397
398
399
400
401
402
403
404
405
406
407
408
  
  /*
   * These exports can't be _GPL due to .h files using this within them, and it
   * might break something that was previously working...
   */
  void *dev_get_drvdata(const struct device *dev)
  {
  	if (dev && dev->p)
  		return dev->p->driver_data;
  	return NULL;
  }
  EXPORT_SYMBOL(dev_get_drvdata);
c87050824   Uwe Kleine-König   driver core: let ...
409
  int dev_set_drvdata(struct device *dev, void *data)
b40284378   Greg Kroah-Hartman   Driver core: move...
410
411
  {
  	int error;
b40284378   Greg Kroah-Hartman   Driver core: move...
412
413
414
  	if (!dev->p) {
  		error = device_private_init(dev);
  		if (error)
c87050824   Uwe Kleine-König   driver core: let ...
415
  			return error;
b40284378   Greg Kroah-Hartman   Driver core: move...
416
417
  	}
  	dev->p->driver_data = data;
c87050824   Uwe Kleine-König   driver core: let ...
418
  	return 0;
b40284378   Greg Kroah-Hartman   Driver core: move...
419
420
  }
  EXPORT_SYMBOL(dev_set_drvdata);