dw_mmc-k3.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (c) 2013 Linaro Ltd.
  3. * Copyright (c) 2013 Hisilicon Limited.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/clk.h>
  13. #include <linux/mmc/host.h>
  14. #include <linux/mmc/dw_mmc.h>
  15. #include <linux/of_address.h>
  16. #include "dw_mmc.h"
  17. #include "dw_mmc-pltfm.h"
  18. static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios)
  19. {
  20. int ret;
  21. ret = clk_set_rate(host->ciu_clk, ios->clock);
  22. if (ret)
  23. dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
  24. host->bus_hz = clk_get_rate(host->ciu_clk);
  25. }
  26. static const struct dw_mci_drv_data k3_drv_data = {
  27. .set_ios = dw_mci_k3_set_ios,
  28. };
  29. static const struct of_device_id dw_mci_k3_match[] = {
  30. { .compatible = "hisilicon,hi4511-dw-mshc", .data = &k3_drv_data, },
  31. {},
  32. };
  33. MODULE_DEVICE_TABLE(of, dw_mci_k3_match);
  34. static int dw_mci_k3_probe(struct platform_device *pdev)
  35. {
  36. const struct dw_mci_drv_data *drv_data;
  37. const struct of_device_id *match;
  38. match = of_match_node(dw_mci_k3_match, pdev->dev.of_node);
  39. drv_data = match->data;
  40. return dw_mci_pltfm_register(pdev, drv_data);
  41. }
  42. #ifdef CONFIG_PM_SLEEP
  43. static int dw_mci_k3_suspend(struct device *dev)
  44. {
  45. struct dw_mci *host = dev_get_drvdata(dev);
  46. int ret;
  47. ret = dw_mci_suspend(host);
  48. if (!ret)
  49. clk_disable_unprepare(host->ciu_clk);
  50. return ret;
  51. }
  52. static int dw_mci_k3_resume(struct device *dev)
  53. {
  54. struct dw_mci *host = dev_get_drvdata(dev);
  55. int ret;
  56. ret = clk_prepare_enable(host->ciu_clk);
  57. if (ret) {
  58. dev_err(host->dev, "failed to enable ciu clock\n");
  59. return ret;
  60. }
  61. return dw_mci_resume(host);
  62. }
  63. #endif /* CONFIG_PM_SLEEP */
  64. static SIMPLE_DEV_PM_OPS(dw_mci_k3_pmops, dw_mci_k3_suspend, dw_mci_k3_resume);
  65. static struct platform_driver dw_mci_k3_pltfm_driver = {
  66. .probe = dw_mci_k3_probe,
  67. .remove = dw_mci_pltfm_remove,
  68. .driver = {
  69. .name = "dwmmc_k3",
  70. .of_match_table = dw_mci_k3_match,
  71. .pm = &dw_mci_k3_pmops,
  72. },
  73. };
  74. module_platform_driver(dw_mci_k3_pltfm_driver);
  75. MODULE_DESCRIPTION("K3 Specific DW-MSHC Driver Extension");
  76. MODULE_LICENSE("GPL v2");
  77. MODULE_ALIAS("platform:dwmmc-k3");