diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 19:14:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 19:14:07 -0400 |
commit | 0a58471541cc823ef8056d23945c39fec154481c (patch) | |
tree | 04a8499be0659ac16f82f3b0d0d8d2c2ccafe4dd /drivers/of/platform.c | |
parent | ff933a0817f95efbeb97bec5ca609a13f8aed686 (diff) | |
parent | 08d38bebb4dcd6414944f8277ea5ea30010664fe (diff) |
Merge tag 'cleanup-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc into next
Pull ARM SoC cleanups from Olof Johansson:
"Cleanups for 3.16. Among these are:
- a bunch of misc cleanups for Broadcom platforms, mostly
housekeeping
- enabling Common Clock Framework on the older s3c24xx Samsung
chipsets
- cleanup of the Versatile Express system controller code, moving it
to syscon
- power management cleanups for OMAP platforms
plus a handful of other cleanups across the place"
* tag 'cleanup-for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (87 commits)
ARM: kconfig: allow PCI support to be selected with ARCH_MULTIPLATFORM
clk: samsung: fix build error
ARM: vexpress: refine dependencies for new code
clk: samsung: clk-s3c2410-dlck: do not use PNAME macro as it declares __initdata
cpufreq: exynos: Fix the compile error
ARM: S3C24XX: move debug-macro.S into the common space
ARM: S3C24XX: use generic DEBUG_UART_PHY/_VIRT in debug macro
ARM: S3C24XX: trim down debug uart handling
ARM: compressed/head.S: remove s3c24xx special case
ARM: EXYNOS: Remove unnecessary inclusion of cpu.h
ARM: EXYNOS: Migrate Exynos specific macros from plat to mach
ARM: EXYNOS: Remove exynos_subsys registration
ARM: EXYNOS: Remove duplicate lines in Makefile
ARM: EXYNOS: use v7_exit_coherency_flush macro for cache disabling
ARM: OMAP4: PRCM: remove references to cm-regbits-44xx.h from PRCM core files
ARM: OMAP3/4: PRM: add support of late_init call to prm_ll_ops
ARM: OMAP3/OMAP4: PRM: add prm_features flags and add IO wakeup under it
ARM: OMAP3/4: PRM: provide io chain reconfig function through irq setup
ARM: OMAP2+: PRM: remove unnecessary cpu_is_XXX calls from prm_init / exit
ARM: OMAP2+: PRCM: cleanup some header includes
...
Diffstat (limited to 'drivers/of/platform.c')
-rw-r--r-- | drivers/of/platform.c | 74 |
1 files changed, 69 insertions, 5 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index bd47fbc53dc9..e8376d646d98 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -206,12 +206,13 @@ static struct platform_device *of_platform_device_create_pdata( | |||
206 | { | 206 | { |
207 | struct platform_device *dev; | 207 | struct platform_device *dev; |
208 | 208 | ||
209 | if (!of_device_is_available(np)) | 209 | if (!of_device_is_available(np) || |
210 | of_node_test_and_set_flag(np, OF_POPULATED)) | ||
210 | return NULL; | 211 | return NULL; |
211 | 212 | ||
212 | dev = of_device_alloc(np, bus_id, parent); | 213 | dev = of_device_alloc(np, bus_id, parent); |
213 | if (!dev) | 214 | if (!dev) |
214 | return NULL; | 215 | goto err_clear_flag; |
215 | 216 | ||
216 | #if defined(CONFIG_MICROBLAZE) | 217 | #if defined(CONFIG_MICROBLAZE) |
217 | dev->archdata.dma_mask = 0xffffffffUL; | 218 | dev->archdata.dma_mask = 0xffffffffUL; |
@@ -229,10 +230,14 @@ static struct platform_device *of_platform_device_create_pdata( | |||
229 | 230 | ||
230 | if (of_device_add(dev) != 0) { | 231 | if (of_device_add(dev) != 0) { |
231 | platform_device_put(dev); | 232 | platform_device_put(dev); |
232 | return NULL; | 233 | goto err_clear_flag; |
233 | } | 234 | } |
234 | 235 | ||
235 | return dev; | 236 | return dev; |
237 | |||
238 | err_clear_flag: | ||
239 | of_node_clear_flag(np, OF_POPULATED); | ||
240 | return NULL; | ||
236 | } | 241 | } |
237 | 242 | ||
238 | /** | 243 | /** |
@@ -264,14 +269,15 @@ static struct amba_device *of_amba_device_create(struct device_node *node, | |||
264 | 269 | ||
265 | pr_debug("Creating amba device %s\n", node->full_name); | 270 | pr_debug("Creating amba device %s\n", node->full_name); |
266 | 271 | ||
267 | if (!of_device_is_available(node)) | 272 | if (!of_device_is_available(node) || |
273 | of_node_test_and_set_flag(node, OF_POPULATED)) | ||
268 | return NULL; | 274 | return NULL; |
269 | 275 | ||
270 | dev = amba_device_alloc(NULL, 0, 0); | 276 | dev = amba_device_alloc(NULL, 0, 0); |
271 | if (!dev) { | 277 | if (!dev) { |
272 | pr_err("%s(): amba_device_alloc() failed for %s\n", | 278 | pr_err("%s(): amba_device_alloc() failed for %s\n", |
273 | __func__, node->full_name); | 279 | __func__, node->full_name); |
274 | return NULL; | 280 | goto err_clear_flag; |
275 | } | 281 | } |
276 | 282 | ||
277 | /* setup generic device info */ | 283 | /* setup generic device info */ |
@@ -311,6 +317,8 @@ static struct amba_device *of_amba_device_create(struct device_node *node, | |||
311 | 317 | ||
312 | err_free: | 318 | err_free: |
313 | amba_device_put(dev); | 319 | amba_device_put(dev); |
320 | err_clear_flag: | ||
321 | of_node_clear_flag(node, OF_POPULATED); | ||
314 | return NULL; | 322 | return NULL; |
315 | } | 323 | } |
316 | #else /* CONFIG_ARM_AMBA */ | 324 | #else /* CONFIG_ARM_AMBA */ |
@@ -487,4 +495,60 @@ int of_platform_populate(struct device_node *root, | |||
487 | return rc; | 495 | return rc; |
488 | } | 496 | } |
489 | EXPORT_SYMBOL_GPL(of_platform_populate); | 497 | EXPORT_SYMBOL_GPL(of_platform_populate); |
498 | |||
499 | static int of_platform_device_destroy(struct device *dev, void *data) | ||
500 | { | ||
501 | bool *children_left = data; | ||
502 | |||
503 | /* Do not touch devices not populated from the device tree */ | ||
504 | if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED)) { | ||
505 | *children_left = true; | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | /* Recurse, but don't touch this device if it has any children left */ | ||
510 | if (of_platform_depopulate(dev) != 0) { | ||
511 | *children_left = true; | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | if (dev->bus == &platform_bus_type) | ||
516 | platform_device_unregister(to_platform_device(dev)); | ||
517 | #ifdef CONFIG_ARM_AMBA | ||
518 | else if (dev->bus == &amba_bustype) | ||
519 | amba_device_unregister(to_amba_device(dev)); | ||
520 | #endif | ||
521 | else { | ||
522 | *children_left = true; | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | of_node_clear_flag(dev->of_node, OF_POPULATED); | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | /** | ||
532 | * of_platform_depopulate() - Remove devices populated from device tree | ||
533 | * @parent: device which childred will be removed | ||
534 | * | ||
535 | * Complementary to of_platform_populate(), this function removes children | ||
536 | * of the given device (and, recurrently, their children) that have been | ||
537 | * created from their respective device tree nodes (and only those, | ||
538 | * leaving others - eg. manually created - unharmed). | ||
539 | * | ||
540 | * Returns 0 when all children devices have been removed or | ||
541 | * -EBUSY when some children remained. | ||
542 | */ | ||
543 | int of_platform_depopulate(struct device *parent) | ||
544 | { | ||
545 | bool children_left = false; | ||
546 | |||
547 | device_for_each_child(parent, &children_left, | ||
548 | of_platform_device_destroy); | ||
549 | |||
550 | return children_left ? -EBUSY : 0; | ||
551 | } | ||
552 | EXPORT_SYMBOL_GPL(of_platform_depopulate); | ||
553 | |||
490 | #endif /* CONFIG_OF_ADDRESS */ | 554 | #endif /* CONFIG_OF_ADDRESS */ |