Commit c15f63bf authored by Juuso Oikarinen's avatar Juuso Oikarinen Committed by John W. Linville

wl1271: Update interrupt handling by removing an extra SPI read

Remove separate interrupt register reading from the interrupt handling
routine. This will slightly improve interrupt performance.
Signed-off-by: default avatarJuuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: default avatarLuciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: default avatarLuciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 284134eb
...@@ -76,20 +76,14 @@ static void wl1271_power_on(struct wl1271 *wl) ...@@ -76,20 +76,14 @@ static void wl1271_power_on(struct wl1271 *wl)
wl->set_power(true); wl->set_power(true);
} }
static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_status *status) static void wl1271_fw_status(struct wl1271 *wl,
struct wl1271_fw_status *status)
{ {
u32 total = 0; u32 total = 0;
int i; int i;
/* wl1271_spi_reg_read(wl, FW_STATUS_ADDR, status,
* FIXME: Reading the FW status directly from the registers seems to sizeof(*status), false);
* be the right thing to do, but it doesn't work. And in the
* reference driver, there is a workaround called
* USE_SDIO_24M_WORKAROUND, which reads the status from memory
* instead, so we do the same here.
*/
wl1271_spi_mem_read(wl, STATUS_MEM_ADDRESS, status, sizeof(*status));
wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
"drv_rx_counter = %d, tx_results_counter = %d)", "drv_rx_counter = %d, tx_results_counter = %d)",
...@@ -114,11 +108,10 @@ static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_status *status) ...@@ -114,11 +108,10 @@ static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_status *status)
wl->time_offset = jiffies_to_usecs(jiffies) - status->fw_localtime; wl->time_offset = jiffies_to_usecs(jiffies) - status->fw_localtime;
} }
#define WL1271_IRQ_MAX_LOOPS 10
static void wl1271_irq_work(struct work_struct *work) static void wl1271_irq_work(struct work_struct *work)
{ {
u32 intr, ctr = WL1271_IRQ_MAX_LOOPS;
int ret; int ret;
u32 intr;
struct wl1271 *wl = struct wl1271 *wl =
container_of(work, struct wl1271, irq_work); container_of(work, struct wl1271, irq_work);
...@@ -135,7 +128,8 @@ static void wl1271_irq_work(struct work_struct *work) ...@@ -135,7 +128,8 @@ static void wl1271_irq_work(struct work_struct *work)
wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); wl1271_fw_status(wl, wl->fw_status);
intr = wl->fw_status->intr;
if (!intr) { if (!intr) {
wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
goto out_sleep; goto out_sleep;
...@@ -143,43 +137,35 @@ static void wl1271_irq_work(struct work_struct *work) ...@@ -143,43 +137,35 @@ static void wl1271_irq_work(struct work_struct *work)
intr &= WL1271_INTR_MASK; intr &= WL1271_INTR_MASK;
do { if (intr & (WL1271_ACX_INTR_EVENT_A |
wl1271_fw_status(wl, wl->fw_status); WL1271_ACX_INTR_EVENT_B)) {
wl1271_debug(DEBUG_IRQ,
"WL1271_ACX_INTR_EVENT (0x%x)", intr);
if (intr & (WL1271_ACX_INTR_EVENT_A | if (intr & WL1271_ACX_INTR_EVENT_A)
WL1271_ACX_INTR_EVENT_B)) { wl1271_event_handle(wl, 0);
wl1271_debug(DEBUG_IRQ, else
"WL1271_ACX_INTR_EVENT (0x%x)", intr); wl1271_event_handle(wl, 1);
if (intr & WL1271_ACX_INTR_EVENT_A) }
wl1271_event_handle(wl, 0);
else
wl1271_event_handle(wl, 1);
}
if (intr & WL1271_ACX_INTR_INIT_COMPLETE) if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
wl1271_debug(DEBUG_IRQ, wl1271_debug(DEBUG_IRQ,
"WL1271_ACX_INTR_INIT_COMPLETE"); "WL1271_ACX_INTR_INIT_COMPLETE");
if (intr & WL1271_ACX_INTR_HW_AVAILABLE) if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
if (intr & WL1271_ACX_INTR_DATA) { if (intr & WL1271_ACX_INTR_DATA) {
u8 tx_res_cnt = wl->fw_status->tx_results_counter - u8 tx_res_cnt = wl->fw_status->tx_results_counter -
wl->tx_results_count; wl->tx_results_count;
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
/* check for tx results */ /* check for tx results */
if (tx_res_cnt) if (tx_res_cnt)
wl1271_tx_complete(wl, tx_res_cnt); wl1271_tx_complete(wl, tx_res_cnt);
wl1271_rx(wl, wl->fw_status); wl1271_rx(wl, wl->fw_status);
} }
intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
intr &= WL1271_INTR_MASK;
} while (intr && --ctr);
out_sleep: out_sleep:
wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#define REGISTERS_WORK_SIZE 0x0000b000 #define REGISTERS_WORK_SIZE 0x0000b000
#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC #define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
#define STATUS_MEM_ADDRESS 0x40400 #define FW_STATUS_ADDR (0x14FC0 + 0xA000)
/* ELP register commands */ /* ELP register commands */
#define ELPCTRL_WAKE_UP 0x1 #define ELPCTRL_WAKE_UP 0x1
......
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