Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 291471
b: refs/heads/master
c: d1f4159
h: refs/heads/master
i:
  291469: 770a73b
  291467: 82fc4de
  291463: 4ce28fe
  291455: fe49a59
v: v3
  • Loading branch information
Raja Mani authored and Kalle Valo committed Mar 1, 2012
1 parent e57a9e1 commit 47efa0b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: af840ba7e2886ee69e252e752ebd0cb34e78f6f4
refs/heads/master: d1f4159723450252b643bcddff064153f32918bc
34 changes: 26 additions & 8 deletions trunk/drivers/net/wireless/ath/ath6kl/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ struct ath6kl_sdio {
/* scatter request list head */
struct list_head scat_req;

/* Avoids disabling irq while the interrupts being handled */
struct mutex mtx_irq;
atomic_t irq_handling;
wait_queue_head_t irq_wq;

spinlock_t scat_lock;
bool scatter_enabled;
Expand Down Expand Up @@ -463,7 +463,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");

ar_sdio = sdio_get_drvdata(func);
mutex_lock(&ar_sdio->mtx_irq);
atomic_set(&ar_sdio->irq_handling, 1);
/*
* Release the host during interrups so we can pick it back up when
* we process commands.
Expand All @@ -472,7 +472,10 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)

status = ath6kl_hif_intr_bh_handler(ar_sdio->ar);
sdio_claim_host(ar_sdio->func);
mutex_unlock(&ar_sdio->mtx_irq);

atomic_set(&ar_sdio->irq_handling, 0);
wake_up(&ar_sdio->irq_wq);

WARN_ON(status && status != -ECANCELED);
}

Expand Down Expand Up @@ -573,21 +576,35 @@ static void ath6kl_sdio_irq_enable(struct ath6kl *ar)
sdio_release_host(ar_sdio->func);
}

static bool ath6kl_sdio_is_on_irq(struct ath6kl *ar)
{
struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);

return !atomic_read(&ar_sdio->irq_handling);
}

static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
{
struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
int ret;

sdio_claim_host(ar_sdio->func);

mutex_lock(&ar_sdio->mtx_irq);
if (atomic_read(&ar_sdio->irq_handling)) {
sdio_release_host(ar_sdio->func);

ret = wait_event_interruptible(ar_sdio->irq_wq,
ath6kl_sdio_is_on_irq(ar));
if (ret)
return;

sdio_claim_host(ar_sdio->func);
}

ret = sdio_release_irq(ar_sdio->func);
if (ret)
ath6kl_err("Failed to release sdio irq: %d\n", ret);

mutex_unlock(&ar_sdio->mtx_irq);

sdio_release_host(ar_sdio->func);
}

Expand Down Expand Up @@ -1288,14 +1305,15 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
spin_lock_init(&ar_sdio->scat_lock);
spin_lock_init(&ar_sdio->wr_async_lock);
mutex_init(&ar_sdio->dma_buffer_mutex);
mutex_init(&ar_sdio->mtx_irq);

INIT_LIST_HEAD(&ar_sdio->scat_req);
INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
INIT_LIST_HEAD(&ar_sdio->wr_asyncq);

INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work);

init_waitqueue_head(&ar_sdio->irq_wq);

for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);

Expand Down

0 comments on commit 47efa0b

Please sign in to comment.