Skip to contentSkip to conversation

sdhci-s3c: support non-standard clock setting for c210

PATCH In review Jaehoon Chung 4 participants 8 messages Aug 31, 2010 – Sep 28, 2010

Subsystems (5)
lore
Share & tools
lore

Jaehoon Chung

author maintainer
#0 lore raw

PATCH 1/1 sdhci-s3c: support non-standard clock setting for c210

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.

---
 arch/arm/plat-samsung/include/plat/sdhci.h |   19 ++++++++
 drivers/mmc/host/sdhci-s3c.c               |   68 ++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 0 deletions(-)
arch/arm/plat-samsung/include/plat/sdhci.h +19 -0
index 30844c2..7c75ee3 100644
@@ -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 */
drivers/mmc/host/sdhci-s3c.c +68 -0

98 lines not on this page · raw message

-- 1.6.0.4

#1 lore raw
Quoted 44 lines · Jaehoon Chung

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.

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

samsung/include/plat/sdhci.h
index 30844c2..7c75ee3 100644

arch/arm/plat-samsung/include/plat/sdhci.h +10 -0
@@ -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;

arch/arm/plat-samsung/include/plat/sdhci.h static inline void s5pv210_default_sdhci3(void) { } · line 310

Quoted 10 lines
arch/arm/plat-samsung/include/plat/sdhci.h +9 -0
+#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 */

It would be helpful to me if you could separate platform and driver patches. And if you want to add s3c_hsmmc_setname(), please send together code that it is used.

Quoted 27 lines
drivers/mmc/host/sdhci-s3c.c +11 -0
index 71ad416..3927793 100644
@@ -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);

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 256

Quoted 10 lines
drivers/mmc/host/sdhci-s3c.c +10 -0
+	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

drivers/mmc/host/sdhci-s3c.c static int sdhci_s3c_resume(struct platform_device

Quoted 48 lines
drivers/mmc/host/sdhci-s3c.c +30 -0
+*/
+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,
drivers/mmc/host/sdhci-s3c.c +6 -0
 	.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;
drivers/mmc/host/sdhci-s3c.c +0 -0
 	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
@@ -520,6 +577,16 @@ static int sdhci_s3c_resume(struct platform_device

*dev)

Quoted 17 lines
drivers/mmc/host/sdhci-s3c.c +10 -0
 #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),

drivers/mmc/host/sdhci-s3c.c static struct platform_driver sdhci_s3c_driver = {

Quoted 8 lines
drivers/mmc/host/sdhci-s3c.c +1 -1
@@ -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

How do you think about using quirk to separate S5PV310 case as following? I think this is more general method in here...And will be submitted soon after fixing something.

From: Hyuk Lee <[email protected]>

drivers/mmc/host/sdhci-s3c.c +0 -0
index 71ad416..1ac2f36 100644
@@ -96,6 +96,11 @@ static unsigned int sdhci_s3c_get_max_clk(struct

sdhci_host *host)
unsigned int rate, max;
int clk;

+ /* There is only one clock source(sclk) if there is no clock divider
+ * in the host controller */
+ if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER)
+ return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk],
UINT_MAX);
+
/* note, a reset will reset the clock source */

sdhci_s3c_check_sclk(host);
@@ -130,6 +135,11 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
if (!clksrc)
return UINT_MAX;

+ if(ourhost->host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER) {
+ rate = clk_round_rate(clksrc,wanted);
+ return (wanted - rate);
+ }
+
rate = clk_get_rate(clksrc);

for (div = 1; div < 256; div *= 2) {
@@ -159,6 +169,7 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
int best_src = 0;
int src;
u32 ctrl;
+ unsigned int timeout;

/* don't bother if the clock is going off. */
if (clock == 0)
@@ -204,6 +215,31 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
(ourhost->pdata->cfg_card)(ourhost->pdev,
host->ioaddr,
&ios, NULL);
}
+
+ if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER) {
+ writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
+
+ writew(SDHCI_CLOCK_INT_EN, host->ioaddr +
SDHCI_CLOCK_CONTROL);
+
+ /* Wait max 20 ms */
+ timeout = 20;
+ while (!((sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+ & SDHCI_CLOCK_INT_STABLE)) {
+ if (timeout == 0) {
+ printk(KERN_ERR "%s: Internal clock never "
+ "stabilised.\n",
mmc_hostname(host->mmc));
+ return;
+ }
+ timeout--;
+ mdelay(1);
+ }
+
+ writew(SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN,
+ host->ioaddr + SDHCI_CLOCK_CONTROL);
+
+ host->clock = clock;
+ }
}

