mirror of https://gitee.com/openkylin/linux.git
net: mdio: Fix lockdep falls positive splat
MDIO devices can be stacked upon each other. The current code supports two levels, which until recently has been enough for a DSA mdio bus on top of another bus. Now we have hardware which has an MDIO mux in the middle. Define an MDIO MUTEX class with three levels. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7c3da7d0d4
commit
9a6f2b0113
|
@ -45,13 +45,7 @@ static int mdio_mux_read(struct mii_bus *bus, int phy_id, int regnum)
|
||||||
struct mdio_mux_parent_bus *pb = cb->parent;
|
struct mdio_mux_parent_bus *pb = cb->parent;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* In theory multiple mdio_mux could be stacked, thus creating
|
mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX);
|
||||||
* more than a single level of nesting. But in practice,
|
|
||||||
* SINGLE_DEPTH_NESTING will cover the vast majority of use
|
|
||||||
* cases. We use it, instead of trying to handle the general
|
|
||||||
* case.
|
|
||||||
*/
|
|
||||||
mutex_lock_nested(&pb->mii_bus->mdio_lock, SINGLE_DEPTH_NESTING);
|
|
||||||
r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
|
r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
|
||||||
if (r)
|
if (r)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -76,7 +70,7 @@ static int mdio_mux_write(struct mii_bus *bus, int phy_id,
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
mutex_lock_nested(&pb->mii_bus->mdio_lock, SINGLE_DEPTH_NESTING);
|
mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX);
|
||||||
r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
|
r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
|
||||||
if (r)
|
if (r)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -457,7 +457,7 @@ int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum)
|
||||||
|
|
||||||
BUG_ON(in_interrupt());
|
BUG_ON(in_interrupt());
|
||||||
|
|
||||||
mutex_lock_nested(&bus->mdio_lock, SINGLE_DEPTH_NESTING);
|
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||||
retval = bus->read(bus, addr, regnum);
|
retval = bus->read(bus, addr, regnum);
|
||||||
mutex_unlock(&bus->mdio_lock);
|
mutex_unlock(&bus->mdio_lock);
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val)
|
||||||
|
|
||||||
BUG_ON(in_interrupt());
|
BUG_ON(in_interrupt());
|
||||||
|
|
||||||
mutex_lock_nested(&bus->mdio_lock, SINGLE_DEPTH_NESTING);
|
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||||
err = bus->write(bus, addr, regnum, val);
|
err = bus->write(bus, addr, regnum, val);
|
||||||
mutex_unlock(&bus->mdio_lock);
|
mutex_unlock(&bus->mdio_lock);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,17 @@
|
||||||
|
|
||||||
struct mii_bus;
|
struct mii_bus;
|
||||||
|
|
||||||
|
/* Multiple levels of nesting are possible. However typically this is
|
||||||
|
* limited to nested DSA like layer, a MUX layer, and the normal
|
||||||
|
* user. Instead of trying to handle the general case, just define
|
||||||
|
* these cases.
|
||||||
|
*/
|
||||||
|
enum mdio_mutex_lock_class {
|
||||||
|
MDIO_MUTEX_NORMAL,
|
||||||
|
MDIO_MUTEX_MUX,
|
||||||
|
MDIO_MUTEX_NESTED,
|
||||||
|
};
|
||||||
|
|
||||||
struct mdio_device {
|
struct mdio_device {
|
||||||
struct device dev;
|
struct device dev;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue