Commit 14b6257a authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Rafael J. Wysocki
Browse files

device core: add BUS_NOTIFY_DRIVER_NOT_BOUND notification



The users of BUS_NOTIFY_BIND_DRIVER have no chance to do any cleanup in case of
a probe failure. In the result there might be problems, such as some resources
that had been allocated will continue to be allocated and therefore lead to a
resource leak.

Introduce a new notification to inform the subscriber that ->probe() failed. Do
the same in case of failed device_bind_driver() call.

Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 4077a387
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -268,6 +268,9 @@ int device_bind_driver(struct device *dev)
	ret = driver_sysfs_add(dev);
	if (!ret)
		driver_bound(dev);
	else if (dev->bus)
		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
	return ret;
}
EXPORT_SYMBOL_GPL(device_bind_driver);
@@ -290,7 +293,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
	/* If using pinctrl, bind pins now before probing */
	ret = pinctrl_bind_pins(dev);
	if (ret)
		goto probe_failed;
		goto pinctrl_bind_failed;

	if (driver_sysfs_add(dev)) {
		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
@@ -334,6 +337,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
	goto done;

probe_failed:
	if (dev->bus)
		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
pinctrl_bind_failed:
	devres_release_all(dev);
	driver_sysfs_remove(dev);
	dev->driver = NULL;
@@ -701,7 +708,6 @@ static void __device_release_driver(struct device *dev)
			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
						     BUS_NOTIFY_UNBOUND_DRIVER,
						     dev);

	}
}

+1 −0
Original line number Diff line number Diff line
@@ -191,6 +191,7 @@ extern int bus_unregister_notifier(struct bus_type *bus,
						      unbound */
#define BUS_NOTIFY_UNBOUND_DRIVER	0x00000007 /* driver is unbound
						      from the device */
#define BUS_NOTIFY_DRIVER_NOT_BOUND	0x00000008 /* driver fails to be bound */

extern struct kset *bus_get_kset(struct bus_type *bus);
extern struct klist *bus_get_device_klist(struct bus_type *bus);