diff options
Diffstat (limited to 'drivers/net/phy/dp83822.c')
-rw-r--r-- | drivers/net/phy/dp83822.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index c162c9551bd1..fff371ca1086 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -119,21 +119,6 @@ struct dp83822_private { u16 fx_sd_enable; }; -static int dp83822_ack_interrupt(struct phy_device *phydev) -{ - int err; - - err = phy_read(phydev, MII_DP83822_MISR1); - if (err < 0) - return err; - - err = phy_read(phydev, MII_DP83822_MISR2); - if (err < 0) - return err; - - return 0; -} - static int dp83822_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) { @@ -303,6 +288,41 @@ static int dp83822_config_intr(struct phy_device *phydev) return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status); } +static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev) +{ + int irq_status; + + /* The MISR1 and MISR2 registers are holding the interrupt status in + * the upper half (15:8), while the lower half (7:0) is used for + * controlling the interrupt enable state of those individual interrupt + * sources. To determine the possible interrupt sources, just read the + * MISR* register and use it directly to know which interrupts have + * been enabled previously or not. + */ + irq_status = phy_read(phydev, MII_DP83822_MISR1); + if (irq_status < 0) { + phy_error(phydev); + return IRQ_NONE; + } + if (irq_status & ((irq_status & GENMASK(7, 0)) << 8)) + goto trigger_machine; + + irq_status = phy_read(phydev, MII_DP83822_MISR2); + if (irq_status < 0) { + phy_error(phydev); + return IRQ_NONE; + } + if (irq_status & ((irq_status & GENMASK(7, 0)) << 8)) + goto trigger_machine; + + return IRQ_NONE; + +trigger_machine: + phy_trigger_machine(phydev); + + return IRQ_HANDLED; +} + static int dp8382x_disable_wol(struct phy_device *phydev) { int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN | @@ -574,8 +594,8 @@ static int dp83822_resume(struct phy_device *phydev) .read_status = dp83822_read_status, \ .get_wol = dp83822_get_wol, \ .set_wol = dp83822_set_wol, \ - .ack_interrupt = dp83822_ack_interrupt, \ .config_intr = dp83822_config_intr, \ + .handle_interrupt = dp83822_handle_interrupt, \ .suspend = dp83822_suspend, \ .resume = dp83822_resume, \ } @@ -589,8 +609,8 @@ static int dp83822_resume(struct phy_device *phydev) .config_init = dp8382x_config_init, \ .get_wol = dp83822_get_wol, \ .set_wol = dp83822_set_wol, \ - .ack_interrupt = dp83822_ack_interrupt, \ .config_intr = dp83822_config_intr, \ + .handle_interrupt = dp83822_handle_interrupt, \ .suspend = dp83822_suspend, \ .resume = dp83822_resume, \ } |