Re: [PATCH v2 1/1] mmc: Support of SDIO irq for dw_mmc

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

 



Hi,

On 23 August 2011 14:20, Shashidhar Hiremath
<shashidharh@xxxxxxxxxxxxxxx> wrote:
> The Patch adds the support for SDIO interrupts for all slots.
> It includes enabling of SDIO interrupts through dw_mci_enable_sdio_irq
> and the handling of the slot specific interrupts in the Interrupt Service
> Routine.
>
> Signed-off-by: Shashidhar Hiremath <shashidharh@xxxxxxxxxxxxxxx>
> ---
> v2:
> * As per Suggestions by James Hogan
> -fixed code that was disabling other interrupts.
> -removed [int_mask &= 0xFFFF0000; and int_mask &= 0xFFFF0000;] as it
> was unnecessary
> -modified (slot->id + 16) with appropriate Macro SDMMC_INT_SDIO(i)
>  drivers/mmc/host/dw_mmc.c |   35 +++++++++++++++++++++++++++++++----
>  drivers/mmc/host/dw_mmc.h |    2 +-
>  2 files changed, 32 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 66dcddb..b06f8f1 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -746,11 +746,29 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
>        return present;
>  }
>
> +static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
> +{
> +       struct dw_mci_slot *slot = mmc_priv(mmc);
> +       struct dw_mci *host = slot->host;
> +       u32 int_mask;
> +
> +       /* Enable/disable Slot Specific SDIO interrupt */
> +       int_mask = mci_readl(host, INTMASK);
> +       if (enb) {
> +               mci_writel(host, INTMASK,
> +                          (int_mask | (1 << SDMMC_INT_SDIO(slot->id))));
> +       } else {
> +               mci_writel(host, INTMASK,
> +                          (int_mask & ~(1 << SDMMC_INT_SDIO(slot->id))));
> +       }
> +}
> +
>  static const struct mmc_host_ops dw_mci_ops = {
> -       .request        = dw_mci_request,
> -       .set_ios        = dw_mci_set_ios,
> -       .get_ro         = dw_mci_get_ro,
> -       .get_cd         = dw_mci_get_cd,
> +       .request                = dw_mci_request,
> +       .set_ios                = dw_mci_set_ios,
> +       .get_ro                 = dw_mci_get_ro,
> +       .get_cd                 = dw_mci_get_cd,
> +       .enable_sdio_irq        = dw_mci_enable_sdio_irq,
>  };
>
>  static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
> @@ -1179,6 +1197,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>        struct dw_mci *host = dev_id;
>        u32 status, pending;
>        unsigned int pass_count = 0;
> +       int i;
>
>        do {
>                status = mci_readl(host, RINTSTS);
> @@ -1249,6 +1268,14 @@ static irqreturn_t dw_mci_interrupt(int irq,
> void *dev_id)
>                        tasklet_schedule(&host->card_tasklet);
>                }
>
> +               /* Handle SDIO Interrupts */
> +               for (i = 0; i < host->num_slots; i++) {
> +                       struct dw_mci_slot *slot = host->slot[i];
> +                       if (pending & SDMMC_INT_SDIO(i)) {
> +                               mci_writel(host, RINTSTS, SDMMC_INT_SDIO(i));
> +                               mmc_signal_sdio_irq(slot->mmc);

A potential problem that just occured to me, is that the TRM says (in
the note after the table of interrupt status bits):
"The SDIO interrupts, receive fifo data request (RXDR), and transmit
FIFO data request (txdr) are set by level-sensitive interrupt sources.
Therefore, the interrupt source should be first cleared before you can
clear the interrupt bit of the Raw interrupt register"

I'm guessing the source would get cleared somewhere in the
mmc_signal_sdio_irq function, depending on the sdio driver, therefore
I think it'd be more correct to clear each interrupt after the
mmc_signal_sdio_irq() call to prevent it immediately retriggering.

Cheers
James

> +                       }
> +               }
>        } while (pass_count++ < 5);
>
>  #ifdef CONFIG_MMC_DW_IDMAC
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 23c662a..ecf1043 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -82,7 +82,7 @@
>  #define SDMMC_CTYPE_4BIT               BIT(0)
>  #define SDMMC_CTYPE_1BIT               0
>  /* Interrupt status & mask register defines */
> -#define SDMMC_INT_SDIO                 BIT(16)
> +#define SDMMC_INT_SDIO(n)              BIT((16 + (n)))
>  #define SDMMC_INT_EBE                  BIT(15)
>  #define SDMMC_INT_ACD                  BIT(14)
>  #define SDMMC_INT_SBE                  BIT(13)
> --
> 1.7.2.3
>
>
> --
> regards,
> Shashidhar Hiremath
> --
> 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
>



-- 
James Hogan
--
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