* [PATCH] sdhci-s3c: support non-standard clock setting for c210
@ 2010-08-31 10:32 Jaehoon Chung
2010-09-02 10:20 ` Kukjin Kim
2010-09-28 5:31 ` Kyungmin Park
0 siblings, 2 replies; 8+ messages in thread
From: Jaehoon Chung @ 2010-08-31 10:32 UTC (permalink / raw)
To: linux-mmc, Kyungmin Park, matt, Marek Szyprowski, Kukjin Kim,
Andrew
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 <jh80.chung@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
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
^ permalink raw reply related [flat|nested] 8+ messages in thread
* RE: [PATCH] sdhci-s3c: support non-standard clock setting for c210
2010-08-31 10:32 [PATCH] sdhci-s3c: support non-standard clock setting for c210 Jaehoon Chung
@ 2010-09-02 10:20 ` Kukjin Kim
2010-09-02 10:32 ` Kyungmin Park
2010-09-28 5:31 ` Kyungmin Park
1 sibling, 1 reply; 8+ messages in thread
From: Kukjin Kim @ 2010-09-02 10:20 UTC (permalink / raw)
To: 'Jaehoon Chung', linux-mmc, 'Kyungmin Park', matt,
'Marek Szyprowski'
Jaehoon Chung wrote:
>
> 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 <jh80.chung@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>
> ---
> 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 */
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.
> 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
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 <hyuk1.lee@samsung.com>
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 71ad416..1ac2f36 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -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 <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] sdhci-s3c: support non-standard clock setting for c210
2010-09-02 10:20 ` Kukjin Kim
@ 2010-09-02 10:32 ` Kyungmin Park
2010-09-02 10:47 ` Kukjin Kim
2010-09-02 11:00 ` Kukjin Kim
0 siblings, 2 replies; 8+ messages in thread
From: Kyungmin Park @ 2010-09-02 10:32 UTC (permalink / raw)
To: Kukjin Kim
Cc: Jaehoon Chung, linux-mmc, matt, Marek Szyprowski, Andrew Morton,
Ben Dooks
On Thu, Sep 2, 2010 at 7:20 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> Jaehoon Chung wrote:
>>
>> 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 <jh80.chung@samsung.com>
>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>>
>> ---
>> 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 */
>
> 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.
>
>> 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
>
> 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.
>
> From: Hyuk Lee <hyuk1.lee@samsung.com>
>
> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> index 71ad416..1ac2f36 100644
> --- a/drivers/mmc/host/sdhci-s3c.c
> +++ b/drivers/mmc/host/sdhci-s3c.c
> @@ -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);
what's the clk_bus[2]?
Thank you,
Kyungmin Park
> +
> 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 <kgene.kim@samsung.com>, 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@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH] sdhci-s3c: support non-standard clock setting for c210
2010-09-02 10:32 ` Kyungmin Park
@ 2010-09-02 10:47 ` Kukjin Kim
2010-09-02 11:01 ` Kyungmin Park
2010-09-02 11:01 ` Jaehoon Chung
2010-09-02 11:00 ` Kukjin Kim
1 sibling, 2 replies; 8+ messages in thread
From: Kukjin Kim @ 2010-09-02 10:47 UTC (permalink / raw)
To: 'Kyungmin Park'
Cc: 'Jaehoon Chung', linux-mmc, matt,
'Marek Szyprowski', 'Andrew Morton',
'Ben Dooks', linux-arm-kernel
Kyungmin Park wrote:
>
> On Thu, Sep 2, 2010 at 7:20 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> > Jaehoon Chung wrote:
> >>
> >> 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 <jh80.chung@samsung.com>
> >> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
^^^
Unnecessary whitespace
If your patch includes arch/arm stuff, please add Linux-arm-kernel
maillinglist.
(Cc'ed that)
> >>
> >> ---
> >> 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 */
> >
> > 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.
> >
> >> 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
(snip)
> >
> > 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"?
>
I'd like to ask you why there is quirk in sdmmc driver.
> 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;
...
> 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?
> >
> > From: Hyuk Lee <hyuk1.lee@samsung.com>
> >
> > diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> > index 71ad416..1ac2f36 100644
> > --- a/drivers/mmc/host/sdhci-s3c.c
> > +++ b/drivers/mmc/host/sdhci-s3c.c
(snip)
> > @@ -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]?
>
Should be clk_bus[ourhost->cur_clk]
(snip)
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH] sdhci-s3c: support non-standard clock setting for c210
2010-09-02 10:32 ` Kyungmin Park
2010-09-02 10:47 ` Kukjin Kim
@ 2010-09-02 11:00 ` Kukjin Kim
1 sibling, 0 replies; 8+ messages in thread
From: Kukjin Kim @ 2010-09-02 11:00 UTC (permalink / raw)
To: 'Kukjin Kim', 'Kyungmin Park'
Cc: 'Jaehoon Chung', linux-mmc, matt,
'Marek Szyprowski', 'Andrew Morton',
'Ben Dooks', linux-arm-kernel
Kukjin Kim wrote:
>
> Kyungmin Park wrote:
> >
> > On Thu, Sep 2, 2010 at 7:20 PM, Kukjin Kim <kgene.kim@samsung.com>
wrote:
> > > Jaehoon Chung wrote:
> > >>
> > >> 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 <jh80.chung@samsung.com>
> > >> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ^^^
> Unnecessary whitespace
>
> If your patch includes arch/arm stuff, please add Linux-arm-kernel
maillinglist.
> (Cc'ed that)
>
> > >>
> > >> ---
> > >> 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
(snip)
> > >> 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
>
> (snip)
>
> > >
> > > 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.
mm...I will think about your comments again. Then let's discuss about this
issue.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
> > What's the meaning of "general method"?
> >
> I'd like to ask you why there is quirk in sdmmc driver.
>
> > 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;
> ...
>
> > 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?
>
> > >
> > > From: Hyuk Lee <hyuk1.lee@samsung.com>
> > >
> > > diff --git a/drivers/mmc/host/sdhci-s3c.c
b/drivers/mmc/host/sdhci-s3c.c
> > > index 71ad416..1ac2f36 100644
> > > --- a/drivers/mmc/host/sdhci-s3c.c
> > > +++ b/drivers/mmc/host/sdhci-s3c.c
>
> (snip)
>
> > > @@ -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]?
> >
> Should be clk_bus[ourhost->cur_clk]
>
> (snip)
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] sdhci-s3c: support non-standard clock setting for c210
2010-09-02 10:47 ` Kukjin Kim
@ 2010-09-02 11:01 ` Kyungmin Park
2010-09-02 11:01 ` Jaehoon Chung
1 sibling, 0 replies; 8+ messages in thread
From: Kyungmin Park @ 2010-09-02 11:01 UTC (permalink / raw)
To: Kukjin Kim
Cc: Jaehoon Chung, linux-mmc, matt, Marek Szyprowski, Andrew Morton,
Ben Dooks, linux-arm-kernel
On Thu, Sep 2, 2010 at 7:47 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> Kyungmin Park wrote:
>>
>> On Thu, Sep 2, 2010 at 7:20 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
>> > Jaehoon Chung wrote:
>> >>
>> >> 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 <jh80.chung@samsung.com>
>> >> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ^^^
> Unnecessary whitespace
>
> If your patch includes arch/arm stuff, please add Linux-arm-kernel
> maillinglist.
> (Cc'ed that)
>
>> >>
>> >> ---
>> >> 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 */
>> >
>> > 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.
>> >
>> >> 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
>
> (snip)
>
>> >
>> > 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"?
>>
> I'd like to ask you why there is quirk in sdmmc driver.
>
>> 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;
What's the difference override the functions?
> ...
>
>> 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
>
>> >
>> > From: Hyuk Lee <hyuk1.lee@samsung.com>
>> >
>> > diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
>> > index 71ad416..1ac2f36 100644
>> > --- a/drivers/mmc/host/sdhci-s3c.c
>> > +++ b/drivers/mmc/host/sdhci-s3c.c
>
> (snip)
>
>> > @@ -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]?
>>
> Should be clk_bus[ourhost->cur_clk]
>
> (snip)
>
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, 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@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] sdhci-s3c: support non-standard clock setting for c210
2010-09-02 10:47 ` Kukjin Kim
2010-09-02 11:01 ` Kyungmin Park
@ 2010-09-02 11:01 ` Jaehoon Chung
1 sibling, 0 replies; 8+ messages in thread
From: Jaehoon Chung @ 2010-09-02 11:01 UTC (permalink / raw)
To: Kukjin Kim
Cc: 'Kyungmin Park', linux-mmc, matt,
'Marek Szyprowski', 'Andrew Morton',
'Ben Dooks', linux-arm-kernel
Kukjin Kim wrote:
> Kyungmin Park wrote:
>
>> On Thu, Sep 2, 2010 at 7:20 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
>>
>>> Jaehoon Chung wrote:
>>>
>>>> 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 <jh80.chung@samsung.com>
>>>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>>>>
> ^^^
> 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)
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 85f6f23..42581f8 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -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
>>>> ---
>>>> 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 */
>>>>
>>> It would be helpful to me if you could separate platform and driver
>>>
> patches.
>
i will seperate platform and driver patches, then i will resend to
mailing list.
>>> And if you want to add s3c_hsmmc_setname(), please send together code
>>>
> that
>
>>> it is used.
>>>
>>>
>>>> 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
>>>>
>
> (snip)
>
>
>>> 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"?
>>
>>
> I'd like to ask you why there is quirk in sdmmc driver.
>
>
>> 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;
> ...
>
>
>> 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?
>
>
>>> From: Hyuk Lee <hyuk1.lee@samsung.com>
>>>
>>> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
>>> index 71ad416..1ac2f36 100644
>>> --- a/drivers/mmc/host/sdhci-s3c.c
>>> +++ b/drivers/mmc/host/sdhci-s3c.c
>>>
>
> (snip)
>
>
>>> @@ -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]?
>>
>>
> Should be clk_bus[ourhost->cur_clk]
>
> (snip)
>
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.
>
>
>
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] sdhci-s3c: support non-standard clock setting for c210
2010-08-31 10:32 [PATCH] sdhci-s3c: support non-standard clock setting for c210 Jaehoon Chung
2010-09-02 10:20 ` Kukjin Kim
@ 2010-09-28 5:31 ` Kyungmin Park
1 sibling, 0 replies; 8+ messages in thread
From: Kyungmin Park @ 2010-09-28 5:31 UTC (permalink / raw)
To: Jaehoon Chung
Cc: linux-mmc, matt, Marek Szyprowski, Kukjin Kim, Andrew Morton,
Ben Dooks
To Ben,
Maybe you missing this patch. It's the jaehoon's approach.
Thank you,
Kyungmin Park
2010/8/31 Jaehoon Chung <jh80.chung@samsung.com>:
> 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 <jh80.chung@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>
> ---
> 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 majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-09-28 5:31 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-31 10:32 [PATCH] sdhci-s3c: support non-standard clock setting for c210 Jaehoon Chung
2010-09-02 10:20 ` Kukjin Kim
2010-09-02 10:32 ` Kyungmin Park
2010-09-02 10:47 ` Kukjin Kim
2010-09-02 11:01 ` Kyungmin Park
2010-09-02 11:01 ` Jaehoon Chung
2010-09-02 11:00 ` Kukjin Kim
2010-09-28 5:31 ` Kyungmin Park
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).