@@ -31,6 +31,47 @@ static int lan88xx_write_page(struct phy_device *phydev, int page)
31
31
return __phy_write (phydev , LAN88XX_EXT_PAGE_ACCESS , page );
32
32
}
33
33
34
+ static int lan88xx_phy_config_intr (struct phy_device * phydev )
35
+ {
36
+ int rc ;
37
+
38
+ if (phydev -> interrupts == PHY_INTERRUPT_ENABLED ) {
39
+ /* unmask all source and clear them before enable */
40
+ rc = phy_write (phydev , LAN88XX_INT_MASK , 0x7FFF );
41
+ rc = phy_read (phydev , LAN88XX_INT_STS );
42
+ rc = phy_write (phydev , LAN88XX_INT_MASK ,
43
+ LAN88XX_INT_MASK_MDINTPIN_EN_ |
44
+ LAN88XX_INT_MASK_LINK_CHANGE_ );
45
+ } else {
46
+ rc = phy_write (phydev , LAN88XX_INT_MASK , 0 );
47
+ if (rc )
48
+ return rc ;
49
+
50
+ /* Ack interrupts after they have been disabled */
51
+ rc = phy_read (phydev , LAN88XX_INT_STS );
52
+ }
53
+
54
+ return rc < 0 ? rc : 0 ;
55
+ }
56
+
57
+ static irqreturn_t lan88xx_handle_interrupt (struct phy_device * phydev )
58
+ {
59
+ int irq_status ;
60
+
61
+ irq_status = phy_read (phydev , LAN88XX_INT_STS );
62
+ if (irq_status < 0 ) {
63
+ phy_error (phydev );
64
+ return IRQ_NONE ;
65
+ }
66
+
67
+ if (!(irq_status & LAN88XX_INT_STS_LINK_CHANGE_ ))
68
+ return IRQ_NONE ;
69
+
70
+ phy_trigger_machine (phydev );
71
+
72
+ return IRQ_HANDLED ;
73
+ }
74
+
34
75
static int lan88xx_suspend (struct phy_device * phydev )
35
76
{
36
77
struct lan88xx_priv * priv = phydev -> priv ;
@@ -347,9 +388,8 @@ static struct phy_driver microchip_phy_driver[] = {
347
388
.config_aneg = lan88xx_config_aneg ,
348
389
.link_change_notify = lan88xx_link_change_notify ,
349
390
350
- /* Interrupt handling is broken, do not define related
351
- * functions to force polling.
352
- */
391
+ .config_intr = lan88xx_phy_config_intr ,
392
+ .handle_interrupt = lan88xx_handle_interrupt ,
353
393
354
394
.suspend = lan88xx_suspend ,
355
395
.resume = genphy_resume ,
0 commit comments