dw_mmc-k3.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. static int dw_mci_k3_suspend(struct device *dev)
  43. {
  44. struct dw_mci *host = dev_get_drvdata(dev);
  45. int ret;
  46. ret = dw_mci_suspend(host);
  47. if (!ret)
  48. clk_disable_unprepare(host->ciu_clk);
  49. return ret;
  50. }
  51. static int dw_mci_k3_resume(struct device *dev)
  52. {
  53. struct dw_mci *host = dev_get_drvdata(dev);
  54. int ret;
  55. ret = clk_prepare_enable(host->ciu_clk);
  56. if (ret) {
  57. dev_err(host->dev, "failed to enable ciu clock\n");
  58. return ret;
  59. }
  60. return dw_mci_resume(host);
  61. }
  62. static SIMPLE_DEV_PM_OPS(dw_mci_k3_pmops, dw_mci_k3_suspend, dw_mci_k3_resume);
  63. static struct platform_driver dw_mci_k3_pltfm_driver = {
  64. .probe = dw_mci_k3_probe,
  65. .remove = dw_mci_pltfm_remove,
  66. .driver = {
  67. .name = "dwmmc_k3",
  68. .of_match_table = dw_mci_k3_match,
  69. .pm = &dw_mci_k3_pmops,
  70. },
  71. };
  72. module_platform_driver(dw_mci_k3_pltfm_driver);
  73. MODULE_DESCRIPTION("K3 Specific DW-MSHC Driver Extension");
  74. MODULE_LICENSE("GPL v2");
  75. MODULE_ALIAS("platform:dwmmc-k3");