From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
To: lee.jones@linaro.org
Cc: sameo@linux.intel.com, patches@opensource.wolfsonmicro.com,
linux-kernel@vger.kernel.org
Subject: [PATCH 1/2] mfd: core: Add the option to order destruction of MFD cells
Date: Mon, 2 Jun 2014 10:01:43 +0100 [thread overview]
Message-ID: <1401699704-17902-1-git-send-email-ckeepax@opensource.wolfsonmicro.com> (raw)
Sometimes MFD children will have interdependancies. For example an MFD
device might contain a regulator cell and another cell which requires
that regulator to function. Probe deferral will ensure that these
devices probe in the correct order, however currently nothing ensures
they are destroyed in the correct order. As such it is possible for a
cell to be destroyed whilst another cell still expects it to exist. For
example the cell mentioned earlier would attempt to do a regulator_put
as part of its own tear-down but the regulator may have already been
destroyed.
This patch add a field remove_level to the mfd_cell data structure which
allows users to group the destruction of the MFD cells. Cells with a
lower remove_level will be destroyed first. This approach also doesn't
alter the destruction order for existing devices, so should be
no-op for devices not explicitly using it.
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
drivers/mfd/mfd-core.c | 33 +++++++++++++++++++++++++++++----
include/linux/mfd/core.h | 3 +++
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 2676492..0c12787 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -226,11 +226,19 @@ fail:
}
EXPORT_SYMBOL(mfd_add_devices);
+struct mfd_remove_data {
+ atomic_t *cnts;
+
+ int level;
+ int next_level;
+};
+
static int mfd_remove_devices_fn(struct device *dev, void *c)
{
struct platform_device *pdev;
const struct mfd_cell *cell;
- atomic_t **usage_count = c;
+ struct mfd_remove_data *rd = c;
+ atomic_t **usage_count = &rd->cnts;
if (dev->type != &mfd_dev_type)
return 0;
@@ -238,6 +246,15 @@ static int mfd_remove_devices_fn(struct device *dev, void *c)
pdev = to_platform_device(dev);
cell = mfd_get_cell(pdev);
+ if (rd->level < cell->remove_level) {
+ if (!rd->next_level || rd->next_level > cell->remove_level)
+ rd->next_level = cell->remove_level;
+
+ return 0;
+ }
+
+ dev_dbg(dev, "Removing from MFD\n");
+
/* find the base address of usage_count pointers (for freeing) */
if (!*usage_count || (cell->usage_count < *usage_count))
*usage_count = cell->usage_count;
@@ -248,10 +265,18 @@ static int mfd_remove_devices_fn(struct device *dev, void *c)
void mfd_remove_devices(struct device *parent)
{
- atomic_t *cnts = NULL;
+ struct mfd_remove_data rd = {};
+
+ do {
+ rd.level = rd.next_level;
+ rd.next_level = 0;
+
+ dev_dbg(parent, "Running remove for level: %d\n", rd.level);
+
+ device_for_each_child(parent, &rd, mfd_remove_devices_fn);
+ } while (rd.next_level);
- device_for_each_child(parent, &cnts, mfd_remove_devices_fn);
- kfree(cnts);
+ kfree(rd.cnts);
}
EXPORT_SYMBOL(mfd_remove_devices);
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index bdba8c6..40586a6 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -65,6 +65,9 @@ struct mfd_cell {
*/
const char **parent_supplies;
int num_parent_supplies;
+
+ /* Cells with a lower remove level will be destroyed first */
+ int remove_level;
};
/*
--
1.7.2.5
next reply other threads:[~2014-06-02 9:09 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-02 9:01 Charles Keepax [this message]
2014-06-02 9:01 ` [PATCH 2/2] mfd: arizona: Destroy regulators after the other MFD cells Charles Keepax
2014-06-17 14:54 ` Lee Jones
2014-06-17 15:16 ` Charles Keepax
2014-06-02 21:01 ` [PATCH 1/2] mfd: core: Add the option to order destruction of " Mark Brown
2014-06-03 9:49 ` Charles Keepax
2014-06-03 10:35 ` Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1401699704-17902-1-git-send-email-ckeepax@opensource.wolfsonmicro.com \
--to=ckeepax@opensource.wolfsonmicro.com \
--cc=lee.jones@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=patches@opensource.wolfsonmicro.com \
--cc=sameo@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox