diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 0a68d784ea18..54e89c97ce11 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -137,6 +137,10 @@ const struct dsa_device_ops *dsa_tag_driver_get(int tag_protocol)
 	return ops;
 }
 
+void dsa_tag_driver_put(const struct dsa_device_ops *ops)
+{
+}
+
 static int dev_is_class(struct device *dev, void *class)
 {
 	if (dev->class != NULL && !strcmp(dev->class->name, class))
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index ba91bda8bdd3..bbc9f56e89b9 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -335,6 +335,8 @@ static void dsa_port_teardown(struct dsa_port *dp)
 	case DSA_PORT_TYPE_UNUSED:
 		break;
 	case DSA_PORT_TYPE_CPU:
+		dsa_tag_driver_put(dp->tag_ops);
+		/* fall-through */
 	case DSA_PORT_TYPE_DSA:
 		dsa_port_link_unregister_of(dp);
 		break;
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index abe3abeb0bb9..ea482e88f7b8 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -85,6 +85,7 @@ struct dsa_slave_priv {
 
 /* dsa.c */
 const struct dsa_device_ops *dsa_tag_driver_get(int tag_protocol);
+void dsa_tag_driver_put(const struct dsa_device_ops *ops);
 
 bool dsa_schedule_work(struct work_struct *work);
 const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops);
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c
index a8c076250237..219f4fa7ff4b 100644
--- a/net/dsa/legacy.c
+++ b/net/dsa/legacy.c
@@ -163,6 +163,8 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
 		dst->cpu_dp->dst = dst;
 	}
 
+	dsa_tag_driver_put(dst->cpu_dp->tag_ops);
+
 	memcpy(ds->rtable, cd->rtable, sizeof(ds->rtable));
 
 	/*