diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-23 18:24:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-23 18:24:08 -0700 |
commit | 30d38542ec777468bb6a31829076a2dbc5690e35 (patch) | |
tree | 698b7a4fdd730befa34c4c9642cdbe72ce7d336a /drivers/mfd/mfd-core.c | |
parent | 20b7997e8abdf338dcc27fb4f1333c4973a7f113 (diff) | |
parent | 044e5f45e4ad890d03bd1e8bb44c634397cac24d (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (85 commits)
[ARM] pxa: add base support for PXA930 Handheld Platform (aka SAAR)
[ARM] pxa: add base support for PXA930 Evaluation Board (aka TavorEVB)
[ARM] pxa: add base support for PXA930 (aka Tavor-P)
[ARM] Update mach-types
[ARM] pxa: make littleton to use the new smc91x platform data
[ARM] pxa: make zylonite to use the new smc91x platform data
[ARM] pxa: make mainstone to use the new smc91x platform data
[ARM] pxa: make lubbock to use new smc91x platform data
[NET] smc91x: prepare SMC_USE_PXA_DMA to be specified in platform data
[NET] smc91x: prepare for SMC_IO_SHIFT to be a platform configurable variable
[NET] smc91x: add SMC91X_NOWAIT flag to platform data
[NET] smc91x: favor the use of SMC91X_USE_* instead of SMC_CAN_USE_*
[NET] smc91x: remove "irq_flags" from "struct smc91x_platdata"
[ARM] 5146/1: pxa2xx: convert all boards to call pxa2xx_transceiver_mode helper
Support for LCD on e740 e750 e400 and e800 e-series PDAs
E-series UDC support
PXA UDC - allow use of inverted GPIO for pullup
Add e350 support
Fix broken e-series build
E-series GPIO / IRQ definitions.
...
Diffstat (limited to 'drivers/mfd/mfd-core.c')
-rw-r--r-- | drivers/mfd/mfd-core.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c new file mode 100644 index 00000000000..d7d88ce053a --- /dev/null +++ b/drivers/mfd/mfd-core.c @@ -0,0 +1,114 @@ +/* + * drivers/mfd/mfd-core.c + * + * core MFD support + * Copyright (c) 2006 Ian Molton + * Copyright (c) 2007,2008 Dmitry Baryshkov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/mfd/core.h> + +static int mfd_add_device(struct platform_device *parent, + const struct mfd_cell *cell, + struct resource *mem_base, + int irq_base) +{ + struct resource res[cell->num_resources]; + struct platform_device *pdev; + int ret = -ENOMEM; + int r; + + pdev = platform_device_alloc(cell->name, parent->id); + if (!pdev) + goto fail_alloc; + + pdev->dev.parent = &parent->dev; + + ret = platform_device_add_data(pdev, + cell, sizeof(struct mfd_cell)); + if (ret) + goto fail_device; + + memzero(res, sizeof(res)); + for (r = 0; r < cell->num_resources; r++) { + res[r].name = cell->resources[r].name; + res[r].flags = cell->resources[r].flags; + + /* Find out base to use */ + if (cell->resources[r].flags & IORESOURCE_MEM) { + res[r].parent = mem_base; + res[r].start = mem_base->start + + cell->resources[r].start; + res[r].end = mem_base->start + + cell->resources[r].end; + } else if (cell->resources[r].flags & IORESOURCE_IRQ) { + res[r].start = irq_base + + cell->resources[r].start; + res[r].end = irq_base + + cell->resources[r].end; + } else { + res[r].parent = cell->resources[r].parent; + res[r].start = cell->resources[r].start; + res[r].end = cell->resources[r].end; + } + } + + platform_device_add_resources(pdev, res, cell->num_resources); + + ret = platform_device_add(pdev); + if (ret) + goto fail_device; + + return 0; + +/* platform_device_del(pdev); */ +fail_device: + platform_device_put(pdev); +fail_alloc: + return ret; +} + +int mfd_add_devices( + struct platform_device *parent, + const struct mfd_cell *cells, int n_devs, + struct resource *mem_base, + int irq_base) +{ + int i; + int ret = 0; + + for (i = 0; i < n_devs; i++) { + ret = mfd_add_device(parent, cells + i, mem_base, irq_base); + if (ret) + break; + } + + if (ret) + mfd_remove_devices(parent); + + return ret; +} +EXPORT_SYMBOL(mfd_add_devices); + +static int mfd_remove_devices_fn(struct device *dev, void *unused) +{ + platform_device_unregister( + container_of(dev, struct platform_device, dev)); + return 0; +} + +void mfd_remove_devices(struct platform_device *parent) +{ + device_for_each_child(&parent->dev, NULL, mfd_remove_devices_fn); +} +EXPORT_SYMBOL(mfd_remove_devices); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); |