Commit 683f2244 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller

net: dsa: mv88e6xxx: introduce wait mask routine

The current mv88e6xxx_wait routine is used to wait for a given mask
to be cleared to zero. However in some cases, the driver may have
to wait for a given mask to be of a certain non-zero value.

Thus provide a generic wait mask routine that will be used to implement
the current mv88e6xxx_wait function, and use it to wait for 88E6185
PPU states.
Signed-off-by: default avatarVivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 92993853
...@@ -80,6 +80,29 @@ int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val) ...@@ -80,6 +80,29 @@ int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
return 0; return 0;
} }
int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
u16 mask, u16 val)
{
u16 data;
int err;
int i;
/* There's no bus specific operation to wait for a mask */
for (i = 0; i < 16; i++) {
err = mv88e6xxx_read(chip, addr, reg, &data);
if (err)
return err;
if ((data & mask) == val)
return 0;
usleep_range(1000, 2000);
}
dev_err(chip->dev, "Timeout while waiting for switch\n");
return -ETIMEDOUT;
}
struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip) struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
{ {
struct mv88e6xxx_mdio_bus *mdio_bus; struct mv88e6xxx_mdio_bus *mdio_bus;
...@@ -365,24 +388,7 @@ static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip) ...@@ -365,24 +388,7 @@ static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)
int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask) int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
{ {
int i; return mv88e6xxx_wait_mask(chip, addr, reg, mask, 0x0000);
for (i = 0; i < 16; i++) {
u16 val;
int err;
err = mv88e6xxx_read(chip, addr, reg, &val);
if (err)
return err;
if (!(val & mask))
return 0;
usleep_range(1000, 2000);
}
dev_err(chip->dev, "Timeout while waiting for switch\n");
return -ETIMEDOUT;
} }
/* Indirect write to single pointer-data register with an Update bit */ /* Indirect write to single pointer-data register with an Update bit */
......
...@@ -588,6 +588,8 @@ static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int po ...@@ -588,6 +588,8 @@ static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int po
int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
u16 mask, u16 val);
int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg,
u16 update); u16 update);
int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask); int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask);
......
...@@ -32,48 +32,27 @@ int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) ...@@ -32,48 +32,27 @@ int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask); return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask);
} }
int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg,
u16 mask, u16 val)
{
return mv88e6xxx_wait_mask(chip, chip->info->global1_addr, reg,
mask, val);
}
/* Offset 0x00: Switch Global Status Register */ /* Offset 0x00: Switch Global Status Register */
static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip) static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip)
{ {
u16 state; return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
int i, err; MV88E6185_G1_STS_PPU_STATE_MASK,
MV88E6185_G1_STS_PPU_STATE_DISABLED);
for (i = 0; i < 16; i++) {
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state);
if (err)
return err;
/* Check the value of the PPUState bits 15:14 */
state &= MV88E6185_G1_STS_PPU_STATE_MASK;
if (state == MV88E6185_G1_STS_PPU_STATE_DISABLED)
return 0;
usleep_range(1000, 2000);
}
return -ETIMEDOUT;
} }
static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
{ {
u16 state; return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
int i, err; MV88E6185_G1_STS_PPU_STATE_MASK,
MV88E6185_G1_STS_PPU_STATE_POLLING);
for (i = 0; i < 16; ++i) {
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state);
if (err)
return err;
/* Check the value of the PPUState bits 15:14 */
state &= MV88E6185_G1_STS_PPU_STATE_MASK;
if (state == MV88E6185_G1_STS_PPU_STATE_POLLING)
return 0;
usleep_range(1000, 2000);
}
return -ETIMEDOUT;
} }
static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
......
...@@ -250,6 +250,8 @@ ...@@ -250,6 +250,8 @@
int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val); int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val); int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val);
int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask); int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask);
int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg,
u16 mask, u16 val);
int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr); int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment