Merge tag 'locking-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / net / phy / aquantia_main.c
index 41e7c14..968dd43 100644 (file)
@@ -52,6 +52,7 @@
 #define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT  BIT(1)
 
 #define MDIO_AN_TX_VEND_INT_STATUS2            0xcc01
+#define MDIO_AN_TX_VEND_INT_STATUS2_MASK       BIT(0)
 
 #define MDIO_AN_TX_VEND_INT_MASK2              0xd401
 #define MDIO_AN_TX_VEND_INT_MASK2_LINK         BIT(0)
@@ -246,6 +247,13 @@ static int aqr_config_intr(struct phy_device *phydev)
        bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
        int err;
 
+       if (en) {
+               /* Clear any pending interrupts before enabling them */
+               err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
+               if (err < 0)
+                       return err;
+       }
+
        err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,
                            en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);
        if (err < 0)
@@ -256,18 +264,39 @@ static int aqr_config_intr(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       return phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,
-                            en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
-                            VEND1_GLOBAL_INT_VEND_MASK_AN : 0);
+       err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,
+                           en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
+                           VEND1_GLOBAL_INT_VEND_MASK_AN : 0);
+       if (err < 0)
+               return err;
+
+       if (!en) {
+               /* Clear any pending interrupts after we have disabled them */
+               err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
 }
 
-static int aqr_ack_interrupt(struct phy_device *phydev)
+static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)
 {
-       int reg;
+       int irq_status;
+
+       irq_status = phy_read_mmd(phydev, MDIO_MMD_AN,
+                                 MDIO_AN_TX_VEND_INT_STATUS2);
+       if (irq_status < 0) {
+               phy_error(phydev);
+               return IRQ_NONE;
+       }
+
+       if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK))
+               return IRQ_NONE;
+
+       phy_trigger_machine(phydev);
 
-       reg = phy_read_mmd(phydev, MDIO_MMD_AN,
-                          MDIO_AN_TX_VEND_INT_STATUS2);
-       return (reg < 0) ? reg : 0;
+       return IRQ_HANDLED;
 }
 
 static int aqr_read_status(struct phy_device *phydev)
@@ -584,7 +613,7 @@ static struct phy_driver aqr_driver[] = {
        .name           = "Aquantia AQ1202",
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
-       .ack_interrupt  = aqr_ack_interrupt,
+       .handle_interrupt = aqr_handle_interrupt,
        .read_status    = aqr_read_status,
 },
 {
@@ -592,7 +621,7 @@ static struct phy_driver aqr_driver[] = {
        .name           = "Aquantia AQ2104",
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
-       .ack_interrupt  = aqr_ack_interrupt,
+       .handle_interrupt = aqr_handle_interrupt,
        .read_status    = aqr_read_status,
 },
 {
@@ -600,7 +629,7 @@ static struct phy_driver aqr_driver[] = {
        .name           = "Aquantia AQR105",
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
-       .ack_interrupt  = aqr_ack_interrupt,
+       .handle_interrupt = aqr_handle_interrupt,
        .read_status    = aqr_read_status,
        .suspend        = aqr107_suspend,
        .resume         = aqr107_resume,
@@ -610,7 +639,7 @@ static struct phy_driver aqr_driver[] = {
        .name           = "Aquantia AQR106",
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
-       .ack_interrupt  = aqr_ack_interrupt,
+       .handle_interrupt = aqr_handle_interrupt,
        .read_status    = aqr_read_status,
 },
 {
@@ -620,7 +649,7 @@ static struct phy_driver aqr_driver[] = {
        .config_init    = aqr107_config_init,
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
-       .ack_interrupt  = aqr_ack_interrupt,
+       .handle_interrupt = aqr_handle_interrupt,
        .read_status    = aqr107_read_status,
        .get_tunable    = aqr107_get_tunable,
        .set_tunable    = aqr107_set_tunable,
@@ -638,7 +667,7 @@ static struct phy_driver aqr_driver[] = {
        .config_init    = aqcs109_config_init,
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
-       .ack_interrupt  = aqr_ack_interrupt,
+       .handle_interrupt = aqr_handle_interrupt,
        .read_status    = aqr107_read_status,
        .get_tunable    = aqr107_get_tunable,
        .set_tunable    = aqr107_set_tunable,
@@ -654,7 +683,7 @@ static struct phy_driver aqr_driver[] = {
        .name           = "Aquantia AQR405",
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
-       .ack_interrupt  = aqr_ack_interrupt,
+       .handle_interrupt = aqr_handle_interrupt,
        .read_status    = aqr_read_status,
 },
 };