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 James,
    If I understand your concern correctly, for level triggered
interrupts,the interrupt action needs to taken first,than the
interrupt source needs to be cleared,only then I can clear Raw
Interrupt Status register right ?

So ,accordingly ,will the below code be in appropriate order ?
                 if (pending & SDMMC_INT_SDIO(i)) {
                             mmc_signal_sdio_irq(slot->mmc);
                             mci_writel(host, RINTSTS, SDMMC_INT_SDIO(i));


On Tue, Aug 23, 2011 at 7:56 PM, James Hogan <james@xxxxxxxxxxxxx> wrote:
> 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
>



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


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

  Powered by Linux