Commit 7fcd4274 authored by Charles Keepax's avatar Charles Keepax Committed by Mark Brown

mfd: Allow mapping regulator supplies to MFD device from children

Occasionally, it is useful to map supplies from a child device onto the
MFD device. A typical usecase for this would be if the MFD device is
represented as a single node in device tree. All supplies will be
defined in device tree as existing on the MFD device. When a child
depends on frameworks which might have no knowledge of MFD to lookup
supplies on its behalf the supply will not be found.

This patch adds a list of supplies that should be looked up on the
parent rather than the child as part of the mfd_cell structure.
Signed-off-by: default avatarCharles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: default avatarLee Jones <lee.jones@linaro.org>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent a06ccd9c
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/regulator/consumer.h>
static struct device_type mfd_dev_type = { static struct device_type mfd_dev_type = {
.name = "mfd_device", .name = "mfd_device",
...@@ -99,6 +100,13 @@ static int mfd_add_device(struct device *parent, int id, ...@@ -99,6 +100,13 @@ static int mfd_add_device(struct device *parent, int id,
pdev->dev.dma_mask = parent->dma_mask; pdev->dev.dma_mask = parent->dma_mask;
pdev->dev.dma_parms = parent->dma_parms; pdev->dev.dma_parms = parent->dma_parms;
ret = devm_regulator_bulk_register_supply_alias(
&pdev->dev, cell->parent_supplies,
parent, cell->parent_supplies,
cell->num_parent_supplies);
if (ret < 0)
goto fail_res;
if (parent->of_node && cell->of_compatible) { if (parent->of_node && cell->of_compatible) {
for_each_child_of_node(parent->of_node, np) { for_each_child_of_node(parent->of_node, np) {
if (of_device_is_compatible(np, cell->of_compatible)) { if (of_device_is_compatible(np, cell->of_compatible)) {
...@@ -112,12 +120,12 @@ static int mfd_add_device(struct device *parent, int id, ...@@ -112,12 +120,12 @@ static int mfd_add_device(struct device *parent, int id,
ret = platform_device_add_data(pdev, ret = platform_device_add_data(pdev,
cell->platform_data, cell->pdata_size); cell->platform_data, cell->pdata_size);
if (ret) if (ret)
goto fail_res; goto fail_alias;
} }
ret = mfd_platform_add_cell(pdev, cell); ret = mfd_platform_add_cell(pdev, cell);
if (ret) if (ret)
goto fail_res; goto fail_alias;
for (r = 0; r < cell->num_resources; r++) { for (r = 0; r < cell->num_resources; r++) {
res[r].name = cell->resources[r].name; res[r].name = cell->resources[r].name;
...@@ -152,17 +160,17 @@ static int mfd_add_device(struct device *parent, int id, ...@@ -152,17 +160,17 @@ static int mfd_add_device(struct device *parent, int id,
if (!cell->ignore_resource_conflicts) { if (!cell->ignore_resource_conflicts) {
ret = acpi_check_resource_conflict(&res[r]); ret = acpi_check_resource_conflict(&res[r]);
if (ret) if (ret)
goto fail_res; goto fail_alias;
} }
} }
ret = platform_device_add_resources(pdev, res, cell->num_resources); ret = platform_device_add_resources(pdev, res, cell->num_resources);
if (ret) if (ret)
goto fail_res; goto fail_alias;
ret = platform_device_add(pdev); ret = platform_device_add(pdev);
if (ret) if (ret)
goto fail_res; goto fail_alias;
if (cell->pm_runtime_no_callbacks) if (cell->pm_runtime_no_callbacks)
pm_runtime_no_callbacks(&pdev->dev); pm_runtime_no_callbacks(&pdev->dev);
...@@ -171,6 +179,10 @@ static int mfd_add_device(struct device *parent, int id, ...@@ -171,6 +179,10 @@ static int mfd_add_device(struct device *parent, int id,
return 0; return 0;
fail_alias:
devm_regulator_bulk_unregister_supply_alias(&pdev->dev,
cell->parent_supplies,
cell->num_parent_supplies);
fail_res: fail_res:
kfree(res); kfree(res);
fail_device: fail_device:
......
...@@ -59,6 +59,12 @@ struct mfd_cell { ...@@ -59,6 +59,12 @@ struct mfd_cell {
* pm_runtime_no_callbacks(). * pm_runtime_no_callbacks().
*/ */
bool pm_runtime_no_callbacks; bool pm_runtime_no_callbacks;
/* A list of regulator supplies that should be mapped to the MFD
* device rather than the child device when requested
*/
const char **parent_supplies;
int num_parent_supplies;
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment