This is sdhci-s3c patch for c210.
c210 didn't use divider of host controller.

Host Controller need other clock setting methods. 

So I add the callback functions for s5pc210.
also I set 400KHz for initial clock.

Signed-off-by: Jaehoon Chung <[email protected]>
 Signed-off-by: Kyungmin Park <[email protected]>

---
 arch/arm/plat-samsung/include/plat/sdhci.h |   19 ++++++++
 drivers/mmc/host/sdhci-s3c.c               |   68 ++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h 
b/arch/arm/plat-samsung/include/plat/sdhci.h
index 30844c2..7c75ee3 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -15,6 +15,8 @@
 #ifndef __PLAT_S3C_SDHCI_H
 #define __PLAT_S3C_SDHCI_H __FILE__
 
+#include <plat/devs.h>
+
 struct platform_device;
 struct mmc_host;
 struct mmc_card;
@@ -288,4 +290,21 @@ static inline void s5pv210_default_sdhci3(void) { }
 
 #endif /* CONFIG_S5PV210_SETUP_SDHCI */
 
+/* re-define device name depending on support. */
+static inline void s3c_hsmmc_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+       s3c_device_hsmmc0.name = name;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+       s3c_device_hsmmc1.name = name;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+       s3c_device_hsmmc2.name = name;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+       s3c_device_hsmmc3.name = name;
+#endif
+}
+
 #endif /* __PLAT_S3C_SDHCI_H */
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 71ad416..3927793 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -52,6 +52,11 @@ struct sdhci_s3c {
        struct clk              *clk_bus[MAX_BUS_CLK];
 };
 
+enum soc_type {
+       TYPE_SAMSUNG,   /* S5PC1XX, S3C... */
+       TYPE_S5PC210,   /* S5PC210 */
+};
+
 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
 {
        return sdhci_priv(host);
@@ -232,6 +237,52 @@ static unsigned int sdhci_s3c_get_min_clock(struct 
sdhci_host *host)
        return min;
 }
 
+/**
+* sdhci_s3c_get_max_clk - callback to get maximum clock frequency.
+*/
+static unsigned int sdhci_s5pc210_get_max_clock(struct sdhci_host *host)
+{
+       struct sdhci_s3c *ourhost = to_s3c(host);
+       unsigned int rate;
+       int ptr = ourhost->cur_clk;
+
+       rate = clk_round_rate(ourhost->clk_bus[ptr], UINT_MAX);
+
+       return rate;
+}
+
+/**
+ * sdhci_s3c_get_min_clock - callback to get minimal supported clock value
+*/
+static unsigned int sdhci_s5pc210_get_min_clock(struct sdhci_host *host)
+{
+       struct sdhci_s3c *ourhost = to_s3c(host);
+       unsigned int rate;
+       int ptr = ourhost->cur_clk;
+
+       rate = clk_round_rate(ourhost->clk_bus[ptr], 400000);
+
+       return rate;
+}
+
+/**
+ * sdhci_s5pc210_set_clock - callback on clock change
+*/
+static void sdhci_s5pc210_set_clock(struct sdhci_host *host,
+               unsigned int clock)
+{
+       struct sdhci_s3c *ourhost = to_s3c(host);
+
+       if (clock == 0)
+               return;
+
+       sdhci_s3c_set_clock(host, clock);
+
+       clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
+
+       host->clock = clock;
+}
+
 static struct sdhci_ops sdhci_s3c_ops = {
        .get_max_clock          = sdhci_s3c_get_max_clk,
        .set_clock              = sdhci_s3c_set_clock,
@@ -395,6 +446,12 @@ static int __devinit sdhci_s3c_probe(struct 
platform_device *pdev)
        host->quirks = 0;
        host->irq = irq;
 
+       if (pdev->id_entry->driver_data == TYPE_S5PC210) {
+               sdhci_s3c_ops.set_clock = sdhci_s5pc210_set_clock;
+               sdhci_s3c_ops.get_min_clock = sdhci_s5pc210_get_min_clock;
+               sdhci_s3c_ops.get_max_clock = sdhci_s5pc210_get_max_clock;
+       }
+
        /* Setup quirks for the controller */
        host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
        host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
@@ -520,6 +577,16 @@ static int sdhci_s3c_resume(struct platform_device *dev)
 #define sdhci_s3c_resume NULL
 #endif
 
+static struct platform_device_id sdhci_driver_ids[] = {
+       {
+               .name           = "s3c-sdhci",
+               .driver_data    = TYPE_SAMSUNG,
+       }, {
+               .name           = "s5pc210-sdhci",
+               .driver_data    = TYPE_S5PC210,
+       }, { },
+};
+
 static struct platform_driver sdhci_s3c_driver = {
        .probe          = sdhci_s3c_probe,
        .remove         = __devexit_p(sdhci_s3c_remove),
@@ -529,6 +596,7 @@ static struct platform_driver sdhci_s3c_driver = {
                .owner  = THIS_MODULE,
                .name   = "s3c-sdhci",
        },
+       .id_table       = sdhci_driver_ids,
 };
 
 static int __init sdhci_s3c_init(void)
-- 1.6.0.4 
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to