diff options
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 8856d74545d9..ac419a15fcd4 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -49,6 +49,28 @@ static struct kobject *dev_kobj; | |||
49 | struct kobject *sysfs_dev_char_kobj; | 49 | struct kobject *sysfs_dev_char_kobj; |
50 | struct kobject *sysfs_dev_block_kobj; | 50 | struct kobject *sysfs_dev_block_kobj; |
51 | 51 | ||
52 | static DEFINE_MUTEX(device_hotplug_lock); | ||
53 | |||
54 | void lock_device_hotplug(void) | ||
55 | { | ||
56 | mutex_lock(&device_hotplug_lock); | ||
57 | } | ||
58 | |||
59 | void unlock_device_hotplug(void) | ||
60 | { | ||
61 | mutex_unlock(&device_hotplug_lock); | ||
62 | } | ||
63 | |||
64 | int lock_device_hotplug_sysfs(void) | ||
65 | { | ||
66 | if (mutex_trylock(&device_hotplug_lock)) | ||
67 | return 0; | ||
68 | |||
69 | /* Avoid busy looping (5 ms of sleep should do). */ | ||
70 | msleep(5); | ||
71 | return restart_syscall(); | ||
72 | } | ||
73 | |||
52 | #ifdef CONFIG_BLOCK | 74 | #ifdef CONFIG_BLOCK |
53 | static inline int device_is_not_partition(struct device *dev) | 75 | static inline int device_is_not_partition(struct device *dev) |
54 | { | 76 | { |
@@ -408,9 +430,9 @@ static ssize_t show_online(struct device *dev, struct device_attribute *attr, | |||
408 | { | 430 | { |
409 | bool val; | 431 | bool val; |
410 | 432 | ||
411 | lock_device_hotplug(); | 433 | device_lock(dev); |
412 | val = !dev->offline; | 434 | val = !dev->offline; |
413 | unlock_device_hotplug(); | 435 | device_unlock(dev); |
414 | return sprintf(buf, "%u\n", val); | 436 | return sprintf(buf, "%u\n", val); |
415 | } | 437 | } |
416 | 438 | ||
@@ -424,7 +446,10 @@ static ssize_t store_online(struct device *dev, struct device_attribute *attr, | |||
424 | if (ret < 0) | 446 | if (ret < 0) |
425 | return ret; | 447 | return ret; |
426 | 448 | ||
427 | lock_device_hotplug(); | 449 | ret = lock_device_hotplug_sysfs(); |
450 | if (ret) | ||
451 | return ret; | ||
452 | |||
428 | ret = val ? device_online(dev) : device_offline(dev); | 453 | ret = val ? device_online(dev) : device_offline(dev); |
429 | unlock_device_hotplug(); | 454 | unlock_device_hotplug(); |
430 | return ret < 0 ? ret : count; | 455 | return ret < 0 ? ret : count; |
@@ -1479,18 +1504,6 @@ EXPORT_SYMBOL_GPL(put_device); | |||
1479 | EXPORT_SYMBOL_GPL(device_create_file); | 1504 | EXPORT_SYMBOL_GPL(device_create_file); |
1480 | EXPORT_SYMBOL_GPL(device_remove_file); | 1505 | EXPORT_SYMBOL_GPL(device_remove_file); |
1481 | 1506 | ||
1482 | static DEFINE_MUTEX(device_hotplug_lock); | ||
1483 | |||
1484 | void lock_device_hotplug(void) | ||
1485 | { | ||
1486 | mutex_lock(&device_hotplug_lock); | ||
1487 | } | ||
1488 | |||
1489 | void unlock_device_hotplug(void) | ||
1490 | { | ||
1491 | mutex_unlock(&device_hotplug_lock); | ||
1492 | } | ||
1493 | |||
1494 | static int device_check_offline(struct device *dev, void *not_used) | 1507 | static int device_check_offline(struct device *dev, void *not_used) |
1495 | { | 1508 | { |
1496 | int ret; | 1509 | int ret; |