From patchwork Fri Jul 8 09:07:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 71661 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp342737qgy; Fri, 8 Jul 2016 02:07:58 -0700 (PDT) X-Received: by 10.66.236.69 with SMTP id us5mr8085147pac.69.1467968878129; Fri, 08 Jul 2016 02:07:58 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id kc6si3099301pab.189.2016.07.08.02.07.58; Fri, 08 Jul 2016 02:07:58 -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 S1754280AbcGHJHz (ORCPT + 4 others); Fri, 8 Jul 2016 05:07:55 -0400 Received: from mail-lf0-f53.google.com ([209.85.215.53]:35824 "EHLO mail-lf0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752008AbcGHJHq (ORCPT ); Fri, 8 Jul 2016 05:07:46 -0400 Received: by mail-lf0-f53.google.com with SMTP id l188so26027072lfe.2 for ; Fri, 08 Jul 2016 02:07:45 -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=3z39m2BB9japJCpRiMNp05hpbB7O00sW6H0bLJsVfzU=; b=ZwfP89v7RUcCuOixueDoDBTCPSc+xQRWRdks6KwvwQQ0IzRuqUrC+HMpyYJZoPZYZj iRvK6ggxMuP0EfToRNZY9FgUOYflWf4dIuefd4ojM45fccI+OZbqDpoDAR7S0KVXjsUz hLUt5myyLtvSgn/JOGpPb8ytXGDOY/Rnb7itY= 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=3z39m2BB9japJCpRiMNp05hpbB7O00sW6H0bLJsVfzU=; b=SjIbjmaA4a+eaKoXTnBnefjSFZa+UQmJ55knWsRJu+LuTogjiYy/3YDk87n6DgmVIa McKxJ4ifzQuBGfBEMY9/mB5BFdlkJnDHedCT/f4ofFsEof3DpZ/a6vbUJdnvm6dpKDAk NtF7K8J5Vjo7BSLQ7bmy8/sm6smzJo1HybdVJEiqvBge+mHDUXA+1c55AKyjEmxuKPn4 8luyKGAV4DHpIkSxTwAkzULmpEVknW+vG95898bXgZtZC8+RHq4fjtGQaz4adyZfQtdr rDgRFA1bWs8LwjoTS44JI//C6wMH2/znpJuHV+fUvSW6bmBpHeNEZYLu5EfMTQS6Q0Ny DwHg== X-Gm-Message-State: ALyK8tKYkkYva5VfgBFVMSAwNLgOtx1lk/W82iZOscTmWk05sPJmqtZOtjgdc2DQhSRIRFTT X-Received: by 10.25.1.65 with SMTP id 62mr1128570lfb.114.1467968864976; Fri, 08 Jul 2016 02:07:44 -0700 (PDT) Received: from localhost.localdomain.localdomain (c-cc7c71d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.124.204]) by smtp.gmail.com with ESMTPSA id 16sm6666907lja.31.2016.07.08.02.07.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Jul 2016 02:07:44 -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 , Alexandre Belloni , Tony Lindgren , "Rafael J . Wysocki" , John Stultz Subject: [PATCH 3/3] RFC: net: smsc911x: add wake-up event interrupt support Date: Fri, 8 Jul 2016 11:07:32 +0200 Message-Id: <1467968852-6175-3-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1467968852-6175-1-git-send-email-linus.walleij@linaro.org> References: <1467968852-6175-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: Alexandre Belloni Cc: Tony Lindgren Cc: Rafael J. Wysocki Cc: John Stultz Signed-off-by: Linus Walleij --- Added some wakeup people at CC who can (hopefully) tell me if I'm doing this right or not. --- drivers/net/ethernet/smsc/smsc911x.c | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) -- 2.7.4 diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 125d58ac22bd..e43755ae130a 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" @@ -153,6 +154,9 @@ struct smsc911x_data { /* Reset GPIO */ struct gpio_desc *reset_gpiod; + /* PME interrupt */ + int pme_irq; + /* clock */ struct clk *clk; }; @@ -1882,6 +1886,17 @@ 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"); + /* 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) { @@ -2525,6 +2540,33 @@ 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) { + char *pme_name; + + /* + * 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); @@ -2613,6 +2655,9 @@ static int smsc911x_suspend(struct device *dev) PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ | PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_); + if (pdata->pme_irq && device_may_wakeup(dev)) + enable_irq_wake(pdata->pme_irq); + return 0; } @@ -2622,6 +2667,9 @@ static int smsc911x_resume(struct device *dev) struct smsc911x_data *pdata = netdev_priv(ndev); unsigned int to = 100; + if (pdata->pme_irq && device_may_wakeup(dev)) + disable_irq_wake(pdata->pme_irq); + /* Note 3.11 from the datasheet: * "When the LAN9220 is in a power saving state, a write of any * data to the BYTE_TEST register will wake-up the device."