net: mvpp2: restructure "link status" interrupt handling
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>
This commit is contained in:
parent
b599a5b9e1
commit
36cfd3a6e5
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user