Commit 96021f09 authored by Dan Williams's avatar Dan Williams Committed by John W. Linville

libertas: consolidate SDIO firmware wait code

Consolidate a bunch of C&P code that waits for the firmware to be ready.
Signed-off-by: default avatarDan Williams <dcbw@redhat.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent edbe056a
...@@ -314,12 +314,28 @@ static int if_sdio_handle_event(struct if_sdio_card *card, ...@@ -314,12 +314,28 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
return ret; return ret;
} }
static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition)
{
u8 status;
unsigned long timeout;
int ret = 0;
timeout = jiffies + HZ;
while (1) {
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
if (ret || (status & condition))
break;
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
mdelay(1);
}
return ret;
}
static int if_sdio_card_to_host(struct if_sdio_card *card) static int if_sdio_card_to_host(struct if_sdio_card *card)
{ {
int ret; int ret;
u8 status;
u16 size, type, chunk; u16 size, type, chunk;
unsigned long timeout;
lbs_deb_enter(LBS_DEB_SDIO); lbs_deb_enter(LBS_DEB_SDIO);
...@@ -334,19 +350,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card) ...@@ -334,19 +350,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
goto out; goto out;
} }
timeout = jiffies + HZ; ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
while (1) { if (ret)
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); goto out;
if (ret)
goto out;
if (status & IF_SDIO_IO_RDY)
break;
if (time_after(jiffies, timeout)) {
ret = -ETIMEDOUT;
goto out;
}
mdelay(1);
}
/* /*
* The transfer must be in one transaction or the firmware * The transfer must be in one transaction or the firmware
...@@ -413,8 +419,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) ...@@ -413,8 +419,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
{ {
struct if_sdio_card *card; struct if_sdio_card *card;
struct if_sdio_packet *packet; struct if_sdio_packet *packet;
unsigned long timeout;
u8 status;
int ret; int ret;
unsigned long flags; unsigned long flags;
...@@ -434,25 +438,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) ...@@ -434,25 +438,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
sdio_claim_host(card->func); sdio_claim_host(card->func);
timeout = jiffies + HZ; ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
while (1) { if (ret == 0) {
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); ret = sdio_writesb(card->func, card->ioport,
if (ret) packet->buffer, packet->nb);
goto release;
if (status & IF_SDIO_IO_RDY)
break;
if (time_after(jiffies, timeout)) {
ret = -ETIMEDOUT;
goto release;
}
mdelay(1);
} }
ret = sdio_writesb(card->func, card->ioport,
packet->buffer, packet->nb);
if (ret) if (ret)
goto release; lbs_pr_err("error %d sending packet to firmware\n", ret);
release:
sdio_release_host(card->func); sdio_release_host(card->func);
kfree(packet); kfree(packet);
...@@ -465,10 +459,11 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) ...@@ -465,10 +459,11 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
/* Firmware */ /* Firmware */
/********************************************************************/ /********************************************************************/
#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
static int if_sdio_prog_helper(struct if_sdio_card *card) static int if_sdio_prog_helper(struct if_sdio_card *card)
{ {
int ret; int ret;
u8 status;
const struct firmware *fw; const struct firmware *fw;
unsigned long timeout; unsigned long timeout;
u8 *chunk_buffer; u8 *chunk_buffer;
...@@ -500,20 +495,9 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) ...@@ -500,20 +495,9 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
size = fw->size; size = fw->size;
while (size) { while (size) {
timeout = jiffies + HZ; ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
while (1) { if (ret)
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); goto release;
if (ret)
goto release;
if ((status & IF_SDIO_IO_RDY) &&
(status & IF_SDIO_DL_RDY))
break;
if (time_after(jiffies, timeout)) {
ret = -ETIMEDOUT;
goto release;
}
mdelay(1);
}
chunk_size = min(size, (size_t)60); chunk_size = min(size, (size_t)60);
...@@ -583,7 +567,6 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) ...@@ -583,7 +567,6 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
static int if_sdio_prog_real(struct if_sdio_card *card) static int if_sdio_prog_real(struct if_sdio_card *card)
{ {
int ret; int ret;
u8 status;
const struct firmware *fw; const struct firmware *fw;
unsigned long timeout; unsigned long timeout;
u8 *chunk_buffer; u8 *chunk_buffer;
...@@ -615,20 +598,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card) ...@@ -615,20 +598,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
size = fw->size; size = fw->size;
while (size) { while (size) {
timeout = jiffies + HZ; ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
while (1) { if (ret)
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); goto release;
if (ret)
goto release;
if ((status & IF_SDIO_IO_RDY) &&
(status & IF_SDIO_DL_RDY))
break;
if (time_after(jiffies, timeout)) {
ret = -ETIMEDOUT;
goto release;
}
mdelay(1);
}
req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
if (ret) if (ret)
......
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