From aa613de676986f136fa6f48a4d709b5d264f4f38 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 27 Jun 2008 10:37:19 +0100 Subject: [ARM] 5127/1: Core MFD support This patch provides a common subdevice registration system for MFD type chips, using platfrom device. Signed-off-by: Ian Molton Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King --- drivers/mfd/mfd-core.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 drivers/mfd/mfd-core.c (limited to 'drivers/mfd/mfd-core.c') diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c new file mode 100644 index 000000000000..d7d88ce053a6 --- /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 +#include +#include + +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"); -- cgit v1.2.3 From c82dd5321cf779f1f536ef26b383cbe8c9de7f10 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 25 Jul 2008 01:45:22 -0700 Subject: mfd: don't use memzero For it doesn't exist on i386. Cc: Ian Molton Cc: Dmitry Baryshkov Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mfd/mfd-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mfd/mfd-core.c') diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index d7d88ce053a6..0454be4266c1 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -36,7 +36,7 @@ static int mfd_add_device(struct platform_device *parent, if (ret) goto fail_device; - memzero(res, sizeof(res)); + memset(res, 0, sizeof(res)); for (r = 0; r < cell->num_resources; r++) { res[r].name = cell->resources[r].name; res[r].flags = cell->resources[r].flags; -- cgit v1.2.3 From 96ee41993b5b25ee0fbde2d4dcaac1f8c5ef5cc4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 28 Jul 2008 18:26:42 +0200 Subject: mfd: Use to_platform_device instead of container_of Convert mfd_remove_devices_fn() to use to_platform_device() instead of doing container_of(). Signed-off-by: Ben Dooks Acked-by: Dmitry Baryshkov Signed-off-by: Samuel Ortiz --- drivers/mfd/mfd-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/mfd/mfd-core.c') diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 0454be4266c1..4dc861a7ac56 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -99,8 +99,7 @@ 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)); + platform_device_unregister(to_platform_device(dev)); return 0; } -- cgit v1.2.3 From 7f71ac9374fec066e428892a68db158946cee1fb Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 28 Jul 2008 18:29:09 +0200 Subject: mfd: Coding style fixes Fix some coding style fixes in the mfd core driver. Signed-off-by: Ben Dooks Signed-off-by: Samuel Ortiz --- drivers/mfd/mfd-core.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/mfd/mfd-core.c') diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 4dc861a7ac56..50207700140c 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -16,9 +16,9 @@ #include static int mfd_add_device(struct platform_device *parent, - const struct mfd_cell *cell, - struct resource *mem_base, - int irq_base) + const struct mfd_cell *cell, + struct resource *mem_base, + int irq_base) { struct resource res[cell->num_resources]; struct platform_device *pdev; @@ -75,11 +75,10 @@ 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 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; -- cgit v1.2.3 From 56edb58be157a06dc147a988af3588059556d392 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Tue, 29 Jul 2008 01:23:32 +0200 Subject: mfd: add platform_data to mfd_cell Adding platform_data to mfd_cell allows passing of platform data directly to the platform_device created for each cell and thus reuse of existing drivers. On the other side it can be used as a hook to mfd_cell itself removing the need in mfd_get_cell method. Signed-off-by: Mike Rapoport Acked-by: Dmitry Baryshkov Signed-off-by: Samuel Ortiz --- drivers/mfd/mfd-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mfd/mfd-core.c') diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 50207700140c..ad4e4d16a36a 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -32,7 +32,7 @@ static int mfd_add_device(struct platform_device *parent, pdev->dev.parent = &parent->dev; ret = platform_device_add_data(pdev, - cell, sizeof(struct mfd_cell)); + cell->platform_data, cell->data_size); if (ret) goto fail_device; -- cgit v1.2.3 From 424f525a1241351da947fb48a938128ddd774511 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 29 Jul 2008 01:30:26 +0200 Subject: mfd: accept pure device as a parent, not only platform_device Signed-off-by: Dmitry Baryshkov Signed-off-by: Samuel Ortiz --- drivers/mfd/mfd-core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/mfd/mfd-core.c') diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index ad4e4d16a36a..9c9c126ed334 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -15,7 +15,7 @@ #include #include -static int mfd_add_device(struct platform_device *parent, +static int mfd_add_device(struct device *parent, int id, const struct mfd_cell *cell, struct resource *mem_base, int irq_base) @@ -25,11 +25,11 @@ static int mfd_add_device(struct platform_device *parent, int ret = -ENOMEM; int r; - pdev = platform_device_alloc(cell->name, parent->id); + pdev = platform_device_alloc(cell->name, id); if (!pdev) goto fail_alloc; - pdev->dev.parent = &parent->dev; + pdev->dev.parent = parent; ret = platform_device_add_data(pdev, cell->platform_data, cell->data_size); @@ -75,7 +75,7 @@ fail_alloc: return ret; } -int mfd_add_devices(struct platform_device *parent, +int mfd_add_devices(struct device *parent, int id, const struct mfd_cell *cells, int n_devs, struct resource *mem_base, int irq_base) @@ -84,7 +84,7 @@ int mfd_add_devices(struct platform_device *parent, int ret = 0; for (i = 0; i < n_devs; i++) { - ret = mfd_add_device(parent, cells + i, mem_base, irq_base); + ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); if (ret) break; } @@ -102,9 +102,9 @@ static int mfd_remove_devices_fn(struct device *dev, void *unused) return 0; } -void mfd_remove_devices(struct platform_device *parent) +void mfd_remove_devices(struct device *parent) { - device_for_each_child(&parent->dev, NULL, mfd_remove_devices_fn); + device_for_each_child(parent, NULL, mfd_remove_devices_fn); } EXPORT_SYMBOL(mfd_remove_devices); -- cgit v1.2.3