aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-pxav3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci-pxav3.c')
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c62
1 files changed, 40 insertions, 22 deletions
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 5036d7d39529..45238871192d 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -58,6 +58,12 @@
58#define SDCE_MISC_INT (1<<2) 58#define SDCE_MISC_INT (1<<2)
59#define SDCE_MISC_INT_EN (1<<1) 59#define SDCE_MISC_INT_EN (1<<1)
60 60
61struct sdhci_pxa {
62 struct clk *clk_core;
63 struct clk *clk_io;
64 u8 power_mode;
65};
66
61/* 67/*
62 * These registers are relative to the second register region, for the 68 * These registers are relative to the second register region, for the
63 * MBus bridge. 69 * MBus bridge.
@@ -211,6 +217,7 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
211 case MMC_TIMING_UHS_SDR104: 217 case MMC_TIMING_UHS_SDR104:
212 ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180; 218 ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
213 break; 219 break;
220 case MMC_TIMING_MMC_DDR52:
214 case MMC_TIMING_UHS_DDR50: 221 case MMC_TIMING_UHS_DDR50:
215 ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180; 222 ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
216 break; 223 break;
@@ -283,9 +290,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
283 struct sdhci_host *host = NULL; 290 struct sdhci_host *host = NULL;
284 struct sdhci_pxa *pxa = NULL; 291 struct sdhci_pxa *pxa = NULL;
285 const struct of_device_id *match; 292 const struct of_device_id *match;
286
287 int ret; 293 int ret;
288 struct clk *clk;
289 294
290 pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL); 295 pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL);
291 if (!pxa) 296 if (!pxa)
@@ -305,14 +310,20 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
305 pltfm_host = sdhci_priv(host); 310 pltfm_host = sdhci_priv(host);
306 pltfm_host->priv = pxa; 311 pltfm_host->priv = pxa;
307 312
308 clk = devm_clk_get(dev, NULL); 313 pxa->clk_io = devm_clk_get(dev, "io");
309 if (IS_ERR(clk)) { 314 if (IS_ERR(pxa->clk_io))
315 pxa->clk_io = devm_clk_get(dev, NULL);
316 if (IS_ERR(pxa->clk_io)) {
310 dev_err(dev, "failed to get io clock\n"); 317 dev_err(dev, "failed to get io clock\n");
311 ret = PTR_ERR(clk); 318 ret = PTR_ERR(pxa->clk_io);
312 goto err_clk_get; 319 goto err_clk_get;
313 } 320 }
314 pltfm_host->clk = clk; 321 pltfm_host->clk = pxa->clk_io;
315 clk_prepare_enable(clk); 322 clk_prepare_enable(pxa->clk_io);
323
324 pxa->clk_core = devm_clk_get(dev, "core");
325 if (!IS_ERR(pxa->clk_core))
326 clk_prepare_enable(pxa->clk_core);
316 327
317 /* enable 1/8V DDR capable */ 328 /* enable 1/8V DDR capable */
318 host->mmc->caps |= MMC_CAP_1_8V_DDR; 329 host->mmc->caps |= MMC_CAP_1_8V_DDR;
@@ -385,7 +396,9 @@ err_add_host:
385 pm_runtime_disable(&pdev->dev); 396 pm_runtime_disable(&pdev->dev);
386err_of_parse: 397err_of_parse:
387err_cd_req: 398err_cd_req:
388 clk_disable_unprepare(clk); 399 clk_disable_unprepare(pxa->clk_io);
400 if (!IS_ERR(pxa->clk_core))
401 clk_disable_unprepare(pxa->clk_core);
389err_clk_get: 402err_clk_get:
390err_mbus_win: 403err_mbus_win:
391 sdhci_pltfm_free(pdev); 404 sdhci_pltfm_free(pdev);
@@ -396,12 +409,15 @@ static int sdhci_pxav3_remove(struct platform_device *pdev)
396{ 409{
397 struct sdhci_host *host = platform_get_drvdata(pdev); 410 struct sdhci_host *host = platform_get_drvdata(pdev);
398 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 411 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
412 struct sdhci_pxa *pxa = pltfm_host->priv;
399 413
400 pm_runtime_get_sync(&pdev->dev); 414 pm_runtime_get_sync(&pdev->dev);
401 sdhci_remove_host(host, 1); 415 sdhci_remove_host(host, 1);
402 pm_runtime_disable(&pdev->dev); 416 pm_runtime_disable(&pdev->dev);
403 417
404 clk_disable_unprepare(pltfm_host->clk); 418 clk_disable_unprepare(pxa->clk_io);
419 if (!IS_ERR(pxa->clk_core))
420 clk_disable_unprepare(pxa->clk_core);
405 421
406 sdhci_pltfm_free(pdev); 422 sdhci_pltfm_free(pdev);
407 423
@@ -436,20 +452,21 @@ static int sdhci_pxav3_resume(struct device *dev)
436} 452}
437#endif 453#endif
438 454
439#ifdef CONFIG_PM_RUNTIME 455#ifdef CONFIG_PM
440static int sdhci_pxav3_runtime_suspend(struct device *dev) 456static int sdhci_pxav3_runtime_suspend(struct device *dev)
441{ 457{
442 struct sdhci_host *host = dev_get_drvdata(dev); 458 struct sdhci_host *host = dev_get_drvdata(dev);
443 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 459 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
460 struct sdhci_pxa *pxa = pltfm_host->priv;
444 unsigned long flags; 461 unsigned long flags;
445 462
446 if (pltfm_host->clk) { 463 spin_lock_irqsave(&host->lock, flags);
447 spin_lock_irqsave(&host->lock, flags); 464 host->runtime_suspended = true;
448 host->runtime_suspended = true; 465 spin_unlock_irqrestore(&host->lock, flags);
449 spin_unlock_irqrestore(&host->lock, flags);
450 466
451 clk_disable_unprepare(pltfm_host->clk); 467 clk_disable_unprepare(pxa->clk_io);
452 } 468 if (!IS_ERR(pxa->clk_core))
469 clk_disable_unprepare(pxa->clk_core);
453 470
454 return 0; 471 return 0;
455} 472}
@@ -458,15 +475,16 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
458{ 475{
459 struct sdhci_host *host = dev_get_drvdata(dev); 476 struct sdhci_host *host = dev_get_drvdata(dev);
460 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 477 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
478 struct sdhci_pxa *pxa = pltfm_host->priv;
461 unsigned long flags; 479 unsigned long flags;
462 480
463 if (pltfm_host->clk) { 481 clk_prepare_enable(pxa->clk_io);
464 clk_prepare_enable(pltfm_host->clk); 482 if (!IS_ERR(pxa->clk_core))
483 clk_prepare_enable(pxa->clk_core);
465 484
466 spin_lock_irqsave(&host->lock, flags); 485 spin_lock_irqsave(&host->lock, flags);
467 host->runtime_suspended = false; 486 host->runtime_suspended = false;
468 spin_unlock_irqrestore(&host->lock, flags); 487 spin_unlock_irqrestore(&host->lock, flags);
469 }
470 488
471 return 0; 489 return 0;
472} 490}