/**
@@ -221,6 +257,11 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
unsigned int delta, min = UINT_MAX;
int src;

+ /* There is only one clock source(sclk) if there is no clock divider
+ * in the host controller */
+ if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER)
+ return clk_round_rate(ourhost->clk_bus[2], 400000);
+
for (src = 0; src < MAX_BUS_CLK; src++) {
delta = sdhci_s3c_consider_clock(ourhost, src, 0); if (delta == UINT_MAX)

...

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

#2 lore raw
Quoted 170 lines · Kukjin Kim
Quoted 44 lines · Jaehoon Chung

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.

---
 arch/arm/plat-samsung/include/plat/sdhci.h |   19 ++++++++ drivers/mmc/host/sdhci-s3c.c               |   68
++++++++++++++++++++++++++++

 2 files changed, 87 insertions(+), 0 deletions(-)
arch/arm/plat- renamed from arch/arm/plat-samsung/include/plat/sdhci.h +0 -0

samsung/include/plat/sdhci.h
index 30844c2..7c75ee3 100644

arch/arm/plat-samsung/include/plat/sdhci.h +10 -0
@@ -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;

arch/arm/plat-samsung/include/plat/sdhci.h static inline void s5pv210_default_sdhci3(void) { } · line 310

Quoted 10 lines
arch/arm/plat-samsung/include/plat/sdhci.h +9 -0
+#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 */

It would be helpful to me if you could separate platform and driver patches. And if you want to add s3c_hsmmc_setname(), please send together code that it is used.

Quoted 27 lines
drivers/mmc/host/sdhci-s3c.c +11 -0
index 71ad416..3927793 100644
@@ -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);

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 256

Quoted 10 lines
drivers/mmc/host/sdhci-s3c.c +10 -0
+     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

drivers/mmc/host/sdhci-s3c.c static int sdhci_s3c_resume(struct platform_device

Quoted 48 lines
drivers/mmc/host/sdhci-s3c.c +30 -0
+*/
+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,

drivers/mmc/host/sdhci-s3c.c +6 -0
@@ -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;

drivers/mmc/host/sdhci-s3c.c +0 -0
@@ -520,6 +577,16 @@ static int sdhci_s3c_resume(struct platform_device

*dev)

Quoted 23 lines
drivers/mmc/host/sdhci-s3c.c +11 -0
  #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,
  };
 
Quoted 6 lines

drivers/mmc/host/sdhci-s3c.c static struct platform_driver sdhci_s3c_driver = {

Quoted 2 lines
drivers/mmc/host/sdhci-s3c.c +0 -1
  static int __init sdhci_s3c_init(void)
-- 1.6.0.4

How do you think about using quirk to separate S5PV310 case as following? I think this is more general method in here...And will be submitted soon after fixing something.

What's the meaning of "general method"?

and how/where do you set the host->quirks? when board or platform set the these quirks? who know it uses nonstandard quirk?
In case s5pc210 don't have standard host controller. it's more clear to use own functions instead of quirks.

Quoted 80 lines

From: Hyuk Lee <[email protected]>

drivers/mmc/host/sdhci-s3c.c +5 -0
index 71ad416..1ac2f36 100644
@@ -96,6 +96,11 @@ static unsigned int sdhci_s3c_get_max_clk(struct
 sdhci_host *host)
        unsigned int rate, max;
        int clk;
 
+       /* There is only one clock source(sclk) if there is no clock divider
+        * in the host controller */
+       if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER)
+               return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk],
 UINT_MAX);
+
        /* note, a reset will reset the clock source */

       sdhci_s3c_check_sclk(host);

