From patchwork Wed Apr 29 14:50:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eyal Reizer X-Patchwork-Id: 6296641 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4522C9F32B for ; Wed, 29 Apr 2015 14:50:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4F2B22012D for ; Wed, 29 Apr 2015 14:50:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C82DB2017D for ; Wed, 29 Apr 2015 14:50:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1423016AbbD2OuQ (ORCPT ); Wed, 29 Apr 2015 10:50:16 -0400 Received: from mail-wi0-f170.google.com ([209.85.212.170]:37580 "EHLO mail-wi0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1423070AbbD2OuP (ORCPT ); Wed, 29 Apr 2015 10:50:15 -0400 Received: by widdi4 with SMTP id di4so68895223wid.0 for ; Wed, 29 Apr 2015 07:50:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=i3wjfN95npJlM0JACpNraRKt6avwbUa4bUdv/EClwdg=; b=y920Xjgs17B6TJ1bV9tWh/NtTQFRnnf5TbGkUkBRmahUFQ7bRQ5tMJ3gYREUQje6HJ kUeKYy3Yo22AurNKG1/kLx726q78KIDYm8AgqViy0Ck1M1kYDrIcU/ltbGWWfXrXtBZL DnVNw5MkaD8gdsq0ebdcr/KhVWg7tbiy3vA0ESJ88OCmgyDRGUARS5hardYOAXUFDnT6 t7NnG868ueeNGltoXAWcMBRqrQOg3D0nF6ZhRf4hAc/6H9f5aVeaR81dtrskRGeHPKnf RsOfROOga8kiOig/yEyGJ95wYfQ2nE6vjCg9jFcn/pL7gTllHRo51w5PcLVuNqwHu9lF yGIg== X-Received: by 10.180.83.130 with SMTP id q2mr6386991wiy.89.1430319013023; Wed, 29 Apr 2015 07:50:13 -0700 (PDT) Received: from localhost.localdomain ([5.102.254.113]) by mx.google.com with ESMTPSA id kc4sm39296824wjc.2.2015.04.29.07.50.11 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 Apr 2015 07:50:12 -0700 (PDT) From: Eyal Reizer X-Google-Original-From: Eyal Reizer To: linux-wireless@vger.kernel.org Cc: Eyal Reizer Subject: [PATCH] wl18xx: wlan_irq: support platform dependent interrupt types Date: Wed, 29 Apr 2015 17:50:03 +0300 Message-Id: <1430319003-13123-1-git-send-email-eyalr@ti.com> X-Mailer: git-send-email 1.7.9.5 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_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 * Interrupt request need to happen when the wilink chip is powered on and driving the wlan_irq line. This avoids spurious interrupt issues that are a result of different external pulls configuration on different platforms * Allow working with wl18xx level-low and falling edge irqs by configuring wl18xx to invert the device interrupt Signed-off-by: Eyal Reizer --- drivers/net/wireless/ti/wl18xx/main.c | 26 +++++++++++++++++++++++++- drivers/net/wireless/ti/wl18xx/reg.h | 1 + drivers/net/wireless/ti/wlcore/main.c | 26 ++++++++++++++------------ 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 11bd64a..ca2200b 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "../wlcore/wlcore.h" #include "../wlcore/debug.h" @@ -580,7 +581,7 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { [PART_TOP_PRCM_ELP_SOC] = { - .mem = { .start = 0x00A02000, .size = 0x00010000 }, + .mem = { .start = 0x00A00000, .size = 0x00012000 }, .reg = { .start = 0x00807000, .size = 0x00005000 }, .mem2 = { .start = 0x00800000, .size = 0x0000B000 }, .mem3 = { .start = 0x00000000, .size = 0x00000000 }, @@ -864,6 +865,7 @@ static int wl18xx_pre_upload(struct wl1271 *wl) { u32 tmp; int ret; + u16 irq_invert; BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) > WL18XX_PHY_INIT_MEM_SIZE); @@ -913,6 +915,28 @@ static int wl18xx_pre_upload(struct wl1271 *wl) /* re-enable FDSP clock */ ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, MEM_FDSP_CLK_120_ENABLE); + if (ret < 0) + goto out; + + ret = irq_get_trigger_type(wl->irq); + if ((ret == IRQ_TYPE_LEVEL_LOW) || (ret == IRQ_TYPE_EDGE_FALLING)) { + wl1271_info("using inverted interrupt logic: %d", ret); + ret = wlcore_set_partition(wl, + &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + if (ret < 0) + goto out; + + ret = wl18xx_top_reg_read(wl, TOP_FN0_CCCR_REG_32, &irq_invert); + if (ret < 0) + goto out; + + irq_invert |= BIT(1); + ret = wl18xx_top_reg_write(wl, TOP_FN0_CCCR_REG_32, irq_invert); + if (ret < 0) + goto out; + + ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); + } out: return ret; diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index a433a75..bac2364 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -109,6 +109,7 @@ #define WL18XX_WELP_ARM_COMMAND (WL18XX_REGISTERS_BASE + 0x7100) #define WL18XX_ENABLE (WL18XX_REGISTERS_BASE + 0x01543C) +#define TOP_FN0_CCCR_REG_32 (WL18XX_TOP_OCP_BASE + 0x64) /* PRCM registers */ #define PLATFORM_DETECTION 0xA0E3E0 diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index f0286a9..f4d6301 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5991,10 +5991,6 @@ static int wl12xx_get_hw_info(struct wl1271 *wl) { int ret; - ret = wl12xx_set_power_on(wl); - if (ret < 0) - return ret; - ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id); if (ret < 0) goto out; @@ -6010,7 +6006,6 @@ static int wl12xx_get_hw_info(struct wl1271 *wl) ret = wl->ops->get_mac(wl); out: - wl1271_power_off(wl); return ret; } @@ -6473,10 +6468,22 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context) else wl->irq_flags |= IRQF_ONESHOT; + ret = wl12xx_set_power_on(wl); + if (ret < 0) + goto out_free_nvs; + + ret = wl12xx_get_hw_info(wl); + if (ret < 0) { + wl1271_error("couldn't get hw info"); + wl1271_power_off(wl); + goto out_free_nvs; + } + ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq, wl->irq_flags, pdev->name, wl); if (ret < 0) { - wl1271_error("request_irq() failed: %d", ret); + wl1271_error("interrupt configuration failed"); + wl1271_power_off(wl); goto out_free_nvs; } @@ -6490,12 +6497,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context) } #endif disable_irq(wl->irq); - - ret = wl12xx_get_hw_info(wl); - if (ret < 0) { - wl1271_error("couldn't get hw info"); - goto out_irq; - } + wl1271_power_off(wl); ret = wl->ops->identify_chip(wl); if (ret < 0)