diff options
| author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-10-26 12:56:40 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-10-31 11:21:39 -0400 |
| commit | d8cb70d10a2d4e6b083b89044a68d860d0bf1eec (patch) | |
| tree | d84cbb7ce12f6a2514237ef29688f2c40fbd3707 | |
| parent | 5984a2fc7e7c9ab118e78ae9799e98fc4ade40f9 (diff) | |
[ARM] Fix pxamci regression
Fix:
WARNING: at arch/arm/mach-pxa/clock.c:69 clk_disable()
[<c002d7c8>] (dump_stack+0x0/0x14) from [<c00334f4>] (clk_disable+0x34/0xa0)
[<c00334c0>] (clk_disable+0x0/0xa0) from [<c028a43c>] (pxamci_set_ios+0x74/0xf0)
[<c028a3c8>] (pxamci_set_ios+0x0/0xf0) from [<c0281548>] (mmc_power_off+0x90/0x9c)
[<c02814b8>] (mmc_power_off+0x0/0x9c) from [<c0281a30>] (mmc_start_host+0x18/0x28)
[<c0281a18>] (mmc_start_host+0x0/0x28) from [<c02825a0>] (mmc_add_host+0xe8/0x104)
[<c02824b8>] (mmc_add_host+0x0/0x104) from [<c028a7d0>] (pxamci_probe+0x24c/0x2f4)
[<c028a584>] (pxamci_probe+0x0/0x2f4) from [<c01e5948>] (platform_drv_probe+0x20/0x24)
...
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | drivers/mmc/host/pxamci.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index a25ee71998a9..1654a3330340 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #define DRIVER_NAME "pxa2xx-mci" | 39 | #define DRIVER_NAME "pxa2xx-mci" |
| 40 | 40 | ||
| 41 | #define NR_SG 1 | 41 | #define NR_SG 1 |
| 42 | #define CLKRT_OFF (~0) | ||
| 42 | 43 | ||
| 43 | struct pxamci_host { | 44 | struct pxamci_host { |
| 44 | struct mmc_host *mmc; | 45 | struct mmc_host *mmc; |
| @@ -371,6 +372,9 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 371 | unsigned long rate = host->clkrate; | 372 | unsigned long rate = host->clkrate; |
| 372 | unsigned int clk = rate / ios->clock; | 373 | unsigned int clk = rate / ios->clock; |
| 373 | 374 | ||
| 375 | if (host->clkrt == CLKRT_OFF) | ||
| 376 | clk_enable(host->clk); | ||
| 377 | |||
| 374 | /* | 378 | /* |
| 375 | * clk might result in a lower divisor than we | 379 | * clk might result in a lower divisor than we |
| 376 | * desire. check for that condition and adjust | 380 | * desire. check for that condition and adjust |
| @@ -379,14 +383,16 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 379 | if (rate / clk > ios->clock) | 383 | if (rate / clk > ios->clock) |
| 380 | clk <<= 1; | 384 | clk <<= 1; |
| 381 | host->clkrt = fls(clk) - 1; | 385 | host->clkrt = fls(clk) - 1; |
| 382 | clk_enable(host->clk); | ||
| 383 | 386 | ||
| 384 | /* | 387 | /* |
| 385 | * we write clkrt on the next command | 388 | * we write clkrt on the next command |
| 386 | */ | 389 | */ |
| 387 | } else { | 390 | } else { |
| 388 | pxamci_stop_clock(host); | 391 | pxamci_stop_clock(host); |
| 389 | clk_disable(host->clk); | 392 | if (host->clkrt != CLKRT_OFF) { |
| 393 | host->clkrt = CLKRT_OFF; | ||
| 394 | clk_disable(host->clk); | ||
| 395 | } | ||
| 390 | } | 396 | } |
| 391 | 397 | ||
| 392 | if (host->power_mode != ios->power_mode) { | 398 | if (host->power_mode != ios->power_mode) { |
| @@ -498,6 +504,7 @@ static int pxamci_probe(struct platform_device *pdev) | |||
| 498 | host->mmc = mmc; | 504 | host->mmc = mmc; |
| 499 | host->dma = -1; | 505 | host->dma = -1; |
| 500 | host->pdata = pdev->dev.platform_data; | 506 | host->pdata = pdev->dev.platform_data; |
| 507 | host->clkrt = CLKRT_OFF; | ||
| 501 | 508 | ||
| 502 | host->clk = clk_get(&pdev->dev, "MMCCLK"); | 509 | host->clk = clk_get(&pdev->dev, "MMCCLK"); |
| 503 | if (IS_ERR(host->clk)) { | 510 | if (IS_ERR(host->clk)) { |
