From patchwork Wed Aug 24 12:59:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 74606 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp303640qga; Wed, 24 Aug 2016 06:00:27 -0700 (PDT) X-Received: by 10.66.17.138 with SMTP id o10mr5461044pad.112.1472043627820; Wed, 24 Aug 2016 06:00:27 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i8si9649755pat.21.2016.08.24.06.00.27; Wed, 24 Aug 2016 06:00:27 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755301AbcHXNAU (ORCPT + 4 others); Wed, 24 Aug 2016 09:00:20 -0400 Received: from mail-lf0-f44.google.com ([209.85.215.44]:34693 "EHLO mail-lf0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753456AbcHXNAR (ORCPT ); Wed, 24 Aug 2016 09:00:17 -0400 Received: by mail-lf0-f44.google.com with SMTP id l89so11307681lfi.1 for ; Wed, 24 Aug 2016 06:00:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=h19uwJRVhbzIFRoJL97dbE8xhW6/uyKOvVotizHTQws=; b=eFBv2iKKgvZxwn0adJwyKp36KPggPLhQK8wbvGp5IdEvMR+T0jk+HTnvXDnbE7IMxE jEx7I1b0Gve70f2mEHTiqIyEdzb8gs0oN9Xxd1aHyQw0/fLjEBGqk4r77tXxPxOUAPu7 MzOx61mUpbHXfYsG+Owt2n8FewMszvKN/0e+Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=h19uwJRVhbzIFRoJL97dbE8xhW6/uyKOvVotizHTQws=; b=iODXJ0vKyuddVirxbpEv38zvjNDW5XQeuCTq0Vf1RASWOvQDC1Z7V85J8BkJtPvH+M OcEQI/uRK2hdiyfsOOxTgMPQqvgCS0fwadO+FgNucm0DMHf8Kf16QeoGpf+ElmPvF/qt Mfs2tuCmPrbecQ3sE6IJF8WuiiZD6VUnBTtIsCf6Caxs4N/EiCBPOQ4xcNzc6L8kfVrg NdpKsnyYP7qdI2l/HLIrNDzMlsPB7f9mLBXgD1Mugh6rWF86lQ/MXBGhYKOFz5Ytm3h4 /6bQu9S/FajGY4p1jN2EsAGYzhyKnsoK3hVYnIoxRR5koG3uoF7hjYdJrorK5Io8cWgs q+Mg== X-Gm-Message-State: AEkooutPhpKjXCPB07JN4eFuT+xlKUkjSKmLyCRg467r9js1ZLpE3S9XVXiC56H0jVixE9er X-Received: by 10.46.71.84 with SMTP id u81mr836583lja.19.1472043600502; Wed, 24 Aug 2016 06:00:00 -0700 (PDT) Received: from linuslaptop.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id 184sm1882012lfz.22.2016.08.24.05.59.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Aug 2016 05:59:59 -0700 (PDT) From: Linus Walleij To: netdev@vger.kernel.org, "David S . Miller" , Steve Glendinning Cc: Guenter Roeck , Jeremy Linton , Kamlakant Patel , Pavel Fedin , Linus Walleij , Sudeep Holla , Tony Lindgren , Florian Fainelli Subject: [PATCH 3/3 v2] net: smsc911x: add wake-up event interrupt support Date: Wed, 24 Aug 2016 14:59:42 +0200 Message-Id: <1472043582-7653-3-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1472043582-7653-1-git-send-email-linus.walleij@linaro.org> References: <1472043582-7653-1-git-send-email-linus.walleij@linaro.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The SMSC911x have a line out of the chip called "PME", Power Management Event. When connected to an asynchronous interrupt controller this is able to wake the system up from sleep in response to certain network events. This is the first attempt to support this in the Linux driver: the Qualcomm APQ8060 Dragonboard has this line routed to a GPIO line on the primary SoC padring, and as such it can be armed as a wakeup interrupt. The patch is inspired by the wakeup code in the RTC subsystem. The code looks for an additional interrupt - apart from the ordinary device interrupt - and in case that is present, we register an interrupt handler to respons to this, and flag the device and this interrupt as a wakeup. Cc: Sudeep Holla Cc: Tony Lindgren Cc: Florian Fainelli Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - Call pm_wakeup_event() in the wakeup IRQ thread to account for the wakeup event. - Drop the enable/disable_irq_wake() calls from suspend/resume: this is handled from the irq core when you call dev_pm_set_wake_irq() as we do. --- drivers/net/ethernet/smsc/smsc911x.c | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) -- 2.7.4 diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 8ab8d4b9614b..8fffc1dc2bdd 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -63,6 +63,7 @@ #include #include #include +#include #include "smsc911x.h" @@ -151,6 +152,9 @@ struct smsc911x_data { /* Reset GPIO */ struct gpio_desc *reset_gpiod; + /* PME interrupt */ + int pme_irq; + /* clock */ struct clk *clk; }; @@ -1881,6 +1885,19 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id) return serviced; } +static irqreturn_t smsc911x_pme_irq_thread(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct smsc911x_data *pdata __maybe_unused = netdev_priv(dev); + + SMSC_TRACE(pdata, pm, "wakeup event"); + pm_wakeup_event(&dev->dev, 50); + /* This signal is active for 50 ms, wait for it to deassert */ + usleep_range(50000, 100000); + + return IRQ_HANDLED; +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void smsc911x_poll_controller(struct net_device *dev) { @@ -2501,6 +2518,31 @@ static int smsc911x_drv_probe(struct platform_device *pdev) goto out_disable_resources; } + irq = platform_get_irq(pdev, 1); + if (irq == -EPROBE_DEFER) { + retval = -EPROBE_DEFER; + goto out_disable_resources; + /* It's perfectly fine to not have a PME IRQ */ + } else if (irq > 0) { + /* + * The Power Management Event (PME) IRQ appears as + * a pulse waking up the system from sleep in response to a + * network event. + */ + retval = request_threaded_irq(irq, NULL, + smsc911x_pme_irq_thread, + IRQF_ONESHOT, "smsc911x-pme", + dev); + if (retval) { + SMSC_WARN(pdata, probe, + "Unable to claim requested PME irq: %d", irq); + goto out_disable_resources; + } + pdata->pme_irq = irq; + device_init_wakeup(&pdev->dev, true); + dev_pm_set_wake_irq(&pdev->dev, irq); + } + netif_carrier_off(dev); retval = register_netdev(dev);