diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-30 14:14:25 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-30 14:14:25 +0200 |
commit | 7bc583d102d6f89c3dc4b502caec6ba03c9d318f (patch) | |
tree | 550e6333f2205f006849984b52408ed796bcd0c5 /drivers/base | |
parent | da48afb26b40ebb5d6b0e84793e0662859c7ea20 (diff) | |
parent | f943db40c29f3c82a56956e9ca36f21d6d855db9 (diff) | |
download | linux-7bc583d102d6f89c3dc4b502caec6ba03c9d318f.tar.bz2 |
Merge branch 'acpi-hotplug'
* acpi-hotplug:
ACPI / hotplug: Remove containers synchronously
driver core / ACPI: Avoid device hot remove locking issues
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/core.c | 43 | ||||
-rw-r--r-- | drivers/base/memory.c | 4 |
2 files changed, 31 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; struct kobject *sysfs_dev_char_kobj; struct kobject *sysfs_dev_block_kobj; +static DEFINE_MUTEX(device_hotplug_lock); + +void lock_device_hotplug(void) +{ + mutex_lock(&device_hotplug_lock); +} + +void unlock_device_hotplug(void) +{ + mutex_unlock(&device_hotplug_lock); +} + +int lock_device_hotplug_sysfs(void) +{ + if (mutex_trylock(&device_hotplug_lock)) + return 0; + + /* Avoid busy looping (5 ms of sleep should do). */ + msleep(5); + return restart_syscall(); +} + #ifdef CONFIG_BLOCK static inline int device_is_not_partition(struct device *dev) { @@ -408,9 +430,9 @@ static ssize_t show_online(struct device *dev, struct device_attribute *attr, { bool val; - lock_device_hotplug(); + device_lock(dev); val = !dev->offline; - unlock_device_hotplug(); + device_unlock(dev); return sprintf(buf, "%u\n", val); } @@ -424,7 +446,10 @@ static ssize_t store_online(struct device *dev, struct device_attribute *attr, if (ret < 0) return ret; - lock_device_hotplug(); + ret = lock_device_hotplug_sysfs(); + if (ret) + return ret; + ret = val ? device_online(dev) : device_offline(dev); unlock_device_hotplug(); return ret < 0 ? ret : count; @@ -1479,18 +1504,6 @@ EXPORT_SYMBOL_GPL(put_device); EXPORT_SYMBOL_GPL(device_create_file); EXPORT_SYMBOL_GPL(device_remove_file); -static DEFINE_MUTEX(device_hotplug_lock); - -void lock_device_hotplug(void) -{ - mutex_lock(&device_hotplug_lock); -} - -void unlock_device_hotplug(void) -{ - mutex_unlock(&device_hotplug_lock); -} - static int device_check_offline(struct device *dev, void *not_used) { 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, mem = container_of(dev, struct memory_block, dev); - lock_device_hotplug(); + ret = lock_device_hotplug_sysfs(); + if (ret) + return ret; if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) { offline = false; |