mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-26 04:16:39 +00:00
wilc1000: configure registers to handle chip wakeup sequence
Use the correct sequence to configure clockless registers for chip wake-up. The following sequence is expected from WILC chip for wakeup: - set wakeup bit in wakeup_reg register - after setting the wakeup bit, read back the clock status bit for wakeup complete. For SDIO/SPI modules, the wakeup sequence is the same except uses different register values so refactored the code to use common function for both SDIO/SPI bus. Signed-off-by: Ajay Singh <ajay.kathat@microchip.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20210916164902.74629-5-ajay.kathat@microchip.com
This commit is contained in:
parent
0ec5408cd4
commit
5bb9de8bcb
5 changed files with 53 additions and 55 deletions
|
@ -1726,7 +1726,6 @@ int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
|
|||
*wilc = wl;
|
||||
wl->io_type = io_type;
|
||||
wl->hif_func = ops;
|
||||
wl->chip_ps_state = WILC_CHIP_WAKEDUP;
|
||||
|
||||
for (i = 0; i < NQUEUES; i++)
|
||||
INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
|
||||
|
|
|
@ -265,7 +265,6 @@ struct wilc {
|
|||
bool suspend_event;
|
||||
|
||||
struct workqueue_struct *hif_workqueue;
|
||||
enum chip_ps_states chip_ps_state;
|
||||
struct wilc_cfg cfg;
|
||||
void *bus_data;
|
||||
struct net_device *monitor_dev;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "cfg80211.h"
|
||||
#include "wlan_cfg.h"
|
||||
|
||||
#define WAKE_UP_TRIAL_RETRY 10000
|
||||
|
||||
static inline bool is_wilc1000(u32 id)
|
||||
{
|
||||
return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
|
||||
|
@ -611,60 +613,62 @@ EXPORT_SYMBOL_GPL(chip_allow_sleep);
|
|||
|
||||
void chip_wakeup(struct wilc *wilc)
|
||||
{
|
||||
u32 reg, clk_status_reg;
|
||||
const struct wilc_hif_func *h = wilc->hif_func;
|
||||
u32 ret = 0;
|
||||
u32 clk_status_val = 0, trials = 0;
|
||||
u32 wakeup_reg, wakeup_bit;
|
||||
u32 clk_status_reg, clk_status_bit;
|
||||
u32 to_host_from_fw_reg, to_host_from_fw_bit;
|
||||
u32 from_host_to_fw_reg, from_host_to_fw_bit;
|
||||
const struct wilc_hif_func *hif_func = wilc->hif_func;
|
||||
|
||||
if (wilc->io_type == WILC_HIF_SPI) {
|
||||
do {
|
||||
h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, ®);
|
||||
h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
|
||||
reg | WILC_SPI_WAKEUP_BIT);
|
||||
h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
|
||||
reg & ~WILC_SPI_WAKEUP_BIT);
|
||||
|
||||
do {
|
||||
usleep_range(2000, 2500);
|
||||
wilc_get_chipid(wilc, true);
|
||||
} while (wilc_get_chipid(wilc, true) == 0);
|
||||
} while (wilc_get_chipid(wilc, true) == 0);
|
||||
} else if (wilc->io_type == WILC_HIF_SDIO) {
|
||||
h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG,
|
||||
WILC_SDIO_HOST_TO_FW_BIT);
|
||||
usleep_range(200, 400);
|
||||
h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®);
|
||||
do {
|
||||
h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
|
||||
reg | WILC_SDIO_WAKEUP_BIT);
|
||||
h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
|
||||
&clk_status_reg);
|
||||
|
||||
while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
|
||||
usleep_range(2000, 2500);
|
||||
|
||||
h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
|
||||
&clk_status_reg);
|
||||
}
|
||||
if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
|
||||
h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
|
||||
reg & ~WILC_SDIO_WAKEUP_BIT);
|
||||
}
|
||||
} while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT));
|
||||
if (wilc->io_type == WILC_HIF_SDIO) {
|
||||
wakeup_reg = WILC_SDIO_WAKEUP_REG;
|
||||
wakeup_bit = WILC_SDIO_WAKEUP_BIT;
|
||||
clk_status_reg = WILC_SDIO_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC_SDIO_CLK_STATUS_BIT;
|
||||
from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
|
||||
from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
|
||||
to_host_from_fw_reg = WILC_SDIO_FW_TO_HOST_REG;
|
||||
to_host_from_fw_bit = WILC_SDIO_FW_TO_HOST_BIT;
|
||||
} else {
|
||||
wakeup_reg = WILC_SPI_WAKEUP_REG;
|
||||
wakeup_bit = WILC_SPI_WAKEUP_BIT;
|
||||
clk_status_reg = WILC_SPI_CLK_STATUS_REG;
|
||||
clk_status_bit = WILC_SPI_CLK_STATUS_BIT;
|
||||
from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
|
||||
from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
|
||||
to_host_from_fw_reg = WILC_SPI_FW_TO_HOST_REG;
|
||||
to_host_from_fw_bit = WILC_SPI_FW_TO_HOST_BIT;
|
||||
}
|
||||
|
||||
if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) {
|
||||
if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) {
|
||||
u32 val32;
|
||||
/* indicate host wakeup */
|
||||
ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg,
|
||||
from_host_to_fw_bit);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32);
|
||||
val32 |= BIT(6);
|
||||
h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32);
|
||||
/* Set wake-up bit */
|
||||
ret = hif_func->hif_write_reg(wilc, wakeup_reg,
|
||||
wakeup_bit);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32);
|
||||
val32 |= BIT(6);
|
||||
h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32);
|
||||
while (trials < WAKE_UP_TRIAL_RETRY) {
|
||||
ret = hif_func->hif_read_reg(wilc, clk_status_reg,
|
||||
&clk_status_val);
|
||||
if (ret) {
|
||||
pr_err("Bus error %d %x\n", ret, clk_status_val);
|
||||
return;
|
||||
}
|
||||
if (clk_status_val & clk_status_bit)
|
||||
break;
|
||||
|
||||
trials++;
|
||||
}
|
||||
if (trials >= WAKE_UP_TRIAL_RETRY) {
|
||||
pr_err("Failed to wake-up the chip\n");
|
||||
return;
|
||||
}
|
||||
wilc->chip_ps_state = WILC_CHIP_WAKEDUP;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(chip_wakeup);
|
||||
|
||||
|
|
|
@ -97,6 +97,8 @@
|
|||
#define WILC_SPI_WAKEUP_REG 0x1
|
||||
#define WILC_SPI_WAKEUP_BIT BIT(1)
|
||||
|
||||
#define WILC_SPI_CLK_STATUS_REG 0x0f
|
||||
#define WILC_SPI_CLK_STATUS_BIT BIT(2)
|
||||
#define WILC_SPI_HOST_TO_FW_REG 0x0b
|
||||
#define WILC_SPI_HOST_TO_FW_BIT BIT(0)
|
||||
|
||||
|
|
|
@ -48,12 +48,6 @@ enum {
|
|||
WILC_FW_MAX_PSPOLL_PS = 4
|
||||
};
|
||||
|
||||
enum chip_ps_states {
|
||||
WILC_CHIP_WAKEDUP = 0,
|
||||
WILC_CHIP_SLEEPING_AUTO = 1,
|
||||
WILC_CHIP_SLEEPING_MANUAL = 2
|
||||
};
|
||||
|
||||
enum bus_acquire {
|
||||
WILC_BUS_ACQUIRE_ONLY = 0,
|
||||
WILC_BUS_ACQUIRE_AND_WAKEUP = 1,
|
||||
|
|
Loading…
Reference in a new issue