Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1d5e83aac54b64b71b225fd5cf2e82491ad145f6
Commit:     1d5e83aac54b64b71b225fd5cf2e82491ad145f6
Parent:     5bae7ac9feba925fd0099057f6b23d7be80b7b41
Author:     Andy Fleming <[EMAIL PROTECTED]>
AuthorDate: Tue Jul 10 16:42:04 2007 -0500
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Wed Jul 18 18:29:37 2007 -0400

    Fix Vitesse 824x PHY interrupt acking
    
    The Vitesse 824x PHY doesn't allow an interrupt to be cleared if
    the mask bit for that interrupt isn't set.  This means that the PHY
    Lib's order of handling interrupts (disable, then clear) breaks on this
    PHY.  However, clearing then disabling the interrupt opens up the code
    for a silly race condition.  So rather than change the PHY Lib, we change
    the Vitesse driver so it always clears interrupts before disabling them.
    Further, the ack function only clears the interrupt if interrupts are
    enabled.
    
    Signed-off-by: Andy Fleming <[EMAIL PROTECTED]>
    Signed-off-by: York Sun <[EMAIL PROTECTED]>
    Acked-by: Haiying Wang <[EMAIL PROTECTED]>
---
 drivers/net/phy/vitesse.c |   23 +++++++++++++++++++++--
 1 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 596222b..f39ab76 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -65,7 +65,15 @@ static int vsc824x_config_init(struct phy_device *phydev)
 
 static int vsc824x_ack_interrupt(struct phy_device *phydev)
 {
-       int err = phy_read(phydev, MII_VSC8244_ISTAT);
+       int err = 0;
+       
+       /*
+        * Don't bother to ACK the interrupts if interrupts
+        * are disabled.  The 824x cannot clear the interrupts
+        * if they are disabled.
+        */
+       if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+               err = phy_read(phydev, MII_VSC8244_ISTAT);
 
        return (err < 0) ? err : 0;
 }
@@ -77,8 +85,19 @@ static int vsc824x_config_intr(struct phy_device *phydev)
        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
                err = phy_write(phydev, MII_VSC8244_IMASK,
                                MII_VSC8244_IMASK_MASK);
-       else
+       else {
+               /*
+                * The Vitesse PHY cannot clear the interrupt
+                * once it has disabled them, so we clear them first
+                */
+               err = phy_read(phydev, MII_VSC8244_ISTAT);
+
+               if (err)
+                       return err;
+
                err = phy_write(phydev, MII_VSC8244_IMASK, 0);
+       }
+
        return err;
 }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to