From patchwork Wed Mar 9 00:28:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamal Mostafa X-Patchwork-Id: 594559 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 60DE5140328; Wed, 9 Mar 2016 11:29:06 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1adRzs-0005XD-A8; Wed, 09 Mar 2016 00:29:04 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1adRzb-0005N0-IZ for kernel-team@lists.ubuntu.com; Wed, 09 Mar 2016 00:28:47 +0000 Received: from 1.general.kamal.us.vpn ([10.172.68.52] helo=fourier) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1adRzb-00035D-4G; Wed, 09 Mar 2016 00:28:47 +0000 Received: from kamal by fourier with local (Exim 4.86) (envelope-from ) id 1adRzT-0007VX-Fc; Tue, 08 Mar 2016 16:28:39 -0800 From: Kamal Mostafa To: Florian Fainelli Subject: [3.19.y-ckt stable] Patch "net: phy: Fix phy_mac_interrupt()" has been added to the 3.19.y-ckt tree Date: Tue, 8 Mar 2016 16:28:33 -0800 Message-Id: <1457483313-28824-1-git-send-email-kamal@canonical.com> X-Mailer: git-send-email 2.7.0 X-Extended-Stable: 3.19 Cc: Kamal Mostafa , "David S . Miller" , kernel-team@lists.ubuntu.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com This is a note to let you know that I have just added a patch titled net: phy: Fix phy_mac_interrupt() to the linux-3.19.y-queue branch of the 3.19.y-ckt extended stable tree which can be found at: http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.19.y-queue This patch is scheduled to be released in version 3.19.8-ckt16. If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.19.y-ckt tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Kamal ---8<------------------------------------------------------------ From 4a73352facaf7d6dd7d7fc2add82c83220af2142 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 18 Jan 2016 19:33:07 -0800 Subject: net: phy: Fix phy_mac_interrupt() commit deccd16f91f930af8e91ffbbfc839d0ad8da999d upstream. Commit 5ea94e7686a3 ("phy: add phy_mac_interrupt()") to use with PHY_IGNORE_INTERRUPT added a cancel_work_sync() into phy_mac_interrupt() which is allowed to sleep, whereas phy_mac_interrupt() is expected to be callable from interrupt context. Now that we have fixed how the PHY state machine treats PHY_IGNORE_INTERRUPT with respect to state changes, we can just set the new link state, and queue the PHY state machine for execution so it is going to read the new link state. For that to work properly, we need to update phy_change() not to try to invoke any interrupt callbacks if we have configured the PHY device for PHY_IGNORE_INTERRUPT, because that PHY device and its driver are not required to implement those. Fixes: 5ea94e7686a3 ("phy: add phy_mac_interrupt() to use with PHY_IGNORE_INTERRUPT") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Kamal Mostafa --- drivers/net/phy/phy.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) -- 2.7.0 diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 15a7387..7503c4d 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -659,25 +659,29 @@ 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; + if (phy_interrupt_is_valid(phydev)) { + if (phydev->drv->did_interrupt && + !phydev->drv->did_interrupt(phydev)) + goto ignore; - if (phy_disable_interrupts(phydev)) - goto phy_err; + if (phy_disable_interrupts(phydev)) + goto phy_err; + } mutex_lock(&phydev->lock); if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) phydev->state = PHY_CHANGELINK; mutex_unlock(&phydev->lock); - atomic_dec(&phydev->irq_disable); - enable_irq(phydev->irq); + if (phy_interrupt_is_valid(phydev)) { + atomic_dec(&phydev->irq_disable); + enable_irq(phydev->irq); - /* Reenable interrupts */ - if (PHY_HALTED != phydev->state && - phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED)) - goto irq_enable_err; + /* Reenable interrupts */ + if (PHY_HALTED != phydev->state && + phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED)) + goto irq_enable_err; + } /* reschedule state queue work to run as soon as possible */ cancel_delayed_work_sync(&phydev->state_queue); @@ -952,9 +956,10 @@ void phy_state_machine(struct work_struct *work) void phy_mac_interrupt(struct phy_device *phydev, int new_link) { - cancel_work_sync(&phydev->phy_queue); phydev->link = new_link; - schedule_work(&phydev->phy_queue); + + /* Trigger a state machine change */ + queue_work(system_power_efficient_wq, &phydev->phy_queue); } EXPORT_SYMBOL(phy_mac_interrupt);