aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/core.c43
-rw-r--r--drivers/base/memory.c4
-rw-r--r--include/linux/device.h1
3 files changed, 32 insertions, 16 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;
49struct kobject *sysfs_dev_char_kobj; 49struct kobject *sysfs_dev_char_kobj;
50struct kobject *sysfs_dev_block_kobj; 50struct kobject *sysfs_dev_block_kobj;
51 51
52static DEFINE_MUTEX(device_hotplug_lock);
53
54void lock_device_hotplug(void)
55{
56 mutex_lock(&device_hotplug_lock);
57}
58
59void unlock_device_hotplug(void)
60{
61 mutex_unlock(&device_hotplug_lock);
62}
63
64int 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
53static inline int device_is_not_partition(struct device *dev) 75static 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);
1479EXPORT_SYMBOL_GPL(device_create_file); 1504EXPORT_SYMBOL_GPL(device_create_file);
1480EXPORT_SYMBOL_GPL(device_remove_file); 1505EXPORT_SYMBOL_GPL(device_remove_file);
1481 1506
1482static DEFINE_MUTEX(device_hotplug_lock);
1483
1484void lock_device_hotplug(void)
1485{
1486 mutex_lock(&device_hotplug_lock);
1487}
1488
1489void unlock_device_hotplug(void)
1490{
1491 mutex_unlock(&device_hotplug_lock);
1492}
1493
1494static int device_check_offline(struct device *dev, void *not_used) 1507static int device_check_offline(struct device *dev, void *not_used)
1495{ 1508{
1496 int ret; 1509 int ret;
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 2b7813ec6d02..6f4c99ff1ce7 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -351,7 +351,9 @@ store_mem_state(struct device *dev,
351 351
352 mem = container_of(dev, struct memory_block, dev); 352 mem = container_of(dev, struct memory_block, dev);
353 353
354 lock_device_hotplug(); 354 ret = lock_device_hotplug_sysfs();
355 if (ret)
356 return ret;
355 357
356 if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) { 358 if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) {
357 offline = false; 359 offline = false;
diff --git a/include/linux/device.h b/include/linux/device.h
index 22b546a58591..545a04285120 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -895,6 +895,7 @@ static inline bool device_supports_offline(struct device *dev)
895 895
896extern void lock_device_hotplug(void); 896extern void lock_device_hotplug(void);
897extern void unlock_device_hotplug(void); 897extern void unlock_device_hotplug(void);
898extern int lock_device_hotplug_sysfs(void);
898extern int device_offline(struct device *dev); 899extern int device_offline(struct device *dev);
899extern int device_online(struct device *dev); 900extern int device_online(struct device *dev);
900/* 901/*