drivers/mmc/host/sdhci-s3c.c +5 -0
@@ -130,6 +135,11 @@ static unsigned int sdhci_s3c_consider_clock(struct
 sdhci_s3c *ourhost,
        if (!clksrc)
                return UINT_MAX;
 
+       if(ourhost->host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER) {
+               rate = clk_round_rate(clksrc,wanted);
+               return (wanted - rate);
+       }
+
        rate = clk_get_rate(clksrc);
 

       for (div = 1; div < 256; div *= 2) {

drivers/mmc/host/sdhci-s3c.c +1 -0
@@ -159,6 +169,7 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host,
 unsigned int clock)
        int best_src = 0;
        int src;
        u32 ctrl;
+       unsigned int timeout;
 
        /* don't bother if the clock is going off. */

       if (clock == 0)

drivers/mmc/host/sdhci-s3c.c +14 -0
@@ -204,6 +215,31 @@ static void sdhci_s3c_set_clock(struct sdhci_host
 *host, unsigned int clock)
                        (ourhost->pdata->cfg_card)(ourhost->pdev,
 host->ioaddr,
                                                   &ios, NULL);
        }
+
+       if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER) {
+               writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+               clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
+
+               writew(SDHCI_CLOCK_INT_EN, host->ioaddr +
 SDHCI_CLOCK_CONTROL);
+
+               /* Wait max 20 ms */
+               timeout = 20;
+               while (!((sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+                       & SDHCI_CLOCK_INT_STABLE)) {
+                       if (timeout == 0) {
+                               printk(KERN_ERR "%s: Internal clock never "
+                                       "stabilised.\n",

mmc_hostname(host->mmc));
+                               return;
+                       }
+                       timeout--;
+                       mdelay(1);
+               }

drivers/mmc/host/sdhci-s3c.c +6 -0
+
+               writew(SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN,
+                               host->ioaddr + SDHCI_CLOCK_CONTROL);
+
+               host->clock = clock;
+       }

 }

 /**

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 264

Quoted 8 lines
drivers/mmc/host/sdhci-s3c.c +4 -0
@@ -221,6 +257,11 @@ static unsigned int sdhci_s3c_get_min_clock(struct
 sdhci_host *host)
        unsigned int delta, min = UINT_MAX;
        int src;
 
+       /* There is only one clock source(sclk) if there is no clock divider
+        * in the host controller */
+       if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER)
+               return clk_round_rate(ourhost->clk_bus[2], 400000);

what's the clk_bus[2]?

Thank you,
Kyungmin Park

