OSDN Git Service

net: mvpp2: restructure "link status" interrupt handling
authorRussell King <rmk+kernel@armlinux.org.uk>
Wed, 9 Sep 2020 16:25:35 +0000 (17:25 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 9 Sep 2020 21:22:41 +0000 (14:22 -0700)
The "link status" interrupt is used for more than just link status.
Restructure mvpp2_link_status_isr() so we can add additional handling.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c

index ee8b6a9..bb72843 100644 (file)
@@ -2974,44 +2974,17 @@ static irqreturn_t mvpp2_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-/* Per-port interrupt for link status changes */
-static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
+static void mvpp2_isr_handle_link(struct mvpp2_port *port, bool link)
 {
-       struct mvpp2_port *port = (struct mvpp2_port *)dev_id;
        struct net_device *dev = port->dev;
-       bool event = false, link = false;
-       u32 val;
-
-       mvpp22_gop_mask_irq(port);
-
-       if (mvpp2_port_supports_xlg(port) &&
-           mvpp2_is_xlg(port->phy_interface)) {
-               val = readl(port->base + MVPP22_XLG_INT_STAT);
-               if (val & MVPP22_XLG_INT_STAT_LINK) {
-                       event = true;
-                       val = readl(port->base + MVPP22_XLG_STATUS);
-                       if (val & MVPP22_XLG_STATUS_LINK_UP)
-                               link = true;
-               }
-       } else if (phy_interface_mode_is_rgmii(port->phy_interface) ||
-                  phy_interface_mode_is_8023z(port->phy_interface) ||
-                  port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
-               val = readl(port->base + MVPP22_GMAC_INT_STAT);
-               if (val & MVPP22_GMAC_INT_STAT_LINK) {
-                       event = true;
-                       val = readl(port->base + MVPP2_GMAC_STATUS0);
-                       if (val & MVPP2_GMAC_STATUS0_LINK_UP)
-                               link = true;
-               }
-       }
 
        if (port->phylink) {
                phylink_mac_change(port->phylink, link);
-               goto handled;
+               return;
        }
 
-       if (!netif_running(dev) || !event)
-               goto handled;
+       if (!netif_running(dev))
+               return;
 
        if (link) {
                mvpp2_interrupts_enable(port);
@@ -3028,8 +3001,54 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
 
                mvpp2_interrupts_disable(port);
        }
+}
+
+static void mvpp2_isr_handle_xlg(struct mvpp2_port *port)
+{
+       bool link;
+       u32 val;
+
+       val = readl(port->base + MVPP22_XLG_INT_STAT);
+       if (val & MVPP22_XLG_INT_STAT_LINK) {
+               val = readl(port->base + MVPP22_XLG_STATUS);
+               if (val & MVPP22_XLG_STATUS_LINK_UP)
+                       link = true;
+               mvpp2_isr_handle_link(port, link);
+       }
+}
+
+static void mvpp2_isr_handle_gmac_internal(struct mvpp2_port *port)
+{
+       bool link;
+       u32 val;
+
+       if (phy_interface_mode_is_rgmii(port->phy_interface) ||
+           phy_interface_mode_is_8023z(port->phy_interface) ||
+           port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+               val = readl(port->base + MVPP22_GMAC_INT_STAT);
+               if (val & MVPP22_GMAC_INT_STAT_LINK) {
+                       val = readl(port->base + MVPP2_GMAC_STATUS0);
+                       if (val & MVPP2_GMAC_STATUS0_LINK_UP)
+                               link = true;
+                       mvpp2_isr_handle_link(port, link);
+               }
+       }
+}
+
+/* Per-port interrupt for link status changes */
+static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
+{
+       struct mvpp2_port *port = (struct mvpp2_port *)dev_id;
+
+       mvpp22_gop_mask_irq(port);
+
+       if (mvpp2_port_supports_xlg(port) &&
+           mvpp2_is_xlg(port->phy_interface)) {
+               mvpp2_isr_handle_xlg(port);
+       } else {
+               mvpp2_isr_handle_gmac_internal(port);
+       }
 
-handled:
        mvpp22_gop_unmask_irq(port);
        return IRQ_HANDLED;
 }