mmc: tegra: clean up interrupts logic in tuning
Pavan Kunapuli [Wed, 27 Jun 2012 12:21:54 +0000 (17:21 +0530)]
Disable the normal interrupts signalling before
tuning and enable it only after the entire tuning
process is done.

Bug 860102

Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-on: http://git-master/r/111589
(cherry picked from commit 15a97f33f6cf1fc1c25441142f69f62ce5f7029b)
Change-Id: I9eba9af65a50928dc4bb475e06cbf401963751bc
Reviewed-on: http://git-master/r/116433
Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>

drivers/mmc/host/sdhci-tegra.c

index 9329cb5..86cee26 100644 (file)
@@ -674,36 +674,15 @@ static void sdhci_tegra_set_tap_delay(struct sdhci_host *sdhci,
        sdhci_writel(sdhci, vendor_ctrl, SDHCI_VENDOR_CLOCK_CNTRL);
 }
 
-static void sdhci_tegra_clear_set_irqs(struct sdhci_host *host,
-       u32 clear, u32 set)
-{
-       u32 ier;
-
-       ier = sdhci_readl(host, SDHCI_INT_ENABLE);
-       ier &= ~clear;
-       ier |= set;
-       sdhci_writel(host, ier, SDHCI_INT_ENABLE);
-       sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
-}
-
 static int sdhci_tegra_run_frequency_tuning(struct sdhci_host *sdhci)
 {
        int err = 0;
        u8 ctrl;
-       u32 ier;
        u32 mask;
        unsigned int timeout = 10;
        int flags;
        u32 intstatus;
 
-       /*
-        * As per the Host Controller spec v3.00, tuning command
-        * generates Buffer Read Ready interrupt only, so enable that.
-        */
-       ier = sdhci_readl(sdhci, SDHCI_INT_ENABLE);
-       sdhci_tegra_clear_set_irqs(sdhci, ier, SDHCI_INT_DATA_AVAIL |
-               SDHCI_INT_DATA_CRC);
-
        mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
        while (sdhci_readl(sdhci, SDHCI_PRESENT_STATE) & mask) {
                if (timeout == 0) {
@@ -775,7 +754,6 @@ static int sdhci_tegra_run_frequency_tuning(struct sdhci_host *sdhci)
        }
        mdelay(1);
 out:
-       sdhci_tegra_clear_set_irqs(sdhci, SDHCI_INT_DATA_AVAIL, ier);
        return err;
 }
 
@@ -789,6 +767,7 @@ static int sdhci_tegra_execute_tuning(struct sdhci_host *sdhci)
        unsigned int temp_pass_window = 0;
        unsigned int best_low_pass_tap = 0;
        unsigned int best_pass_window = 0;
+       u32 ier;
 
        /* Tuning is valid only in SDR104 and SDR50 modes */
        ctrl_2 = sdhci_readw(sdhci, SDHCI_HOST_CONTROL2);
@@ -801,11 +780,20 @@ static int sdhci_tegra_execute_tuning(struct sdhci_host *sdhci)
        if (tap_delay_status == NULL) {
                dev_err(mmc_dev(sdhci->mmc), "failed to allocate memory"
                        "for storing tap_delay_status\n");
-               err = -ENOMEM;
-               goto out;
+               return -ENOMEM;
        }
 
        /*
+        * Disable all interrupts signalling.Enable interrupt status
+        * detection for buffer read ready and data crc. We use
+        * polling for tuning as it involves less overhead.
+        */
+       ier = sdhci_readl(sdhci, SDHCI_INT_ENABLE);
+       sdhci_writel(sdhci, 0, SDHCI_SIGNAL_ENABLE);
+       sdhci_writel(sdhci, SDHCI_INT_DATA_AVAIL |
+               SDHCI_INT_DATA_CRC, SDHCI_INT_ENABLE);
+
+       /*
         * Set each tap delay value and run frequency tuning. After each
         * run, update the tap delay status as working or not working.
         */
@@ -856,7 +844,10 @@ static int sdhci_tegra_execute_tuning(struct sdhci_host *sdhci)
        /* Run frequency tuning */
        err = sdhci_tegra_run_frequency_tuning(sdhci);
 
-out:
+       /* Enable the normal interrupts signalling */
+       sdhci_writel(sdhci, ier, SDHCI_INT_ENABLE);
+       sdhci_writel(sdhci, ier, SDHCI_SIGNAL_ENABLE);
+
        if (tap_delay_status)
                kfree(tap_delay_status);