From patchwork Mon Apr 18 12:22:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitkumar Karwar X-Patchwork-Id: 8871881 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 3479CBF29F for ; Mon, 18 Apr 2016 12:23:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 02B5C20221 for ; Mon, 18 Apr 2016 12:23:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C36862017D for ; Mon, 18 Apr 2016 12:23:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751879AbcDRMXJ (ORCPT ); Mon, 18 Apr 2016 08:23:09 -0400 Received: from mx0a-0016f401.pphosted.com ([67.231.148.174]:7911 "EHLO mx0a-0016f401.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751342AbcDRMXH (ORCPT ); Mon, 18 Apr 2016 08:23:07 -0400 Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u3IC5fVE023609; Mon, 18 Apr 2016 05:23:05 -0700 Received: from sc-exch02.marvell.com ([199.233.58.182]) by mx0a-0016f401.pphosted.com with ESMTP id 22bjrk4y1w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 18 Apr 2016 05:23:05 -0700 Received: from SC-EXCH03.marvell.com (10.93.176.83) by SC-EXCH02.marvell.com (10.93.176.82) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Mon, 18 Apr 2016 05:23:04 -0700 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH03.marvell.com (10.93.176.83) with Microsoft SMTP Server id 15.0.1104.5 via Frontend Transport; Mon, 18 Apr 2016 05:23:04 -0700 Received: from pe-lt101 (unknown [10.31.130.27]) by maili.marvell.com (Postfix) with ESMTP id 850D33F703F; Mon, 18 Apr 2016 05:23:03 -0700 (PDT) Received: from pe-lt101 (pe-lt077 [127.0.0.1]) by pe-lt101 (8.14.4/8.14.4) with ESMTP id u3ICMU4x001453; Mon, 18 Apr 2016 05:22:31 -0700 Received: (from root@localhost) by pe-lt101 (8.14.4/8.14.4/Submit) id u3ICMUeP001452; Mon, 18 Apr 2016 05:22:30 -0700 From: Amitkumar Karwar To: CC: , Wei-Ning Huang , Xinming Hu , Amitkumar Karwar Subject: [PATCH v7 2/2] mwifiex: add platform specific wakeup interrupt support Date: Mon, 18 Apr 2016 05:22:23 -0700 Message-ID: <1460982143-1419-2-git-send-email-akarwar@marvell.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1460982143-1419-1-git-send-email-akarwar@marvell.com> References: <1460982143-1419-1-git-send-email-akarwar@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-04-18_06:, , signatures=0 X-Proofpoint-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1603290000 definitions=main-1604180152 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Xinming Hu On some arm-based platforms, we need to configure platform specific parameters by device tree node and also define our node as a child node of parent SDIO host controller. This patch parses these parameters from device tree. It includes calibration data dowoload to firmware, wakeup pin configured to firmware, and soc specific wake up gpio, which will be set as wakeup interrupt pin. Signed-off-by: Xinming Hu Signed-off-by: Amitkumar Karwar --- drivers/net/wireless/marvell/mwifiex/main.h | 11 ++++ drivers/net/wireless/marvell/mwifiex/sdio.c | 77 ++++++++++++++++++++++++++ drivers/net/wireless/marvell/mwifiex/sdio.h | 7 +++ drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 14 ++++- 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 63069dd..4c742a5 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -37,6 +37,17 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "decl.h" #include "ioctl.h" diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index a0aec3e..cbd9dcd 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -73,6 +73,66 @@ static struct memory_type_mapping mem_type_mapping_tbl[] = { {"EXTLAST", NULL, 0, 0xFE}, }; +static const struct of_device_id mwifiex_sdio_of_match_table[] = { + { .compatible = "marvell,sd8897" }, + { .compatible = "marvell,sd8997" }, + { } +}; + +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); + } + + 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) +{ + struct mwifiex_plt_wake_cfg *cfg; + int ret; + + if (!dev->of_node || + !of_match_node(mwifiex_sdio_of_match_table, dev->of_node)) { + pr_err("sdio platform data not available"); + return -1; + } + + 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->irq_wifi = irq_of_parse_and_map(card->plt_of_node, 0); + if (!cfg->irq_wifi) { + dev_err(dev, "fail to parse irq_wifi from device tree"); + } else { + ret = devm_request_irq(dev, cfg->irq_wifi, + mwifiex_wake_irq_wifi, + IRQF_TRIGGER_LOW, + "wifi_wake", cfg); + if (ret) { + dev_err(dev, + "Failed to request irq_wifi %d (%d)\n", + cfg->irq_wifi, ret); + } + disable_irq(cfg->irq_wifi); + } + } + + return 0; +} + /* * SDIO probe. * @@ -127,6 +187,9 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) return -EIO; } + /* device tree node parsing and platform specific configuration*/ + mwifiex_sdio_probe_of(&func->dev, card); + if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops, MWIFIEX_SDIO)) { pr_err("%s: add card failed\n", __func__); @@ -183,6 +246,13 @@ 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); + } + return 0; } @@ -262,6 +332,13 @@ 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); + } + /* Enable the Host Sleep */ if (!mwifiex_enable_hs(adapter)) { mwifiex_dbg(adapter, ERROR, diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h index b9fbc5c..db837f1 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.h +++ b/drivers/net/wireless/marvell/mwifiex/sdio.h @@ -154,6 +154,11 @@ a->mpa_rx.start_port = 0; \ } while (0) +struct mwifiex_plt_wake_cfg { + int irq_wifi; + bool wake_by_wifi; +}; + /* data structure for SDIO MPA TX */ struct mwifiex_sdio_mpa_tx { /* multiport tx aggregation buffer pointer */ @@ -237,6 +242,8 @@ 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; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c index 8cb895b..e436574 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c @@ -2162,6 +2162,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) enum state_11d_t state_11d; struct mwifiex_ds_11n_tx_cfg tx_cfg; u8 sdio_sp_rx_aggr_enable; + int data; if (first_sta) { if (priv->adapter->iface_type == MWIFIEX_PCIE) { @@ -2182,9 +2183,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init) * The cal-data can be read from device tree and/or * a configuration file and downloaded to firmware. */ - adapter->dt_node = - of_find_node_by_name(NULL, "marvell_cfgdata"); - if (adapter->dt_node) { + if (priv->adapter->iface_type == MWIFIEX_SDIO && + adapter->dev->of_node) { + adapter->dt_node = adapter->dev->of_node; + if (of_property_read_u32(adapter->dt_node, + "marvell,wakeup-pin", + &data) == 0) { + pr_debug("Wakeup pin = 0x%x\n", data); + adapter->hs_cfg.gpio = data; + } + ret = mwifiex_dnld_dt_cfgdata(priv, adapter->dt_node, "marvell,caldata"); if (ret)