#include <net/dsa.h>
 #include "mv88e6xxx.h"
 
+/* MDIO bus access can be nested in the case of PHYs connected to the
+ * internal MDIO bus of the switch, which is accessed via MDIO bus of
+ * the Ethernet interface. Avoid lockdep false positives by using
+ * mutex_lock_nested().
+ */
+static int mv88e6xxx_mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
+{
+       int ret;
+
+       mutex_lock_nested(&bus->mdio_lock, SINGLE_DEPTH_NESTING);
+       ret = bus->read(bus, addr, regnum);
+       mutex_unlock(&bus->mdio_lock);
+
+       return ret;
+}
+
+static int mv88e6xxx_mdiobus_write(struct mii_bus *bus, int addr, u32 regnum,
+                                  u16 val)
+{
+       int ret;
+
+       mutex_lock_nested(&bus->mdio_lock, SINGLE_DEPTH_NESTING);
+       ret = bus->write(bus, addr, regnum, val);
+       mutex_unlock(&bus->mdio_lock);
+
+       return ret;
+}
+
 /* If the switch's ADDR[4:0] strap pins are strapped to zero, it will
  * use all 32 SMI bus addresses on its SMI bus, and all switch registers
  * will be directly accessible on some {device address,register address}
        int i;
 
        for (i = 0; i < 16; i++) {
-               ret = mdiobus_read(bus, sw_addr, SMI_CMD);
+               ret = mv88e6xxx_mdiobus_read(bus, sw_addr, SMI_CMD);
                if (ret < 0)
                        return ret;
 
        int ret;
 
        if (sw_addr == 0)
-               return mdiobus_read(bus, addr, reg);
+               return mv88e6xxx_mdiobus_read(bus, addr, reg);
 
        /* Wait for the bus to become free. */
        ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
                return ret;
 
        /* Transmit the read command. */
-       ret = mdiobus_write(bus, sw_addr, SMI_CMD,
-                           SMI_CMD_OP_22_READ | (addr << 5) | reg);
+       ret = mv88e6xxx_mdiobus_write(bus, sw_addr, SMI_CMD,
+                                     SMI_CMD_OP_22_READ | (addr << 5) | reg);
        if (ret < 0)
                return ret;
 
                return ret;
 
        /* Read the data. */
-       ret = mdiobus_read(bus, sw_addr, SMI_DATA);
+       ret = mv88e6xxx_mdiobus_read(bus, sw_addr, SMI_DATA);
        if (ret < 0)
                return ret;
 
        int ret;
 
        if (sw_addr == 0)
-               return mdiobus_write(bus, addr, reg, val);
+               return mv88e6xxx_mdiobus_write(bus, addr, reg, val);
 
        /* Wait for the bus to become free. */
        ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
                return ret;
 
        /* Transmit the data to write. */
-       ret = mdiobus_write(bus, sw_addr, SMI_DATA, val);
+       ret = mv88e6xxx_mdiobus_write(bus, sw_addr, SMI_DATA, val);
        if (ret < 0)
                return ret;
 
        /* Transmit the write command. */
-       ret = mdiobus_write(bus, sw_addr, SMI_CMD,
-                           SMI_CMD_OP_22_WRITE | (addr << 5) | reg);
+       ret = mv88e6xxx_mdiobus_write(bus, sw_addr, SMI_CMD,
+                                     SMI_CMD_OP_22_WRITE | (addr << 5) | reg);
        if (ret < 0)
                return ret;