return chip->tag_protocol;
 }
 
-static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds, int port,
+static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds,
                                         enum dsa_tag_protocol proto)
 {
        struct mv88e6xxx_chip *chip = ds->priv;
        enum dsa_tag_protocol old_protocol;
+       struct dsa_port *cpu_dp;
        int err;
 
        switch (proto) {
        chip->tag_protocol = proto;
 
        mv88e6xxx_reg_lock(chip);
-       err = mv88e6xxx_setup_port_mode(chip, port);
+       dsa_switch_for_each_cpu_port(cpu_dp, ds) {
+               err = mv88e6xxx_setup_port_mode(chip, cpu_dp->index);
+               if (err) {
+                       mv88e6xxx_reg_unlock(chip);
+                       goto unwind;
+               }
+       }
        mv88e6xxx_reg_unlock(chip);
 
-       if (err)
-               chip->tag_protocol = old_protocol;
+       return 0;
+
+unwind:
+       chip->tag_protocol = old_protocol;
+
+       mv88e6xxx_reg_lock(chip);
+       dsa_switch_for_each_cpu_port_continue_reverse(cpu_dp, ds)
+               mv88e6xxx_setup_port_mode(chip, cpu_dp->index);
+       mv88e6xxx_reg_unlock(chip);
 
        return err;
 }
 
  * tag_8021q setup can fail, the NPI setup can't. So either the change is made,
  * or the restoration is guaranteed to work.
  */
-static int felix_change_tag_protocol(struct dsa_switch *ds, int cpu,
+static int felix_change_tag_protocol(struct dsa_switch *ds,
                                     enum dsa_tag_protocol proto)
 {
        struct ocelot *ocelot = ds->priv;
        struct felix *felix = ocelot_to_felix(ocelot);
        enum dsa_tag_protocol old_proto = felix->tag_proto;
-       bool cpu_port_active = false;
-       struct dsa_port *dp;
+       struct dsa_port *cpu_dp;
        int err;
 
        if (proto != DSA_TAG_PROTO_SEVILLE &&
            proto != DSA_TAG_PROTO_OCELOT_8021Q)
                return -EPROTONOSUPPORT;
 
-       /* We don't support multiple CPU ports, yet the DT blob may have
-        * multiple CPU ports defined. The first CPU port is the active one,
-        * the others are inactive. In this case, DSA will call
-        * ->change_tag_protocol() multiple times, once per CPU port.
-        * Since we implement the tagging protocol change towards "ocelot" or
-        * "seville" as effectively initializing the NPI port, what we are
-        * doing is effectively changing who the NPI port is to the last @cpu
-        * argument passed, which is an unused DSA CPU port and not the one
-        * that should actively pass traffic.
-        * Suppress DSA's calls on CPU ports that are inactive.
-        */
-       dsa_switch_for_each_user_port(dp, ds) {
-               if (dp->cpu_dp->index == cpu) {
-                       cpu_port_active = true;
-                       break;
-               }
-       }
-
-       if (!cpu_port_active)
-               return 0;
+       dsa_switch_for_each_cpu_port(cpu_dp, ds) {
+               felix_del_tag_protocol(ds, cpu_dp->index, old_proto);
 
-       felix_del_tag_protocol(ds, cpu, old_proto);
+               err = felix_set_tag_protocol(ds, cpu_dp->index, proto);
+               if (err) {
+                       felix_set_tag_protocol(ds, cpu_dp->index, old_proto);
+                       return err;
+               }
 
-       err = felix_set_tag_protocol(ds, cpu, proto);
-       if (err) {
-               felix_set_tag_protocol(ds, cpu, old_proto);
-               return err;
+               /* Stop at first CPU port */
+               break;
        }
 
        felix->tag_proto = proto;
 
        return 0;
 }
 
-static int rtl8365mb_change_tag_protocol(struct dsa_switch *ds, int cpu_index,
+static int rtl8365mb_change_tag_protocol(struct dsa_switch *ds,
                                         enum dsa_tag_protocol proto)
 {
        struct realtek_priv *priv = ds->priv;
 
        dsa_switch_for_each_port((_dp), (_ds)) \
                if (dsa_port_is_cpu((_dp)))
 
+#define dsa_switch_for_each_cpu_port_continue_reverse(_dp, _ds) \
+       dsa_switch_for_each_port_continue_reverse((_dp), (_ds)) \
+               if (dsa_port_is_cpu((_dp)))
+
 static inline u32 dsa_user_ports(struct dsa_switch *ds)
 {
        struct dsa_port *dp;
        enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds,
                                                  int port,
                                                  enum dsa_tag_protocol mprot);
-       int     (*change_tag_protocol)(struct dsa_switch *ds, int port,
+       int     (*change_tag_protocol)(struct dsa_switch *ds,
                                       enum dsa_tag_protocol proto);
        /*
         * Method for switch drivers to connect to the tagging protocol driver
 
 {
        const struct dsa_device_ops *tag_ops = ds->dst->tag_ops;
        struct dsa_switch_tree *dst = ds->dst;
-       struct dsa_port *cpu_dp;
        int err;
 
        if (tag_ops->proto == dst->default_proto)
                goto connect;
 
-       dsa_switch_for_each_cpu_port(cpu_dp, ds) {
-               rtnl_lock();
-               err = ds->ops->change_tag_protocol(ds, cpu_dp->index,
-                                                  tag_ops->proto);
-               rtnl_unlock();
-               if (err) {
-                       dev_err(ds->dev, "Unable to use tag protocol \"%s\": %pe\n",
-                               tag_ops->name, ERR_PTR(err));
-                       return err;
-               }
+       rtnl_lock();
+       err = ds->ops->change_tag_protocol(ds, tag_ops->proto);
+       rtnl_unlock();
+       if (err) {
+               dev_err(ds->dev, "Unable to use tag protocol \"%s\": %pe\n",
+                       tag_ops->name, ERR_PTR(err));
+               return err;
        }
 
 connect:
 
 
        ASSERT_RTNL();
 
-       dsa_switch_for_each_cpu_port(cpu_dp, ds) {
-               err = ds->ops->change_tag_protocol(ds, cpu_dp->index,
-                                                  tag_ops->proto);
-               if (err)
-                       return err;
+       err = ds->ops->change_tag_protocol(ds, tag_ops->proto);
+       if (err)
+               return err;
 
+       dsa_switch_for_each_cpu_port(cpu_dp, ds)
                dsa_port_set_tag_protocol(cpu_dp, tag_ops);
-       }
 
        /* Now that changing the tag protocol can no longer fail, let's update
         * the remaining bits which are "duplicated for faster access", and the