aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-03 23:03:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-03 23:03:24 -0400
commit9929780e86854833e649b39b290b5fe921eb1701 (patch)
tree7e3944e926a5ab81bb10397259df404280c75e45
parent7a53eea1f7b527fd3b6d7ca992914840981afe99 (diff)
parentdd01c75f1df311793de6ef217c72036552000c9a (diff)
Merge tag 'driver-core-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH: "Here are the "big" driver core patches for 4.9-rc1. Also in here are a number of debugfs fixes that cropped up due to the changes that happened in 4.8 for that filesystem. Overall, nothing major, just a few fixes and cleanups. All of these have been in linux-next with no reported issues" * tag 'driver-core-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (23 commits) drivers: dma-coherent: Move spinlock in dma_alloc_from_coherent() drivers: dma-coherent: Fix DMA coherent size for less than page MAINTAINERS: extend firmware_class maintainer list debugfs: propagate release() call result driver-core: platform: Catch errors from calls to irq_get_irq_data sysfs print name of undiscoverable attribute group carl9170: fix debugfs crashes b43legacy: fix debugfs crash b43: fix debugfs crash debugfs: introduce a public file_operations accessor device core: Remove deprecated create_singlethread_workqueue drivers/base dmam_declare_coherent_memory leaks platform: don't return 0 from platform_get_irq[_byname]() on error cpu: clean up register_cpu func dma-mapping: use vma_pages(). drivers: dma-coherent: use vma_pages(). attribute_container: Fix typo base: soc: make it explicitly non-modular drivers: base: dma-mapping: page align the size when unmap_kernel_range platform driver: fix use-after-free in platform_device_del() ...
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/base/Kconfig10
-rw-r--r--drivers/base/attribute_container.c2
-rw-r--r--drivers/base/core.c39
-rw-r--r--drivers/base/cpu.c11
-rw-r--r--drivers/base/dd.c33
-rw-r--r--drivers/base/dma-coherent.c10
-rw-r--r--drivers/base/dma-mapping.c11
-rw-r--r--drivers/base/platform.c18
-rw-r--r--drivers/base/soc.c9
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c6
-rw-r--r--drivers/net/wireless/broadcom/b43/debugfs.c6
-rw-r--r--drivers/net/wireless/broadcom/b43legacy/debugfs.c6
-rw-r--r--fs/debugfs/file.c15
-rw-r--r--fs/debugfs/internal.h4
-rw-r--r--fs/sysfs/group.c4
-rw-r--r--include/linux/debugfs.h17
17 files changed, 132 insertions, 70 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 154782568de2..d52eae7c0755 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4866,6 +4866,7 @@ F: tools/firewire/
4866 4866
4867FIRMWARE LOADER (request_firmware) 4867FIRMWARE LOADER (request_firmware)
4868M: Ming Lei <ming.lei@canonical.com> 4868M: Ming Lei <ming.lei@canonical.com>
4869M: Luis R. Rodriguez <mcgrof@kernel.org>
4869L: linux-kernel@vger.kernel.org 4870L: linux-kernel@vger.kernel.org
4870S: Maintained 4871S: Maintained
4871F: Documentation/firmware_class/ 4872F: Documentation/firmware_class/
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 98504ec99c7d..fdf44cac08e6 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -212,6 +212,16 @@ config DEBUG_DEVRES
212 212
213 If you are unsure about this, Say N here. 213 If you are unsure about this, Say N here.
214 214
215config DEBUG_TEST_DRIVER_REMOVE
216 bool "Test driver remove calls during probe"
217 depends on DEBUG_KERNEL
218 help
219 Say Y here if you want the Driver core to test driver remove functions
220 by calling probe, remove, probe. This tests the remove path without
221 having to unbind the driver or unload the driver module.
222
223 If you are unsure about this, say N here.
224
215config SYS_HYPERVISOR 225config SYS_HYPERVISOR
216 bool 226 bool
217 default n 227 default n
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 2ba4cac080c5..95e3ef82f3b7 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -243,7 +243,7 @@ attribute_container_remove_device(struct device *dev,
243 * @dev: The generic device to run the trigger for 243 * @dev: The generic device to run the trigger for
244 * @fn the function to execute for each classdev. 244 * @fn the function to execute for each classdev.
245 * 245 *
246 * This funcion is for executing a trigger when you need to know both 246 * This function is for executing a trigger when you need to know both
247 * the container and the classdev. If you only care about the 247 * the container and the classdev. If you only care about the
248 * container, then use attribute_container_trigger() instead. 248 * container, then use attribute_container_trigger() instead.
249 */ 249 */
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 70c5be5b03a7..ce057a568673 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -836,11 +836,29 @@ static struct kobject *get_device_parent(struct device *dev,
836 return NULL; 836 return NULL;
837} 837}
838 838
839static inline bool live_in_glue_dir(struct kobject *kobj,
840 struct device *dev)
841{
842 if (!kobj || !dev->class ||
843 kobj->kset != &dev->class->p->glue_dirs)
844 return false;
845 return true;
846}
847
848static inline struct kobject *get_glue_dir(struct device *dev)
849{
850 return dev->kobj.parent;
851}
852
853/*
854 * make sure cleaning up dir as the last step, we need to make
855 * sure .release handler of kobject is run with holding the
856 * global lock
857 */
839static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) 858static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
840{ 859{
841 /* see if we live in a "glue" directory */ 860 /* see if we live in a "glue" directory */
842 if (!glue_dir || !dev->class || 861 if (!live_in_glue_dir(glue_dir, dev))
843 glue_dir->kset != &dev->class->p->glue_dirs)
844 return; 862 return;
845 863
846 mutex_lock(&gdp_mutex); 864 mutex_lock(&gdp_mutex);
@@ -848,11 +866,6 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
848 mutex_unlock(&gdp_mutex); 866 mutex_unlock(&gdp_mutex);
849} 867}
850 868
851static void cleanup_device_parent(struct device *dev)
852{
853 cleanup_glue_dir(dev, dev->kobj.parent);
854}
855
856static int device_add_class_symlinks(struct device *dev) 869static int device_add_class_symlinks(struct device *dev)
857{ 870{
858 struct device_node *of_node = dev_of_node(dev); 871 struct device_node *of_node = dev_of_node(dev);
@@ -1028,6 +1041,7 @@ int device_add(struct device *dev)
1028 struct kobject *kobj; 1041 struct kobject *kobj;
1029 struct class_interface *class_intf; 1042 struct class_interface *class_intf;
1030 int error = -EINVAL; 1043 int error = -EINVAL;
1044 struct kobject *glue_dir = NULL;
1031 1045
1032 dev = get_device(dev); 1046 dev = get_device(dev);
1033 if (!dev) 1047 if (!dev)
@@ -1072,8 +1086,10 @@ int device_add(struct device *dev)
1072 /* first, register with generic layer. */ 1086 /* first, register with generic layer. */
1073 /* we require the name to be set before, and pass NULL */ 1087 /* we require the name to be set before, and pass NULL */
1074 error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); 1088 error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
1075 if (error) 1089 if (error) {
1090 glue_dir = get_glue_dir(dev);
1076 goto Error; 1091 goto Error;
1092 }
1077 1093
1078 /* notify platform of device entry */ 1094 /* notify platform of device entry */
1079 if (platform_notify) 1095 if (platform_notify)
@@ -1154,9 +1170,10 @@ done:
1154 device_remove_file(dev, &dev_attr_uevent); 1170 device_remove_file(dev, &dev_attr_uevent);
1155 attrError: 1171 attrError:
1156 kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1172 kobject_uevent(&dev->kobj, KOBJ_REMOVE);
1173 glue_dir = get_glue_dir(dev);
1157 kobject_del(&dev->kobj); 1174 kobject_del(&dev->kobj);
1158 Error: 1175 Error:
1159 cleanup_device_parent(dev); 1176 cleanup_glue_dir(dev, glue_dir);
1160 put_device(parent); 1177 put_device(parent);
1161name_error: 1178name_error:
1162 kfree(dev->p); 1179 kfree(dev->p);
@@ -1232,6 +1249,7 @@ EXPORT_SYMBOL_GPL(put_device);
1232void device_del(struct device *dev) 1249void device_del(struct device *dev)
1233{ 1250{
1234 struct device *parent = dev->parent; 1251 struct device *parent = dev->parent;
1252 struct kobject *glue_dir = NULL;
1235 struct class_interface *class_intf; 1253 struct class_interface *class_intf;
1236 1254
1237 /* Notify clients of device removal. This call must come 1255 /* Notify clients of device removal. This call must come
@@ -1277,8 +1295,9 @@ void device_del(struct device *dev)
1277 blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 1295 blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
1278 BUS_NOTIFY_REMOVED_DEVICE, dev); 1296 BUS_NOTIFY_REMOVED_DEVICE, dev);
1279 kobject_uevent(&dev->kobj, KOBJ_REMOVE); 1297 kobject_uevent(&dev->kobj, KOBJ_REMOVE);
1280 cleanup_device_parent(dev); 1298 glue_dir = get_glue_dir(dev);
1281 kobject_del(&dev->kobj); 1299 kobject_del(&dev->kobj);
1300 cleanup_glue_dir(dev, glue_dir);
1282 put_device(parent); 1301 put_device(parent);
1283} 1302}
1284EXPORT_SYMBOL_GPL(device_del); 1303EXPORT_SYMBOL_GPL(device_del);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 691eeea2f19a..4c28e1a09786 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -371,12 +371,13 @@ int register_cpu(struct cpu *cpu, int num)
371 if (cpu->hotpluggable) 371 if (cpu->hotpluggable)
372 cpu->dev.groups = hotplugable_cpu_attr_groups; 372 cpu->dev.groups = hotplugable_cpu_attr_groups;
373 error = device_register(&cpu->dev); 373 error = device_register(&cpu->dev);
374 if (!error) 374 if (error)
375 per_cpu(cpu_sys_devices, num) = &cpu->dev; 375 return error;
376 if (!error)
377 register_cpu_under_node(num, cpu_to_node(num));
378 376
379 return error; 377 per_cpu(cpu_sys_devices, num) = &cpu->dev;
378 register_cpu_under_node(num, cpu_to_node(num));
379
380 return 0;
380} 381}
381 382
382struct device *get_cpu_device(unsigned cpu) 383struct device *get_cpu_device(unsigned cpu)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 16688f50729c..d22a7260f42b 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -51,7 +51,6 @@
51static DEFINE_MUTEX(deferred_probe_mutex); 51static DEFINE_MUTEX(deferred_probe_mutex);
52static LIST_HEAD(deferred_probe_pending_list); 52static LIST_HEAD(deferred_probe_pending_list);
53static LIST_HEAD(deferred_probe_active_list); 53static LIST_HEAD(deferred_probe_active_list);
54static struct workqueue_struct *deferred_wq;
55static atomic_t deferred_trigger_count = ATOMIC_INIT(0); 54static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
56 55
57/* 56/*
@@ -175,7 +174,7 @@ static void driver_deferred_probe_trigger(void)
175 * Kick the re-probe thread. It may already be scheduled, but it is 174 * Kick the re-probe thread. It may already be scheduled, but it is
176 * safe to kick it again. 175 * safe to kick it again.
177 */ 176 */
178 queue_work(deferred_wq, &deferred_probe_work); 177 schedule_work(&deferred_probe_work);
179} 178}
180 179
181/** 180/**
@@ -211,14 +210,10 @@ void device_unblock_probing(void)
211 */ 210 */
212static int deferred_probe_initcall(void) 211static int deferred_probe_initcall(void)
213{ 212{
214 deferred_wq = create_singlethread_workqueue("deferwq");
215 if (WARN_ON(!deferred_wq))
216 return -ENOMEM;
217
218 driver_deferred_probe_enable = true; 213 driver_deferred_probe_enable = true;
219 driver_deferred_probe_trigger(); 214 driver_deferred_probe_trigger();
220 /* Sort as many dependencies as possible before exiting initcalls */ 215 /* Sort as many dependencies as possible before exiting initcalls */
221 flush_workqueue(deferred_wq); 216 flush_work(&deferred_probe_work);
222 return 0; 217 return 0;
223} 218}
224late_initcall(deferred_probe_initcall); 219late_initcall(deferred_probe_initcall);
@@ -329,6 +324,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
329{ 324{
330 int ret = -EPROBE_DEFER; 325 int ret = -EPROBE_DEFER;
331 int local_trigger_count = atomic_read(&deferred_trigger_count); 326 int local_trigger_count = atomic_read(&deferred_trigger_count);
327 bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE);
332 328
333 if (defer_all_probes) { 329 if (defer_all_probes) {
334 /* 330 /*
@@ -346,6 +342,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
346 drv->bus->name, __func__, drv->name, dev_name(dev)); 342 drv->bus->name, __func__, drv->name, dev_name(dev));
347 WARN_ON(!list_empty(&dev->devres_head)); 343 WARN_ON(!list_empty(&dev->devres_head));
348 344
345re_probe:
349 dev->driver = drv; 346 dev->driver = drv;
350 347
351 /* If using pinctrl, bind pins now before probing */ 348 /* If using pinctrl, bind pins now before probing */
@@ -383,6 +380,25 @@ static int really_probe(struct device *dev, struct device_driver *drv)
383 goto probe_failed; 380 goto probe_failed;
384 } 381 }
385 382
383 if (test_remove) {
384 test_remove = false;
385
386 if (dev->bus && dev->bus->remove)
387 dev->bus->remove(dev);
388 else if (drv->remove)
389 drv->remove(dev);
390
391 devres_release_all(dev);
392 driver_sysfs_remove(dev);
393 dev->driver = NULL;
394 dev_set_drvdata(dev, NULL);
395 if (dev->pm_domain && dev->pm_domain->dismiss)
396 dev->pm_domain->dismiss(dev);
397 pm_runtime_reinit(dev);
398
399 goto re_probe;
400 }
401
386 pinctrl_init_done(dev); 402 pinctrl_init_done(dev);
387 403
388 if (dev->pm_domain && dev->pm_domain->sync) 404 if (dev->pm_domain && dev->pm_domain->sync)
@@ -460,8 +476,7 @@ int driver_probe_done(void)
460void wait_for_device_probe(void) 476void wait_for_device_probe(void)
461{ 477{
462 /* wait for the deferred probe workqueue to finish */ 478 /* wait for the deferred probe workqueue to finish */
463 if (driver_deferred_probe_enable) 479 flush_work(&deferred_probe_work);
464 flush_workqueue(deferred_wq);
465 480
466 /* wait for the known devices to complete their probing */ 481 /* wait for the known devices to complete their probing */
467 wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); 482 wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index bdf28f7dd5e8..640a7e63c453 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -165,6 +165,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
165 int order = get_order(size); 165 int order = get_order(size);
166 unsigned long flags; 166 unsigned long flags;
167 int pageno; 167 int pageno;
168 int dma_memory_map;
168 169
169 if (!dev) 170 if (!dev)
170 return 0; 171 return 0;
@@ -187,11 +188,12 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
187 */ 188 */
188 *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); 189 *dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
189 *ret = mem->virt_base + (pageno << PAGE_SHIFT); 190 *ret = mem->virt_base + (pageno << PAGE_SHIFT);
190 if (mem->flags & DMA_MEMORY_MAP) 191 dma_memory_map = (mem->flags & DMA_MEMORY_MAP);
192 spin_unlock_irqrestore(&mem->spinlock, flags);
193 if (dma_memory_map)
191 memset(*ret, 0, size); 194 memset(*ret, 0, size);
192 else 195 else
193 memset_io(*ret, 0, size); 196 memset_io(*ret, 0, size);
194 spin_unlock_irqrestore(&mem->spinlock, flags);
195 197
196 return 1; 198 return 1;
197 199
@@ -261,8 +263,8 @@ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
261 (mem->virt_base + (mem->size << PAGE_SHIFT))) { 263 (mem->virt_base + (mem->size << PAGE_SHIFT))) {
262 unsigned long off = vma->vm_pgoff; 264 unsigned long off = vma->vm_pgoff;
263 int start = (vaddr - mem->virt_base) >> PAGE_SHIFT; 265 int start = (vaddr - mem->virt_base) >> PAGE_SHIFT;
264 int user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 266 int user_count = vma_pages(vma);
265 int count = size >> PAGE_SHIFT; 267 int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
266 268
267 *ret = -ENXIO; 269 *ret = -ENXIO;
268 if (off < count && user_count <= count - off) { 270 if (off < count && user_count <= count - off) {
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index d799662f19eb..8f8b68c80986 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -198,10 +198,13 @@ int dmam_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
198 198
199 rc = dma_declare_coherent_memory(dev, phys_addr, device_addr, size, 199 rc = dma_declare_coherent_memory(dev, phys_addr, device_addr, size,
200 flags); 200 flags);
201 if (rc == 0) 201 if (rc) {
202 devres_add(dev, res); 202 devres_add(dev, res);
203 else 203 rc = 0;
204 } else {
204 devres_free(res); 205 devres_free(res);
206 rc = -ENOMEM;
207 }
205 208
206 return rc; 209 return rc;
207} 210}
@@ -247,7 +250,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
247{ 250{
248 int ret = -ENXIO; 251 int ret = -ENXIO;
249#if defined(CONFIG_MMU) && !defined(CONFIG_ARCH_NO_COHERENT_DMA_MMAP) 252#if defined(CONFIG_MMU) && !defined(CONFIG_ARCH_NO_COHERENT_DMA_MMAP)
250 unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 253 unsigned long user_count = vma_pages(vma);
251 unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; 254 unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
252 unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr)); 255 unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
253 unsigned long off = vma->vm_pgoff; 256 unsigned long off = vma->vm_pgoff;
@@ -334,7 +337,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
334 return; 337 return;
335 } 338 }
336 339
337 unmap_kernel_range((unsigned long)cpu_addr, size); 340 unmap_kernel_range((unsigned long)cpu_addr, PAGE_ALIGN(size));
338 vunmap(cpu_addr); 341 vunmap(cpu_addr);
339} 342}
340#endif 343#endif
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6482d47deb50..c4af00385502 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -97,7 +97,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
97 int ret; 97 int ret;
98 98
99 ret = of_irq_get(dev->dev.of_node, num); 99 ret = of_irq_get(dev->dev.of_node, num);
100 if (ret >= 0 || ret == -EPROBE_DEFER) 100 if (ret > 0 || ret == -EPROBE_DEFER)
101 return ret; 101 return ret;
102 } 102 }
103 103
@@ -108,9 +108,14 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
108 * IORESOURCE_BITS correspond 1-to-1 to the IRQF_TRIGGER* 108 * IORESOURCE_BITS correspond 1-to-1 to the IRQF_TRIGGER*
109 * settings. 109 * settings.
110 */ 110 */
111 if (r && r->flags & IORESOURCE_BITS) 111 if (r && r->flags & IORESOURCE_BITS) {
112 irqd_set_trigger_type(irq_get_irq_data(r->start), 112 struct irq_data *irqd;
113 r->flags & IORESOURCE_BITS); 113
114 irqd = irq_get_irq_data(r->start);
115 if (!irqd)
116 return -ENXIO;
117 irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS);
118 }
114 119
115 return r ? r->start : -ENXIO; 120 return r ? r->start : -ENXIO;
116#endif 121#endif
@@ -175,7 +180,7 @@ int platform_get_irq_byname(struct platform_device *dev, const char *name)
175 int ret; 180 int ret;
176 181
177 ret = of_irq_get_byname(dev->dev.of_node, name); 182 ret = of_irq_get_byname(dev->dev.of_node, name);
178 if (ret >= 0 || ret == -EPROBE_DEFER) 183 if (ret > 0 || ret == -EPROBE_DEFER)
179 return ret; 184 return ret;
180 } 185 }
181 186
@@ -434,6 +439,7 @@ void platform_device_del(struct platform_device *pdev)
434 int i; 439 int i;
435 440
436 if (pdev) { 441 if (pdev) {
442 device_remove_properties(&pdev->dev);
437 device_del(&pdev->dev); 443 device_del(&pdev->dev);
438 444
439 if (pdev->id_auto) { 445 if (pdev->id_auto) {
@@ -446,8 +452,6 @@ void platform_device_del(struct platform_device *pdev)
446 if (r->parent) 452 if (r->parent)
447 release_resource(r); 453 release_resource(r);
448 } 454 }
449
450 device_remove_properties(&pdev->dev);
451 } 455 }
452} 456}
453EXPORT_SYMBOL_GPL(platform_device_del); 457EXPORT_SYMBOL_GPL(platform_device_del);
diff --git a/drivers/base/soc.c b/drivers/base/soc.c
index 75b98aad6faf..b63f23e6ad61 100644
--- a/drivers/base/soc.c
+++ b/drivers/base/soc.c
@@ -6,7 +6,6 @@
6 */ 6 */
7 7
8#include <linux/sysfs.h> 8#include <linux/sysfs.h>
9#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/stat.h> 10#include <linux/stat.h>
12#include <linux/slab.h> 11#include <linux/slab.h>
@@ -160,11 +159,3 @@ static int __init soc_bus_register(void)
160 return bus_register(&soc_bus_type); 159 return bus_register(&soc_bus_type);
161} 160}
162core_initcall(soc_bus_register); 161core_initcall(soc_bus_register);
163
164static void __exit soc_bus_unregister(void)
165{
166 ida_destroy(&soc_ida);
167
168 bus_unregister(&soc_bus_type);
169}
170module_exit(soc_bus_unregister);
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
index 6808db433283..ec3a64e5d2bb 100644
--- a/drivers/net/wireless/ath/carl9170/debug.c
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -75,7 +75,8 @@ static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
75 75
76 if (!ar) 76 if (!ar)
77 return -ENODEV; 77 return -ENODEV;
78 dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); 78 dfops = container_of(debugfs_real_fops(file),
79 struct carl9170_debugfs_fops, fops);
79 80
80 if (!dfops->read) 81 if (!dfops->read)
81 return -ENOSYS; 82 return -ENOSYS;
@@ -127,7 +128,8 @@ static ssize_t carl9170_debugfs_write(struct file *file,
127 128
128 if (!ar) 129 if (!ar)
129 return -ENODEV; 130 return -ENODEV;
130 dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); 131 dfops = container_of(debugfs_real_fops(file),
132 struct carl9170_debugfs_fops, fops);
131 133
132 if (!dfops->write) 134 if (!dfops->write)
133 return -ENOSYS; 135 return -ENOSYS;
diff --git a/drivers/net/wireless/broadcom/b43/debugfs.c b/drivers/net/wireless/broadcom/b43/debugfs.c
index b4bcd94aff6c..77046384dd80 100644
--- a/drivers/net/wireless/broadcom/b43/debugfs.c
+++ b/drivers/net/wireless/broadcom/b43/debugfs.c
@@ -524,7 +524,8 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
524 goto out_unlock; 524 goto out_unlock;
525 } 525 }
526 526
527 dfops = container_of(file->f_op, struct b43_debugfs_fops, fops); 527 dfops = container_of(debugfs_real_fops(file),
528 struct b43_debugfs_fops, fops);
528 if (!dfops->read) { 529 if (!dfops->read) {
529 err = -ENOSYS; 530 err = -ENOSYS;
530 goto out_unlock; 531 goto out_unlock;
@@ -585,7 +586,8 @@ static ssize_t b43_debugfs_write(struct file *file,
585 goto out_unlock; 586 goto out_unlock;
586 } 587 }
587 588
588 dfops = container_of(file->f_op, struct b43_debugfs_fops, fops); 589 dfops = container_of(debugfs_real_fops(file),
590 struct b43_debugfs_fops, fops);
589 if (!dfops->write) { 591 if (!dfops->write) {
590 err = -ENOSYS; 592 err = -ENOSYS;
591 goto out_unlock; 593 goto out_unlock;
diff --git a/drivers/net/wireless/broadcom/b43legacy/debugfs.c b/drivers/net/wireless/broadcom/b43legacy/debugfs.c
index 090910ea259e..82ef56ed7ca1 100644
--- a/drivers/net/wireless/broadcom/b43legacy/debugfs.c
+++ b/drivers/net/wireless/broadcom/b43legacy/debugfs.c
@@ -221,7 +221,8 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
221 goto out_unlock; 221 goto out_unlock;
222 } 222 }
223 223
224 dfops = container_of(file->f_op, struct b43legacy_debugfs_fops, fops); 224 dfops = container_of(debugfs_real_fops(file),
225 struct b43legacy_debugfs_fops, fops);
225 if (!dfops->read) { 226 if (!dfops->read) {
226 err = -ENOSYS; 227 err = -ENOSYS;
227 goto out_unlock; 228 goto out_unlock;
@@ -287,7 +288,8 @@ static ssize_t b43legacy_debugfs_write(struct file *file,
287 goto out_unlock; 288 goto out_unlock;
288 } 289 }
289 290
290 dfops = container_of(file->f_op, struct b43legacy_debugfs_fops, fops); 291 dfops = container_of(debugfs_real_fops(file),
292 struct b43legacy_debugfs_fops, fops);
291 if (!dfops->write) { 293 if (!dfops->write) {
292 err = -ENOSYS; 294 err = -ENOSYS;
293 goto out_unlock; 295 goto out_unlock;
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 592059f88e04..354e2ab62031 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -97,9 +97,6 @@ EXPORT_SYMBOL_GPL(debugfs_use_file_finish);
97 97
98#define F_DENTRY(filp) ((filp)->f_path.dentry) 98#define F_DENTRY(filp) ((filp)->f_path.dentry)
99 99
100#define REAL_FOPS_DEREF(dentry) \
101 ((const struct file_operations *)(dentry)->d_fsdata)
102
103static int open_proxy_open(struct inode *inode, struct file *filp) 100static int open_proxy_open(struct inode *inode, struct file *filp)
104{ 101{
105 const struct dentry *dentry = F_DENTRY(filp); 102 const struct dentry *dentry = F_DENTRY(filp);
@@ -112,7 +109,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp)
112 goto out; 109 goto out;
113 } 110 }
114 111
115 real_fops = REAL_FOPS_DEREF(dentry); 112 real_fops = debugfs_real_fops(filp);
116 real_fops = fops_get(real_fops); 113 real_fops = fops_get(real_fops);
117 if (!real_fops) { 114 if (!real_fops) {
118 /* Huh? Module did not clean up after itself at exit? */ 115 /* Huh? Module did not clean up after itself at exit? */
@@ -143,7 +140,7 @@ static ret_type full_proxy_ ## name(proto) \
143{ \ 140{ \
144 const struct dentry *dentry = F_DENTRY(filp); \ 141 const struct dentry *dentry = F_DENTRY(filp); \
145 const struct file_operations *real_fops = \ 142 const struct file_operations *real_fops = \
146 REAL_FOPS_DEREF(dentry); \ 143 debugfs_real_fops(filp); \
147 int srcu_idx; \ 144 int srcu_idx; \
148 ret_type r; \ 145 ret_type r; \
149 \ 146 \
@@ -176,7 +173,7 @@ static unsigned int full_proxy_poll(struct file *filp,
176 struct poll_table_struct *wait) 173 struct poll_table_struct *wait)
177{ 174{
178 const struct dentry *dentry = F_DENTRY(filp); 175 const struct dentry *dentry = F_DENTRY(filp);
179 const struct file_operations *real_fops = REAL_FOPS_DEREF(dentry); 176 const struct file_operations *real_fops = debugfs_real_fops(filp);
180 int srcu_idx; 177 int srcu_idx;
181 unsigned int r = 0; 178 unsigned int r = 0;
182 179
@@ -193,7 +190,7 @@ static unsigned int full_proxy_poll(struct file *filp,
193static int full_proxy_release(struct inode *inode, struct file *filp) 190static int full_proxy_release(struct inode *inode, struct file *filp)
194{ 191{
195 const struct dentry *dentry = F_DENTRY(filp); 192 const struct dentry *dentry = F_DENTRY(filp);
196 const struct file_operations *real_fops = REAL_FOPS_DEREF(dentry); 193 const struct file_operations *real_fops = debugfs_real_fops(filp);
197 const struct file_operations *proxy_fops = filp->f_op; 194 const struct file_operations *proxy_fops = filp->f_op;
198 int r = 0; 195 int r = 0;
199 196
@@ -209,7 +206,7 @@ static int full_proxy_release(struct inode *inode, struct file *filp)
209 replace_fops(filp, d_inode(dentry)->i_fop); 206 replace_fops(filp, d_inode(dentry)->i_fop);
210 kfree((void *)proxy_fops); 207 kfree((void *)proxy_fops);
211 fops_put(real_fops); 208 fops_put(real_fops);
212 return 0; 209 return r;
213} 210}
214 211
215static void __full_proxy_fops_init(struct file_operations *proxy_fops, 212static void __full_proxy_fops_init(struct file_operations *proxy_fops,
@@ -241,7 +238,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
241 goto out; 238 goto out;
242 } 239 }
243 240
244 real_fops = REAL_FOPS_DEREF(dentry); 241 real_fops = debugfs_real_fops(filp);
245 real_fops = fops_get(real_fops); 242 real_fops = fops_get(real_fops);
246 if (!real_fops) { 243 if (!real_fops) {
247 /* Huh? Module did not cleanup after itself at exit? */ 244 /* Huh? Module did not cleanup after itself at exit? */
diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h
index bba52634b995..b3e8443a1f47 100644
--- a/fs/debugfs/internal.h
+++ b/fs/debugfs/internal.h
@@ -19,8 +19,4 @@ extern const struct file_operations debugfs_noop_file_operations;
19extern const struct file_operations debugfs_open_proxy_file_operations; 19extern const struct file_operations debugfs_open_proxy_file_operations;
20extern const struct file_operations debugfs_full_proxy_file_operations; 20extern const struct file_operations debugfs_full_proxy_file_operations;
21 21
22struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
23 struct dentry *parent, void *data,
24 const struct file_operations *fops);
25
26#endif /* _DEBUGFS_INTERNAL_H_ */ 22#endif /* _DEBUGFS_INTERNAL_H_ */
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index dc1358b5ec95..ac2de0ed69ad 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -233,8 +233,8 @@ void sysfs_remove_group(struct kobject *kobj,
233 kn = kernfs_find_and_get(parent, grp->name); 233 kn = kernfs_find_and_get(parent, grp->name);
234 if (!kn) { 234 if (!kn) {
235 WARN(!kn, KERN_WARNING 235 WARN(!kn, KERN_WARNING
236 "sysfs group %p not found for kobject '%s'\n", 236 "sysfs group '%s' not found for kobject '%s'\n",
237 grp, kobject_name(kobj)); 237 grp->name, kobject_name(kobj));
238 return; 238 return;
239 } 239 }
240 } else { 240 } else {
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index 1438e2322d5c..4d3f0d1aec73 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -45,6 +45,23 @@ extern struct dentry *arch_debugfs_dir;
45 45
46extern struct srcu_struct debugfs_srcu; 46extern struct srcu_struct debugfs_srcu;
47 47
48/**
49 * debugfs_real_fops - getter for the real file operation
50 * @filp: a pointer to a struct file
51 *
52 * Must only be called under the protection established by
53 * debugfs_use_file_start().
54 */
55static inline const struct file_operations *debugfs_real_fops(struct file *filp)
56 __must_hold(&debugfs_srcu)
57{
58 /*
59 * Neither the pointer to the struct file_operations, nor its
60 * contents ever change -- srcu_dereference() is not needed here.
61 */
62 return filp->f_path.dentry->d_fsdata;
63}
64
48#if defined(CONFIG_DEBUG_FS) 65#if defined(CONFIG_DEBUG_FS)
49 66
50struct dentry *debugfs_create_file(const char *name, umode_t mode, 67struct dentry *debugfs_create_file(const char *name, umode_t mode,