From a8729eb302a5b5da8b0b4d29582c42648a2e0f12 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 7 Apr 2009 02:01:42 +0000 Subject: phylib: Allow early-out in phy_change Marvell 88E1121R Dual PHY device can be hardware-configured to use shared interrupt pin for both PHY ports. For such PHY configurations using shared PHY interrupt phy_interrupt() handler will also schedule a work for PHY port which didn't cause an interrupt. This patch adds a possibility for PHY drivers to provide did_interrupt() function which reports if the PHY (or a PHY port in a multi-PHY device) generated an interrupt. This function is called in phy_change() as phy_change() shouldn't proceed if it is invoked for a PHY which didn't cause an interrupt. So check for interrupt originator in phy_change() to allow early-out. Signed-off-by: Anatolij Gustschin Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/net/phy/phy.c') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 3ff1f425f1b..e3b8932d7d7 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -655,6 +655,10 @@ static void phy_change(struct work_struct *work) struct phy_device *phydev = container_of(work, struct phy_device, phy_queue); + if (phydev->drv->did_interrupt && + !phydev->drv->did_interrupt(phydev)) + goto ignore; + err = phy_disable_interrupts(phydev); if (err) @@ -681,6 +685,11 @@ static void phy_change(struct work_struct *work) return; +ignore: + atomic_dec(&phydev->irq_disable); + enable_irq(phydev->irq); + return; + irq_enable_err: disable_irq(phydev->irq); atomic_inc(&phydev->irq_disable); -- cgit v1.2.3