Commit bd763482 authored by Eyal Reizer's avatar Eyal Reizer Committed by Kalle Valo

wl18xx: wlan_irq: support platform dependent interrupt types

* 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: default avatarEyal Reizer <eyalr@ti.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent ad480137
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/irq.h>
#include "../wlcore/wlcore.h" #include "../wlcore/wlcore.h"
#include "../wlcore/debug.h" #include "../wlcore/debug.h"
...@@ -578,7 +579,7 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { ...@@ -578,7 +579,7 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
[PART_TOP_PRCM_ELP_SOC] = { [PART_TOP_PRCM_ELP_SOC] = {
.mem = { .start = 0x00A02000, .size = 0x00010000 }, .mem = { .start = 0x00A00000, .size = 0x00012000 },
.reg = { .start = 0x00807000, .size = 0x00005000 }, .reg = { .start = 0x00807000, .size = 0x00005000 },
.mem2 = { .start = 0x00800000, .size = 0x0000B000 }, .mem2 = { .start = 0x00800000, .size = 0x0000B000 },
.mem3 = { .start = 0x00000000, .size = 0x00000000 }, .mem3 = { .start = 0x00000000, .size = 0x00000000 },
...@@ -862,6 +863,7 @@ static int wl18xx_pre_upload(struct wl1271 *wl) ...@@ -862,6 +863,7 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
{ {
u32 tmp; u32 tmp;
int ret; int ret;
u16 irq_invert;
BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) > BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) >
WL18XX_PHY_INIT_MEM_SIZE); WL18XX_PHY_INIT_MEM_SIZE);
...@@ -911,6 +913,28 @@ static int wl18xx_pre_upload(struct wl1271 *wl) ...@@ -911,6 +913,28 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
/* re-enable FDSP clock */ /* re-enable FDSP clock */
ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
MEM_FDSP_CLK_120_ENABLE); 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: out:
return ret; return ret;
......
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
#define WL18XX_WELP_ARM_COMMAND (WL18XX_REGISTERS_BASE + 0x7100) #define WL18XX_WELP_ARM_COMMAND (WL18XX_REGISTERS_BASE + 0x7100)
#define WL18XX_ENABLE (WL18XX_REGISTERS_BASE + 0x01543C) #define WL18XX_ENABLE (WL18XX_REGISTERS_BASE + 0x01543C)
#define TOP_FN0_CCCR_REG_32 (WL18XX_TOP_OCP_BASE + 0x64)
/* PRCM registers */ /* PRCM registers */
#define PLATFORM_DETECTION 0xA0E3E0 #define PLATFORM_DETECTION 0xA0E3E0
......
...@@ -5966,10 +5966,6 @@ static int wl12xx_get_hw_info(struct wl1271 *wl) ...@@ -5966,10 +5966,6 @@ static int wl12xx_get_hw_info(struct wl1271 *wl)
{ {
int ret; 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); ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id);
if (ret < 0) if (ret < 0)
goto out; goto out;
...@@ -5985,7 +5981,6 @@ static int wl12xx_get_hw_info(struct wl1271 *wl) ...@@ -5985,7 +5981,6 @@ static int wl12xx_get_hw_info(struct wl1271 *wl)
ret = wl->ops->get_mac(wl); ret = wl->ops->get_mac(wl);
out: out:
wl1271_power_off(wl);
return ret; return ret;
} }
...@@ -6432,10 +6427,22 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context) ...@@ -6432,10 +6427,22 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
else else
wl->irq_flags |= IRQF_ONESHOT; 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, ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq,
wl->irq_flags, pdev->name, wl); wl->irq_flags, pdev->name, wl);
if (ret < 0) { if (ret < 0) {
wl1271_error("request_irq() failed: %d", ret); wl1271_error("interrupt configuration failed");
wl1271_power_off(wl);
goto out_free_nvs; goto out_free_nvs;
} }
...@@ -6449,12 +6456,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context) ...@@ -6449,12 +6456,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
} }
#endif #endif
disable_irq(wl->irq); disable_irq(wl->irq);
wl1271_power_off(wl);
ret = wl12xx_get_hw_info(wl);
if (ret < 0) {
wl1271_error("couldn't get hw info");
goto out_irq;
}
ret = wl->ops->identify_chip(wl); ret = wl->ops->identify_chip(wl);
if (ret < 0) if (ret < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment