diff --git a/drivers/base/core.c b/drivers/base/core.c index 4dbe8276f579..38f76847ae11 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3358,7 +3358,7 @@ bool kill_device(struct device *dev) */ lockdep_assert_held(&dev->mutex); - if (dev->p->dead) + if (!dev->p || dev->p->dead) return false; dev->p->dead = true; return true; @@ -3382,6 +3382,7 @@ void device_del(struct device *dev) { struct device *parent = dev->parent; struct kobject *glue_dir = NULL; + struct kobject *kobj = &dev->kobj; struct class_interface *class_intf; unsigned int noio_flag; @@ -3400,7 +3401,8 @@ void device_del(struct device *dev) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DEL_DEVICE, dev); - dpm_sysfs_remove(dev); + if (kobj->sd) + dpm_sysfs_remove(dev); if (parent) klist_del(&dev->p->knode_parent); if (MAJOR(dev->devt)) { @@ -3408,7 +3410,7 @@ void device_del(struct device *dev) device_remove_sys_dev_entry(dev); device_remove_file(dev, &dev_attr_dev); } - if (dev->class) { + if (dev->class && dev->p) { device_remove_class_symlinks(dev); mutex_lock(&dev->class->p->mutex); @@ -3421,11 +3423,13 @@ void device_del(struct device *dev) klist_del(&dev->p->knode_class); mutex_unlock(&dev->class->p->mutex); } - device_remove_file(dev, &dev_attr_uevent); + if (kobj->sd) + device_remove_file(dev, &dev_attr_uevent); device_remove_attrs(dev); bus_remove_device(dev); device_pm_remove(dev); - driver_deferred_probe_del(dev); + if (dev->p) + driver_deferred_probe_del(dev); device_platform_notify(dev, KOBJ_REMOVE); device_remove_properties(dev); device_links_purge(dev);