Simple syscon devices may require deassertion of a reset signal in order to access their register set. Rather than requiring a custom driver to implement this, we can use the generic "resets" specifiers to link a reset line to the syscon. This change adds an optional reset line to the syscon device description, and code to perform the deassertion/assertion on probe/remove. Signed-off-by: Jeremy Kerr <jk@xxxxxxxxxxxxxxxxxxxx> --- drivers/mfd/syscon.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index bdb2ce7ff03b..a0483dbfe17a 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -20,6 +20,7 @@ #include <linux/platform_data/syscon.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/mfd/syscon.h> #include <linux/slab.h> @@ -31,6 +32,7 @@ static LIST_HEAD(syscon_list); struct syscon { struct device_node *np; struct regmap *regmap; + struct reset_control *reset; struct list_head list; }; @@ -280,6 +282,7 @@ static int syscon_probe(struct platform_device *pdev) struct regmap_config syscon_config = syscon_regmap_config; struct resource *res; void __iomem *base; + int rc; syscon = devm_kzalloc(dev, sizeof(*syscon), GFP_KERNEL); if (!syscon) @@ -302,13 +305,32 @@ static int syscon_probe(struct platform_device *pdev) return PTR_ERR(syscon->regmap); } + syscon->reset = devm_reset_control_get_optional_exclusive(&pdev->dev, + "reset"); + if (IS_ERR(syscon->reset)) + return PTR_ERR(syscon->reset); + platform_set_drvdata(pdev, syscon); + rc = reset_control_deassert(syscon->reset); + if (rc) { + dev_err(dev, "failed to deassert reset line! rc: %d\n", rc); + return rc; + } + dev_dbg(dev, "regmap %pR registered\n", res); return 0; } +static int syscon_remove(struct platform_device *pdev) +{ + struct syscon *syscon = platform_get_drvdata(pdev); + + reset_control_assert(syscon->reset); + return 0; +} + static const struct platform_device_id syscon_ids[] = { { "syscon", }, { } @@ -319,6 +341,7 @@ static struct platform_driver syscon_driver = { .name = "syscon", }, .probe = syscon_probe, + .remove = syscon_remove, .id_table = syscon_ids, }; -- 2.35.1