140-mmc-sdio-reliability-fix.patch 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. From 8a7013f47196abed7e6a40e93d1de1639cd46228 Mon Sep 17 00:00:00 2001
  2. From: Hans de Goede <hdegoede@redhat.com>
  3. Date: Fri, 10 Jul 2015 17:03:03 +0200
  4. Subject: [PATCH] mmc: sunxi: Don't start commands while the card is busy
  5. Some sdio wifi modules have not been working reliable with the sunxi-mmc
  6. host code. This turns out to be caused by it starting new commands while
  7. the card signals that it is still busy processing a previous command.
  8. This commit fixes this, thereby fixing the wifi reliability issues on
  9. the Cubietruck and other sunxi boards using sdio wifi.
  10. Reported-by: Eugene K <sigintmailru@gmail.com>
  11. Suggested-by: Eugene K <sigintmailru@gmail.com>
  12. Cc: Eugene K <sigintmailru@gmail.com>
  13. Cc: Arend van Spriel <arend@broadcom.com>
  14. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  15. ---
  16. Changes in v2:
  17. -Properly accredit Eugene K for coming up with the fix for this
  18. ---
  19. drivers/mmc/host/sunxi-mmc.c | 32 ++++++++++++++++++++++++++++++++
  20. 1 file changed, 32 insertions(+)
  21. --- a/drivers/mmc/host/sunxi-mmc.c
  22. +++ b/drivers/mmc/host/sunxi-mmc.c
  23. @@ -289,6 +289,24 @@ static int sunxi_mmc_init_host(struct mm
  24. return 0;
  25. }
  26. +/* Wait for card to report ready before starting a new cmd */
  27. +static int sunxi_mmc_wait_card_ready(struct sunxi_mmc_host *host)
  28. +{
  29. + unsigned long expire = jiffies + msecs_to_jiffies(500);
  30. + u32 rval;
  31. +
  32. + do {
  33. + rval = mmc_readl(host, REG_STAS);
  34. + } while (time_before(jiffies, expire) && (rval & SDXC_CARD_DATA_BUSY));
  35. +
  36. + if (rval & SDXC_CARD_DATA_BUSY) {
  37. + dev_err(mmc_dev(host->mmc), "Error R1 ready timeout\n");
  38. + return -EIO;
  39. + }
  40. +
  41. + return 0;
  42. +}
  43. +
  44. static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host,
  45. struct mmc_data *data)
  46. {
  47. @@ -383,6 +401,8 @@ static void sunxi_mmc_send_manual_stop(s
  48. u32 arg, cmd_val, ri;
  49. unsigned long expire = jiffies + msecs_to_jiffies(1000);
  50. + sunxi_mmc_wait_card_ready(host);
  51. +
  52. cmd_val = SDXC_START | SDXC_RESP_EXPIRE |
  53. SDXC_STOP_ABORT_CMD | SDXC_CHECK_RESPONSE_CRC;
  54. @@ -597,6 +617,11 @@ static int sunxi_mmc_oclk_onoff(struct s
  55. {
  56. unsigned long expire = jiffies + msecs_to_jiffies(250);
  57. u32 rval;
  58. + int ret;
  59. +
  60. + ret = sunxi_mmc_wait_card_ready(host);
  61. + if (ret)
  62. + return ret;
  63. rval = mmc_readl(host, REG_CLKCR);
  64. rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON);
  65. @@ -784,6 +809,13 @@ static void sunxi_mmc_request(struct mmc
  66. mmc_request_done(mmc, mrq);
  67. return;
  68. }
  69. +
  70. + ret = sunxi_mmc_wait_card_ready(host);
  71. + if (ret) {
  72. + mrq->cmd->error = ret;
  73. + mmc_request_done(mmc, mrq);
  74. + return;
  75. + }
  76. if (data) {
  77. ret = sunxi_mmc_map_dma(host, data);