From 946bc2509eb88ff0c64dd727a11c5a29b6bc2574 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:27 -0400 Subject: net: dsa: mv88e6xxx: check errors in mv88e6352_serdes_irq_link The mv88e6352_serdes_irq_link helper is not checking for any error that may occur during hardware accesses. Worst, the "up" boolean is set from the potentially unused "status" variable, if read operations failed. As done in mv88e6390_serdes_irq_link_sgmii, return right away and do not call dsa_port_phylink_mac_change if an error occurred. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/serdes.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 38c0da2492c0..7eb7ed68c91d 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -186,14 +186,19 @@ static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port) struct dsa_switch *ds = chip->ds; u16 status; bool up; + int err; - mv88e6352_serdes_read(chip, MII_BMSR, &status); + err = mv88e6352_serdes_read(chip, MII_BMSR, &status); + if (err) + return; /* Status must be read twice in order to give the current link * status. Otherwise the change in link status since the last * read of the register is returned. */ - mv88e6352_serdes_read(chip, MII_BMSR, &status); + err = mv88e6352_serdes_read(chip, MII_BMSR, &status); + if (err) + return; up = status & BMSR_LSTATUS; -- cgit v1.2.3 From f441ed0f4c89c14dd68ce477f513bae43509237e Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:28 -0400 Subject: net: dsa: mv88e6xxx: fix SERDES IRQ mapping The current mv88e6xxx SERDES code checks for negative error code from irq_find_mapping, while this function returns an unsigned integer. This patch removes this dead code and simply returns 0 is no IRQ is found. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.h | 2 +- drivers/net/dsa/mv88e6xxx/serdes.c | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 421e8b84bec3..2016f51c868b 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -199,7 +199,7 @@ struct mv88e6xxx_port { u64 vtu_member_violation; u64 vtu_miss_violation; u8 cmode; - int serdes_irq; + unsigned int serdes_irq; }; struct mv88e6xxx_chip { diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 7eb7ed68c91d..f65652e6edec 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -249,11 +249,8 @@ int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ); - if (chip->ports[port].serdes_irq < 0) { - dev_err(chip->dev, "Unable to map SERDES irq: %d\n", - chip->ports[port].serdes_irq); - return chip->ports[port].serdes_irq; - } + if (!chip->ports[port].serdes_irq) + return 0; /* Requesting the IRQ will trigger irq callbacks. So we cannot * hold the reg_lock. @@ -690,11 +687,8 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain, port); - if (chip->ports[port].serdes_irq < 0) { - dev_err(chip->dev, "Unable to map SERDES irq: %d\n", - chip->ports[port].serdes_irq); - return chip->ports[port].serdes_irq; - } + if (!chip->ports[port].serdes_irq) + return 0; /* Requesting the IRQ will trigger irq callbacks. So we cannot * hold the reg_lock. -- cgit v1.2.3 From 4241ef52372ebee93f4ed67e08c9316ccb20bdd7 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:29 -0400 Subject: net: dsa: mv88e6xxx: introduce .serdes_irq_mapping Introduce a new .serdes_irq_mapping operation to prepare the abstraction of IRQ mapping from the SERDES IRQ setup code. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 11 +++++++++++ drivers/net/dsa/mv88e6xxx/chip.h | 2 ++ drivers/net/dsa/mv88e6xxx/serdes.c | 26 ++++++++++++++++++++------ drivers/net/dsa/mv88e6xxx/serdes.h | 12 ++++++++++++ 4 files changed, 45 insertions(+), 6 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index c648f9fbfa59..0ab4ce86eda7 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2931,6 +2931,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6341_serdes_get_lane, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3178,6 +3179,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6352_serdes_power, + .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3261,6 +3263,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3308,6 +3311,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390x_serdes_get_lane, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3355,6 +3359,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .avb_ops = &mv88e6390_avb_ops, @@ -3403,6 +3408,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6352_serdes_power, + .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3492,6 +3498,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3629,6 +3636,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6341_serdes_get_lane, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3760,6 +3768,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6352_serdes_power, + .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3814,6 +3823,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3865,6 +3875,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390x_serdes_get_lane, + .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 2016f51c868b..b116bd7f6109 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -447,6 +447,8 @@ struct mv88e6xxx_ops { int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port, u8 *lane); /* SERDES interrupt handling */ + unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip, + int port); int (*serdes_irq_setup)(struct mv88e6xxx_chip *chip, int port); void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port); diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index f65652e6edec..4fb1dca64ef1 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -240,18 +240,25 @@ static int mv88e6352_serdes_irq_disable(struct mv88e6xxx_chip *chip) return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, 0); } +unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) +{ + return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ); +} + int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) { + unsigned int irq; int err; if (!mv88e6352_port_has_serdes(chip, port)) return 0; - chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain, - MV88E6352_SERDES_IRQ); - if (!chip->ports[port].serdes_irq) + irq = mv88e6xxx_serdes_irq_mapping(chip, port); + if (!irq) return 0; + chip->ports[port].serdes_irq = irq; + /* Requesting the IRQ will trigger irq callbacks. So we cannot * hold the reg_lock. */ @@ -673,8 +680,14 @@ out: return ret; } +unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) +{ + return irq_find_mapping(chip->g2_irq.domain, port); +} + int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) { + unsigned int irq; int err; u8 lane; @@ -685,11 +698,12 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) return err; } - chip->ports[port].serdes_irq = irq_find_mapping(chip->g2_irq.domain, - port); - if (!chip->ports[port].serdes_irq) + irq = mv88e6xxx_serdes_irq_mapping(chip, port); + if (!irq) return 0; + chip->ports[port].serdes_irq = irq; + /* Requesting the IRQ will trigger irq callbacks. So we cannot * hold the reg_lock. */ diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index c2e6fc3ddf8b..cb8d287c9388 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -90,6 +90,10 @@ static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); +unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, + int port); +unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, + int port); int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); @@ -106,5 +110,13 @@ int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); +static inline unsigned int +mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) +{ + if (!chip->info->ops->serdes_irq_mapping) + return 0; + + return chip->info->ops->serdes_irq_mapping(chip, port); +} #endif -- cgit v1.2.3 From 5122d4ec9e8053a5944bf77db6bd6c89143531d7 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:30 -0400 Subject: net: dsa: mv88e6xxx: simplify .serdes_get_lane Because the mapping between a SERDES interface and its lane is static, we don't need to stick with negative error codes actually and we can simply return 0 if there is no lane, just like the IRQ mapping. This way we can keep a simple and intuitive API using unsigned lane numbers while simplifying the implementations with single return statements. Last but not least, fix the reverse chrismas tree in mv88e6390x_serdes_get_lane. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.h | 2 +- drivers/net/dsa/mv88e6xxx/port.c | 13 ++-- drivers/net/dsa/mv88e6xxx/serdes.c | 152 ++++++++++++++----------------------- drivers/net/dsa/mv88e6xxx/serdes.h | 29 ++++--- 4 files changed, 74 insertions(+), 122 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index b116bd7f6109..add0ec5188ec 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -444,7 +444,7 @@ struct mv88e6xxx_ops { int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); /* SERDES lane mapping */ - int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port, u8 *lane); + u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port); /* SERDES interrupt handling */ unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip, diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index 4f841335ea32..06e2bdf6fa82 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -431,11 +431,8 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, if (cmode == chip->ports[port].cmode) return 0; - err = mv88e6xxx_serdes_get_lane(chip, port, &lane); - if (err && err != -ENODEV) - return err; - - if (err != -ENODEV) { + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (lane) { if (chip->ports[port].serdes_irq) { err = mv88e6390_serdes_irq_disable(chip, port, lane); if (err) @@ -463,9 +460,9 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, chip->ports[port].cmode = cmode; - err = mv88e6xxx_serdes_get_lane(chip, port, &lane); - if (err) - return err; + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (!lane) + return -ENODEV; err = mv88e6390_serdes_power(chip, port, true); if (err) diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 4fb1dca64ef1..ce6d97e5caf8 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -295,149 +295,119 @@ void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) chip->ports[port].serdes_irq = 0; } -int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) +u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) { u8 cmode = chip->ports[port].cmode; + u8 lane = 0; - if (port != 5) - return -ENODEV; - - if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || - cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { - *lane = MV88E6341_PORT5_LANE; - return 0; + switch (port) { + case 5: + if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || + cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || + cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) + lane = MV88E6341_PORT5_LANE; + break; } - return -ENODEV; + return lane; } -int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) +u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) { u8 cmode = chip->ports[port].cmode; + u8 lane = 0; switch (port) { case 9: if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { - *lane = MV88E6390_PORT9_LANE0; - return 0; - } + cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) + lane = MV88E6390_PORT9_LANE0; break; case 10: if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { - *lane = MV88E6390_PORT10_LANE0; - return 0; - } - break; - default: + cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) + lane = MV88E6390_PORT10_LANE0; break; } - return -ENODEV; + return lane; } -int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane) +u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) { - u8 cmode_port9, cmode_port10, cmode_port; - - cmode_port9 = chip->ports[9].cmode; - cmode_port10 = chip->ports[10].cmode; - cmode_port = chip->ports[port].cmode; + u8 cmode_port = chip->ports[port].cmode; + u8 cmode_port10 = chip->ports[10].cmode; + u8 cmode_port9 = chip->ports[9].cmode; + u8 lane = 0; switch (port) { case 2: if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { - *lane = MV88E6390_PORT9_LANE1; - return 0; - } - } + cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) + lane = MV88E6390_PORT9_LANE1; break; case 3: if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || - cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { - *lane = MV88E6390_PORT9_LANE2; - return 0; - } - } + cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) + lane = MV88E6390_PORT9_LANE2; break; case 4: if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || - cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { - *lane = MV88E6390_PORT9_LANE3; - return 0; - } - } + cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) + lane = MV88E6390_PORT9_LANE3; break; case 5: if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || - cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { - *lane = MV88E6390_PORT10_LANE1; - return 0; - } - } + cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) + lane = MV88E6390_PORT10_LANE1; break; case 6: if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || - cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { - *lane = MV88E6390_PORT10_LANE2; - return 0; - } - } + cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) + lane = MV88E6390_PORT10_LANE2; break; case 7: if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || - cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { - *lane = MV88E6390_PORT10_LANE3; - return 0; - } - } + cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) + if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) + lane = MV88E6390_PORT10_LANE3; break; case 9: if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI || - cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - *lane = MV88E6390_PORT9_LANE0; - return 0; - } + cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) + lane = MV88E6390_PORT9_LANE0; break; case 10: if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI || - cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { - *lane = MV88E6390_PORT10_LANE0; - return 0; - } - break; - default: + cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) + lane = MV88E6390_PORT10_LANE0; break; } - return -ENODEV; + return lane; } /* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */ @@ -497,14 +467,10 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) { u8 cmode = chip->ports[port].cmode; u8 lane; - int err; - err = mv88e6xxx_serdes_get_lane(chip, port, &lane); - if (err) { - if (err == -ENODEV) - err = 0; - return err; - } + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (!lane) + return 0; switch (cmode) { case MV88E6XXX_PORT_STS_CMODE_SGMII: @@ -657,8 +623,8 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) mv88e6xxx_reg_lock(chip); - err = mv88e6xxx_serdes_get_lane(chip, port->port, &lane); - if (err) + lane = mv88e6xxx_serdes_get_lane(chip, port->port); + if (!lane) goto out; switch (cmode) { @@ -691,12 +657,9 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) int err; u8 lane; - err = mv88e6xxx_serdes_get_lane(chip, port, &lane); - if (err) { - if (err == -ENODEV) - err = 0; - return err; - } + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (!lane) + return 0; irq = mv88e6xxx_serdes_irq_mapping(chip, port); if (!irq) @@ -725,16 +688,11 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) { - int err; u8 lane; - err = mv88e6xxx_serdes_get_lane(chip, port, &lane); - if (err) { - if (err != -ENODEV) - dev_err(chip->dev, "Unable to free SERDES irq: %d\n", - err); + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (!lane) return; - } mv88e6390_serdes_irq_disable(chip, port, lane); diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index cb8d287c9388..4718dcca6b3c 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -74,22 +74,9 @@ #define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11) #define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10) -/* Put the SERDES lane address a port is using into *lane. If a port has - * multiple lanes, should put the first lane the port is using. If a port does - * not have a lane, return -ENODEV. - */ -static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, - int port, u8 *lane) -{ - if (!chip->info->ops->serdes_get_lane) - return -EOPNOTSUPP; - - return chip->info->ops->serdes_get_lane(chip, port, lane); -} - -int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); -int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); -int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); +u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); +u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); +u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port); unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, @@ -110,6 +97,16 @@ int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); +/* Return the (first) SERDES lane address a port is using, 0 otherwise. */ +static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, + int port) +{ + if (!chip->info->ops->serdes_get_lane) + return 0; + + return chip->info->ops->serdes_get_lane(chip, port); +} + static inline unsigned int mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) { -- cgit v1.2.3 From 9db4a7257e601491cf8e0b7e7e1461f7cde294bb Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:31 -0400 Subject: net: dsa: mv88e6xxx: implement mv88e6352_serdes_get_lane Even though 88E6352 has no dedicated lane for SERDES interfaces, it uses a similar code as the other .serdes_get_lane implementations to check the port's CMODE and ensure that SERDES operations are doable. For consistency, implement mv88e6352_serdes_get_lane for the 88E6352 and similar switches which simply returns an unused 0xff lane address. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 4 ++++ drivers/net/dsa/mv88e6xxx/serdes.c | 11 ++++++++++- drivers/net/dsa/mv88e6xxx/serdes.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 0ab4ce86eda7..3962e7368ae5 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3093,6 +3093,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = { .rmu_disable = mv88e6352_g1_rmu_disable, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, + .serdes_get_lane = mv88e6352_serdes_get_lane, .serdes_power = mv88e6352_serdes_power, .gpio_ops = &mv88e6352_gpio_ops, .phylink_validate = mv88e6352_phylink_validate, @@ -3178,6 +3179,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .rmu_disable = mv88e6352_g1_rmu_disable, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, + .serdes_get_lane = mv88e6352_serdes_get_lane, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_setup = mv88e6352_serdes_irq_setup, @@ -3407,6 +3409,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .rmu_disable = mv88e6352_g1_rmu_disable, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, + .serdes_get_lane = mv88e6352_serdes_get_lane, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_setup = mv88e6352_serdes_irq_setup, @@ -3767,6 +3770,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .rmu_disable = mv88e6352_g1_rmu_disable, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, + .serdes_get_lane = mv88e6352_serdes_get_lane, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_setup = mv88e6352_serdes_irq_setup, diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index ce6d97e5caf8..9fb2773a3eb5 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -69,13 +69,22 @@ static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip *chip, bool on) return err; } -static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port) +u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) { u8 cmode = chip->ports[port].cmode; + u8 lane = 0; if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) || (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) || (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII)) + lane = 0xff; /* Unused */ + + return lane; +} + +static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port) +{ + if (mv88e6xxx_serdes_get_lane(chip, port)) return true; return false; diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index 4718dcca6b3c..7df27a0de9aa 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -75,6 +75,7 @@ #define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10) u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); +u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, -- cgit v1.2.3 From 6600d8e5822d9b3f98c82db3e96df6895b1e87d8 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:32 -0400 Subject: net: dsa: mv88e6xxx: merge mv88e6352_serdes_power_set The mv88e6352_serdes_power_set helper is only used at one place, in mv88e6352_serdes_power. Keep it simple and merge the two functions together. Use mv88e6xxx_serdes_get_lane instead of mv88e6352_port_has_serdes to avoid moving code. No functional changes. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/serdes.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 9fb2773a3eb5..e8ad66987be9 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -49,11 +49,14 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, return mv88e6xxx_phy_write(chip, lane, reg_c45, val); } -static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip *chip, bool on) +int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) { u16 val, new_val; int err; + if (!mv88e6xxx_serdes_get_lane(chip, port)) + return 0; + err = mv88e6352_serdes_read(chip, MII_BMCR, &val); if (err) return err; @@ -90,19 +93,6 @@ static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port) return false; } -int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) -{ - int err; - - if (mv88e6352_port_has_serdes(chip, port)) { - err = mv88e6352_serdes_power_set(chip, on); - if (err < 0) - return err; - } - - return 0; -} - struct mv88e6352_serdes_hw_stat { char string[ETH_GSTRING_LEN]; int sizeof_stat; -- cgit v1.2.3 From dc272f600eb3c3453c1289b095c6749d3241ae81 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:33 -0400 Subject: net: dsa: mv88e6xxx: pass lane to .serdes_power Now the first step of all .serdes_power implementations is getting the lane mapping. Since we have an operation for that, call it in the wrapper and pass the lane down to the .serdes_power operation. This also allows to avoid querying the SERDES lane twice in mv88e6xxx_port_set_cmode. At the same time provide mv88e6xxx_serdes_power_{up,down} helpers and prefer up/down instead of on/off as in the documentation. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 8 +++++--- drivers/net/dsa/mv88e6xxx/chip.h | 3 ++- drivers/net/dsa/mv88e6xxx/port.c | 4 ++-- drivers/net/dsa/mv88e6xxx/serdes.c | 32 +++++++++++++------------------- drivers/net/dsa/mv88e6xxx/serdes.h | 24 ++++++++++++++++++++++-- 5 files changed, 44 insertions(+), 27 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 3962e7368ae5..3522b11d5566 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2057,13 +2057,15 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port) static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) { + u8 lane; int err; - if (!chip->info->ops->serdes_power) + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (!lane) return 0; if (on) { - err = chip->info->ops->serdes_power(chip, port, true); + err = mv88e6xxx_serdes_power_up(chip, port, lane); if (err) return err; @@ -2074,7 +2076,7 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port, chip->ports[port].serdes_irq) chip->info->ops->serdes_irq_free(chip, port); - err = chip->info->ops->serdes_power(chip, port, false); + err = mv88e6xxx_serdes_power_down(chip, port, lane); } return err; diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index add0ec5188ec..724ce2bf8258 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -441,7 +441,8 @@ struct mv88e6xxx_ops { int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip); /* Power on/off a SERDES interface */ - int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); + int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool up); /* SERDES lane mapping */ u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port); diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index 06e2bdf6fa82..df71c08eda35 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -439,7 +439,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, return err; } - err = mv88e6390_serdes_power(chip, port, false); + err = mv88e6xxx_serdes_power_down(chip, port, lane); if (err) return err; } @@ -464,7 +464,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, if (!lane) return -ENODEV; - err = mv88e6390_serdes_power(chip, port, true); + err = mv88e6xxx_serdes_power_up(chip, port, lane); if (err) return err; diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index e8ad66987be9..e3ea8cca85b0 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -49,19 +49,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, return mv88e6xxx_phy_write(chip, lane, reg_c45, val); } -int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) +int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool up) { u16 val, new_val; int err; - if (!mv88e6xxx_serdes_get_lane(chip, port)) - return 0; - err = mv88e6352_serdes_read(chip, MII_BMCR, &val); if (err) return err; - if (on) + if (up) new_val = val & ~BMCR_PDOWN; else new_val = val | BMCR_PDOWN; @@ -409,9 +407,9 @@ u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) return lane; } -/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */ +/* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, - bool on) + bool up) { u16 val, new_val; int err; @@ -422,7 +420,7 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, if (err) return err; - if (on) + if (up) new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET | MV88E6390_PCS_CONTROL_1_LOOPBACK | MV88E6390_PCS_CONTROL_1_PDOWN); @@ -436,9 +434,9 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, return err; } -/* Set the power on/off for SGMII and 1000Base-X */ +/* Set power up/down for SGMII and 1000Base-X */ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, - bool on) + bool up) { u16 val, new_val; int err; @@ -448,7 +446,7 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, if (err) return err; - if (on) + if (up) new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET | MV88E6390_SGMII_CONTROL_LOOPBACK | MV88E6390_SGMII_CONTROL_PDOWN); @@ -462,23 +460,19 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, return err; } -int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) +int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool up) { u8 cmode = chip->ports[port].cmode; - u8 lane; - - lane = mv88e6xxx_serdes_get_lane(chip, port); - if (!lane) - return 0; switch (cmode) { case MV88E6XXX_PORT_STS_CMODE_SGMII: case MV88E6XXX_PORT_STS_CMODE_1000BASEX: case MV88E6XXX_PORT_STS_CMODE_2500BASEX: - return mv88e6390_serdes_power_sgmii(chip, lane, on); + return mv88e6390_serdes_power_sgmii(chip, lane, up); case MV88E6XXX_PORT_STS_CMODE_XAUI: case MV88E6XXX_PORT_STS_CMODE_RXAUI: - return mv88e6390_serdes_power_10g(chip, lane, on); + return mv88e6390_serdes_power_10g(chip, lane, up); } return 0; diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index 7df27a0de9aa..c70023f57090 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -82,8 +82,10 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port); unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port); -int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); -int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); +int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool on); +int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool on); int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); @@ -108,6 +110,24 @@ static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, return chip->info->ops->serdes_get_lane(chip, port); } +static inline int mv88e6xxx_serdes_power_up(struct mv88e6xxx_chip *chip, + int port, u8 lane) +{ + if (!chip->info->ops->serdes_power) + return -EOPNOTSUPP; + + return chip->info->ops->serdes_power(chip, port, lane, true); +} + +static inline int mv88e6xxx_serdes_power_down(struct mv88e6xxx_chip *chip, + int port, u8 lane) +{ + if (!chip->info->ops->serdes_power) + return -EOPNOTSUPP; + + return chip->info->ops->serdes_power(chip, port, lane, false); +} + static inline unsigned int mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) { -- cgit v1.2.3 From 61a46b4147b2767728eb0486be31e2e4b65dd3de Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:34 -0400 Subject: 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 Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 11 ++++++ drivers/net/dsa/mv88e6xxx/chip.h | 2 ++ drivers/net/dsa/mv88e6xxx/port.c | 4 +-- drivers/net/dsa/mv88e6xxx/serdes.c | 73 +++++++++++++++----------------------- drivers/net/dsa/mv88e6xxx/serdes.h | 26 +++++++++++--- 5 files changed, 66 insertions(+), 50 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 3522b11d5566..258174634bb2 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2934,6 +2934,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6341_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3184,6 +3185,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .serdes_get_lane = mv88e6352_serdes_get_lane, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, + .serdes_irq_enable = mv88e6352_serdes_irq_enable, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3268,6 +3270,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3316,6 +3319,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390x_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3364,6 +3368,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .avb_ops = &mv88e6390_avb_ops, @@ -3414,6 +3419,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .serdes_get_lane = mv88e6352_serdes_get_lane, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, + .serdes_irq_enable = mv88e6352_serdes_irq_enable, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3504,6 +3510,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3642,6 +3649,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6341_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3775,6 +3783,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .serdes_get_lane = mv88e6352_serdes_get_lane, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, + .serdes_irq_enable = mv88e6352_serdes_irq_enable, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3830,6 +3839,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3882,6 +3892,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390x_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, + .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 724ce2bf8258..0c7b0f6053d8 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -452,6 +452,8 @@ struct mv88e6xxx_ops { int port); int (*serdes_irq_setup)(struct mv88e6xxx_chip *chip, int port); void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port); + int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool enable); /* Statistics from the SERDES interface */ int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index df71c08eda35..04006344adb2 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -434,7 +434,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, lane = mv88e6xxx_serdes_get_lane(chip, port); if (lane) { if (chip->ports[port].serdes_irq) { - err = mv88e6390_serdes_irq_disable(chip, port, lane); + err = mv88e6xxx_serdes_irq_disable(chip, port, lane); if (err) return err; } @@ -469,7 +469,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, return err; if (chip->ports[port].serdes_irq) { - err = mv88e6390_serdes_irq_enable(chip, port, lane); + err = mv88e6xxx_serdes_irq_enable(chip, port, lane); if (err) return err; } 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. diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index c70023f57090..e2d38b5d4222 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -88,15 +88,15 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, bool on); int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); +int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool enable); +int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, + bool enable); int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int port, uint8_t *data); int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, uint64_t *data); -int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, - u8 lane); -int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, - u8 lane); int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); @@ -137,4 +137,22 @@ mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) return chip->info->ops->serdes_irq_mapping(chip, port); } +static inline int mv88e6xxx_serdes_irq_enable(struct mv88e6xxx_chip *chip, + int port, u8 lane) +{ + if (!chip->info->ops->serdes_irq_enable) + return -EOPNOTSUPP; + + return chip->info->ops->serdes_irq_enable(chip, port, lane, true); +} + +static inline int mv88e6xxx_serdes_irq_disable(struct mv88e6xxx_chip *chip, + int port, u8 lane) +{ + if (!chip->info->ops->serdes_irq_enable) + return -EOPNOTSUPP; + + return chip->info->ops->serdes_irq_enable(chip, port, lane, false); +} + #endif -- cgit v1.2.3 From 907b9b9fcaef7fb193105d9d61cd795b38ee2530 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:35 -0400 Subject: net: dsa: mv88e6xxx: introduce .serdes_irq_status Introduce a new .serdes_irq_status operation to prepare the abstraction of IRQ thread from the SERDES IRQ setup code. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 11 +++++++ drivers/net/dsa/mv88e6xxx/chip.h | 2 ++ drivers/net/dsa/mv88e6xxx/serdes.c | 59 ++++++++++++++++++++++++-------------- drivers/net/dsa/mv88e6xxx/serdes.h | 13 +++++++++ 4 files changed, 64 insertions(+), 21 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 258174634bb2..c2061e20bb32 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2935,6 +2935,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .serdes_get_lane = mv88e6341_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, + .serdes_irq_status = mv88e6390_serdes_irq_status, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3186,6 +3187,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable, + .serdes_irq_status = mv88e6352_serdes_irq_status, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3271,6 +3273,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, + .serdes_irq_status = mv88e6390_serdes_irq_status, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3320,6 +3323,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .serdes_get_lane = mv88e6390x_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, + .serdes_irq_status = mv88e6390_serdes_irq_status, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3369,6 +3373,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, + .serdes_irq_status = mv88e6390_serdes_irq_status, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .avb_ops = &mv88e6390_avb_ops, @@ -3420,6 +3425,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable, + .serdes_irq_status = mv88e6352_serdes_irq_status, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3511,6 +3517,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, + .serdes_irq_status = mv88e6390_serdes_irq_status, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3650,6 +3657,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .serdes_get_lane = mv88e6341_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, + .serdes_irq_status = mv88e6390_serdes_irq_status, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3784,6 +3792,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable, + .serdes_irq_status = mv88e6352_serdes_irq_status, .serdes_irq_setup = mv88e6352_serdes_irq_setup, .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3840,6 +3849,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .serdes_get_lane = mv88e6390_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, + .serdes_irq_status = mv88e6390_serdes_irq_status, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, @@ -3893,6 +3903,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .serdes_get_lane = mv88e6390x_serdes_get_lane, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, + .serdes_irq_status = mv88e6390_serdes_irq_status, .serdes_irq_setup = mv88e6390_serdes_irq_setup, .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 0c7b0f6053d8..9a73fd1d643b 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -454,6 +454,8 @@ struct mv88e6xxx_ops { void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port); int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane, bool enable); + irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port, + u8 lane); /* Statistics from the SERDES interface */ int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 3562ef03ae55..d37419ba26ab 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -202,25 +202,33 @@ static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port) dsa_port_phylink_mac_change(ds, port, up); } -static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id) +irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, + u8 lane) { - struct mv88e6xxx_port *port = dev_id; - struct mv88e6xxx_chip *chip = port->chip; irqreturn_t ret = IRQ_NONE; u16 status; int err; - mv88e6xxx_reg_lock(chip); - err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status); if (err) - goto out; + return ret; if (status & MV88E6352_SERDES_INT_LINK_CHANGE) { ret = IRQ_HANDLED; - mv88e6352_serdes_irq_link(chip, port->port); + mv88e6352_serdes_irq_link(chip, port); } -out: + + return ret; +} + +static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id) +{ + struct mv88e6xxx_port *port = dev_id; + struct mv88e6xxx_chip *chip = port->chip; + irqreturn_t ret = IRQ_NONE; + + mv88e6xxx_reg_lock(chip); + ret = mv88e6xxx_serdes_irq_status(chip, port->port, 0); mv88e6xxx_reg_unlock(chip); return ret; @@ -589,21 +597,13 @@ static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip, return err; } -static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) +irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, + u8 lane) { - struct mv88e6xxx_port *port = dev_id; - struct mv88e6xxx_chip *chip = port->chip; + u8 cmode = chip->ports[port].cmode; irqreturn_t ret = IRQ_NONE; - u8 cmode = port->cmode; u16 status; int err; - u8 lane; - - mv88e6xxx_reg_lock(chip); - - lane = mv88e6xxx_serdes_get_lane(chip, port->port); - if (!lane) - goto out; switch (cmode) { case MV88E6XXX_PORT_STS_CMODE_SGMII: @@ -611,13 +611,30 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) case MV88E6XXX_PORT_STS_CMODE_2500BASEX: err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status); if (err) - goto out; + return ret; if (status & (MV88E6390_SGMII_INT_LINK_DOWN | MV88E6390_SGMII_INT_LINK_UP)) { ret = IRQ_HANDLED; - mv88e6390_serdes_irq_link_sgmii(chip, port->port, lane); + mv88e6390_serdes_irq_link_sgmii(chip, port, lane); } } + + return ret; +} + +static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) +{ + struct mv88e6xxx_port *port = dev_id; + struct mv88e6xxx_chip *chip = port->chip; + irqreturn_t ret = IRQ_NONE; + u8 lane; + + mv88e6xxx_reg_lock(chip); + lane = mv88e6xxx_serdes_get_lane(chip, port->port); + if (!lane) + goto out; + + ret = mv88e6xxx_serdes_irq_status(chip, port->port, lane); out: mv88e6xxx_reg_unlock(chip); diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index e2d38b5d4222..52f937347a36 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -92,6 +92,10 @@ int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, bool enable); int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, bool enable); +irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, + u8 lane); +irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, + u8 lane); int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int port, uint8_t *data); @@ -155,4 +159,13 @@ static inline int mv88e6xxx_serdes_irq_disable(struct mv88e6xxx_chip *chip, return chip->info->ops->serdes_irq_enable(chip, port, lane, false); } +static inline irqreturn_t +mv88e6xxx_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, u8 lane) +{ + if (!chip->info->ops->serdes_irq_status) + return IRQ_NONE; + + return chip->info->ops->serdes_irq_status(chip, port, lane); +} + #endif -- cgit v1.2.3 From 45de77ff8286156f78ac2beef03f6088bb3e451b Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Sat, 31 Aug 2019 16:18:36 -0400 Subject: net: dsa: mv88e6xxx: centralize SERDES IRQ handling The .serdes_irq_setup are all following the same steps: get the SERDES lane, get the IRQ mapping, request the IRQ, then enable it. So do the .serdes_irq_free implementations: get the SERDES lane, disable the IRQ, then free it. This patch removes these operations in favor of generic functions. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 96 ++++++++++++++++++------- drivers/net/dsa/mv88e6xxx/chip.h | 2 - drivers/net/dsa/mv88e6xxx/serdes.c | 142 ------------------------------------- drivers/net/dsa/mv88e6xxx/serdes.h | 4 -- 4 files changed, 69 insertions(+), 175 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/serdes.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index c2061e20bb32..30365a54c31b 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2054,6 +2054,71 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port) return 0; } +static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id) +{ + struct mv88e6xxx_port *mvp = dev_id; + struct mv88e6xxx_chip *chip = mvp->chip; + irqreturn_t ret = IRQ_NONE; + int port = mvp->port; + u8 lane; + + mv88e6xxx_reg_lock(chip); + lane = mv88e6xxx_serdes_get_lane(chip, port); + if (lane) + ret = mv88e6xxx_serdes_irq_status(chip, port, lane); + mv88e6xxx_reg_unlock(chip); + + return ret; +} + +static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port, + u8 lane) +{ + struct mv88e6xxx_port *dev_id = &chip->ports[port]; + unsigned int irq; + int err; + + /* Nothing to request if this SERDES port has no IRQ */ + irq = mv88e6xxx_serdes_irq_mapping(chip, port); + if (!irq) + return 0; + + /* Requesting the IRQ will trigger IRQ callbacks, so release the lock */ + mv88e6xxx_reg_unlock(chip); + err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn, + IRQF_ONESHOT, "mv88e6xxx-serdes", dev_id); + mv88e6xxx_reg_lock(chip); + if (err) + return err; + + dev_id->serdes_irq = irq; + + return mv88e6xxx_serdes_irq_enable(chip, port, lane); +} + +static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port, + u8 lane) +{ + struct mv88e6xxx_port *dev_id = &chip->ports[port]; + unsigned int irq = dev_id->serdes_irq; + int err; + + /* Nothing to free if no IRQ has been requested */ + if (!irq) + return 0; + + err = mv88e6xxx_serdes_irq_disable(chip, port, lane); + + /* Freeing the IRQ will trigger IRQ callbacks, so release the lock */ + mv88e6xxx_reg_unlock(chip); + free_irq(irq, dev_id); + mv88e6xxx_reg_lock(chip); + + dev_id->serdes_irq = 0; + + return err; +} + static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) { @@ -2069,12 +2134,11 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port, if (err) return err; - if (chip->info->ops->serdes_irq_setup) - err = chip->info->ops->serdes_irq_setup(chip, port); + err = mv88e6xxx_serdes_irq_request(chip, port, lane); } else { - if (chip->info->ops->serdes_irq_free && - chip->ports[port].serdes_irq) - chip->info->ops->serdes_irq_free(chip, port); + err = mv88e6xxx_serdes_irq_free(chip, port, lane); + if (err) + return err; err = mv88e6xxx_serdes_power_down(chip, port, lane); } @@ -2936,8 +3000,6 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, - .serdes_irq_setup = mv88e6390_serdes_irq_setup, - .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .phylink_validate = mv88e6341_phylink_validate, }; @@ -3188,8 +3250,6 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable, .serdes_irq_status = mv88e6352_serdes_irq_status, - .serdes_irq_setup = mv88e6352_serdes_irq_setup, - .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .phylink_validate = mv88e6352_phylink_validate, }; @@ -3274,8 +3334,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, - .serdes_irq_setup = mv88e6390_serdes_irq_setup, - .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .phylink_validate = mv88e6390_phylink_validate, }; @@ -3324,8 +3382,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, - .serdes_irq_setup = mv88e6390_serdes_irq_setup, - .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .phylink_validate = mv88e6390x_phylink_validate, }; @@ -3374,8 +3430,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, - .serdes_irq_setup = mv88e6390_serdes_irq_setup, - .serdes_irq_free = mv88e6390_serdes_irq_free, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, .phylink_validate = mv88e6390_phylink_validate, @@ -3426,8 +3480,6 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable, .serdes_irq_status = mv88e6352_serdes_irq_status, - .serdes_irq_setup = mv88e6352_serdes_irq_setup, - .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6352_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, @@ -3518,8 +3570,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, - .serdes_irq_setup = mv88e6390_serdes_irq_setup, - .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, @@ -3658,8 +3708,6 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, - .serdes_irq_setup = mv88e6390_serdes_irq_setup, - .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, @@ -3793,8 +3841,6 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable, .serdes_irq_status = mv88e6352_serdes_irq_status, - .serdes_irq_setup = mv88e6352_serdes_irq_setup, - .serdes_irq_free = mv88e6352_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6352_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, @@ -3850,8 +3896,6 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, - .serdes_irq_setup = mv88e6390_serdes_irq_setup, - .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, @@ -3904,8 +3948,6 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, - .serdes_irq_setup = mv88e6390_serdes_irq_setup, - .serdes_irq_free = mv88e6390_serdes_irq_free, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 9a73fd1d643b..6bc0a4e4fe7b 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -450,8 +450,6 @@ struct mv88e6xxx_ops { /* SERDES interrupt handling */ unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip, int port); - int (*serdes_irq_setup)(struct mv88e6xxx_chip *chip, int port); - void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port); int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane, bool enable); irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port, diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index d37419ba26ab..902feb398746 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -221,19 +221,6 @@ irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, return ret; } -static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id) -{ - struct mv88e6xxx_port *port = dev_id; - struct mv88e6xxx_chip *chip = port->chip; - irqreturn_t ret = IRQ_NONE; - - mv88e6xxx_reg_lock(chip); - ret = mv88e6xxx_serdes_irq_status(chip, port->port, 0); - mv88e6xxx_reg_unlock(chip); - - return ret; -} - int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, bool enable) { @@ -250,61 +237,6 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ); } -int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) -{ - unsigned int irq; - u8 lane; - int err; - - lane = mv88e6xxx_serdes_get_lane(chip, port); - if (!lane) - return 0; - - irq = mv88e6xxx_serdes_irq_mapping(chip, port); - if (!irq) - return 0; - - chip->ports[port].serdes_irq = irq; - - /* Requesting the IRQ will trigger irq callbacks. So we cannot - * hold the reg_lock. - */ - mv88e6xxx_reg_unlock(chip); - err = request_threaded_irq(chip->ports[port].serdes_irq, NULL, - mv88e6352_serdes_thread_fn, - IRQF_ONESHOT, "mv88e6xxx-serdes", - &chip->ports[port]); - mv88e6xxx_reg_lock(chip); - - if (err) { - dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n", - err); - return err; - } - - return mv88e6xxx_serdes_irq_enable(chip, port, lane); -} - -void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) -{ - u8 lane; - - lane = mv88e6xxx_serdes_get_lane(chip, port); - if (!lane) - return; - - mv88e6xxx_serdes_irq_disable(chip, port, lane); - - /* Freeing the IRQ will trigger irq callbacks. So we cannot - * hold the reg_lock. - */ - mv88e6xxx_reg_unlock(chip); - free_irq(chip->ports[port].serdes_irq, &chip->ports[port]); - mv88e6xxx_reg_lock(chip); - - chip->ports[port].serdes_irq = 0; -} - u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) { u8 cmode = chip->ports[port].cmode; @@ -622,81 +554,7 @@ irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, return ret; } -static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id) -{ - struct mv88e6xxx_port *port = dev_id; - struct mv88e6xxx_chip *chip = port->chip; - irqreturn_t ret = IRQ_NONE; - u8 lane; - - mv88e6xxx_reg_lock(chip); - lane = mv88e6xxx_serdes_get_lane(chip, port->port); - if (!lane) - goto out; - - ret = mv88e6xxx_serdes_irq_status(chip, port->port, lane); -out: - mv88e6xxx_reg_unlock(chip); - - return ret; -} - unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) { return irq_find_mapping(chip->g2_irq.domain, port); } - -int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port) -{ - unsigned int irq; - int err; - u8 lane; - - lane = mv88e6xxx_serdes_get_lane(chip, port); - if (!lane) - return 0; - - irq = mv88e6xxx_serdes_irq_mapping(chip, port); - if (!irq) - return 0; - - chip->ports[port].serdes_irq = irq; - - /* Requesting the IRQ will trigger irq callbacks. So we cannot - * hold the reg_lock. - */ - mv88e6xxx_reg_unlock(chip); - err = request_threaded_irq(chip->ports[port].serdes_irq, NULL, - mv88e6390_serdes_thread_fn, - IRQF_ONESHOT, "mv88e6xxx-serdes", - &chip->ports[port]); - mv88e6xxx_reg_lock(chip); - - if (err) { - dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n", - err); - return err; - } - - return mv88e6xxx_serdes_irq_enable(chip, port, lane); -} - -void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port) -{ - u8 lane; - - lane = mv88e6xxx_serdes_get_lane(chip, port); - if (!lane) - return; - - mv88e6xxx_serdes_irq_disable(chip, port, lane); - - /* Freeing the IRQ will trigger irq callbacks. So we cannot - * hold the reg_lock. - */ - mv88e6xxx_reg_unlock(chip); - free_irq(chip->ports[port].serdes_irq, &chip->ports[port]); - mv88e6xxx_reg_lock(chip); - - chip->ports[port].serdes_irq = 0; -} diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h index 52f937347a36..bd8df36ab537 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.h +++ b/drivers/net/dsa/mv88e6xxx/serdes.h @@ -86,8 +86,6 @@ int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, bool on); int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, bool on); -int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); -void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, bool enable); int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, @@ -101,8 +99,6 @@ int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int port, uint8_t *data); int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, uint64_t *data); -int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); -void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); /* Return the (first) SERDES lane address a port is using, 0 otherwise. */ static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, -- cgit v1.2.3