From 2c348fb47a270f935f57eba83adf774869bbfaf3 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 28 Mar 2011 14:49:27 +1100 Subject: Revert "mfd: Add mfd_clone_cell(), convert cs5535-mfd/olpc-xo1 to it" This reverts commit fa1df691688f34cbcd5bf77bd084bbe47e9d6bfe. --- arch/x86/platform/olpc/olpc-xo1.c | 11 ++++---- drivers/mfd/cs5535-mfd.c | 18 ------------- drivers/mfd/mfd-core.c | 53 +++++++++++++++++++++++++++++++-------- include/linux/mfd/core.h | 27 +++++++------------- 4 files changed, 57 insertions(+), 52 deletions(-) diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c index 386e3a159cca..99513642a0e6 100644 --- a/arch/x86/platform/olpc/olpc-xo1.c +++ b/arch/x86/platform/olpc/olpc-xo1.c @@ -121,21 +121,22 @@ static int __init olpc_xo1_init(void) { int r; - r = platform_driver_register(&cs5535_pms_drv); + r = mfd_shared_platform_driver_register(&cs5535_pms_drv, "cs5535-pms"); if (r) return r; - r = platform_driver_register(&cs5535_acpi_drv); + r = mfd_shared_platform_driver_register(&cs5535_acpi_drv, + "cs5535-acpi"); if (r) - platform_driver_unregister(&cs5535_pms_drv); + mfd_shared_platform_driver_unregister(&cs5535_pms_drv); return r; } static void __exit olpc_xo1_exit(void) { - platform_driver_unregister(&cs5535_acpi_drv); - platform_driver_unregister(&cs5535_pms_drv); + mfd_shared_platform_driver_unregister(&cs5535_acpi_drv); + mfd_shared_platform_driver_unregister(&cs5535_pms_drv); } MODULE_AUTHOR("Daniel Drake "); diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 24959ddd9324..886a06871065 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c @@ -27,7 +27,6 @@ #include #include #include -#include #define DRV_NAME "cs5535-mfd" @@ -112,22 +111,6 @@ static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { }, }; -#ifdef CONFIG_OLPC -static void __devinit cs5535_clone_olpc_cells(void) -{ - const char *acpi_clones[] = { "olpc-xo1-acpi" }; - const char *pms_clones[] = { "olpc-xo1-pms" }; - - if (!machine_is_olpc()) - return; - - mfd_clone_cell("cs5535-acpi", acpi_clones, ARRAY_SIZE(acpi_clones)); - mfd_clone_cell("cs5535-pms", pms_clones, ARRAY_SIZE(pms_clones)); -} -#else -static void cs5535_clone_olpc_cells(void) { } -#endif - static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -156,7 +139,6 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); goto err_disable; } - cs5535_clone_olpc_cells(); dev_info(&pdev->dev, "%zu devices registered.\n", ARRAY_SIZE(cs5535_mfd_cells)); diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index d01574d98870..79eda0264fb2 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -184,12 +184,16 @@ void mfd_remove_devices(struct device *parent) } EXPORT_SYMBOL(mfd_remove_devices); -int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) +static int add_shared_platform_device(const char *cell, const char *name) { struct mfd_cell cell_entry; struct device *dev; struct platform_device *pdev; - int i; + int err; + + /* check if we've already registered a device (don't fail if we have) */ + if (bus_find_device_by_name(&platform_bus_type, NULL, name)) + return 0; /* fetch the parent cell's device (should already be registered!) */ dev = bus_find_device_by_name(&platform_bus_type, NULL, cell); @@ -202,17 +206,44 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) WARN_ON(!cell_entry.enable); - for (i = 0; i < n_clones; i++) { - cell_entry.name = clones[i]; - /* don't give up if a single call fails; just report error */ - if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) - dev_err(dev, "failed to create platform device '%s'\n", - clones[i]); - } + cell_entry.name = name; + err = mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0); + if (err) + dev_err(dev, "MFD add devices failed: %d\n", err); + return err; +} - return 0; +int mfd_shared_platform_driver_register(struct platform_driver *drv, + const char *cellname) +{ + int err; + + err = add_shared_platform_device(cellname, drv->driver.name); + if (err) + printk(KERN_ERR "failed to add platform device %s\n", + drv->driver.name); + + err = platform_driver_register(drv); + if (err) + printk(KERN_ERR "failed to add platform driver %s\n", + drv->driver.name); + + return err; +} +EXPORT_SYMBOL(mfd_shared_platform_driver_register); + +void mfd_shared_platform_driver_unregister(struct platform_driver *drv) +{ + struct device *dev; + + dev = bus_find_device_by_name(&platform_bus_type, NULL, + drv->driver.name); + if (dev) + platform_device_unregister(to_platform_device(dev)); + + platform_driver_unregister(drv); } -EXPORT_SYMBOL(mfd_clone_cell); +EXPORT_SYMBOL(mfd_shared_platform_driver_unregister); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index ad1b19aa6508..1408bf8eed5f 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h @@ -62,24 +62,6 @@ struct mfd_cell { extern int mfd_cell_enable(struct platform_device *pdev); extern int mfd_cell_disable(struct platform_device *pdev); -/* - * "Clone" multiple platform devices for a single cell. This is to be used - * for devices that have multiple users of a cell. For example, if an mfd - * driver wants the cell "foo" to be used by a GPIO driver, an MTD driver, - * and a platform driver, the following bit of code would be use after first - * calling mfd_add_devices(): - * - * const char *fclones[] = { "foo-gpio", "foo-mtd" }; - * err = mfd_clone_cells("foo", fclones, ARRAY_SIZE(fclones)); - * - * Each driver (MTD, GPIO, and platform driver) would then register - * platform_drivers for "foo-mtd", "foo-gpio", and "foo", respectively. - * The cell's .enable/.disable hooks should be used to deal with hardware - * resource contention. - */ -extern int mfd_clone_cell(const char *cell, const char **clones, - size_t n_clones); - /* * Given a platform device that's been created by mfd_add_devices(), fetch * the mfd_cell that created it. @@ -105,4 +87,13 @@ extern int mfd_add_devices(struct device *parent, int id, extern void mfd_remove_devices(struct device *parent); +/* + * For MFD drivers with clients sharing access to resources, these create + * multiple platform devices per cell. Contention handling must still be + * handled via drivers (ie, with enable/disable hooks). + */ +extern int mfd_shared_platform_driver_register(struct platform_driver *drv, + const char *cellname); +extern void mfd_shared_platform_driver_unregister(struct platform_driver *drv); + #endif -- cgit v1.2.3