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: Vivien Didelot <vivien.dide...@gmail.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c    | 42 +++++++++++++++-----------
 drivers/net/dsa/mv88e6xxx/chip.h    |  2 ++
 drivers/net/dsa/mv88e6xxx/global1.c | 47 ++++++++---------------------
 drivers/net/dsa/mv88e6xxx/global1.h |  2 ++
 4 files changed, 41 insertions(+), 52 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index d3804ffd3d2a..bd61d0d3a245 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -80,6 +80,29 @@ int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, 
int reg, u16 val)
        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 mv88e6xxx_mdio_bus *mdio_bus;
@@ -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 i;
-
-       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;
+       return mv88e6xxx_wait_mask(chip, addr, reg, mask, 0x0000);
 }
 
 /* Indirect write to single pointer-data register with an Update bit */
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 8c6d3c906197..95b44532a282 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -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_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,
                     u16 update);
 int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask);
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c 
b/drivers/net/dsa/mv88e6xxx/global1.c
index bbd31c9f8b48..482f9f8465af 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
@@ -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);
 }
 
+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 */
 
 static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip)
 {
-       u16 state;
-       int i, err;
-
-       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;
+       return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
+                                     MV88E6185_G1_STS_PPU_STATE_MASK,
+                                     MV88E6185_G1_STS_PPU_STATE_DISABLED);
 }
 
 static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
 {
-       u16 state;
-       int i, err;
-
-       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;
+       return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
+                                     MV88E6185_G1_STS_PPU_STATE_MASK,
+                                     MV88E6185_G1_STS_PPU_STATE_POLLING);
 }
 
 static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h 
b/drivers/net/dsa/mv88e6xxx/global1.h
index d444266f7d78..48869d7984f4 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -250,6 +250,8 @@
 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_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);
 
-- 
2.22.0

Reply via email to