On Tue, Apr 30, 2024 at 10:37:10AM +0200, Herve Codina wrote: > From: Clément Léger <clement.leger@xxxxxxxxxxx> > > Syscon releasing is not supported. > Without release function, unbinding a driver that uses syscon whether > explicitly or due to a module removal left the used syscon in a in-use > state. > > For instance a syscon_node_to_regmap() call from a consumer retrieve a > syscon regmap instance. Internally, syscon_node_to_regmap() can create > syscon instance and add it to the existing syscon list. No API is > available to release this syscon instance, remove it from the list and > free it when it is not used anymore. > > Introduce reference counting in syscon in order to keep track of syscon > usage using syscon_{get,put}() and add a device managed version of > syscon_regmap_lookup_by_phandle(), to automatically release the syscon > instance on the consumer removal. > > Signed-off-by: Clément Léger <clement.leger@xxxxxxxxxxx> > Signed-off-by: Herve Codina <herve.codina@xxxxxxxxxxx> ... > diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h > index c315903f6dab..164b9bcb49c3 100644 > --- a/include/linux/mfd/syscon.h > +++ b/include/linux/mfd/syscon.h > @@ -15,6 +15,7 @@ > #include <linux/errno.h> > > struct device_node; > +struct device; > > #ifdef CONFIG_MFD_SYSCON > struct regmap *device_node_to_regmap(struct device_node *np); > @@ -28,6 +29,11 @@ struct regmap *syscon_regmap_lookup_by_phandle_args(struct device_node *np, > unsigned int *out_args); > struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np, > const char *property); > +void syscon_put_regmap(struct regmap *regmap); > + > +struct regmap *devm_syscon_regmap_lookup_by_phandle(struct device *dev, > + struct device_node *np, > + const char *property); > #else > static inline struct regmap *device_node_to_regmap(struct device_node *np) > { > @@ -67,6 +73,18 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle_optional( > return NULL; > } > > +static intline void syscon_put_regmap(struct regmap *regmap) intline -> inline > +{ > +} ...