This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Bogus interrupts on AM1808's MMC1 controller while using twilink over SDIO

Other Parts Discussed in Thread: AM1808

We're experiencing a strange problem in the Davinci MMC host controller on an AM1808 evaluation board. The setup includes a tiwlink card connected to MMC1. The card communicates with the host over SDIO. While the card is inactive, no interrupts are received on the MMC1 host controller, as expected. When bringing the card up (through ifconfig tiwlan0 up) and after configuration of the network, we see the MMC receiving interrupts as expected. However, it seems that "bogus interrupts" are received by the MMC host. These interrupts have no corresponding bit set in the MMC's status (MMCSTAT register), suggesting that the interrupt was not generated by the MMC controller. These bogus interrupts amount to about 26 percent of the total interrupts received on the MMC controller. It should be noted that MMC1's interrupt line is internal to the SOC, so we do not suspect noise on an external interrupt line. Also, this same phenomenon repeats itself exactly when using a twilink card on MMC0. 

What may be the source of these "bogus interrupts"?

  • Hi,

    Are you seeing bogus interrupts even when using MMC/SD cards and unmodified TI software?

    Since we do not support SDIO in TI releases, I assume some changes were made to support SDIO?

    This experiment will help narrow the source of these interrupts.

    Thanks,

    Sekhar

  • Hi Sekhar,

    We have not modified the driver code but we have added the MMC1 entries in the platform entries and it is working fine for us.

    The existing code for mmc0 has been reused for MMC1. We are also seeing same bogus interrupt in case of MMC0.

     

    Best Regards

    Sanjay

  • Hi Sanjay,

    I am still not clear if you see "Suprious interrupts" with MMC/SD card transactions or only with the WLAN card you are interfacing. I tried inserting the following code into the MMC/SD driver and tested with SDHC card, but did not get any spurious interrupts:

    diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
    index 33d9f1b..f688a53 100644
    --- a/drivers/mmc/host/davinci_mmc.c
    +++ b/drivers/mmc/host/davinci_mmc.c
    @@ -950,6 +950,9 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
            }

            status = readl(host->base + DAVINCI_MMCST0);
    +       if (!(status & 0x3FFF))
    +               printk("Spurious interrupt\n");
    +
            qstatus = status;

            /* handle FIFO first when using PIO for data.

    Also, I am surprised that you did not have to do any modifications to the MMC/SD driver to support SDIO. There is a patch that has been submitted to DaVinci Linux mailing list to add SDIO support to this driver. This patch hasn't been merged yet.

    http://www.mail-archive.com/davinci-linux-open-source@linux.davincidsp.com/msg17678.html

    Thanks,

    Sekhar

     

  • Hello Sekhar,

    I am working along with Sanjay on this issue. We do not require the SDIO patch to the Davinci MMC. Our tiwlink card has an interrupt line to the system. Incoming events are handled by this interrupt, which does all the necessary transactions with the MMC host controller. This is why no major change was done to the MMC host controller code. We have made a minor change to the davinci mmc code which provides virtual card detect functionality for the wifi adapter. I can provide you the patch, but the change does not affect the low-level behavior of the driver.

    In any event, we repeated the experiment you suggested and used an SD card. We did not see spurious interrupts in this case. However, it is possible that the low frequency of interrupts generated when working with the SD card may also affect the triggering of the spurious interrupt problem. What is the transfer rate of the SDHC card you used?

     

    Regards,

       Yotam Rubin

  • Hello again,

      We have tested the same scenario, only using a class 4 SD card (5.2 mbps). We are seeing the bogus interrupts being received on MMC 0. The interrupts are received at a relatively low frequency. I am providing a debug log from the kernel showing the exact amounts of valid interrupts vs. bogus interrupts:

    -----------------------------------------

    Spurious interrupts: 0
    Bogus interrupts: 40293
    Valid interrupts: 4356522

    -----------------------------------------

    A bogus interrupt is an interrupt whose respective status register (MMCSTAT) was to 0, meaning no interrupt should have been raised. A spurious interrupt is an interrupt with a corresponding bit set in the status register, but which was received out of a data/cmd context. In our case, no spurious interrupts are received, but we are seeing quite a few bogus interrupts.

     

  • Hey!

     

    Regarding the patch. I'm not sure what version of the code you have, but in my code, there's a check for spurious interrupts right before the reading of the status register:

    drivers/mmc/host/davincid_mmc.c:

        if (host->cmd == NULL && host->data == NULL) {
                    status = readl(host->base + DAVINCI_MMCST0);
                    dev_dbg(mmc_dev(host->mmc),
                                    "Spurious interrupt 0x%04x\n", status);

                    /* Disable the interrupt from mmcsd */
                    writel(0, host->base + DAVINCI_MMCIM);
                    return IRQ_NONE;
            }

          status = readl(host->base + DAVINCI_MMCST0);

     

    If we have the same code, and  MMC debugging is disabled on your kernel, then you should never see the printk's, because the IRQ handler would have exited by that time... Just wondering...

     

  • Some updates,

     Ido Yariv who is also working with us has found the root of the problem:

    drivers/mmc/host/davinci_mmc.c:

        while (host->bytes_left && (status & (MMCST0_DXRDY | MMCST0_DRRDY))) {
                    davinci_fifo_data_trans(host, rw_threshold);
                    status = readl(host->base + DAVINCI_MMCST0);
                    if (!status)
                            break;
                    qstatus |= status;
            }

    The above code basically polls the status register for interrupts, and processes them in order to prevent many interrupts from being raised on the CPU. However, consider the following:

    1. Interrupt handler is entered. 
    2. During the while loop, an MMC interrupt is raised. PIC will mark interrupt as pending
    3. The status register of the raised interrupt will also be set to 0
    4. Interrupt handler returns and CPU interrupts are enabled
    5. The pending MMC interrupt is raised. In the interrupt handler, the status register is read. Because all status registers were processed in the previous interrupt, its value will be 0 and the interrupt is spurious

    A pretty good ad-hoc (if not perfect) solution is to mask MMC interrupts at the beginning of the handler, and reenable them after the while loop.

     

  • I'm interested in SDIO IRQs for AM1808 too. Meanwhile SDIO IRQs are already supported in the mainline kernel without having to apply a patch to support them.

    Is the above mentioned problem with bogus/spurious interrupts already solved in the davinci_mmc drivers of the mainline kernel?