Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 228905
b: refs/heads/master
c: 253e0a7
h: refs/heads/master
i:
  228903: 78f0576
v: v3
  • Loading branch information
Jeongbae Seo authored and Chris Ball committed Jan 9, 2011
1 parent 6e51198 commit a82741e
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b3824f2c6f16ef19060a53ef9345a124de175098
refs/heads/master: 253e0a7c3dc4bbbc69fc6bfd7c01bc4c9397a5e5
62 changes: 62 additions & 0 deletions trunk/drivers/mmc/host/sdhci-s3c.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
if (!clksrc)
return UINT_MAX;

/*
* Clock divider's step is different as 1 from that of host controller
* when 'clk_type' is S3C_SDHCI_CLK_DIV_EXTERNAL.
*/
if (ourhost->pdata->clk_type) {
rate = clk_round_rate(clksrc, wanted);
return wanted - rate;
}

rate = clk_get_rate(clksrc);

for (div = 1; div < 256; div *= 2) {
Expand Down Expand Up @@ -232,6 +241,42 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
return min;
}

/* sdhci_cmu_get_max_clk - callback to get maximum clock frequency.*/
static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host)
{
struct sdhci_s3c *ourhost = to_s3c(host);

return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], UINT_MAX);
}

/* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */
static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host)
{
struct sdhci_s3c *ourhost = to_s3c(host);

/*
* initial clock can be in the frequency range of
* 100KHz-400KHz, so we set it as max value.
*/
return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], 400000);
}

/* sdhci_cmu_set_clock - callback on clock change.*/
static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
{
struct sdhci_s3c *ourhost = to_s3c(host);

/* don't bother if the clock is going off */
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,
Expand Down Expand Up @@ -361,6 +406,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)

clks++;
sc->clk_bus[ptr] = clk;

/*
* save current clock index to know which clock bus
* is used later in overriding functions.
*/
sc->cur_clk = ptr;

clk_enable(clk);

dev_info(dev, "clock source %d: %s (%ld Hz)\n",
Expand Down Expand Up @@ -427,6 +479,16 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
/* HSMMC on Samsung SoCs uses SDCLK as timeout clock */
host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;

/*
* If controller does not have internal clock divider,
* we can use overriding functions instead of default.
*/
if (pdata->clk_type) {
sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
}

/* It supports additional host capabilities if needed */
if (pdata->host_caps)
host->mmc->caps |= pdata->host_caps;
Expand Down

0 comments on commit a82741e

Please sign in to comment.