diff --git a/drivers/base/core.c b/drivers/base/core.c index 60833f94f7854322797f236e4227d926263b4cdb..b5f8b5a26ab062ce57c923e128971c5a8becb3e2 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2929,6 +2929,36 @@ void device_shutdown(void) spin_unlock(&devices_kset->list_lock); } +void device_shutdown_by_driver(char *drv_name) +{ + struct device *dev, *parent, *next; + int len = 0; + + if (!drv_name) + return; + + len = strlen(drv_name); + if (!len) + return; + + wait_for_device_probe(); + device_block_probing(); + + spin_lock(&devices_kset->list_lock); + list_for_each_entry_safe(dev, next, &devices_kset->list, kobj.entry) { + if (dev->driver && len == strlen(dev->driver->name) && + !strncmp(dev->driver->name, drv_name, len)) { + parent = get_device(dev->parent); + get_device(dev); + list_del(&dev->kobj.entry); + spin_unlock(&devices_kset->list_lock); + device_shutdown_one(dev, parent); + spin_lock(&devices_kset->list_lock); + } + } + spin_unlock(&devices_kset->list_lock); +} + /* * Device logging functions */ diff --git a/include/linux/device.h b/include/linux/device.h index 8f882549edeece99cb85f105cba968b2735d4942..b397ca8c3caefeb75f5d9f2782b48cdb72af451c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1321,6 +1321,7 @@ static inline int devtmpfs_mount(const char *mountpoint) { return 0; } /* drivers/base/power/shutdown.c */ extern void device_shutdown(void); +extern void device_shutdown_by_driver(char *drv_name); /* debugging and troubleshooting/diagnostic helpers. */ extern const char *dev_driver_string(const struct device *dev);