aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/if_sdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/if_sdio.c')
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c127
1 files changed, 64 insertions, 63 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 7d1a3c6b6ce0..64dd345d30f5 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -35,6 +35,8 @@
35#include <linux/mmc/card.h> 35#include <linux/mmc/card.h>
36#include <linux/mmc/sdio_func.h> 36#include <linux/mmc/sdio_func.h>
37#include <linux/mmc/sdio_ids.h> 37#include <linux/mmc/sdio_ids.h>
38#include <linux/mmc/sdio.h>
39#include <linux/mmc/host.h>
38 40
39#include "host.h" 41#include "host.h"
40#include "decl.h" 42#include "decl.h"
@@ -313,12 +315,30 @@ out:
313 return ret; 315 return ret;
314} 316}
315 317
318static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition)
319{
320 u8 status;
321 unsigned long timeout;
322 int ret = 0;
323
324 timeout = jiffies + HZ;
325 while (1) {
326 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
327 if (ret)
328 return ret;
329 if ((status & condition) == condition)
330 break;
331 if (time_after(jiffies, timeout))
332 return -ETIMEDOUT;
333 mdelay(1);
334 }
335 return ret;
336}
337
316static int if_sdio_card_to_host(struct if_sdio_card *card) 338static int if_sdio_card_to_host(struct if_sdio_card *card)
317{ 339{
318 int ret; 340 int ret;
319 u8 status;
320 u16 size, type, chunk; 341 u16 size, type, chunk;
321 unsigned long timeout;
322 342
323 lbs_deb_enter(LBS_DEB_SDIO); 343 lbs_deb_enter(LBS_DEB_SDIO);
324 344
@@ -333,19 +353,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
333 goto out; 353 goto out;
334 } 354 }
335 355
336 timeout = jiffies + HZ; 356 ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
337 while (1) { 357 if (ret)
338 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 358 goto out;
339 if (ret)
340 goto out;
341 if (status & IF_SDIO_IO_RDY)
342 break;
343 if (time_after(jiffies, timeout)) {
344 ret = -ETIMEDOUT;
345 goto out;
346 }
347 mdelay(1);
348 }
349 359
350 /* 360 /*
351 * The transfer must be in one transaction or the firmware 361 * The transfer must be in one transaction or the firmware
@@ -412,8 +422,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
412{ 422{
413 struct if_sdio_card *card; 423 struct if_sdio_card *card;
414 struct if_sdio_packet *packet; 424 struct if_sdio_packet *packet;
415 unsigned long timeout;
416 u8 status;
417 int ret; 425 int ret;
418 unsigned long flags; 426 unsigned long flags;
419 427
@@ -433,25 +441,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
433 441
434 sdio_claim_host(card->func); 442 sdio_claim_host(card->func);
435 443
436 timeout = jiffies + HZ; 444 ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
437 while (1) { 445 if (ret == 0) {
438 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 446 ret = sdio_writesb(card->func, card->ioport,
439 if (ret) 447 packet->buffer, packet->nb);
440 goto release;
441 if (status & IF_SDIO_IO_RDY)
442 break;
443 if (time_after(jiffies, timeout)) {
444 ret = -ETIMEDOUT;
445 goto release;
446 }
447 mdelay(1);
448 } 448 }
449 449
450 ret = sdio_writesb(card->func, card->ioport,
451 packet->buffer, packet->nb);
452 if (ret) 450 if (ret)
453 goto release; 451 lbs_pr_err("error %d sending packet to firmware\n", ret);
454release: 452
455 sdio_release_host(card->func); 453 sdio_release_host(card->func);
456 454
457 kfree(packet); 455 kfree(packet);
@@ -464,10 +462,11 @@ release:
464/* Firmware */ 462/* Firmware */
465/********************************************************************/ 463/********************************************************************/
466 464
465#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
466
467static int if_sdio_prog_helper(struct if_sdio_card *card) 467static int if_sdio_prog_helper(struct if_sdio_card *card)
468{ 468{
469 int ret; 469 int ret;
470 u8 status;
471 const struct firmware *fw; 470 const struct firmware *fw;
472 unsigned long timeout; 471 unsigned long timeout;
473 u8 *chunk_buffer; 472 u8 *chunk_buffer;
@@ -499,20 +498,14 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
499 size = fw->size; 498 size = fw->size;
500 499
501 while (size) { 500 while (size) {
502 timeout = jiffies + HZ; 501 ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
503 while (1) { 502 if (ret)
504 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 503 goto release;
505 if (ret) 504
506 goto release; 505 /* On some platforms (like Davinci) the chip needs more time
507 if ((status & IF_SDIO_IO_RDY) && 506 * between helper blocks.
508 (status & IF_SDIO_DL_RDY)) 507 */
509 break; 508 mdelay(2);
510 if (time_after(jiffies, timeout)) {
511 ret = -ETIMEDOUT;
512 goto release;
513 }
514 mdelay(1);
515 }
516 509
517 chunk_size = min(size, (size_t)60); 510 chunk_size = min(size, (size_t)60);
518 511
@@ -582,7 +575,6 @@ out:
582static int if_sdio_prog_real(struct if_sdio_card *card) 575static int if_sdio_prog_real(struct if_sdio_card *card)
583{ 576{
584 int ret; 577 int ret;
585 u8 status;
586 const struct firmware *fw; 578 const struct firmware *fw;
587 unsigned long timeout; 579 unsigned long timeout;
588 u8 *chunk_buffer; 580 u8 *chunk_buffer;
@@ -614,20 +606,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
614 size = fw->size; 606 size = fw->size;
615 607
616 while (size) { 608 while (size) {
617 timeout = jiffies + HZ; 609 ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
618 while (1) { 610 if (ret)
619 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 611 goto release;
620 if (ret)
621 goto release;
622 if ((status & IF_SDIO_IO_RDY) &&
623 (status & IF_SDIO_DL_RDY))
624 break;
625 if (time_after(jiffies, timeout)) {
626 ret = -ETIMEDOUT;
627 goto release;
628 }
629 mdelay(1);
630 }
631 612
632 req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); 613 req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
633 if (ret) 614 if (ret)
@@ -943,6 +924,7 @@ static int if_sdio_probe(struct sdio_func *func,
943 int ret, i; 924 int ret, i;
944 unsigned int model; 925 unsigned int model;
945 struct if_sdio_packet *packet; 926 struct if_sdio_packet *packet;
927 struct mmc_host *host = func->card->host;
946 928
947 lbs_deb_enter(LBS_DEB_SDIO); 929 lbs_deb_enter(LBS_DEB_SDIO);
948 930
@@ -1023,6 +1005,25 @@ static int if_sdio_probe(struct sdio_func *func,
1023 if (ret) 1005 if (ret)
1024 goto disable; 1006 goto disable;
1025 1007
1008 /* For 1-bit transfers to the 8686 model, we need to enable the
1009 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
1010 * bit to allow access to non-vendor registers. */
1011 if ((card->model == IF_SDIO_MODEL_8686) &&
1012 (host->caps & MMC_CAP_SDIO_IRQ) &&
1013 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
1014 u8 reg;
1015
1016 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
1017 reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
1018 if (ret)
1019 goto release_int;
1020
1021 reg |= SDIO_BUS_ECSI;
1022 sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
1023 if (ret)
1024 goto release_int;
1025 }
1026
1026 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret); 1027 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
1027 if (ret) 1028 if (ret)
1028 goto release_int; 1029 goto release_int;