diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 19:28:19 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 19:28:19 -0400 |
| commit | 158e0d3621683ee0cdfeeba56f0e5ddd97ae984f (patch) | |
| tree | cc59e84001f0a496a681242a875ecad6463aa50e /drivers | |
| parent | 675c354a95d5375153b8bb80a0448cab916c7991 (diff) | |
| parent | 72099304eeb316c4b00df3ae83efe4375729bd78 (diff) | |
Merge tag 'driver-core-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core and sysfs updates from Greg KH:
"Here's the big driver core / sysfs update for 3.15-rc1.
Lots of kernfs updates to make it useful for other subsystems, and a
few other tiny driver core patches.
All have been in linux-next for a while"
* tag 'driver-core-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (42 commits)
Revert "sysfs, driver-core: remove unused {sysfs|device}_schedule_callback_owner()"
kernfs: cache atomic_write_len in kernfs_open_file
numa: fix NULL pointer access and memory leak in unregister_one_node()
Revert "driver core: synchronize device shutdown"
kernfs: fix off by one error.
kernfs: remove duplicate dir.c at the top dir
x86: align x86 arch with generic CPU modalias handling
cpu: add generic support for CPU feature based module autoloading
sysfs: create bin_attributes under the requested group
driver core: unexport static function create_syslog_header
firmware: use power efficient workqueue for unloading and aborting fw load
firmware: give a protection when map page failed
firmware: google memconsole driver fixes
firmware: fix google/gsmi duplicate efivars_sysfs_init()
drivers/base: delete non-required instances of include <linux/init.h>
kernfs: fix kernfs_node_from_dentry()
ACPI / platform: drop redundant ACPI_HANDLE check
kernfs: fix hash calculation in kernfs_rename_ns()
kernfs: add CONFIG_KERNFS
sysfs, kobject: add sysfs wrapper for kernfs_enable_ns()
...
Diffstat (limited to 'drivers')
26 files changed, 146 insertions, 111 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index ec36e7772e57..8fa8deab6449 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
| @@ -185,6 +185,9 @@ config GENERIC_CPU_DEVICES | |||
| 185 | bool | 185 | bool |
| 186 | default n | 186 | default n |
| 187 | 187 | ||
| 188 | config GENERIC_CPU_AUTOPROBE | ||
| 189 | bool | ||
| 190 | |||
| 188 | config SOC_BUS | 191 | config SOC_BUS |
| 189 | bool | 192 | bool |
| 190 | 193 | ||
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index ecc1929d7f6a..b84ca8f13f9e 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/attribute_container.h> | 14 | #include <linux/attribute_container.h> |
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/device.h> | 15 | #include <linux/device.h> |
| 17 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 2b567177ef78..0dd65281cc65 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/genhd.h> | 23 | #include <linux/genhd.h> |
| 24 | #include <linux/kallsyms.h> | 24 | #include <linux/kallsyms.h> |
| 25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
| 26 | #include <linux/async.h> | ||
| 27 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
| 28 | #include <linux/netdevice.h> | 27 | #include <linux/netdevice.h> |
| 29 | #include <linux/sysfs.h> | 28 | #include <linux/sysfs.h> |
| @@ -571,6 +570,23 @@ void device_remove_file(struct device *dev, | |||
| 571 | EXPORT_SYMBOL_GPL(device_remove_file); | 570 | EXPORT_SYMBOL_GPL(device_remove_file); |
| 572 | 571 | ||
| 573 | /** | 572 | /** |
| 573 | * device_remove_file_self - remove sysfs attribute file from its own method. | ||
| 574 | * @dev: device. | ||
| 575 | * @attr: device attribute descriptor. | ||
| 576 | * | ||
| 577 | * See kernfs_remove_self() for details. | ||
| 578 | */ | ||
| 579 | bool device_remove_file_self(struct device *dev, | ||
| 580 | const struct device_attribute *attr) | ||
| 581 | { | ||
| 582 | if (dev) | ||
| 583 | return sysfs_remove_file_self(&dev->kobj, &attr->attr); | ||
| 584 | else | ||
| 585 | return false; | ||
| 586 | } | ||
| 587 | EXPORT_SYMBOL_GPL(device_remove_file_self); | ||
| 588 | |||
| 589 | /** | ||
| 574 | * device_create_bin_file - create sysfs binary attribute file for device. | 590 | * device_create_bin_file - create sysfs binary attribute file for device. |
| 575 | * @dev: device. | 591 | * @dev: device. |
| 576 | * @attr: device binary attribute descriptor. | 592 | * @attr: device binary attribute descriptor. |
| @@ -2003,7 +2019,6 @@ void device_shutdown(void) | |||
| 2003 | spin_lock(&devices_kset->list_lock); | 2019 | spin_lock(&devices_kset->list_lock); |
| 2004 | } | 2020 | } |
| 2005 | spin_unlock(&devices_kset->list_lock); | 2021 | spin_unlock(&devices_kset->list_lock); |
| 2006 | async_synchronize_full(); | ||
| 2007 | } | 2022 | } |
| 2008 | 2023 | ||
| 2009 | /* | 2024 | /* |
| @@ -2058,7 +2073,6 @@ create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen) | |||
| 2058 | 2073 | ||
| 2059 | return pos; | 2074 | return pos; |
| 2060 | } | 2075 | } |
| 2061 | EXPORT_SYMBOL(create_syslog_header); | ||
| 2062 | 2076 | ||
| 2063 | int dev_vprintk_emit(int level, const struct device *dev, | 2077 | int dev_vprintk_emit(int level, const struct device *dev, |
| 2064 | const char *fmt, va_list args) | 2078 | const char *fmt, va_list args) |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index f48370dfc908..006b1bc5297d 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/percpu.h> | 15 | #include <linux/percpu.h> |
| 16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
| 17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
| 18 | #include <linux/cpufeature.h> | ||
| 18 | 19 | ||
| 19 | #include "base.h" | 20 | #include "base.h" |
| 20 | 21 | ||
| @@ -286,6 +287,41 @@ static void cpu_device_release(struct device *dev) | |||
| 286 | */ | 287 | */ |
| 287 | } | 288 | } |
| 288 | 289 | ||
| 290 | #ifdef CONFIG_GENERIC_CPU_AUTOPROBE | ||
| 291 | static ssize_t print_cpu_modalias(struct device *dev, | ||
| 292 | struct device_attribute *attr, | ||
| 293 | char *buf) | ||
| 294 | { | ||
| 295 | ssize_t n; | ||
| 296 | u32 i; | ||
| 297 | |||
| 298 | n = sprintf(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:", | ||
| 299 | CPU_FEATURE_TYPEVAL); | ||
| 300 | |||
| 301 | for (i = 0; i < MAX_CPU_FEATURES; i++) | ||
| 302 | if (cpu_have_feature(i)) { | ||
| 303 | if (PAGE_SIZE < n + sizeof(",XXXX\n")) { | ||
| 304 | WARN(1, "CPU features overflow page\n"); | ||
| 305 | break; | ||
| 306 | } | ||
| 307 | n += sprintf(&buf[n], ",%04X", i); | ||
| 308 | } | ||
| 309 | buf[n++] = '\n'; | ||
| 310 | return n; | ||
| 311 | } | ||
| 312 | |||
| 313 | static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
| 314 | { | ||
| 315 | char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
| 316 | if (buf) { | ||
| 317 | print_cpu_modalias(NULL, NULL, buf); | ||
| 318 | add_uevent_var(env, "MODALIAS=%s", buf); | ||
| 319 | kfree(buf); | ||
| 320 | } | ||
| 321 | return 0; | ||
| 322 | } | ||
| 323 | #endif | ||
| 324 | |||
| 289 | /* | 325 | /* |
| 290 | * register_cpu - Setup a sysfs device for a CPU. | 326 | * register_cpu - Setup a sysfs device for a CPU. |
| 291 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in | 327 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in |
| @@ -306,8 +342,8 @@ int register_cpu(struct cpu *cpu, int num) | |||
| 306 | cpu->dev.offline_disabled = !cpu->hotpluggable; | 342 | cpu->dev.offline_disabled = !cpu->hotpluggable; |
| 307 | cpu->dev.offline = !cpu_online(num); | 343 | cpu->dev.offline = !cpu_online(num); |
| 308 | cpu->dev.of_node = of_get_cpu_node(num, NULL); | 344 | cpu->dev.of_node = of_get_cpu_node(num, NULL); |
| 309 | #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE | 345 | #ifdef CONFIG_GENERIC_CPU_AUTOPROBE |
| 310 | cpu->dev.bus->uevent = arch_cpu_uevent; | 346 | cpu->dev.bus->uevent = cpu_uevent; |
| 311 | #endif | 347 | #endif |
| 312 | cpu->dev.groups = common_cpu_attr_groups; | 348 | cpu->dev.groups = common_cpu_attr_groups; |
| 313 | if (cpu->hotpluggable) | 349 | if (cpu->hotpluggable) |
| @@ -330,8 +366,8 @@ struct device *get_cpu_device(unsigned cpu) | |||
| 330 | } | 366 | } |
| 331 | EXPORT_SYMBOL_GPL(get_cpu_device); | 367 | EXPORT_SYMBOL_GPL(get_cpu_device); |
| 332 | 368 | ||
| 333 | #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE | 369 | #ifdef CONFIG_GENERIC_CPU_AUTOPROBE |
| 334 | static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL); | 370 | static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); |
| 335 | #endif | 371 | #endif |
| 336 | 372 | ||
| 337 | static struct attribute *cpu_root_attrs[] = { | 373 | static struct attribute *cpu_root_attrs[] = { |
| @@ -344,7 +380,7 @@ static struct attribute *cpu_root_attrs[] = { | |||
| 344 | &cpu_attrs[2].attr.attr, | 380 | &cpu_attrs[2].attr.attr, |
| 345 | &dev_attr_kernel_max.attr, | 381 | &dev_attr_kernel_max.attr, |
| 346 | &dev_attr_offline.attr, | 382 | &dev_attr_offline.attr, |
| 347 | #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE | 383 | #ifdef CONFIG_GENERIC_CPU_AUTOPROBE |
| 348 | &dev_attr_modalias.attr, | 384 | &dev_attr_modalias.attr, |
| 349 | #endif | 385 | #endif |
| 350 | NULL | 386 | NULL |
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 61d6d62cc0d3..ea77701deda4 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c | |||
| @@ -251,9 +251,8 @@ EXPORT_SYMBOL_GPL(dma_buf_put); | |||
| 251 | * @dmabuf: [in] buffer to attach device to. | 251 | * @dmabuf: [in] buffer to attach device to. |
| 252 | * @dev: [in] device to be attached. | 252 | * @dev: [in] device to be attached. |
| 253 | * | 253 | * |
| 254 | * Returns struct dma_buf_attachment * for this attachment; may return negative | 254 | * Returns struct dma_buf_attachment * for this attachment; returns ERR_PTR on |
| 255 | * error codes. | 255 | * error. |
| 256 | * | ||
| 257 | */ | 256 | */ |
| 258 | struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, | 257 | struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, |
| 259 | struct device *dev) | 258 | struct device *dev) |
| @@ -319,9 +318,8 @@ EXPORT_SYMBOL_GPL(dma_buf_detach); | |||
| 319 | * @attach: [in] attachment whose scatterlist is to be returned | 318 | * @attach: [in] attachment whose scatterlist is to be returned |
| 320 | * @direction: [in] direction of DMA transfer | 319 | * @direction: [in] direction of DMA transfer |
| 321 | * | 320 | * |
| 322 | * Returns sg_table containing the scatterlist to be returned; may return NULL | 321 | * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR |
| 323 | * or ERR_PTR. | 322 | * on error. |
| 324 | * | ||
| 325 | */ | 323 | */ |
| 326 | struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, | 324 | struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, |
| 327 | enum dma_data_direction direction) | 325 | enum dma_data_direction direction) |
| @@ -334,6 +332,8 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, | |||
| 334 | return ERR_PTR(-EINVAL); | 332 | return ERR_PTR(-EINVAL); |
| 335 | 333 | ||
| 336 | sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction); | 334 | sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction); |
| 335 | if (!sg_table) | ||
| 336 | sg_table = ERR_PTR(-ENOMEM); | ||
| 337 | 337 | ||
| 338 | return sg_table; | 338 | return sg_table; |
| 339 | } | 339 | } |
| @@ -544,6 +544,8 @@ EXPORT_SYMBOL_GPL(dma_buf_mmap); | |||
| 544 | * These calls are optional in drivers. The intended use for them | 544 | * These calls are optional in drivers. The intended use for them |
| 545 | * is for mapping objects linear in kernel space for high use objects. | 545 | * is for mapping objects linear in kernel space for high use objects. |
| 546 | * Please attempt to use kmap/kunmap before thinking about these interfaces. | 546 | * Please attempt to use kmap/kunmap before thinking about these interfaces. |
| 547 | * | ||
| 548 | * Returns NULL on error. | ||
| 547 | */ | 549 | */ |
| 548 | void *dma_buf_vmap(struct dma_buf *dmabuf) | 550 | void *dma_buf_vmap(struct dma_buf *dmabuf) |
| 549 | { | 551 | { |
| @@ -566,7 +568,9 @@ void *dma_buf_vmap(struct dma_buf *dmabuf) | |||
| 566 | BUG_ON(dmabuf->vmap_ptr); | 568 | BUG_ON(dmabuf->vmap_ptr); |
| 567 | 569 | ||
| 568 | ptr = dmabuf->ops->vmap(dmabuf); | 570 | ptr = dmabuf->ops->vmap(dmabuf); |
| 569 | if (IS_ERR_OR_NULL(ptr)) | 571 | if (WARN_ON_ONCE(IS_ERR(ptr))) |
| 572 | ptr = NULL; | ||
| 573 | if (!ptr) | ||
| 570 | goto out_unlock; | 574 | goto out_unlock; |
| 571 | 575 | ||
| 572 | dmabuf->vmap_ptr = ptr; | 576 | dmabuf->vmap_ptr = ptr; |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index c30df50e4440..d276e33880be 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
| @@ -649,7 +649,9 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
| 649 | * see the mapped 'buf->data' once the loading | 649 | * see the mapped 'buf->data' once the loading |
| 650 | * is completed. | 650 | * is completed. |
| 651 | * */ | 651 | * */ |
| 652 | fw_map_pages_buf(fw_buf); | 652 | if (fw_map_pages_buf(fw_buf)) |
| 653 | dev_err(dev, "%s: map pages failed\n", | ||
| 654 | __func__); | ||
| 653 | list_del_init(&fw_buf->pending_list); | 655 | list_del_init(&fw_buf->pending_list); |
| 654 | complete_all(&fw_buf->completion); | 656 | complete_all(&fw_buf->completion); |
| 655 | break; | 657 | break; |
| @@ -900,7 +902,8 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, | |||
| 900 | dev_set_uevent_suppress(f_dev, false); | 902 | dev_set_uevent_suppress(f_dev, false); |
| 901 | dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); | 903 | dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); |
| 902 | if (timeout != MAX_SCHEDULE_TIMEOUT) | 904 | if (timeout != MAX_SCHEDULE_TIMEOUT) |
| 903 | schedule_delayed_work(&fw_priv->timeout_work, timeout); | 905 | queue_delayed_work(system_power_efficient_wq, |
| 906 | &fw_priv->timeout_work, timeout); | ||
| 904 | 907 | ||
| 905 | kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); | 908 | kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); |
| 906 | } | 909 | } |
| @@ -908,6 +911,8 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, | |||
| 908 | wait_for_completion(&buf->completion); | 911 | wait_for_completion(&buf->completion); |
| 909 | 912 | ||
| 910 | cancel_delayed_work_sync(&fw_priv->timeout_work); | 913 | cancel_delayed_work_sync(&fw_priv->timeout_work); |
| 914 | if (!buf->data) | ||
| 915 | retval = -ENOMEM; | ||
| 911 | 916 | ||
| 912 | device_remove_file(f_dev, &dev_attr_loading); | 917 | device_remove_file(f_dev, &dev_attr_loading); |
| 913 | err_del_bin_attr: | 918 | err_del_bin_attr: |
| @@ -1570,8 +1575,8 @@ static void device_uncache_fw_images_work(struct work_struct *work) | |||
| 1570 | */ | 1575 | */ |
| 1571 | static void device_uncache_fw_images_delay(unsigned long delay) | 1576 | static void device_uncache_fw_images_delay(unsigned long delay) |
| 1572 | { | 1577 | { |
| 1573 | schedule_delayed_work(&fw_cache.work, | 1578 | queue_delayed_work(system_power_efficient_wq, &fw_cache.work, |
| 1574 | msecs_to_jiffies(delay)); | 1579 | msecs_to_jiffies(delay)); |
| 1575 | } | 1580 | } |
| 1576 | 1581 | ||
| 1577 | static int fw_pm_notify(struct notifier_block *notify_block, | 1582 | static int fw_pm_notify(struct notifier_block *notify_block, |
diff --git a/drivers/base/node.c b/drivers/base/node.c index bc9f43bf7e29..8f7ed9933a7c 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
| @@ -599,7 +599,11 @@ int register_one_node(int nid) | |||
| 599 | 599 | ||
| 600 | void unregister_one_node(int nid) | 600 | void unregister_one_node(int nid) |
| 601 | { | 601 | { |
| 602 | if (!node_devices[nid]) | ||
| 603 | return; | ||
| 604 | |||
| 602 | unregister_node(node_devices[nid]); | 605 | unregister_node(node_devices[nid]); |
| 606 | kfree(node_devices[nid]); | ||
| 603 | node_devices[nid] = NULL; | 607 | node_devices[nid] = NULL; |
| 604 | } | 608 | } |
| 605 | 609 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index bc78848dd59a..e714709704e4 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -481,11 +481,10 @@ static int platform_drv_probe(struct device *_dev) | |||
| 481 | struct platform_device *dev = to_platform_device(_dev); | 481 | struct platform_device *dev = to_platform_device(_dev); |
| 482 | int ret; | 482 | int ret; |
| 483 | 483 | ||
| 484 | if (ACPI_HANDLE(_dev)) | 484 | acpi_dev_pm_attach(_dev, true); |
| 485 | acpi_dev_pm_attach(_dev, true); | ||
| 486 | 485 | ||
| 487 | ret = drv->probe(dev); | 486 | ret = drv->probe(dev); |
| 488 | if (ret && ACPI_HANDLE(_dev)) | 487 | if (ret) |
| 489 | acpi_dev_pm_detach(_dev, true); | 488 | acpi_dev_pm_detach(_dev, true); |
| 490 | 489 | ||
| 491 | if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { | 490 | if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { |
| @@ -508,8 +507,7 @@ static int platform_drv_remove(struct device *_dev) | |||
| 508 | int ret; | 507 | int ret; |
| 509 | 508 | ||
| 510 | ret = drv->remove(dev); | 509 | ret = drv->remove(dev); |
| 511 | if (ACPI_HANDLE(_dev)) | 510 | acpi_dev_pm_detach(_dev, true); |
| 512 | acpi_dev_pm_detach(_dev, true); | ||
| 513 | 511 | ||
| 514 | return ret; | 512 | return ret; |
| 515 | } | 513 | } |
| @@ -520,8 +518,7 @@ static void platform_drv_shutdown(struct device *_dev) | |||
| 520 | struct platform_device *dev = to_platform_device(_dev); | 518 | struct platform_device *dev = to_platform_device(_dev); |
| 521 | 519 | ||
| 522 | drv->shutdown(dev); | 520 | drv->shutdown(dev); |
| 523 | if (ACPI_HANDLE(_dev)) | 521 | acpi_dev_pm_detach(_dev, true); |
| 524 | acpi_dev_pm_detach(_dev, true); | ||
| 525 | } | 522 | } |
| 526 | 523 | ||
| 527 | /** | 524 | /** |
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index e870bbe9ec4e..b99e6c06ee67 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | * This file is released under the GPLv2. | 6 | * This file is released under the GPLv2. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| 11 | #include <linux/device.h> | 10 | #include <linux/device.h> |
| 12 | #include <linux/io.h> | 11 | #include <linux/io.h> |
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index 5da914041305..df2e5eeaeb05 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | * This file is released under the GPLv2. | 6 | * This file is released under the GPLv2. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| 11 | #include <linux/device.h> | 10 | #include <linux/device.h> |
| 12 | #include <linux/export.h> | 11 | #include <linux/export.h> |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index dc127e5dec4b..6f54962aae1d 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | * This file is released under the GPLv2. | 6 | * This file is released under the GPLv2. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| 11 | #include <linux/io.h> | 10 | #include <linux/io.h> |
| 12 | #include <linux/pm_runtime.h> | 11 | #include <linux/pm_runtime.h> |
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index 28dee3053f1f..a089e3bcdfbc 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | * This file is released under the GPLv2. | 6 | * This file is released under the GPLv2. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| 11 | #include <linux/pm_domain.h> | 10 | #include <linux/pm_domain.h> |
| 12 | #include <linux/pm_qos.h> | 11 | #include <linux/pm_qos.h> |
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index fa4187418440..25538675d59e 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
| 16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 19 | #include <linux/cpufreq.h> | 18 | #include <linux/cpufreq.h> |
| 20 | #include <linux/device.h> | 19 | #include <linux/device.h> |
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index fa6bf5279d28..ebd189529760 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/regmap.h> | 13 | #include <linux/regmap.h> |
| 14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/init.h> | ||
| 17 | 16 | ||
| 18 | static int regmap_i2c_write(void *context, const void *data, size_t count) | 17 | static int regmap_i2c_write(void *context, const void *data, size_t count) |
| 19 | { | 18 | { |
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index de45a1e1548f..1e03e7f8bacb 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | 18 | ||
| 19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
| 20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/io.h> | 21 | #include <linux/io.h> |
| 23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 24 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 37f12ae7aada..0eb3097c0d76 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/regmap.h> | 13 | #include <linux/regmap.h> |
| 14 | #include <linux/spi/spi.h> | 14 | #include <linux/spi/spi.h> |
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 17 | 16 | ||
| 18 | #include "internal.h" | 17 | #include "internal.h" |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 94ffee378f10..ad9d17762664 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 24 | * | 24 | * |
| 25 | */ | 25 | */ |
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
| 28 | #include <linux/cpu.h> | 27 | #include <linux/cpu.h> |
| 29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c index e5a67b24587a..f1ab05ea56bb 100644 --- a/drivers/firmware/google/gsmi.c +++ b/drivers/firmware/google/gsmi.c | |||
| @@ -892,13 +892,6 @@ static __init int gsmi_init(void) | |||
| 892 | goto out_remove_sysfs_files; | 892 | goto out_remove_sysfs_files; |
| 893 | } | 893 | } |
| 894 | 894 | ||
| 895 | ret = efivars_sysfs_init(); | ||
| 896 | if (ret) { | ||
| 897 | printk(KERN_INFO "gsmi: Failed to create efivars files\n"); | ||
| 898 | efivars_unregister(&efivars); | ||
| 899 | goto out_remove_sysfs_files; | ||
| 900 | } | ||
| 901 | |||
| 902 | register_reboot_notifier(&gsmi_reboot_notifier); | 895 | register_reboot_notifier(&gsmi_reboot_notifier); |
| 903 | register_die_notifier(&gsmi_die_notifier); | 896 | register_die_notifier(&gsmi_die_notifier); |
| 904 | atomic_notifier_chain_register(&panic_notifier_list, | 897 | atomic_notifier_chain_register(&panic_notifier_list, |
diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c index 2a90ba613613..2f569aaed4c7 100644 --- a/drivers/firmware/google/memconsole.c +++ b/drivers/firmware/google/memconsole.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/kobject.h> | 15 | #include <linux/kobject.h> |
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/dmi.h> | 17 | #include <linux/dmi.h> |
| 18 | #include <linux/io.h> | ||
| 18 | #include <asm/bios_ebda.h> | 19 | #include <asm/bios_ebda.h> |
| 19 | 20 | ||
| 20 | #define BIOS_MEMCONSOLE_V1_MAGIC 0xDEADBABE | 21 | #define BIOS_MEMCONSOLE_V1_MAGIC 0xDEADBABE |
| @@ -41,15 +42,25 @@ struct biosmemcon_ebda { | |||
| 41 | }; | 42 | }; |
| 42 | } __packed; | 43 | } __packed; |
| 43 | 44 | ||
| 44 | static char *memconsole_baseaddr; | 45 | static u32 memconsole_baseaddr; |
| 45 | static size_t memconsole_length; | 46 | static size_t memconsole_length; |
| 46 | 47 | ||
| 47 | static ssize_t memconsole_read(struct file *filp, struct kobject *kobp, | 48 | static ssize_t memconsole_read(struct file *filp, struct kobject *kobp, |
| 48 | struct bin_attribute *bin_attr, char *buf, | 49 | struct bin_attribute *bin_attr, char *buf, |
| 49 | loff_t pos, size_t count) | 50 | loff_t pos, size_t count) |
| 50 | { | 51 | { |
| 51 | return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr, | 52 | char *memconsole; |
| 52 | memconsole_length); | 53 | ssize_t ret; |
| 54 | |||
| 55 | memconsole = ioremap_cache(memconsole_baseaddr, memconsole_length); | ||
| 56 | if (!memconsole) { | ||
| 57 | pr_err("memconsole: ioremap_cache failed\n"); | ||
| 58 | return -ENOMEM; | ||
| 59 | } | ||
| 60 | ret = memory_read_from_buffer(buf, count, &pos, memconsole, | ||
| 61 | memconsole_length); | ||
| 62 | iounmap(memconsole); | ||
| 63 | return ret; | ||
| 53 | } | 64 | } |
| 54 | 65 | ||
| 55 | static struct bin_attribute memconsole_bin_attr = { | 66 | static struct bin_attribute memconsole_bin_attr = { |
| @@ -58,43 +69,42 @@ static struct bin_attribute memconsole_bin_attr = { | |||
| 58 | }; | 69 | }; |
| 59 | 70 | ||
| 60 | 71 | ||
| 61 | static void found_v1_header(struct biosmemcon_ebda *hdr) | 72 | static void __init found_v1_header(struct biosmemcon_ebda *hdr) |
| 62 | { | 73 | { |
| 63 | printk(KERN_INFO "BIOS console v1 EBDA structure found at %p\n", hdr); | 74 | pr_info("BIOS console v1 EBDA structure found at %p\n", hdr); |
| 64 | printk(KERN_INFO "BIOS console buffer at 0x%.8x, " | 75 | pr_info("BIOS console buffer at 0x%.8x, " |
| 65 | "start = %d, end = %d, num = %d\n", | 76 | "start = %d, end = %d, num = %d\n", |
| 66 | hdr->v1.buffer_addr, hdr->v1.start, | 77 | hdr->v1.buffer_addr, hdr->v1.start, |
| 67 | hdr->v1.end, hdr->v1.num_chars); | 78 | hdr->v1.end, hdr->v1.num_chars); |
| 68 | 79 | ||
| 69 | memconsole_length = hdr->v1.num_chars; | 80 | memconsole_length = hdr->v1.num_chars; |
| 70 | memconsole_baseaddr = phys_to_virt(hdr->v1.buffer_addr); | 81 | memconsole_baseaddr = hdr->v1.buffer_addr; |
| 71 | } | 82 | } |
| 72 | 83 | ||
| 73 | static void found_v2_header(struct biosmemcon_ebda *hdr) | 84 | static void __init found_v2_header(struct biosmemcon_ebda *hdr) |
| 74 | { | 85 | { |
| 75 | printk(KERN_INFO "BIOS console v2 EBDA structure found at %p\n", hdr); | 86 | pr_info("BIOS console v2 EBDA structure found at %p\n", hdr); |
| 76 | printk(KERN_INFO "BIOS console buffer at 0x%.8x, " | 87 | pr_info("BIOS console buffer at 0x%.8x, " |
| 77 | "start = %d, end = %d, num_bytes = %d\n", | 88 | "start = %d, end = %d, num_bytes = %d\n", |
| 78 | hdr->v2.buffer_addr, hdr->v2.start, | 89 | hdr->v2.buffer_addr, hdr->v2.start, |
| 79 | hdr->v2.end, hdr->v2.num_bytes); | 90 | hdr->v2.end, hdr->v2.num_bytes); |
| 80 | 91 | ||
| 81 | memconsole_length = hdr->v2.end - hdr->v2.start; | 92 | memconsole_length = hdr->v2.end - hdr->v2.start; |
| 82 | memconsole_baseaddr = phys_to_virt(hdr->v2.buffer_addr | 93 | memconsole_baseaddr = hdr->v2.buffer_addr + hdr->v2.start; |
| 83 | + hdr->v2.start); | ||
| 84 | } | 94 | } |
| 85 | 95 | ||
| 86 | /* | 96 | /* |
| 87 | * Search through the EBDA for the BIOS Memory Console, and | 97 | * Search through the EBDA for the BIOS Memory Console, and |
| 88 | * set the global variables to point to it. Return true if found. | 98 | * set the global variables to point to it. Return true if found. |
| 89 | */ | 99 | */ |
| 90 | static bool found_memconsole(void) | 100 | static bool __init found_memconsole(void) |
| 91 | { | 101 | { |
| 92 | unsigned int address; | 102 | unsigned int address; |
| 93 | size_t length, cur; | 103 | size_t length, cur; |
| 94 | 104 | ||
| 95 | address = get_bios_ebda(); | 105 | address = get_bios_ebda(); |
| 96 | if (!address) { | 106 | if (!address) { |
| 97 | printk(KERN_INFO "BIOS EBDA non-existent.\n"); | 107 | pr_info("BIOS EBDA non-existent.\n"); |
| 98 | return false; | 108 | return false; |
| 99 | } | 109 | } |
| 100 | 110 | ||
| @@ -122,7 +132,7 @@ static bool found_memconsole(void) | |||
| 122 | } | 132 | } |
| 123 | } | 133 | } |
| 124 | 134 | ||
| 125 | printk(KERN_INFO "BIOS console EBDA structure not found!\n"); | 135 | pr_info("BIOS console EBDA structure not found!\n"); |
| 126 | return false; | 136 | return false; |
| 127 | } | 137 | } |
| 128 | 138 | ||
| @@ -139,8 +149,6 @@ MODULE_DEVICE_TABLE(dmi, memconsole_dmi_table); | |||
| 139 | 149 | ||
| 140 | static int __init memconsole_init(void) | 150 | static int __init memconsole_init(void) |
| 141 | { | 151 | { |
| 142 | int ret; | ||
| 143 | |||
| 144 | if (!dmi_check_system(memconsole_dmi_table)) | 152 | if (!dmi_check_system(memconsole_dmi_table)) |
| 145 | return -ENODEV; | 153 | return -ENODEV; |
| 146 | 154 | ||
| @@ -148,10 +156,7 @@ static int __init memconsole_init(void) | |||
| 148 | return -ENODEV; | 156 | return -ENODEV; |
| 149 | 157 | ||
| 150 | memconsole_bin_attr.size = memconsole_length; | 158 | memconsole_bin_attr.size = memconsole_length; |
| 151 | 159 | return sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr); | |
| 152 | ret = sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr); | ||
| 153 | |||
| 154 | return ret; | ||
| 155 | } | 160 | } |
| 156 | 161 | ||
| 157 | static void __exit memconsole_exit(void) | 162 | static void __exit memconsole_exit(void) |
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 56805c39c906..bb516fdd195d 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c | |||
| @@ -471,7 +471,7 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, | |||
| 471 | get_dma_buf(dma_buf); | 471 | get_dma_buf(dma_buf); |
| 472 | 472 | ||
| 473 | sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); | 473 | sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); |
| 474 | if (IS_ERR_OR_NULL(sgt)) { | 474 | if (IS_ERR(sgt)) { |
| 475 | ret = PTR_ERR(sgt); | 475 | ret = PTR_ERR(sgt); |
| 476 | goto fail_detach; | 476 | goto fail_detach; |
| 477 | } | 477 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 59827cc5e770..c786cd4f457b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | |||
| @@ -224,7 +224,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, | |||
| 224 | get_dma_buf(dma_buf); | 224 | get_dma_buf(dma_buf); |
| 225 | 225 | ||
| 226 | sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); | 226 | sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); |
| 227 | if (IS_ERR_OR_NULL(sgt)) { | 227 | if (IS_ERR(sgt)) { |
| 228 | ret = PTR_ERR(sgt); | 228 | ret = PTR_ERR(sgt); |
| 229 | goto err_buf_detach; | 229 | goto err_buf_detach; |
| 230 | } | 230 | } |
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 33d3871d1e13..880be0782dd9 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c | |||
| @@ -719,7 +719,7 @@ static int vb2_dc_map_dmabuf(void *mem_priv) | |||
| 719 | 719 | ||
| 720 | /* get the associated scatterlist for this buffer */ | 720 | /* get the associated scatterlist for this buffer */ |
| 721 | sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir); | 721 | sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir); |
| 722 | if (IS_ERR_OR_NULL(sgt)) { | 722 | if (IS_ERR(sgt)) { |
| 723 | pr_err("Error getting dmabuf scatterlist\n"); | 723 | pr_err("Error getting dmabuf scatterlist\n"); |
| 724 | return -EINVAL; | 724 | return -EINVAL; |
| 725 | } | 725 | } |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 276ef9c18802..4e0acefb7565 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -351,28 +351,17 @@ static struct device_attribute dev_rescan_attr = __ATTR(rescan, | |||
| 351 | (S_IWUSR|S_IWGRP), | 351 | (S_IWUSR|S_IWGRP), |
| 352 | NULL, dev_rescan_store); | 352 | NULL, dev_rescan_store); |
| 353 | 353 | ||
| 354 | static void remove_callback(struct device *dev) | ||
| 355 | { | ||
| 356 | pci_stop_and_remove_bus_device_locked(to_pci_dev(dev)); | ||
| 357 | } | ||
| 358 | |||
| 359 | static ssize_t | 354 | static ssize_t |
| 360 | remove_store(struct device *dev, struct device_attribute *dummy, | 355 | remove_store(struct device *dev, struct device_attribute *attr, |
| 361 | const char *buf, size_t count) | 356 | const char *buf, size_t count) |
| 362 | { | 357 | { |
| 363 | int ret = 0; | ||
| 364 | unsigned long val; | 358 | unsigned long val; |
| 365 | 359 | ||
| 366 | if (kstrtoul(buf, 0, &val) < 0) | 360 | if (kstrtoul(buf, 0, &val) < 0) |
| 367 | return -EINVAL; | 361 | return -EINVAL; |
| 368 | 362 | ||
| 369 | /* An attribute cannot be unregistered by one of its own methods, | 363 | if (val && device_remove_file_self(dev, attr)) |
| 370 | * so we have to use this roundabout approach. | 364 | pci_stop_and_remove_bus_device_locked(to_pci_dev(dev)); |
| 371 | */ | ||
| 372 | if (val) | ||
| 373 | ret = device_schedule_callback(dev, remove_callback); | ||
| 374 | if (ret) | ||
| 375 | count = ret; | ||
| 376 | return count; | 365 | return count; |
| 377 | } | 366 | } |
| 378 | static struct device_attribute dev_remove_attr = __ATTR(remove, | 367 | static struct device_attribute dev_remove_attr = __ATTR(remove, |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index ebf41e228e55..ee0e85abe1fd 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
| @@ -304,12 +304,6 @@ dcssblk_load_segment(char *name, struct segment_info **seg_info) | |||
| 304 | return rc; | 304 | return rc; |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | static void dcssblk_unregister_callback(struct device *dev) | ||
| 308 | { | ||
| 309 | device_unregister(dev); | ||
| 310 | put_device(dev); | ||
| 311 | } | ||
| 312 | |||
| 313 | /* | 307 | /* |
| 314 | * device attribute for switching shared/nonshared (exclusive) | 308 | * device attribute for switching shared/nonshared (exclusive) |
| 315 | * operation (show + store) | 309 | * operation (show + store) |
| @@ -397,7 +391,13 @@ removeseg: | |||
| 397 | blk_cleanup_queue(dev_info->dcssblk_queue); | 391 | blk_cleanup_queue(dev_info->dcssblk_queue); |
| 398 | dev_info->gd->queue = NULL; | 392 | dev_info->gd->queue = NULL; |
| 399 | put_disk(dev_info->gd); | 393 | put_disk(dev_info->gd); |
| 400 | rc = device_schedule_callback(dev, dcssblk_unregister_callback); | 394 | up_write(&dcssblk_devices_sem); |
| 395 | |||
| 396 | if (device_remove_file_self(dev, attr)) { | ||
| 397 | device_unregister(dev); | ||
| 398 | put_device(dev); | ||
| 399 | } | ||
| 400 | return rc; | ||
| 401 | out: | 401 | out: |
| 402 | up_write(&dcssblk_devices_sem); | 402 | up_write(&dcssblk_devices_sem); |
| 403 | return rc; | 403 | return rc; |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index fd3367a1dc7a..dfd7bc681c25 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
| @@ -168,14 +168,12 @@ static ssize_t ccwgroup_online_show(struct device *dev, | |||
| 168 | * Provide an 'ungroup' attribute so the user can remove group devices no | 168 | * Provide an 'ungroup' attribute so the user can remove group devices no |
| 169 | * longer needed or accidentially created. Saves memory :) | 169 | * longer needed or accidentially created. Saves memory :) |
| 170 | */ | 170 | */ |
| 171 | static void ccwgroup_ungroup_callback(struct device *dev) | 171 | static void ccwgroup_ungroup(struct ccwgroup_device *gdev) |
| 172 | { | 172 | { |
| 173 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
| 174 | |||
| 175 | mutex_lock(&gdev->reg_mutex); | 173 | mutex_lock(&gdev->reg_mutex); |
| 176 | if (device_is_registered(&gdev->dev)) { | 174 | if (device_is_registered(&gdev->dev)) { |
| 177 | __ccwgroup_remove_symlinks(gdev); | 175 | __ccwgroup_remove_symlinks(gdev); |
| 178 | device_unregister(dev); | 176 | device_unregister(&gdev->dev); |
| 179 | __ccwgroup_remove_cdev_refs(gdev); | 177 | __ccwgroup_remove_cdev_refs(gdev); |
| 180 | } | 178 | } |
| 181 | mutex_unlock(&gdev->reg_mutex); | 179 | mutex_unlock(&gdev->reg_mutex); |
| @@ -195,10 +193,9 @@ static ssize_t ccwgroup_ungroup_store(struct device *dev, | |||
| 195 | rc = -EINVAL; | 193 | rc = -EINVAL; |
| 196 | goto out; | 194 | goto out; |
| 197 | } | 195 | } |
| 198 | /* Note that we cannot unregister the device from one of its | 196 | |
| 199 | * attribute methods, so we have to use this roundabout approach. | 197 | if (device_remove_file_self(dev, attr)) |
| 200 | */ | 198 | ccwgroup_ungroup(gdev); |
| 201 | rc = device_schedule_callback(dev, ccwgroup_ungroup_callback); | ||
| 202 | out: | 199 | out: |
| 203 | if (rc) { | 200 | if (rc) { |
| 204 | if (rc != -EAGAIN) | 201 | if (rc != -EAGAIN) |
| @@ -224,6 +221,14 @@ static const struct attribute_group *ccwgroup_attr_groups[] = { | |||
| 224 | NULL, | 221 | NULL, |
| 225 | }; | 222 | }; |
| 226 | 223 | ||
| 224 | static void ccwgroup_ungroup_workfn(struct work_struct *work) | ||
| 225 | { | ||
| 226 | struct ccwgroup_device *gdev = | ||
| 227 | container_of(work, struct ccwgroup_device, ungroup_work); | ||
| 228 | |||
| 229 | ccwgroup_ungroup(gdev); | ||
| 230 | } | ||
| 231 | |||
| 227 | static void ccwgroup_release(struct device *dev) | 232 | static void ccwgroup_release(struct device *dev) |
| 228 | { | 233 | { |
| 229 | kfree(to_ccwgroupdev(dev)); | 234 | kfree(to_ccwgroupdev(dev)); |
| @@ -323,6 +328,7 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, | |||
| 323 | atomic_set(&gdev->onoff, 0); | 328 | atomic_set(&gdev->onoff, 0); |
| 324 | mutex_init(&gdev->reg_mutex); | 329 | mutex_init(&gdev->reg_mutex); |
| 325 | mutex_lock(&gdev->reg_mutex); | 330 | mutex_lock(&gdev->reg_mutex); |
| 331 | INIT_WORK(&gdev->ungroup_work, ccwgroup_ungroup_workfn); | ||
| 326 | gdev->count = num_devices; | 332 | gdev->count = num_devices; |
| 327 | gdev->dev.bus = &ccwgroup_bus_type; | 333 | gdev->dev.bus = &ccwgroup_bus_type; |
| 328 | gdev->dev.parent = parent; | 334 | gdev->dev.parent = parent; |
| @@ -404,10 +410,10 @@ EXPORT_SYMBOL(ccwgroup_create_dev); | |||
| 404 | static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, | 410 | static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, |
| 405 | void *data) | 411 | void *data) |
| 406 | { | 412 | { |
| 407 | struct device *dev = data; | 413 | struct ccwgroup_device *gdev = to_ccwgroupdev(data); |
| 408 | 414 | ||
| 409 | if (action == BUS_NOTIFY_UNBIND_DRIVER) | 415 | if (action == BUS_NOTIFY_UNBIND_DRIVER) |
| 410 | device_schedule_callback(dev, ccwgroup_ungroup_callback); | 416 | schedule_work(&gdev->ungroup_work); |
| 411 | 417 | ||
| 412 | return NOTIFY_OK; | 418 | return NOTIFY_OK; |
| 413 | } | 419 | } |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 9117d0bf408e..8ead24c3453a 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
| @@ -649,23 +649,12 @@ store_rescan_field (struct device *dev, struct device_attribute *attr, | |||
| 649 | } | 649 | } |
| 650 | static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field); | 650 | static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field); |
| 651 | 651 | ||
| 652 | static void sdev_store_delete_callback(struct device *dev) | ||
| 653 | { | ||
| 654 | scsi_remove_device(to_scsi_device(dev)); | ||
| 655 | } | ||
| 656 | |||
| 657 | static ssize_t | 652 | static ssize_t |
| 658 | sdev_store_delete(struct device *dev, struct device_attribute *attr, | 653 | sdev_store_delete(struct device *dev, struct device_attribute *attr, |
| 659 | const char *buf, size_t count) | 654 | const char *buf, size_t count) |
| 660 | { | 655 | { |
| 661 | int rc; | 656 | if (device_remove_file_self(dev, attr)) |
| 662 | 657 | scsi_remove_device(to_scsi_device(dev)); | |
| 663 | /* An attribute cannot be unregistered by one of its own methods, | ||
| 664 | * so we have to use this roundabout approach. | ||
| 665 | */ | ||
| 666 | rc = device_schedule_callback(dev, sdev_store_delete_callback); | ||
| 667 | if (rc) | ||
| 668 | count = rc; | ||
| 669 | return count; | 658 | return count; |
| 670 | }; | 659 | }; |
| 671 | static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete); | 660 | static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete); |