Quoted 21 lines
drivers/mmc/host/sdhci-s3c.c +1 -0
+
        for (src = 0; src < MAX_BUS_CLK; src++) {
                delta = sdhci_s3c_consider_clock(ourhost, src, 0);

               if (delta == UINT_MAX)

...

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

--
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

#3 lore raw

PATCH 1/1 sdhci-s3c: support non-standard clock setting for c210

Quoted 7 lines · Kyungmin Park
Quoted 5 lines · Kukjin Kim
Quoted 4 lines · Jaehoon Chung

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

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

Host Controller need other clock setting methods.

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

^^^
Unnecessary whitespace

If your patch includes arch/arm stuff, please add Linux-arm-kernel maillinglist.
(Cc'ed that)

Quoted 8 lines
Quoted 8 lines

Review

Quoted 8 lines

---
 arch/arm/plat-samsung/include/plat/sdhci.h |   19 ++++++++ drivers/mmc/host/sdhci-s3c.c               |   68
++++++++++++++++++++++++++++

 2 files changed, 87 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/arch/arm/plat-

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

samsung/include/plat/sdhci.h
index 30844c2..7c75ee3 100644

arch/arm/plat-samsung/include/plat/sdhci.h +0 -0
@@ -15,6 +15,8 @@
  #ifndef __PLAT_S3C_SDHCI_H
  #define __PLAT_S3C_SDHCI_H __FILE__
 
Quoted 6 lines
Quoted 6 lines

arch/arm/plat-samsung/include/plat/sdhci.h static inline void s5pv210_default_sdhci3(void) {

Quoted 6 lines
arch/arm/plat-samsung/include/plat/sdhci.h +2 -0
+#include <plat/devs.h>
+
  struct platform_device;
  struct mmc_host;
  struct mmc_card;
@@ -288,4 +290,21 @@ static inline void s5pv210_default_sdhci3(void) {

}

Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
arch/arm/plat-samsung/include/plat/sdhci.h +12 -0
  #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
Quoted 8 lines
Quoted 8 lines

arch/arm/plat-samsung/include/plat/sdhci.h static inline void s5pv210_default_sdhci3(void) { · line 309

Quoted 6 lines
arch/arm/plat-samsung/include/plat/sdhci.h +5 -0
+#ifdef CONFIG_S3C_DEV_HSMMC3
+     s3c_device_hsmmc3.name = name;
+#endif
+}
+
  #endif /* __PLAT_S3C_SDHCI_H */

It would be helpful to me if you could separate platform and driver

patches.

Quoted 1 line
Quoted 1 line

And if you want to add s3c_hsmmc_setname(), please send together code

that

Quoted 3 lines
Quoted 3 lines

it is used.

Review

Quoted 1 line
(quoted diff) +0 -0

b/drivers/mmc/host/sdhci-s3c.c

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

index 71ad416..3927793 100644

drivers/mmc/host/sdhci-s3c.c +0 -0

(snip)

Quoted 2 lines
Quoted 2 lines

How do you think about using quirk to separate S5PV310 case as

following?

Quoted 4 lines
Quoted 2 lines

I think this is more general method in here...And will be submitted soon after fixing something.

What's the meaning of "general method"?

I'd like to ask you why there is quirk in sdmmc driver.

Quoted 2 lines

and how/where do you set the host->quirks? when board or platform set the these quirks? who know it uses nonstandard quirk?

How about following?

static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
...
+ if (pdev->id_entry->driver_data == TYPE_S5PV310)
+ host->quirks |= SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER;
...

Quoted 3 lines

In case s5pc210 don't have standard host controller. it's more clear to use own functions instead of quirks.

Why do we add another callback function?

Quoted 7 lines
Quoted 7 lines

From: Hyuk Lee <[email protected]>

drivers/mmc/host/sdhci-s3c.c +0 -0
index 71ad416..1ac2f36 100644

(snip)

Quoted 6 lines

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 261

Quoted 6 lines
drivers/mmc/host/sdhci-s3c.c +1 -0
@@ -221,6 +257,11 @@ static unsigned int sdhci_s3c_get_min_clock(struct
 sdhci_host *host)
        unsigned int delta, min = UINT_MAX;
        int src;
 
+       /* There is only one clock source(sclk) if there is no clock

divider

Quoted 5 lines

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 264

Quoted 3 lines
drivers/mmc/host/sdhci-s3c.c +3 -0
+        * in the host controller */
+       if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER)
+               return clk_round_rate(ourhost->clk_bus[2], 400000);

what's the clk_bus[2]?

Should be clk_bus[ourhost->cur_clk]

(snip)

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

#4 lore raw

PATCH 1/1 sdhci-s3c: support non-standard clock setting for c210

Quoted 94 lines · Kukjin Kim
Quoted 7 lines · Kyungmin Park
Quoted 5 lines · Kukjin Kim
Quoted 4 lines · Jaehoon Chung

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

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

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: Kyungmin Park <[email protected]>

? ^^^
Unnecessary whitespace

If your patch includes arch/arm stuff, please add Linux-arm-kernel maillinglist.
(Cc'ed that)

Quoted 8 lines
Quoted 8 lines

Review

Quoted 8 lines

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

(quoted diff) +0 -0

b/arch/arm/plat-

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

samsung/include/plat/sdhci.h
index 30844c2..7c75ee3 100644

arch/arm/plat-samsung/include/plat/sdhci.h +0 -0
@@ -15,6 +15,8 @@

?#ifndef __PLAT_S3C_SDHCI_H
?#define __PLAT_S3C_SDHCI_H __FILE__

Quoted 6 lines
Quoted 6 lines

arch/arm/plat-samsung/include/plat/sdhci.h static inline void s5pv210_default_sdhci3(void) {

Quoted 6 lines
arch/arm/plat-samsung/include/plat/sdhci.h +2 -0
+#include <plat/devs.h>
+

?struct platform_device;
?struct mmc_host;
?struct mmc_card;

arch/arm/plat-samsung/include/plat/sdhci.h +0 -0
@@ -288,4 +290,21 @@ static inline void s5pv210_default_sdhci3(void) {

}

Quoted 15 lines
Quoted 15 lines
Quoted 15 lines

?#endif /* CONFIG_S5PV210_SETUP_SDHCI */

arch/arm/plat-samsung/include/plat/sdhci.h +12 -0
+/* 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
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
arch/arm/plat-samsung/include/plat/sdhci.h +5 -0
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ ? ? s3c_device_hsmmc3.name = name;
+#endif
+}
+

?#endif /* __PLAT_S3C_SDHCI_H */

It would be helpful to me if you could separate platform and driver

patches.

Quoted 1 line
Quoted 1 line

And if you want to add s3c_hsmmc_setname(), please send together code

that

Quoted 3 lines
Quoted 3 lines

it is used.

Review

Quoted 1 line
(quoted diff) +0 -0

b/drivers/mmc/host/sdhci-s3c.c

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

index 71ad416..3927793 100644

drivers/mmc/host/sdhci-s3c.c +0 -0

(snip)

Quoted 2 lines
Quoted 2 lines

How do you think about using quirk to separate S5PV310 case as

following?

Quoted 4 lines
Quoted 2 lines

I think this is more general method in here...And will be submitted soon after fixing something.

What's the meaning of "general method"?

I'd like to ask you why there is quirk in sdmmc driver.

Quoted 2 lines

and how/where do you set the host->quirks? when board or platform set the these quirks? who know it uses nonstandard quirk?

Quoted 6 lines

How about following?

static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
...
+ ? ? ? if (pdev->id_entry->driver_data == TYPE_S5PV310)
+ ? ? ? ? ? ? ? host->quirks |= SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER;

What's the difference override the functions?

Quoted 6 lines

...

Quoted 3 lines

In case s5pc210 don't have standard host controller. it's more clear to use own functions instead of quirks.

Why do we add another callback function?

It's override functions. See the patch posted.

Usually you insist use your code. then send it early to mailing list and get the feedback.

Thank you,
Kyungmin Park

Quoted 38 lines
Quoted 8 lines
Quoted 8 lines

From: Hyuk Lee <[email protected]>

drivers/mmc/host/sdhci-s3c.c +0 -0
index 71ad416..1ac2f36 100644

(snip)

Quoted 6 lines

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 261

Quoted 6 lines
drivers/mmc/host/sdhci-s3c.c +1 -0
@@ -221,6 +257,11 @@ static unsigned int sdhci_s3c_get_min_clock(struct
 sdhci_host *host)
 ? ? ? ?unsigned int delta, min = UINT_MAX;
 ? ? ? ?int src;
 
+ ? ? ? /* There is only one clock source(sclk) if there is no clock

divider

Quoted 5 lines

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 264

Quoted 3 lines
drivers/mmc/host/sdhci-s3c.c +3 -0
+ ? ? ? ?* in the host controller */
+ ? ? ? if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER)
+ ? ? ? ? ? ? ? return clk_round_rate(ourhost->clk_bus[2], 400000);

what's the clk_bus[2]?

Should be clk_bus[ourhost->cur_clk]

(snip)

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo at vger.kernel.org
More majordomo info at ?http://vger.kernel.org/majordomo-info.html

author maintainer
#5 lore raw

PATCH 1/1 sdhci-s3c: support non-standard clock setting for c210

In reply to Kukjin Kim
Quoted 17 lines · Kukjin Kim
Quoted 7 lines · Kyungmin Park
Quoted 5 lines · Kukjin Kim
Quoted 3 lines · Jaehoon Chung

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

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

Host Controller need other clock setting methods.

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

Quoted 8 lines

^^^
Unnecessary whitespace

If your patch includes arch/arm stuff, please add Linux-arm-kernel maillinglist.
(Cc'ed that)

i will send to Linux-arm-kernel mailing list.
If you want to test this patch. you also applied following patch. (ARM: Samsung: Fix header double inclusion)

arch/arm/plat-samsung/include/plat/devs.h +7 -1
index 85f6f23..42581f8 100644
@@ -8,7 +8,11 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
-*/
+ */
+
+#ifndef __PLAT_SAMSUNG_DEVS_H
+#define __PLAT_SAMSUNG_DEVS_H
+
 #include <linux/platform_device.h>
 
 struct s3c24xx_uart_resources {
@@ -128,3 +132,5 @@ extern struct platform_device s3c_device_ac97;
  */
 extern void *s3c_set_platdata(void *pd, size_t pdsize,
 			      struct platform_device *pdev);
+
+#endif

And s3c_hsmmc_setname() function could be used in cpu.c file

Thanks
Jaehoon Chung

Quoted 50 lines
Quoted 8 lines
Quoted 8 lines

Review

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

b/arch/arm/plat-

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

samsung/include/plat/sdhci.h
index 30844c2..7c75ee3 100644

arch/arm/plat-samsung/include/plat/sdhci.h +0 -0
@@ -15,6 +15,8 @@
 #ifndef __PLAT_S3C_SDHCI_H
 #define __PLAT_S3C_SDHCI_H __FILE__
 
Quoted 7 lines
Quoted 7 lines

arch/arm/plat-samsung/include/plat/sdhci.h static inline void s5pv210_default_sdhci3(void) { · line 290

Quoted 7 lines
arch/arm/plat-samsung/include/plat/sdhci.h +2 -0
+#include <plat/devs.h>
+
 struct platform_device;
 struct mmc_host;
 struct mmc_card;
@@ -288,4 +290,21 @@ static inline void s5pv210_default_sdhci3(void) {
 

}

Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
arch/arm/plat-samsung/include/plat/sdhci.h +13 -0
 #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
Quoted 8 lines
Quoted 8 lines

arch/arm/plat-samsung/include/plat/sdhci.h static inline void s5pv210_default_sdhci3(void) { · line 310

Quoted 6 lines
arch/arm/plat-samsung/include/plat/sdhci.h +4 -0
+     s3c_device_hsmmc3.name = name;
+#endif
+}
+
 #endif /* __PLAT_S3C_SDHCI_H */

It would be helpful to me if you could separate platform and driver

Quoted 2 lines

patches.

i will seperate platform and driver patches, then i will resend to mailing list.

Quoted 91 lines
Quoted 2 lines
Quoted 2 lines

And if you want to add s3c_hsmmc_setname(), please send together code

that

Quoted 5 lines
Quoted 5 lines

it is used.

Review

Quoted 2 lines
(quoted diff) +0 -0

b/drivers/mmc/host/sdhci-s3c.c

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

index 71ad416..3927793 100644

drivers/mmc/host/sdhci-s3c.c +0 -0

(snip)

Quoted 2 lines
Quoted 2 lines

How do you think about using quirk to separate S5PV310 case as

following?

Quoted 6 lines
Quoted 3 lines

I think this is more general method in here...And will be submitted soon after fixing something.

What's the meaning of "general method"?

I'd like to ask you why there is quirk in sdmmc driver.

Quoted 3 lines

and how/where do you set the host->quirks? when board or platform set the these quirks? who know it uses nonstandard quirk?

How about following?

static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
...

(quoted diff) +2 -0
+	if (pdev->id_entry->driver_data == TYPE_S5PV310)
+		host->quirks |= SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER;
...
Quoted 6 lines

In case s5pc210 don't have standard host controller. it's more clear to use own functions instead of quirks.

Why do we add another callback function?

Quoted 7 lines
Quoted 7 lines

From: Hyuk Lee <[email protected]>

drivers/mmc/host/sdhci-s3c.c +0 -0
index 71ad416..1ac2f36 100644

(snip)

Quoted 7 lines

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 262

Quoted 7 lines
drivers/mmc/host/sdhci-s3c.c +1 -0
@@ -221,6 +257,11 @@ static unsigned int sdhci_s3c_get_min_clock(struct
 sdhci_host *host)
       unsigned int delta, min = UINT_MAX;
       int src;
 
+       /* There is only one clock source(sclk) if there is no clock
 

divider

Quoted 7 lines

drivers/mmc/host/sdhci-s3c.c static unsigned int sdhci_s3c_get_min_clock(struct · line 266

Quoted 4 lines
drivers/mmc/host/sdhci-s3c.c +3 -0
+        * in the host controller */
+       if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER)
+               return clk_round_rate(ourhost->clk_bus[2], 400000);
 

what's the clk_bus[2]?

Should be clk_bus[ourhost->cur_clk]

(snip)

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

#6 lore raw

PATCH 1/1 sdhci-s3c: support non-standard clock setting for c210

In reply to Kyungmin Park
Quoted 4 lines · Kukjin Kim
Quoted 2 lines · Kyungmin Park

On Thu, Sep 2, 2010 at 7:20 PM, Kukjin Kim <[email protected]>

Quoted 10 lines · wrote:
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines · Jaehoon Chung

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.

Quoted 6 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

^^^
Unnecessary whitespace

If your patch includes arch/arm stuff, please add Linux-arm-kernel

maillinglist.

Quoted 10 lines

(Cc'ed that)

Quoted 8 lines
Quoted 8 lines

Review

Quoted 8 lines

---
 arch/arm/plat-samsung/include/plat/sdhci.h |   19 ++++++++ drivers/mmc/host/sdhci-s3c.c               |   68
++++++++++++++++++++++++++++

 2 files changed, 87 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/arch/arm/plat-

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

samsung/include/plat/sdhci.h
index 30844c2..7c75ee3 100644

arch/arm/plat-samsung/include/plat/sdhci.h +0 -0

(snip)

Quoted 1 line
Quoted 1 line
Quoted 1 line

Review

Quoted 1 line
(quoted diff) +0 -0

b/drivers/mmc/host/sdhci-s3c.c

Quoted 8 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

index 71ad416..3927793 100644

drivers/mmc/host/sdhci-s3c.c +0 -0

(snip)

Quoted 2 lines
Quoted 2 lines

How do you think about using quirk to separate S5PV310 case as

following?

Quoted 1 line
Quoted 1 line
Quoted 1 line

I think this is more general method in here...And will be submitted

soon

Quoted 1 line
Quoted 1 line
Quoted 1 line

after fixing something.

mm...I will think about your comments again. Then let's discuss about this issue.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

Quoted 18 lines
Quoted 2 lines

What's the meaning of "general method"?

I'd like to ask you why there is quirk in sdmmc driver.

Quoted 2 lines

and how/where do you set the host->quirks? when board or platform set the these quirks? who know it uses nonstandard quirk?

How about following?

static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
...

(quoted diff) +2 -0
+	if (pdev->id_entry->driver_data == TYPE_S5PV310)
+		host->quirks |= SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER;
...
Quoted 4 lines

In case s5pc210 don't have standard host controller. it's more clear to use own functions instead of quirks.

Quoted 6 lines

Why do we add another callback function?

Quoted 4 lines

Review

Quoted 4 lines

From: Hyuk Lee <[email protected]>

(quoted diff) +0 -0

b/drivers/mmc/host/sdhci-s3c.c

Quoted 7 lines
Quoted 3 lines
Quoted 3 lines

index 71ad416..1ac2f36 100644

drivers/mmc/host/sdhci-s3c.c +0 -0

(snip)

Quoted 1 line

drivers/mmc/host/sdhci-s3c.c static unsigned int

Quoted 1 line
drivers/mmc/host/sdhci-s3c.c +0 -0
@@ -221,6 +257,11 @@ static unsigned int

sdhci_s3c_get_min_clock(struct

Quoted 5 lines
Quoted 5 lines

drivers/mmc/host/sdhci-s3c.c static unsigned int · line 261

Quoted 5 lines
drivers/mmc/host/sdhci-s3c.c +1 -0
 sdhci_host *host)
        unsigned int delta, min = UINT_MAX;
        int src;
 
+       /* There is only one clock source(sclk) if there is no clock

divider

Quoted 9 lines
Quoted 5 lines

drivers/mmc/host/sdhci-s3c.c static unsigned int · line 264

Quoted 3 lines
drivers/mmc/host/sdhci-s3c.c +3 -0
+        * in the host controller */
+       if(host->quirks & SDHCI_QUIRK_BROKEN_CLOCK_DIVIDER)
+               return clk_round_rate(ourhost->clk_bus[2], 400000);

what's the clk_bus[2]?

Should be clk_bus[ourhost->cur_clk]

(snip)

#7 lore raw
In reply to Jaehoon Chung

To Ben,

Maybe you missing this patch. It's the jaehoon's approach.

Thank you,
Kyungmin Park

2010/8/31 Jaehoon Chung <[email protected]>:

Quoted 164 lines

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.

---
 arch/arm/plat-samsung/include/plat/sdhci.h |   19 ++++++++ drivers/mmc/host/sdhci-s3c.c               |   68 ++++++++++++++++++++++++++++

 2 files changed, 87 insertions(+), 0 deletions(-)
arch/arm/plat-samsung/include/plat/sdhci.h +19 -0
index 30844c2..7c75ee3 100644
@@ -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 */
drivers/mmc/host/sdhci-s3c.c +68 -2
index 71ad416..3927793 100644
@@ -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