sdhci-sirf.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * SDHCI support for SiRF primaII and marco SoCs
  3. *
  4. * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
  5. *
  6. * Licensed under GPLv2 or later.
  7. */
  8. #include <linux/delay.h>
  9. #include <linux/device.h>
  10. #include <linux/mmc/host.h>
  11. #include <linux/module.h>
  12. #include <linux/of.h>
  13. #include <linux/of_gpio.h>
  14. #include <linux/mmc/slot-gpio.h>
  15. #include <linux/pinctrl/consumer.h>
  16. #include "sdhci-pltfm.h"
  17. struct sdhci_sirf_priv {
  18. struct clk *clk;
  19. int gpio_cd;
  20. };
  21. static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
  22. {
  23. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  24. struct sdhci_sirf_priv *priv = pltfm_host->priv;
  25. return clk_get_rate(priv->clk);
  26. }
  27. static struct sdhci_ops sdhci_sirf_ops = {
  28. .get_max_clock = sdhci_sirf_get_max_clk,
  29. };
  30. static struct sdhci_pltfm_data sdhci_sirf_pdata = {
  31. .ops = &sdhci_sirf_ops,
  32. .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
  33. SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
  34. SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
  35. SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
  36. SDHCI_QUIRK_DELAY_AFTER_POWER,
  37. };
  38. static int sdhci_sirf_probe(struct platform_device *pdev)
  39. {
  40. struct sdhci_host *host;
  41. struct sdhci_pltfm_host *pltfm_host;
  42. struct sdhci_sirf_priv *priv;
  43. struct pinctrl *pinctrl;
  44. int ret;
  45. pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  46. if (IS_ERR(pinctrl)) {
  47. dev_err(&pdev->dev, "unable to get pinmux");
  48. return PTR_ERR(pinctrl);
  49. }
  50. priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_sirf_priv),
  51. GFP_KERNEL);
  52. if (!priv) {
  53. dev_err(&pdev->dev, "unable to allocate private data");
  54. return -ENOMEM;
  55. }
  56. priv->clk = devm_clk_get(&pdev->dev, NULL);
  57. if (IS_ERR(priv->clk)) {
  58. dev_err(&pdev->dev, "unable to get clock");
  59. return PTR_ERR(priv->clk);
  60. }
  61. if (pdev->dev.of_node) {
  62. priv->gpio_cd = of_get_named_gpio(pdev->dev.of_node,
  63. "cd-gpios", 0);
  64. } else {
  65. priv->gpio_cd = -EINVAL;
  66. }
  67. host = sdhci_pltfm_init(pdev, &sdhci_sirf_pdata);
  68. if (IS_ERR(host)) {
  69. ret = PTR_ERR(host);
  70. goto err_sdhci_pltfm_init;
  71. }
  72. pltfm_host = sdhci_priv(host);
  73. pltfm_host->priv = priv;
  74. sdhci_get_of_property(pdev);
  75. clk_prepare_enable(priv->clk);
  76. ret = sdhci_add_host(host);
  77. if (ret)
  78. goto err_sdhci_add;
  79. /*
  80. * We must request the IRQ after sdhci_add_host(), as the tasklet only
  81. * gets setup in sdhci_add_host() and we oops.
  82. */
  83. if (gpio_is_valid(priv->gpio_cd)) {
  84. ret = mmc_gpio_request_cd(host->mmc, priv->gpio_cd);
  85. if (ret) {
  86. dev_err(&pdev->dev, "card detect irq request failed: %d\n",
  87. ret);
  88. goto err_request_cd;
  89. }
  90. }
  91. return 0;
  92. err_request_cd:
  93. sdhci_remove_host(host, 0);
  94. err_sdhci_add:
  95. clk_disable_unprepare(priv->clk);
  96. sdhci_pltfm_free(pdev);
  97. err_sdhci_pltfm_init:
  98. return ret;
  99. }
  100. static int sdhci_sirf_remove(struct platform_device *pdev)
  101. {
  102. struct sdhci_host *host = platform_get_drvdata(pdev);
  103. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  104. struct sdhci_sirf_priv *priv = pltfm_host->priv;
  105. sdhci_pltfm_unregister(pdev);
  106. if (gpio_is_valid(priv->gpio_cd))
  107. mmc_gpio_free_cd(host->mmc);
  108. clk_disable_unprepare(priv->clk);
  109. return 0;
  110. }
  111. #ifdef CONFIG_PM_SLEEP
  112. static int sdhci_sirf_suspend(struct device *dev)
  113. {
  114. struct sdhci_host *host = dev_get_drvdata(dev);
  115. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  116. struct sdhci_sirf_priv *priv = pltfm_host->priv;
  117. int ret;
  118. ret = sdhci_suspend_host(host);
  119. if (ret)
  120. return ret;
  121. clk_disable(priv->clk);
  122. return 0;
  123. }
  124. static int sdhci_sirf_resume(struct device *dev)
  125. {
  126. struct sdhci_host *host = dev_get_drvdata(dev);
  127. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  128. struct sdhci_sirf_priv *priv = pltfm_host->priv;
  129. int ret;
  130. ret = clk_enable(priv->clk);
  131. if (ret) {
  132. dev_dbg(dev, "Resume: Error enabling clock\n");
  133. return ret;
  134. }
  135. return sdhci_resume_host(host);
  136. }
  137. static SIMPLE_DEV_PM_OPS(sdhci_sirf_pm_ops, sdhci_sirf_suspend, sdhci_sirf_resume);
  138. #endif
  139. static const struct of_device_id sdhci_sirf_of_match[] = {
  140. { .compatible = "sirf,prima2-sdhc" },
  141. { }
  142. };
  143. MODULE_DEVICE_TABLE(of, sdhci_sirf_of_match);
  144. static struct platform_driver sdhci_sirf_driver = {
  145. .driver = {
  146. .name = "sdhci-sirf",
  147. .owner = THIS_MODULE,
  148. .of_match_table = sdhci_sirf_of_match,
  149. #ifdef CONFIG_PM_SLEEP
  150. .pm = &sdhci_sirf_pm_ops,
  151. #endif
  152. },
  153. .probe = sdhci_sirf_probe,
  154. .remove = sdhci_sirf_remove,
  155. };
  156. module_platform_driver(sdhci_sirf_driver);
  157. MODULE_DESCRIPTION("SDHCI driver for SiRFprimaII/SiRFmarco");
  158. MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
  159. MODULE_LICENSE("GPL v2");