From 42ed69a64a39d7cc84256bd3cb386f8dc8f09b84 Mon Sep 17 00:00:00 2001 From: Pavan Kunapuli Date: Wed, 27 Jun 2012 17:51:54 +0530 Subject: mmc: tegra: clean up interrupts logic in tuning 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 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 Tested-by: Rohan Somvanshi --- drivers/mmc/host/sdhci-tegra.c | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 9329cb57c548..86cee262b8fd 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -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,10 +780,19 @@ 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); -- cgit v1.2.3