709-v5.3-net-phylink-support-for-link-gpio-interrupt.patch 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. From cba0aba37d2228556e0d1f776d403435868cdbfa Mon Sep 17 00:00:00 2001
  2. From: Russell King <[email protected]>
  3. Date: Tue, 28 May 2019 10:57:23 +0100
  4. Subject: [PATCH 607/660] net: phylink: support for link gpio interrupt
  5. Add support for using GPIO interrupts with a fixed-link GPIO rather than
  6. polling the GPIO every second and invoking the phylink resolution. This
  7. avoids unnecessary calls to mac_config().
  8. Reviewed-by: Florian Fainelli <[email protected]>
  9. Signed-off-by: Russell King <[email protected]>
  10. Signed-off-by: David S. Miller <[email protected]>
  11. Signed-off-by: Russell King <[email protected]>
  12. ---
  13. drivers/net/phy/phylink.c | 36 ++++++++++++++++++++++++++++++++----
  14. 1 file changed, 32 insertions(+), 4 deletions(-)
  15. --- a/drivers/net/phy/phylink.c
  16. +++ b/drivers/net/phy/phylink.c
  17. @@ -59,6 +59,7 @@ struct phylink {
  18. phy_interface_t cur_interface;
  19. struct gpio_desc *link_gpio;
  20. + unsigned int link_irq;
  21. struct timer_list link_poll;
  22. void (*get_fixed_state)(struct net_device *dev,
  23. struct phylink_link_state *s);
  24. @@ -645,7 +646,7 @@ void phylink_destroy(struct phylink *pl)
  25. {
  26. if (pl->sfp_bus)
  27. sfp_unregister_upstream(pl->sfp_bus);
  28. - if (!IS_ERR_OR_NULL(pl->link_gpio))
  29. + if (pl->link_gpio)
  30. gpiod_put(pl->link_gpio);
  31. cancel_work_sync(&pl->resolve);
  32. @@ -912,6 +913,15 @@ void phylink_mac_change(struct phylink *
  33. }
  34. EXPORT_SYMBOL_GPL(phylink_mac_change);
  35. +static irqreturn_t phylink_link_handler(int irq, void *data)
  36. +{
  37. + struct phylink *pl = data;
  38. +
  39. + phylink_run_resolve(pl);
  40. +
  41. + return IRQ_HANDLED;
  42. +}
  43. +
  44. /**
  45. * phylink_start() - start a phylink instance
  46. * @pl: a pointer to a &struct phylink returned from phylink_create()
  47. @@ -947,7 +957,22 @@ void phylink_start(struct phylink *pl)
  48. clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
  49. phylink_run_resolve(pl);
  50. - if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio))
  51. + if (pl->link_an_mode == MLO_AN_FIXED && pl->link_gpio) {
  52. + int irq = gpiod_to_irq(pl->link_gpio);
  53. +
  54. + if (irq > 0) {
  55. + if (!request_irq(irq, phylink_link_handler,
  56. + IRQF_TRIGGER_RISING |
  57. + IRQF_TRIGGER_FALLING,
  58. + "netdev link", pl))
  59. + pl->link_irq = irq;
  60. + else
  61. + irq = 0;
  62. + }
  63. + if (irq <= 0)
  64. + mod_timer(&pl->link_poll, jiffies + HZ);
  65. + }
  66. + if (pl->link_an_mode == MLO_AN_FIXED && pl->get_fixed_state)
  67. mod_timer(&pl->link_poll, jiffies + HZ);
  68. if (pl->sfp_bus)
  69. sfp_upstream_start(pl->sfp_bus);
  70. @@ -973,8 +998,11 @@ void phylink_stop(struct phylink *pl)
  71. phy_stop(pl->phydev);
  72. if (pl->sfp_bus)
  73. sfp_upstream_stop(pl->sfp_bus);
  74. - if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio))
  75. - del_timer_sync(&pl->link_poll);
  76. + del_timer_sync(&pl->link_poll);
  77. + if (pl->link_irq) {
  78. + free_irq(pl->link_irq, pl);
  79. + pl->link_irq = 0;
  80. + }
  81. phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
  82. }