> -----Original Message----- > From: Yicong Yang [mailto:yangyicong@xxxxxxxxxxxxx] > Sent: Wednesday, March 10, 2021 2:22 AM > To: wsa@xxxxxxxxxx; linux-i2c@xxxxxxxxxxxxxxx > Cc: linuxarm@xxxxxxxxxxxxx; Zengtao (B) <prime.zeng@xxxxxxxxxxxxx>; > yangyicong <yangyicong@xxxxxxxxxx> > Subject: [Linuxarm] [PATCH v2 1/3] i2c: core: add managed function for adding > i2c adapters > > Some I2C controller drivers will only unregister the I2C > adapter in their .remove() callback, which can be done > by simply using a managed variant to add the I2C adapter. > > So add the managed functions for adding the I2C adapter. Sounds like a very useful wrapper. We are able to remove some "remove" callbacks afterwards. We have some similar wrappers like devm_hwrng_register which is always helpful. > > Signed-off-by: Yicong Yang <yangyicong@xxxxxxxxxxxxx> > --- > drivers/i2c/i2c-core-base.c | 39 +++++++++++++++++++++++++++++++++++++++ > include/linux/i2c.h | 1 + > 2 files changed, 40 insertions(+) > > diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c > index 63ebf72..61486dc 100644 > --- a/drivers/i2c/i2c-core-base.c > +++ b/drivers/i2c/i2c-core-base.c > @@ -1550,6 +1550,38 @@ int i2c_add_adapter(struct i2c_adapter *adapter) > } > EXPORT_SYMBOL(i2c_add_adapter); > > +static void devm_i2c_del_adapter(struct device *dev, void *ptr); > + > +/** > + * devm_i2c_add_adapter - device-managed variant of i2c_add_adapter() > + * @dev: managing device for adding this I2C adapter > + * @adapter: the adapter to add > + * Context: can sleep > + * > + * Add adapter with dynamic bus number, same with i2c_add_adapter() > + * but the adapter will be auto deleted on driver detach. > + */ > +int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter) > +{ > + struct i2c_adapter **ptr; > + int ret; > + > + ptr = devres_alloc(devm_i2c_del_adapter, sizeof(*ptr), GFP_KERNEL); > + if (!ptr) > + return -ENOMEM; > + > + ret = i2c_add_adapter(adapter); > + if (!ret) { > + *ptr = adapter; > + devres_add(dev, ptr); > + } else { > + devres_free(ptr); > + } > + > + return ret; > +} > +EXPORT_SYMBOL(devm_i2c_add_adapter); > + > /** > * i2c_add_numbered_adapter - declare i2c adapter, use static bus number > * @adap: the adapter to register (with adap->nr initialized) > @@ -1703,6 +1735,13 @@ void i2c_del_adapter(struct i2c_adapter *adap) > } > EXPORT_SYMBOL(i2c_del_adapter); > > +static void devm_i2c_del_adapter(struct device *dev, void *ptr) > +{ > + struct i2c_adapter *adapter = *((struct i2c_adapter **)ptr); > + > + i2c_del_adapter(adapter); > +} > + > static void i2c_parse_timing(struct device *dev, char *prop_name, u32 > *cur_val_p, > u32 def_val, bool use_def) > { > diff --git a/include/linux/i2c.h b/include/linux/i2c.h > index 5662265..10bd0b0 100644 > --- a/include/linux/i2c.h > +++ b/include/linux/i2c.h > @@ -844,6 +844,7 @@ static inline void i2c_mark_adapter_resumed(struct > i2c_adapter *adap) > */ > #if IS_ENABLED(CONFIG_I2C) > int i2c_add_adapter(struct i2c_adapter *adap); > +int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter); > void i2c_del_adapter(struct i2c_adapter *adap); > int i2c_add_numbered_adapter(struct i2c_adapter *adap); > > -- > 2.8.1 Thanks Barry