diff options
-rw-r--r-- | drivers/mmc/host/atmel-mci.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index bdb84da74952..69e438ee043e 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -378,6 +378,8 @@ static int atmci_regs_show(struct seq_file *s, void *v) | |||
378 | { | 378 | { |
379 | struct atmel_mci *host = s->private; | 379 | struct atmel_mci *host = s->private; |
380 | u32 *buf; | 380 | u32 *buf; |
381 | int ret = 0; | ||
382 | |||
381 | 383 | ||
382 | buf = kmalloc(ATMCI_REGS_SIZE, GFP_KERNEL); | 384 | buf = kmalloc(ATMCI_REGS_SIZE, GFP_KERNEL); |
383 | if (!buf) | 385 | if (!buf) |
@@ -388,12 +390,16 @@ static int atmci_regs_show(struct seq_file *s, void *v) | |||
388 | * not disabling interrupts, so IMR and SR may not be | 390 | * not disabling interrupts, so IMR and SR may not be |
389 | * consistent. | 391 | * consistent. |
390 | */ | 392 | */ |
393 | ret = clk_prepare_enable(host->mck); | ||
394 | if (ret) | ||
395 | goto out; | ||
396 | |||
391 | spin_lock_bh(&host->lock); | 397 | spin_lock_bh(&host->lock); |
392 | clk_enable(host->mck); | ||
393 | memcpy_fromio(buf, host->regs, ATMCI_REGS_SIZE); | 398 | memcpy_fromio(buf, host->regs, ATMCI_REGS_SIZE); |
394 | clk_disable(host->mck); | ||
395 | spin_unlock_bh(&host->lock); | 399 | spin_unlock_bh(&host->lock); |
396 | 400 | ||
401 | clk_disable_unprepare(host->mck); | ||
402 | |||
397 | seq_printf(s, "MR:\t0x%08x%s%s ", | 403 | seq_printf(s, "MR:\t0x%08x%s%s ", |
398 | buf[ATMCI_MR / 4], | 404 | buf[ATMCI_MR / 4], |
399 | buf[ATMCI_MR / 4] & ATMCI_MR_RDPROOF ? " RDPROOF" : "", | 405 | buf[ATMCI_MR / 4] & ATMCI_MR_RDPROOF ? " RDPROOF" : "", |
@@ -442,9 +448,10 @@ static int atmci_regs_show(struct seq_file *s, void *v) | |||
442 | val & ATMCI_CFG_LSYNC ? " LSYNC" : ""); | 448 | val & ATMCI_CFG_LSYNC ? " LSYNC" : ""); |
443 | } | 449 | } |
444 | 450 | ||
451 | out: | ||
445 | kfree(buf); | 452 | kfree(buf); |
446 | 453 | ||
447 | return 0; | 454 | return ret; |
448 | } | 455 | } |
449 | 456 | ||
450 | static int atmci_regs_open(struct inode *inode, struct file *file) | 457 | static int atmci_regs_open(struct inode *inode, struct file *file) |
@@ -1262,6 +1269,7 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1262 | struct atmel_mci_slot *slot = mmc_priv(mmc); | 1269 | struct atmel_mci_slot *slot = mmc_priv(mmc); |
1263 | struct atmel_mci *host = slot->host; | 1270 | struct atmel_mci *host = slot->host; |
1264 | unsigned int i; | 1271 | unsigned int i; |
1272 | bool unprepare_clk; | ||
1265 | 1273 | ||
1266 | slot->sdc_reg &= ~ATMCI_SDCBUS_MASK; | 1274 | slot->sdc_reg &= ~ATMCI_SDCBUS_MASK; |
1267 | switch (ios->bus_width) { | 1275 | switch (ios->bus_width) { |
@@ -1277,9 +1285,13 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1277 | unsigned int clock_min = ~0U; | 1285 | unsigned int clock_min = ~0U; |
1278 | u32 clkdiv; | 1286 | u32 clkdiv; |
1279 | 1287 | ||
1288 | clk_prepare(host->mck); | ||
1289 | unprepare_clk = true; | ||
1290 | |||
1280 | spin_lock_bh(&host->lock); | 1291 | spin_lock_bh(&host->lock); |
1281 | if (!host->mode_reg) { | 1292 | if (!host->mode_reg) { |
1282 | clk_enable(host->mck); | 1293 | clk_enable(host->mck); |
1294 | unprepare_clk = false; | ||
1283 | atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); | 1295 | atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); |
1284 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN); | 1296 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN); |
1285 | if (host->caps.has_cfg_reg) | 1297 | if (host->caps.has_cfg_reg) |
@@ -1347,6 +1359,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1347 | } else { | 1359 | } else { |
1348 | bool any_slot_active = false; | 1360 | bool any_slot_active = false; |
1349 | 1361 | ||
1362 | unprepare_clk = false; | ||
1363 | |||
1350 | spin_lock_bh(&host->lock); | 1364 | spin_lock_bh(&host->lock); |
1351 | slot->clock = 0; | 1365 | slot->clock = 0; |
1352 | for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { | 1366 | for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { |
@@ -1360,12 +1374,16 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1360 | if (host->mode_reg) { | 1374 | if (host->mode_reg) { |
1361 | atmci_readl(host, ATMCI_MR); | 1375 | atmci_readl(host, ATMCI_MR); |
1362 | clk_disable(host->mck); | 1376 | clk_disable(host->mck); |
1377 | unprepare_clk = true; | ||
1363 | } | 1378 | } |
1364 | host->mode_reg = 0; | 1379 | host->mode_reg = 0; |
1365 | } | 1380 | } |
1366 | spin_unlock_bh(&host->lock); | 1381 | spin_unlock_bh(&host->lock); |
1367 | } | 1382 | } |
1368 | 1383 | ||
1384 | if (unprepare_clk) | ||
1385 | clk_unprepare(host->mck); | ||
1386 | |||
1369 | switch (ios->power_mode) { | 1387 | switch (ios->power_mode) { |
1370 | case MMC_POWER_UP: | 1388 | case MMC_POWER_UP: |
1371 | set_bit(ATMCI_CARD_NEED_INIT, &slot->flags); | 1389 | set_bit(ATMCI_CARD_NEED_INIT, &slot->flags); |
@@ -2376,10 +2394,12 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
2376 | if (!host->regs) | 2394 | if (!host->regs) |
2377 | goto err_ioremap; | 2395 | goto err_ioremap; |
2378 | 2396 | ||
2379 | clk_enable(host->mck); | 2397 | ret = clk_prepare_enable(host->mck); |
2398 | if (ret) | ||
2399 | goto err_request_irq; | ||
2380 | atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); | 2400 | atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); |
2381 | host->bus_hz = clk_get_rate(host->mck); | 2401 | host->bus_hz = clk_get_rate(host->mck); |
2382 | clk_disable(host->mck); | 2402 | clk_disable_unprepare(host->mck); |
2383 | 2403 | ||
2384 | host->mapbase = regs->start; | 2404 | host->mapbase = regs->start; |
2385 | 2405 | ||
@@ -2482,11 +2502,11 @@ static int __exit atmci_remove(struct platform_device *pdev) | |||
2482 | atmci_cleanup_slot(host->slot[i], i); | 2502 | atmci_cleanup_slot(host->slot[i], i); |
2483 | } | 2503 | } |
2484 | 2504 | ||
2485 | clk_enable(host->mck); | 2505 | clk_prepare_enable(host->mck); |
2486 | atmci_writel(host, ATMCI_IDR, ~0UL); | 2506 | atmci_writel(host, ATMCI_IDR, ~0UL); |
2487 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS); | 2507 | atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS); |
2488 | atmci_readl(host, ATMCI_SR); | 2508 | atmci_readl(host, ATMCI_SR); |
2489 | clk_disable(host->mck); | 2509 | clk_disable_unprepare(host->mck); |
2490 | 2510 | ||
2491 | if (host->dma.chan) | 2511 | if (host->dma.chan) |
2492 | dma_release_channel(host->dma.chan); | 2512 | dma_release_channel(host->dma.chan); |