summaryrefslogtreecommitdiff
path: root/drivers/net/phy/dp83822.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/dp83822.c')
-rw-r--r--drivers/net/phy/dp83822.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
index c162c9551bd1..bb512ac3f533 100644
--- a/drivers/net/phy/dp83822.c
+++ b/drivers/net/phy/dp83822.c
@@ -303,6 +303,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 |
@@ -576,6 +611,7 @@ static int dp83822_resume(struct phy_device *phydev)
.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, \
}
@@ -591,6 +627,7 @@ static int dp83822_resume(struct phy_device *phydev)
.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, \
}