From patchwork Mon Oct 24 17:56:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 9392781 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7909F60231 for ; Mon, 24 Oct 2016 17:57:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7261D29099 for ; Mon, 24 Oct 2016 17:57:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 66BE729164; Mon, 24 Oct 2016 17:57:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B4C6D29099 for ; Mon, 24 Oct 2016 17:57:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S938802AbcJXR5X (ORCPT ); Mon, 24 Oct 2016 13:57:23 -0400 Received: from mail-pf0-f174.google.com ([209.85.192.174]:33163 "EHLO mail-pf0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S938676AbcJXR5Q (ORCPT ); Mon, 24 Oct 2016 13:57:16 -0400 Received: by mail-pf0-f174.google.com with SMTP id 128so103185979pfz.0 for ; Mon, 24 Oct 2016 10:57:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1Pzfpe27xQExVEEzWQtykbzteScbELCqnC8z1Hzs0Y0=; b=FVFdBu3iX8PQXd3D3q0v/u8JXdNuG/vjYpTqv7FtqE+GuAFXG0hiP82ArswASI8yRz hww9PbFpugiBt3pTKYUA5exCj7YVQC8agqWEXdS2OdxokPhCLOCmPvABR3WxAZ7/qRgn 0zlw+euf/oyi9fJOJEqe3NOYajg905k9LDLFVSbkIuCsN+WKtsdng242PL5wddPIU9qi dHTWq9V7Esd+Dt7TqD7KfN4nKwEi94BawfEQUuDv31Tr4dkV/GYzbTuRfaBIwPq1Jv6/ v+yCPz8Wo9tcrFa73BtJraXLUnPuUzC3hcImOpW9EP4aRugPRbQCs5KRHEGR3Z50xdEt cptw== 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=1Pzfpe27xQExVEEzWQtykbzteScbELCqnC8z1Hzs0Y0=; b=ScZAotSxqfYyI55udnQQcHwBQytsi9tCZcjEDf0KzWUyL6TmDJehkBc9Ryxp9/2vcR 21PvqZfexPmom5YCNS9Bh2S4pcwj2aMR4DzhubQ4eliqAS818i9NxiizyQ9aB1ooshu5 EuK+51Zp+36KN7wtLhxHtMREpC3z853djjrC3hhntZIHpZ4OhdX3SsYilSAt7OfKjfbU EVqyqb+xPe5zbsV1qQQLsYNm3wXopZCQd7uN5u9LiG9ixZUnWWc600+YMTjQeuuK5GcI qSaEAGVCNVAwVHpGTT6fQIiiEj7N9RzFX/YxaKkTQMjR2duYRLRAu3ulgnj9lIEoWosR fFGw== X-Gm-Message-State: ABUngvdGoba6P9Q1p6D0XihuOM8kFs2Is8sFwnIoi+LoQQMpupX813jASuXqNcMih/67mMcg X-Received: by 10.99.127.75 with SMTP id p11mr25520478pgn.61.1477331835295; Mon, 24 Oct 2016 10:57:15 -0700 (PDT) Received: from rajat.mtv.corp.google.com ([172.22.64.13]) by smtp.gmail.com with ESMTPSA id e74sm26996567pfk.13.2016.10.24.10.57.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 24 Oct 2016 10:57:14 -0700 (PDT) From: Rajat Jain To: Amitkumar Karwar , Nishant Sarmukadam , Kalle Valo , linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Xinming Hu Cc: Rajat Jain , Brian Norris , rajatxjain@gmail.com Subject: [PATCH 3/3] mwifiex: Enable WoWLAN for both sdio and pcie Date: Mon, 24 Oct 2016 10:56:53 -0700 Message-Id: <1477331813-42151-4-git-send-email-rajatja@google.com> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1477331813-42151-1-git-send-email-rajatja@google.com> References: <1477331813-42151-1-git-send-email-rajatja@google.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Commit ce4f6f0c353b ("mwifiex: add platform specific wakeup interrupt support") added WoWLAN feature only for sdio. This patch moves that code to the common module so that all the interface drivers can use it for free. It enables pcie and sdio for its use currently. Signed-off-by: Rajat Jain --- drivers/net/wireless/marvell/mwifiex/main.c | 41 ++++++++++++++++ drivers/net/wireless/marvell/mwifiex/main.h | 25 ++++++++++ drivers/net/wireless/marvell/mwifiex/pcie.c | 2 + drivers/net/wireless/marvell/mwifiex/sdio.c | 72 ++--------------------------- drivers/net/wireless/marvell/mwifiex/sdio.h | 8 ---- 5 files changed, 73 insertions(+), 75 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index b2f3d96..20c9b77 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1552,14 +1552,55 @@ void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool prepare) } EXPORT_SYMBOL_GPL(mwifiex_do_flr); +static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv) +{ + struct mwifiex_adapter *adapter = priv; + + if (adapter->irq_wakeup >= 0) { + dev_dbg(adapter->dev, "%s: wake by wifi", __func__); + adapter->wake_by_wifi = true; + disable_irq_nosync(irq); + } + + /* Notify PM core we are wakeup source */ + pm_wakeup_event(adapter->dev, 0); + + return IRQ_HANDLED; +} + static void mwifiex_probe_of(struct mwifiex_adapter *adapter) { + int ret; struct device *dev = adapter->dev; if (!dev->of_node) return; adapter->dt_node = dev->of_node; + adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0); + if (!adapter->irq_wakeup) { + dev_info(dev, "fail to parse irq_wakeup from device tree\n"); + return; + } + + ret = devm_request_irq(dev, adapter->irq_wakeup, + mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW, + "wifi_wake", adapter); + if (ret) { + dev_err(dev, "Failed to request irq_wakeup %d (%d)\n", + adapter->irq_wakeup, ret); + goto err_exit; + } + + disable_irq(adapter->irq_wakeup); + if (device_init_wakeup(dev, true)) { + dev_err(dev, "fail to init wakeup for mwifiex\n"); + goto err_exit; + } + return; + +err_exit: + adapter->irq_wakeup = 0; } /* diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 83e0776..12def94 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -1010,6 +1010,10 @@ struct mwifiex_adapter { bool usb_mc_setup; struct cfg80211_wowlan_nd_info *nd_info; struct ieee80211_regdomain *regd; + + /* Wake-on-WLAN (WoWLAN) */ + int irq_wakeup; + bool wake_by_wifi; }; void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter); @@ -1409,6 +1413,27 @@ static inline u8 mwifiex_is_tdls_link_setup(u8 status) return false; } +/* Disable platform specific wakeup interrupt */ +static inline void mwifiex_disable_wake(struct mwifiex_adapter *adapter) +{ + if (adapter->irq_wakeup >= 0) { + disable_irq_wake(adapter->irq_wakeup); + if (!adapter->wake_by_wifi) + disable_irq(adapter->irq_wakeup); + } +} + +/* Enable platform specific wakeup interrupt */ +static inline void mwifiex_enable_wake(struct mwifiex_adapter *adapter) +{ + /* Enable platform specific wakeup interrupt */ + if (adapter->irq_wakeup >= 0) { + adapter->wake_by_wifi = false; + enable_irq(adapter->irq_wakeup); + enable_irq_wake(adapter->irq_wakeup); + } +} + int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, u32 func_init_shutdown); int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8, diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index ea423d5..af93661 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -133,6 +133,7 @@ static int mwifiex_pcie_suspend(struct device *dev) adapter = card->adapter; + mwifiex_enable_wake(adapter); hs_actived = mwifiex_enable_hs(adapter); /* Indicate device suspended */ @@ -179,6 +180,7 @@ static int mwifiex_pcie_resume(struct device *dev) mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), MWIFIEX_ASYNC_CMD); + mwifiex_disable_wake(adapter); return 0; } diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index 558743a..ff5bb45 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -79,67 +79,18 @@ static const struct of_device_id mwifiex_sdio_of_match_table[] = { { } }; -static irqreturn_t mwifiex_wake_irq_wifi(int irq, void *priv) -{ - struct mwifiex_plt_wake_cfg *cfg = priv; - - if (cfg->irq_wifi >= 0) { - pr_info("%s: wake by wifi", __func__); - cfg->wake_by_wifi = true; - disable_irq_nosync(irq); - } - - /* Notify PM core we are wakeup source */ - pm_wakeup_event(cfg->dev, 0); - - return IRQ_HANDLED; -} - /* This function parse device tree node using mmc subnode devicetree API. * The device node is saved in card->plt_of_node. * if the device tree node exist and include interrupts attributes, this * function will also request platform specific wakeup interrupt. */ -static int mwifiex_sdio_probe_of(struct device *dev, struct sdio_mmc_card *card) +static int mwifiex_sdio_probe_of(struct device *dev) { - struct mwifiex_plt_wake_cfg *cfg; - int ret; - if (!of_match_node(mwifiex_sdio_of_match_table, dev->of_node)) { dev_err(dev, "required compatible string missing\n"); return -EINVAL; } - card->plt_of_node = dev->of_node; - card->plt_wake_cfg = devm_kzalloc(dev, sizeof(*card->plt_wake_cfg), - GFP_KERNEL); - cfg = card->plt_wake_cfg; - if (cfg && card->plt_of_node) { - cfg->dev = dev; - cfg->irq_wifi = irq_of_parse_and_map(card->plt_of_node, 0); - if (!cfg->irq_wifi) { - dev_dbg(dev, - "fail to parse irq_wifi from device tree\n"); - } else { - ret = devm_request_irq(dev, cfg->irq_wifi, - mwifiex_wake_irq_wifi, - IRQF_TRIGGER_LOW, - "wifi_wake", cfg); - if (ret) { - dev_dbg(dev, - "Failed to request irq_wifi %d (%d)\n", - cfg->irq_wifi, ret); - card->plt_wake_cfg = NULL; - return 0; - } - disable_irq(cfg->irq_wifi); - } - } - - ret = device_init_wakeup(dev, true); - if (ret) - dev_err(dev, "fail to init wakeup for mwifiex"); - return 0; } @@ -199,11 +150,9 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) /* device tree node parsing and platform specific configuration*/ if (func->dev.of_node) { - ret = mwifiex_sdio_probe_of(&func->dev, card); - if (ret) { - dev_err(&func->dev, "SDIO dt node parse failed\n"); + ret = mwifiex_sdio_probe_of(&func->dev); + if (ret) goto err_disable; - } valid_of_node = true; } @@ -269,12 +218,7 @@ static int mwifiex_sdio_resume(struct device *dev) mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), MWIFIEX_SYNC_CMD); - /* Disable platform specific wakeup interrupt */ - if (card->plt_wake_cfg && card->plt_wake_cfg->irq_wifi >= 0) { - disable_irq_wake(card->plt_wake_cfg->irq_wifi); - if (!card->plt_wake_cfg->wake_by_wifi) - disable_irq(card->plt_wake_cfg->irq_wifi); - } + mwifiex_disable_wake(adapter); return 0; } @@ -354,13 +298,7 @@ static int mwifiex_sdio_suspend(struct device *dev) } adapter = card->adapter; - - /* Enable platform specific wakeup interrupt */ - if (card->plt_wake_cfg && card->plt_wake_cfg->irq_wifi >= 0) { - card->plt_wake_cfg->wake_by_wifi = false; - enable_irq(card->plt_wake_cfg->irq_wifi); - enable_irq_wake(card->plt_wake_cfg->irq_wifi); - } + mwifiex_enable_wake(adapter); /* Enable the Host Sleep */ if (!mwifiex_enable_hs(adapter)) { diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h index 07cdd23..b9fbc5c 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.h +++ b/drivers/net/wireless/marvell/mwifiex/sdio.h @@ -154,12 +154,6 @@ a->mpa_rx.start_port = 0; \ } while (0) -struct mwifiex_plt_wake_cfg { - struct device *dev; - int irq_wifi; - bool wake_by_wifi; -}; - /* data structure for SDIO MPA TX */ struct mwifiex_sdio_mpa_tx { /* multiport tx aggregation buffer pointer */ @@ -243,8 +237,6 @@ struct mwifiex_sdio_card_reg { struct sdio_mmc_card { struct sdio_func *func; struct mwifiex_adapter *adapter; - struct device_node *plt_of_node; - struct mwifiex_plt_wake_cfg *plt_wake_cfg; const char *firmware; const struct mwifiex_sdio_card_reg *reg;