@@ -1355,6 +1355,7 @@ static inline void dsa_tag_generic_flow_dissect(const struct sk_buff *skb,
void dsa_unregister_switch(struct dsa_switch *ds);
int dsa_register_switch(struct dsa_switch *ds);
+int devm_dsa_register_switch(struct device *dev, struct dsa_switch *ds);
void dsa_switch_shutdown(struct dsa_switch *ds);
struct dsa_switch *dsa_switch_find(int tree_index, int sw_index);
void dsa_flush_workqueue(void);
@@ -1544,6 +1544,25 @@ int dsa_register_switch(struct dsa_switch *ds)
}
EXPORT_SYMBOL_GPL(dsa_register_switch);
+static void devm_dsa_unregister_switch(void *data)
+{
+ struct dsa_switch *ds = data;
+
+ dsa_unregister_switch(ds);
+}
+
+int devm_dsa_register_switch(struct device *dev, struct dsa_switch *ds)
+{
+ int err;
+
+ err = dsa_register_switch(ds);
+ if (err)
+ return err;
+
+ return devm_add_action_or_reset(dev, devm_dsa_unregister_switch, ds);
+}
+EXPORT_SYMBOL_GPL(devm_dsa_register_switch);
+
static void dsa_switch_remove(struct dsa_switch *ds)
{
struct dsa_switch_tree *dst = ds->dst;
Some DSA driver can be simplified if devres takes care of unregistering the DSA switch. This permits to effectively drop the remove OP from driver that just execute the dsa_unregister_switch() and nothing else. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- include/net/dsa.h | 1 + net/dsa/dsa.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+)