diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2016-12-06 01:30:28 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-12-06 19:32:28 +0300 |
commit | a199d8b6956f8973d09d684fc71300889c26e8e4 (patch) | |
tree | e118cf13a0d5a96ea0c57b6b42084df79996bd2b /drivers/net/dsa/mv88e6xxx/global1.c | |
parent | 17e708baf7f24192cb1c7c8dd6b32d1941dfb0e8 (diff) | |
download | linux-a199d8b6956f8973d09d684fc71300889c26e8e4.tar.xz |
net: dsa: mv88e6xxx: add PPU operations
Some Marvell chips can enable/disable the PPU on demand. This is needed
to access the PHY registers when there is no indirection mechanism.
Add two new ppu_enable and ppu_disable ops to describe this and finally
get rid of the MV88E6XXX_FLAG_PPU* flags.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/global1.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global1.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c index c868eb06497f..75af86a7fad8 100644 --- a/drivers/net/dsa/mv88e6xxx/global1.c +++ b/drivers/net/dsa/mv88e6xxx/global1.c @@ -35,6 +35,27 @@ int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) /* 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, GLOBAL_STATUS, &state); + if (err) + return err; + + /* Check the value of the PPUState bits 15:14 */ + state &= GLOBAL_STATUS_PPU_STATE_MASK; + if (state != GLOBAL_STATUS_PPU_STATE_POLLING) + return 0; + + usleep_range(1000, 2000); + } + + return -ETIMEDOUT; +} + static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) { u16 state; @@ -154,6 +175,42 @@ int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip) return mv88e6352_g1_wait_ppu_polling(chip); } +int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip) +{ + u16 val; + int err; + + err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val); + if (err) + return err; + + val |= GLOBAL_CONTROL_PPU_ENABLE; + + err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, val); + if (err) + return err; + + return mv88e6185_g1_wait_ppu_polling(chip); +} + +int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip) +{ + u16 val; + int err; + + err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val); + if (err) + return err; + + val &= ~GLOBAL_CONTROL_PPU_ENABLE; + + err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, val); + if (err) + return err; + + return mv88e6185_g1_wait_ppu_disabled(chip); +} + /* Offset 0x1a: Monitor Control */ /* Offset 0x1a: Monitor & MGMT Control on some devices */ |