On Sun, 11 Dec 2022, Jeremy Kerr wrote: > 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 deasserts the reset if detected. > > Signed-off-by: Jeremy Kerr <jk@xxxxxxxxxxxxxxxxxxxx> > > --- > v2: > * do reset control in the early of_syscon_register() path, rather than > the platform device init, which isn't used. > v3: > * use a direct reset_control_deassert rather than handling in the > regmap > --- > drivers/mfd/syscon.c | 27 +++++++++++++++++++++------ > 1 file changed, 21 insertions(+), 6 deletions(-) > > diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c > index bdb2ce7ff03b..05e286a69dbe 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; > }; > > @@ -40,7 +42,7 @@ static const struct regmap_config syscon_regmap_config = { > .reg_stride = 4, > }; > > -static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) > +static struct syscon *of_syscon_register(struct device_node *np, bool check_res) > { > struct clk *clk; > struct syscon *syscon; > @@ -50,6 +52,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) > int ret; > struct regmap_config syscon_config = syscon_regmap_config; > struct resource res; > + struct reset_control *reset; > > syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); > if (!syscon) > @@ -114,7 +117,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) > goto err_regmap; > } > > - if (check_clk) { > + if (check_res) { > clk = of_clk_get(np, 0); > if (IS_ERR(clk)) { > ret = PTR_ERR(clk); > @@ -124,7 +127,17 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) > } else { > ret = regmap_mmio_attach_clk(regmap, clk); > if (ret) > - goto err_attach; > + goto err_attach_clk; > + } > + > + reset = of_reset_control_get_optional_exclusive(np, NULL); > + if (IS_ERR(reset)) { > + ret = PTR_ERR(reset); > + goto err_attach_clk; > + } else { > + ret = reset_control_deassert(reset); > + if (ret) > + goto err_reset; > } The else is superfluous, right? Arnd, besides this are you happy with the patch? -- Lee Jones [李琼斯]