Re: [RFC/PATCH v2 2/3] mmc: sdio: add asynchronous interrupt support on device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 21 September 2012 05:07, Kevin Liu <keyuan.liu@xxxxxxxxx> wrote:
> From: Kevin Liu <kliu5@xxxxxxxxxxx>
>
> Enable asynchronous interrupt on device by default if both host
> and device support it and clock gating is allowed.
>
> If asynchronous interrupt is enabled, then no need to switch bus
> width to 1bit before suspend.
>
> Signed-off-by: Kevin Liu <kliu5@xxxxxxxxxxx>
> ---
>  drivers/mmc/core/sdio.c  |   22 +++++++++++++++++++---
>  include/linux/mmc/card.h |    3 +++
>  include/linux/mmc/host.h |    1 +
>  include/linux/mmc/sdio.h |    5 +++++
>  4 files changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
> index 909c835..b3a3ca8 100644
> --- a/drivers/mmc/core/sdio.c
> +++ b/drivers/mmc/core/sdio.c
> @@ -199,6 +199,21 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
>                 }
>         }
>
> +       if (cccr_vsn >= SDIO_CCCR_REV_3_00) {
> +               if (!(card->quirks & MMC_QUIRK_BROKEN_CLK_GATING) &&
> +                       (card->host->caps2 & MMC_CAP2_ASYNC_INT)) {
> +                       if (mmc_io_rw_direct(card, 0, 0,
> +                               SDIO_CCCR_INT_EXT, 0, &data))
> +                               goto out;
> +                       if (data & SDIO_INT_SAI) {
> +                               data |= SDIO_INT_EAI;
> +                               if (mmc_io_rw_direct(card, 1, 0,
> +                                       SDIO_CCCR_INT_EXT, data, NULL))
> +                                       goto out;
> +                               mmc_card_set_async_int(card);
> +                       }
> +               }
> +       }
>  out:
>         return ret;
>  }
> @@ -290,7 +305,6 @@ static int sdio_disable_wide(struct mmc_card *card)
>         return 0;
>  }
>
> -
>  static int sdio_enable_4bit_bus(struct mmc_card *card)
>  {
>         int err;
> @@ -917,7 +931,8 @@ static int mmc_sdio_suspend(struct mmc_host *host)
>                 }
>         }
>
> -       if (!err && mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
> +       if (!err && mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)
> +               && !mmc_card_async_int(host->card)) {
>                 mmc_claim_host(host);
>                 sdio_disable_wide(host->card);
>                 mmc_release_host(host);
> @@ -940,7 +955,8 @@ static int mmc_sdio_resume(struct mmc_host *host)
>         if (mmc_card_is_removable(host) || !mmc_card_keep_power(host))
>                 err = mmc_sdio_init_card(host, host->ocr, host->card,
>                                         mmc_card_keep_power(host));
> -       else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
> +       else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)
> +               && !mmc_card_async_int(host->card)) {
>                 /* We may have switched to 1-bit mode during suspend */
>                 err = sdio_enable_4bit_bus(host->card);
>                 if (err > 0) {
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 78cc3be..4f0f554 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -231,6 +231,7 @@ struct mmc_card {
>  #define MMC_STATE_HIGHSPEED_200        (1<<8)          /* card is in HS200 mode */
>  #define MMC_STATE_SLEEP                (1<<9)          /* card is in sleep state */
>  #define MMC_STATE_DOING_BKOPS  (1<<10)         /* card is doing BKOPS */
> +#define MMC_STATE_ASYNC_INT    (1<<11)         /* card is async int enabled */
>         unsigned int            quirks;         /* card quirks */
>  #define MMC_QUIRK_LENIENT_FN0  (1<<0)          /* allow SDIO FN0 writes outside of the VS CCCR range */
>  #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)   /* use func->cur_blksize */
> @@ -399,6 +400,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>  #define mmc_card_removed(c)    ((c) && ((c)->state & MMC_CARD_REMOVED))
>  #define mmc_card_is_sleep(c)   ((c)->state & MMC_STATE_SLEEP)
>  #define mmc_card_doing_bkops(c)        ((c)->state & MMC_STATE_DOING_BKOPS)
> +#define mmc_card_async_int(c)  ((c)->state & MMC_STATE_ASYNC_INT)
>
>  #define mmc_card_set_present(c)        ((c)->state |= MMC_STATE_PRESENT)
>  #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
> @@ -412,6 +414,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
>  #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
>  #define mmc_card_set_sleep(c)  ((c)->state |= MMC_STATE_SLEEP)
>  #define mmc_card_set_doing_bkops(c)    ((c)->state |= MMC_STATE_DOING_BKOPS)
> +#define mmc_card_set_async_int(c)      ((c)->state |= MMC_STATE_ASYNC_INT)
>
>  #define mmc_card_clr_doing_bkops(c)    ((c)->state &= ~MMC_STATE_DOING_BKOPS)
>  #define mmc_card_clr_sleep(c)  ((c)->state &= ~MMC_STATE_SLEEP)
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index d5d9bd4..78fd877 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -257,6 +257,7 @@ struct mmc_host {
>  #define MMC_CAP2_HC_ERASE_SZ   (1 << 9)        /* High-capacity erase size */
>  #define MMC_CAP2_CD_ACTIVE_HIGH        (1 << 10)       /* Card-detect signal active high */
>  #define MMC_CAP2_RO_ACTIVE_HIGH        (1 << 11)       /* Write-protect signal active high */
> +#define MMC_CAP2_ASYNC_INT     (1 << 12)       /* Asynchronous interrupt support */
>
>         mmc_pm_flag_t           pm_caps;        /* supported pm features */
>         unsigned int        power_notify_type;
> diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
> index 47e579d..abbb6c8 100644
> --- a/include/linux/mmc/sdio.h
> +++ b/include/linux/mmc/sdio.h
> @@ -161,6 +161,11 @@
>  #define  SDIO_DTSx_SET_TYPE_A  (1 << SDIO_DRIVE_DTSx_SHIFT)
>  #define  SDIO_DTSx_SET_TYPE_C  (2 << SDIO_DRIVE_DTSx_SHIFT)
>  #define  SDIO_DTSx_SET_TYPE_D  (3 << SDIO_DRIVE_DTSx_SHIFT)
> +
> +#define SDIO_CCCR_INT_EXT      0x16
> +#define SDIO_INT_SAI           0x01
> +#define SDIO_INT_EAI           0x02
> +
>  /*
>   * Function Basic Registers (FBR)
>   */
> --
> 1.7.0.4
>

Reviewed-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx>

Kind regards
Ulf Hansson
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux