mmc: sdhci: add hooks for platform specific tuning
authorDong Aisheng <b29396@freescale.com>
Fri, 13 Sep 2013 11:11:30 +0000 (19:11 +0800)
committerChris Ball <cjb@laptop.org>
Thu, 26 Sep 2013 11:53:21 +0000 (07:53 -0400)
The tuning of some platforms may not follow the standard host control
spec v3.0, e.g. Freescale uSDHC on i.MX6Q/DL.
Add a hook here to allow execute platform specific tuning instead of
standard host controller tuning.

The hook only replaces the tuning process, so it's placed after tuning
checking and before the real tuning process.

Some notes for the tuning hook:
1) it needs handle lock itself if it wants to access host controller
according platform specific implementation.
2) do not need to handle runtime pm since it executes with runtime pm
get already.

Signed-off-by: Dong Aisheng <b29396@freescale.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h

index 7a7fb4f0d5a43a4829fa1e258afbf112f4dd9b82..072d78ce2664281c06cf6cb77754d935b25235d6 100644 (file)
@@ -1875,6 +1875,14 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
                return 0;
        }
 
+       if (host->ops->platform_execute_tuning) {
+               spin_unlock(&host->lock);
+               enable_irq(host->irq);
+               err = host->ops->platform_execute_tuning(host, opcode);
+               sdhci_runtime_pm_put(host);
+               return err;
+       }
+
        sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
        /*
index b037f188fe44b26c357b77ebe985f8406aa4c1ac..976c14b5aaf9ccc9f00aa9d6c34602ec3319f52d 100644 (file)
@@ -288,6 +288,7 @@ struct sdhci_ops {
        unsigned int    (*get_ro)(struct sdhci_host *host);
        void    (*platform_reset_enter)(struct sdhci_host *host, u8 mask);
        void    (*platform_reset_exit)(struct sdhci_host *host, u8 mask);
+       int     (*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
        int     (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
        void    (*hw_reset)(struct sdhci_host *host);
        void    (*platform_suspend)(struct sdhci_host *host);