summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@gmail.com>2019-08-31 16:18:36 -0400
committerDavid S. Miller <davem@davemloft.net>2019-09-01 15:16:38 -0400
commit45de77ff8286156f78ac2beef03f6088bb3e451b (patch)
tree4ed06a60199887ca6303fe3acd5d0fcf76af5bde
parent907b9b9fcaef7fb193105d9d61cd795b38ee2530 (diff)
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 <vivien.didelot@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c96
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.h2
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.c142
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.h4
4 files changed, 69 insertions, 175 deletions
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)
2054 return 0; 2054 return 0;
2055} 2055}
2056 2056
2057static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
2058{
2059 struct mv88e6xxx_port *mvp = dev_id;
2060 struct mv88e6xxx_chip *chip = mvp->chip;
2061 irqreturn_t ret = IRQ_NONE;
2062 int port = mvp->port;
2063 u8 lane;
2064
2065 mv88e6xxx_reg_lock(chip);
2066 lane = mv88e6xxx_serdes_get_lane(chip, port);
2067 if (lane)
2068 ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
2069 mv88e6xxx_reg_unlock(chip);
2070
2071 return ret;
2072}
2073
2074static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port,
2075 u8 lane)
2076{
2077 struct mv88e6xxx_port *dev_id = &chip->ports[port];
2078 unsigned int irq;
2079 int err;
2080
2081 /* Nothing to request if this SERDES port has no IRQ */
2082 irq = mv88e6xxx_serdes_irq_mapping(chip, port);
2083 if (!irq)
2084 return 0;
2085
2086 /* Requesting the IRQ will trigger IRQ callbacks, so release the lock */
2087 mv88e6xxx_reg_unlock(chip);
2088 err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn,
2089 IRQF_ONESHOT, "mv88e6xxx-serdes", dev_id);
2090 mv88e6xxx_reg_lock(chip);
2091 if (err)
2092 return err;
2093
2094 dev_id->serdes_irq = irq;
2095
2096 return mv88e6xxx_serdes_irq_enable(chip, port, lane);
2097}
2098
2099static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port,
2100 u8 lane)
2101{
2102 struct mv88e6xxx_port *dev_id = &chip->ports[port];
2103 unsigned int irq = dev_id->serdes_irq;
2104 int err;
2105
2106 /* Nothing to free if no IRQ has been requested */
2107 if (!irq)
2108 return 0;
2109
2110 err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
2111
2112 /* Freeing the IRQ will trigger IRQ callbacks, so release the lock */
2113 mv88e6xxx_reg_unlock(chip);
2114 free_irq(irq, dev_id);
2115 mv88e6xxx_reg_lock(chip);
2116
2117 dev_id->serdes_irq = 0;
2118
2119 return err;
2120}
2121
2057static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port, 2122static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
2058 bool on) 2123 bool on)
2059{ 2124{
@@ -2069,12 +2134,11 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
2069 if (err) 2134 if (err)
2070 return err; 2135 return err;
2071 2136
2072 if (chip->info->ops->serdes_irq_setup) 2137 err = mv88e6xxx_serdes_irq_request(chip, port, lane);
2073 err = chip->info->ops->serdes_irq_setup(chip, port);
2074 } else { 2138 } else {
2075 if (chip->info->ops->serdes_irq_free && 2139 err = mv88e6xxx_serdes_irq_free(chip, port, lane);
2076 chip->ports[port].serdes_irq) 2140 if (err)
2077 chip->info->ops->serdes_irq_free(chip, port); 2141 return err;
2078 2142
2079 err = mv88e6xxx_serdes_power_down(chip, port, lane); 2143 err = mv88e6xxx_serdes_power_down(chip, port, lane);
2080 } 2144 }
@@ -2936,8 +3000,6 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
2936 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 3000 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
2937 .serdes_irq_enable = mv88e6390_serdes_irq_enable, 3001 .serdes_irq_enable = mv88e6390_serdes_irq_enable,
2938 .serdes_irq_status = mv88e6390_serdes_irq_status, 3002 .serdes_irq_status = mv88e6390_serdes_irq_status,
2939 .serdes_irq_setup = mv88e6390_serdes_irq_setup,
2940 .serdes_irq_free = mv88e6390_serdes_irq_free,
2941 .gpio_ops = &mv88e6352_gpio_ops, 3003 .gpio_ops = &mv88e6352_gpio_ops,
2942 .phylink_validate = mv88e6341_phylink_validate, 3004 .phylink_validate = mv88e6341_phylink_validate,
2943}; 3005};
@@ -3188,8 +3250,6 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
3188 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, 3250 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
3189 .serdes_irq_enable = mv88e6352_serdes_irq_enable, 3251 .serdes_irq_enable = mv88e6352_serdes_irq_enable,
3190 .serdes_irq_status = mv88e6352_serdes_irq_status, 3252 .serdes_irq_status = mv88e6352_serdes_irq_status,
3191 .serdes_irq_setup = mv88e6352_serdes_irq_setup,
3192 .serdes_irq_free = mv88e6352_serdes_irq_free,
3193 .gpio_ops = &mv88e6352_gpio_ops, 3253 .gpio_ops = &mv88e6352_gpio_ops,
3194 .phylink_validate = mv88e6352_phylink_validate, 3254 .phylink_validate = mv88e6352_phylink_validate,
3195}; 3255};
@@ -3274,8 +3334,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
3274 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 3334 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3275 .serdes_irq_enable = mv88e6390_serdes_irq_enable, 3335 .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3276 .serdes_irq_status = mv88e6390_serdes_irq_status, 3336 .serdes_irq_status = mv88e6390_serdes_irq_status,
3277 .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3278 .serdes_irq_free = mv88e6390_serdes_irq_free,
3279 .gpio_ops = &mv88e6352_gpio_ops, 3337 .gpio_ops = &mv88e6352_gpio_ops,
3280 .phylink_validate = mv88e6390_phylink_validate, 3338 .phylink_validate = mv88e6390_phylink_validate,
3281}; 3339};
@@ -3324,8 +3382,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
3324 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 3382 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3325 .serdes_irq_enable = mv88e6390_serdes_irq_enable, 3383 .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3326 .serdes_irq_status = mv88e6390_serdes_irq_status, 3384 .serdes_irq_status = mv88e6390_serdes_irq_status,
3327 .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3328 .serdes_irq_free = mv88e6390_serdes_irq_free,
3329 .gpio_ops = &mv88e6352_gpio_ops, 3385 .gpio_ops = &mv88e6352_gpio_ops,
3330 .phylink_validate = mv88e6390x_phylink_validate, 3386 .phylink_validate = mv88e6390x_phylink_validate,
3331}; 3387};
@@ -3374,8 +3430,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
3374 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 3430 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3375 .serdes_irq_enable = mv88e6390_serdes_irq_enable, 3431 .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3376 .serdes_irq_status = mv88e6390_serdes_irq_status, 3432 .serdes_irq_status = mv88e6390_serdes_irq_status,
3377 .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3378 .serdes_irq_free = mv88e6390_serdes_irq_free,
3379 .avb_ops = &mv88e6390_avb_ops, 3433 .avb_ops = &mv88e6390_avb_ops,
3380 .ptp_ops = &mv88e6352_ptp_ops, 3434 .ptp_ops = &mv88e6352_ptp_ops,
3381 .phylink_validate = mv88e6390_phylink_validate, 3435 .phylink_validate = mv88e6390_phylink_validate,
@@ -3426,8 +3480,6 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
3426 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, 3480 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
3427 .serdes_irq_enable = mv88e6352_serdes_irq_enable, 3481 .serdes_irq_enable = mv88e6352_serdes_irq_enable,
3428 .serdes_irq_status = mv88e6352_serdes_irq_status, 3482 .serdes_irq_status = mv88e6352_serdes_irq_status,
3429 .serdes_irq_setup = mv88e6352_serdes_irq_setup,
3430 .serdes_irq_free = mv88e6352_serdes_irq_free,
3431 .gpio_ops = &mv88e6352_gpio_ops, 3483 .gpio_ops = &mv88e6352_gpio_ops,
3432 .avb_ops = &mv88e6352_avb_ops, 3484 .avb_ops = &mv88e6352_avb_ops,
3433 .ptp_ops = &mv88e6352_ptp_ops, 3485 .ptp_ops = &mv88e6352_ptp_ops,
@@ -3518,8 +3570,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
3518 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 3570 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3519 .serdes_irq_enable = mv88e6390_serdes_irq_enable, 3571 .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3520 .serdes_irq_status = mv88e6390_serdes_irq_status, 3572 .serdes_irq_status = mv88e6390_serdes_irq_status,
3521 .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3522 .serdes_irq_free = mv88e6390_serdes_irq_free,
3523 .gpio_ops = &mv88e6352_gpio_ops, 3573 .gpio_ops = &mv88e6352_gpio_ops,
3524 .avb_ops = &mv88e6390_avb_ops, 3574 .avb_ops = &mv88e6390_avb_ops,
3525 .ptp_ops = &mv88e6352_ptp_ops, 3575 .ptp_ops = &mv88e6352_ptp_ops,
@@ -3658,8 +3708,6 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
3658 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 3708 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3659 .serdes_irq_enable = mv88e6390_serdes_irq_enable, 3709 .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3660 .serdes_irq_status = mv88e6390_serdes_irq_status, 3710 .serdes_irq_status = mv88e6390_serdes_irq_status,
3661 .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3662 .serdes_irq_free = mv88e6390_serdes_irq_free,
3663 .gpio_ops = &mv88e6352_gpio_ops, 3711 .gpio_ops = &mv88e6352_gpio_ops,
3664 .avb_ops = &mv88e6390_avb_ops, 3712 .avb_ops = &mv88e6390_avb_ops,
3665 .ptp_ops = &mv88e6352_ptp_ops, 3713 .ptp_ops = &mv88e6352_ptp_ops,
@@ -3793,8 +3841,6 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
3793 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, 3841 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
3794 .serdes_irq_enable = mv88e6352_serdes_irq_enable, 3842 .serdes_irq_enable = mv88e6352_serdes_irq_enable,
3795 .serdes_irq_status = mv88e6352_serdes_irq_status, 3843 .serdes_irq_status = mv88e6352_serdes_irq_status,
3796 .serdes_irq_setup = mv88e6352_serdes_irq_setup,
3797 .serdes_irq_free = mv88e6352_serdes_irq_free,
3798 .gpio_ops = &mv88e6352_gpio_ops, 3844 .gpio_ops = &mv88e6352_gpio_ops,
3799 .avb_ops = &mv88e6352_avb_ops, 3845 .avb_ops = &mv88e6352_avb_ops,
3800 .ptp_ops = &mv88e6352_ptp_ops, 3846 .ptp_ops = &mv88e6352_ptp_ops,
@@ -3850,8 +3896,6 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
3850 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 3896 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3851 .serdes_irq_enable = mv88e6390_serdes_irq_enable, 3897 .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3852 .serdes_irq_status = mv88e6390_serdes_irq_status, 3898 .serdes_irq_status = mv88e6390_serdes_irq_status,
3853 .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3854 .serdes_irq_free = mv88e6390_serdes_irq_free,
3855 .gpio_ops = &mv88e6352_gpio_ops, 3899 .gpio_ops = &mv88e6352_gpio_ops,
3856 .avb_ops = &mv88e6390_avb_ops, 3900 .avb_ops = &mv88e6390_avb_ops,
3857 .ptp_ops = &mv88e6352_ptp_ops, 3901 .ptp_ops = &mv88e6352_ptp_ops,
@@ -3904,8 +3948,6 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
3904 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, 3948 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
3905 .serdes_irq_enable = mv88e6390_serdes_irq_enable, 3949 .serdes_irq_enable = mv88e6390_serdes_irq_enable,
3906 .serdes_irq_status = mv88e6390_serdes_irq_status, 3950 .serdes_irq_status = mv88e6390_serdes_irq_status,
3907 .serdes_irq_setup = mv88e6390_serdes_irq_setup,
3908 .serdes_irq_free = mv88e6390_serdes_irq_free,
3909 .gpio_ops = &mv88e6352_gpio_ops, 3951 .gpio_ops = &mv88e6352_gpio_ops,
3910 .avb_ops = &mv88e6390_avb_ops, 3952 .avb_ops = &mv88e6390_avb_ops,
3911 .ptp_ops = &mv88e6352_ptp_ops, 3953 .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 {
450 /* SERDES interrupt handling */ 450 /* SERDES interrupt handling */
451 unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip, 451 unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,
452 int port); 452 int port);
453 int (*serdes_irq_setup)(struct mv88e6xxx_chip *chip, int port);
454 void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port);
455 int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane, 453 int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane,
456 bool enable); 454 bool enable);
457 irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port, 455 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,
221 return ret; 221 return ret;
222} 222}
223 223
224static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id)
225{
226 struct mv88e6xxx_port *port = dev_id;
227 struct mv88e6xxx_chip *chip = port->chip;
228 irqreturn_t ret = IRQ_NONE;
229
230 mv88e6xxx_reg_lock(chip);
231 ret = mv88e6xxx_serdes_irq_status(chip, port->port, 0);
232 mv88e6xxx_reg_unlock(chip);
233
234 return ret;
235}
236
237int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, 224int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
238 bool enable) 225 bool enable)
239{ 226{
@@ -250,61 +237,6 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
250 return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ); 237 return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
251} 238}
252 239
253int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
254{
255 unsigned int irq;
256 u8 lane;
257 int err;
258
259 lane = mv88e6xxx_serdes_get_lane(chip, port);
260 if (!lane)
261 return 0;
262
263 irq = mv88e6xxx_serdes_irq_mapping(chip, port);
264 if (!irq)
265 return 0;
266
267 chip->ports[port].serdes_irq = irq;
268
269 /* Requesting the IRQ will trigger irq callbacks. So we cannot
270 * hold the reg_lock.
271 */
272 mv88e6xxx_reg_unlock(chip);
273 err = request_threaded_irq(chip->ports[port].serdes_irq, NULL,
274 mv88e6352_serdes_thread_fn,
275 IRQF_ONESHOT, "mv88e6xxx-serdes",
276 &chip->ports[port]);
277 mv88e6xxx_reg_lock(chip);
278
279 if (err) {
280 dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n",
281 err);
282 return err;
283 }
284
285 return mv88e6xxx_serdes_irq_enable(chip, port, lane);
286}
287
288void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
289{
290 u8 lane;
291
292 lane = mv88e6xxx_serdes_get_lane(chip, port);
293 if (!lane)
294 return;
295
296 mv88e6xxx_serdes_irq_disable(chip, port, lane);
297
298 /* Freeing the IRQ will trigger irq callbacks. So we cannot
299 * hold the reg_lock.
300 */
301 mv88e6xxx_reg_unlock(chip);
302 free_irq(chip->ports[port].serdes_irq, &chip->ports[port]);
303 mv88e6xxx_reg_lock(chip);
304
305 chip->ports[port].serdes_irq = 0;
306}
307
308u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) 240u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
309{ 241{
310 u8 cmode = chip->ports[port].cmode; 242 u8 cmode = chip->ports[port].cmode;
@@ -622,81 +554,7 @@ irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
622 return ret; 554 return ret;
623} 555}
624 556
625static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)
626{
627 struct mv88e6xxx_port *port = dev_id;
628 struct mv88e6xxx_chip *chip = port->chip;
629 irqreturn_t ret = IRQ_NONE;
630 u8 lane;
631
632 mv88e6xxx_reg_lock(chip);
633 lane = mv88e6xxx_serdes_get_lane(chip, port->port);
634 if (!lane)
635 goto out;
636
637 ret = mv88e6xxx_serdes_irq_status(chip, port->port, lane);
638out:
639 mv88e6xxx_reg_unlock(chip);
640
641 return ret;
642}
643
644unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 557unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
645{ 558{
646 return irq_find_mapping(chip->g2_irq.domain, port); 559 return irq_find_mapping(chip->g2_irq.domain, port);
647} 560}
648
649int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
650{
651 unsigned int irq;
652 int err;
653 u8 lane;
654
655 lane = mv88e6xxx_serdes_get_lane(chip, port);
656 if (!lane)
657 return 0;
658
659 irq = mv88e6xxx_serdes_irq_mapping(chip, port);
660 if (!irq)
661 return 0;
662
663 chip->ports[port].serdes_irq = irq;
664
665 /* Requesting the IRQ will trigger irq callbacks. So we cannot
666 * hold the reg_lock.
667 */
668 mv88e6xxx_reg_unlock(chip);
669 err = request_threaded_irq(chip->ports[port].serdes_irq, NULL,
670 mv88e6390_serdes_thread_fn,
671 IRQF_ONESHOT, "mv88e6xxx-serdes",
672 &chip->ports[port]);
673 mv88e6xxx_reg_lock(chip);
674
675 if (err) {
676 dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n",
677 err);
678 return err;
679 }
680
681 return mv88e6xxx_serdes_irq_enable(chip, port, lane);
682}
683
684void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
685{
686 u8 lane;
687
688 lane = mv88e6xxx_serdes_get_lane(chip, port);
689 if (!lane)
690 return;
691
692 mv88e6xxx_serdes_irq_disable(chip, port, lane);
693
694 /* Freeing the IRQ will trigger irq callbacks. So we cannot
695 * hold the reg_lock.
696 */
697 mv88e6xxx_reg_unlock(chip);
698 free_irq(chip->ports[port].serdes_irq, &chip->ports[port]);
699 mv88e6xxx_reg_lock(chip);
700
701 chip->ports[port].serdes_irq = 0;
702}
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,
86 bool on); 86 bool on);
87int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane, 87int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
88 bool on); 88 bool on);
89int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
90void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
91int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, 89int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
92 bool enable); 90 bool enable);
93int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane, 91int 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,
101 int port, uint8_t *data); 99 int port, uint8_t *data);
102int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 100int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
103 uint64_t *data); 101 uint64_t *data);
104int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
105void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
106 102
107/* Return the (first) SERDES lane address a port is using, 0 otherwise. */ 103/* Return the (first) SERDES lane address a port is using, 0 otherwise. */
108static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, 104static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,