diff options
author | Vivien Didelot <vivien.didelot@gmail.com> | 2019-08-31 23:18:34 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-09-01 22:16:38 +0300 |
commit | 61a46b4147b2767728eb0486be31e2e4b65dd3de (patch) | |
tree | 2e12788f4af2e7e4358260a9e911d8e72c64483b /drivers/net/dsa/mv88e6xxx/serdes.c | |
parent | dc272f600eb3c3453c1289b095c6749d3241ae81 (diff) | |
download | linux-61a46b4147b2767728eb0486be31e2e4b65dd3de.tar.xz |
net: dsa: mv88e6xxx: introduce .serdes_irq_enable
Introduce a new .serdes_irq_enable operation to prepare the abstraction
of IRQ enabling from the SERDES IRQ setup code.
Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/serdes.c | 73 |
1 files changed, 29 insertions, 44 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index e3ea8cca85b0..3562ef03ae55 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -226,15 +226,15 @@ out: return ret; } -static int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip) +int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool enable) { - return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, - MV88E6352_SERDES_INT_LINK_CHANGE); -} + u16 val = 0; -static int mv88e6352_serdes_irq_disable(struct mv88e6xxx_chip *chip) -{ - return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, 0); + if (enable) + val |= MV88E6352_SERDES_INT_LINK_CHANGE; + + return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val); } unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) @@ -245,9 +245,11 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) { unsigned int irq; + u8 lane; int err; - if (!mv88e6352_port_has_serdes(chip, port)) + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (!lane) return 0; irq = mv88e6xxx_serdes_irq_mapping(chip, port); @@ -272,15 +274,18 @@ int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) return err; } - return mv88e6352_serdes_irq_enable(chip); + return mv88e6xxx_serdes_irq_enable(chip, port, lane); } void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) { - if (!mv88e6352_port_has_serdes(chip, port)) + u8 lane; + + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (!lane) return; - mv88e6352_serdes_irq_disable(chip); + mv88e6xxx_serdes_irq_disable(chip, port, lane); /* Freeing the IRQ will trigger irq callbacks. So we cannot * hold the reg_lock. @@ -546,51 +551,31 @@ static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip, } static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip, - u8 lane) -{ - return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, - MV88E6390_SGMII_INT_ENABLE, - MV88E6390_SGMII_INT_LINK_DOWN | - MV88E6390_SGMII_INT_LINK_UP); -} - -static int mv88e6390_serdes_irq_disable_sgmii(struct mv88e6xxx_chip *chip, - u8 lane) + u8 lane, bool enable) { - return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, - MV88E6390_SGMII_INT_ENABLE, 0); -} + u16 val = 0; -int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, - u8 lane) -{ - u8 cmode = chip->ports[port].cmode; - int err = 0; + if (enable) + val |= MV88E6390_SGMII_INT_LINK_DOWN | + MV88E6390_SGMII_INT_LINK_UP; - switch (cmode) { - case MV88E6XXX_PORT_STS_CMODE_SGMII: - case MV88E6XXX_PORT_STS_CMODE_1000BASEX: - case MV88E6XXX_PORT_STS_CMODE_2500BASEX: - err = mv88e6390_serdes_irq_enable_sgmii(chip, lane); - } - - return err; + return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS, + MV88E6390_SGMII_INT_ENABLE, val); } -int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, - u8 lane) +int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool enable) { u8 cmode = chip->ports[port].cmode; - int err = 0; switch (cmode) { case MV88E6XXX_PORT_STS_CMODE_SGMII: case MV88E6XXX_PORT_STS_CMODE_1000BASEX: case MV88E6XXX_PORT_STS_CMODE_2500BASEX: - err = mv88e6390_serdes_irq_disable_sgmii(chip, lane); + return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable); } - return err; + return 0; } static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip, @@ -676,7 +661,7 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) return err; } - return mv88e6390_serdes_irq_enable(chip, port, lane); + return mv88e6xxx_serdes_irq_enable(chip, port, lane); } void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) @@ -687,7 +672,7 @@ void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) if (!lane) return; - mv88e6390_serdes_irq_disable(chip, port, lane); + mv88e6xxx_serdes_irq_disable(chip, port, lane); /* Freeing the IRQ will trigger irq callbacks. So we cannot * hold the reg_lock. |