irq-gic-pm.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright (C) 2016 NVIDIA CORPORATION, All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <linux/module.h>
  17. #include <linux/clk.h>
  18. #include <linux/of_device.h>
  19. #include <linux/of_irq.h>
  20. #include <linux/irqchip/arm-gic.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/pm_clock.h>
  23. #include <linux/pm_runtime.h>
  24. #include <linux/slab.h>
  25. struct gic_clk_data {
  26. unsigned int num_clocks;
  27. const char *const *clocks;
  28. };
  29. static int gic_runtime_resume(struct device *dev)
  30. {
  31. struct gic_chip_data *gic = dev_get_drvdata(dev);
  32. int ret;
  33. ret = pm_clk_resume(dev);
  34. if (ret)
  35. return ret;
  36. /*
  37. * On the very first resume, the pointer to the driver data
  38. * will be NULL and this is intentional, because we do not
  39. * want to restore the GIC on the very first resume. So if
  40. * the pointer is not valid just return.
  41. */
  42. if (!gic)
  43. return 0;
  44. gic_dist_restore(gic);
  45. gic_cpu_restore(gic);
  46. return 0;
  47. }
  48. static int gic_runtime_suspend(struct device *dev)
  49. {
  50. struct gic_chip_data *gic = dev_get_drvdata(dev);
  51. gic_dist_save(gic);
  52. gic_cpu_save(gic);
  53. return pm_clk_suspend(dev);
  54. }
  55. static int gic_get_clocks(struct device *dev, const struct gic_clk_data *data)
  56. {
  57. struct clk *clk;
  58. unsigned int i;
  59. int ret;
  60. if (!dev || !data)
  61. return -EINVAL;
  62. ret = pm_clk_create(dev);
  63. if (ret)
  64. return ret;
  65. for (i = 0; i < data->num_clocks; i++) {
  66. clk = of_clk_get_by_name(dev->of_node, data->clocks[i]);
  67. if (IS_ERR(clk)) {
  68. dev_err(dev, "failed to get clock %s\n",
  69. data->clocks[i]);
  70. ret = PTR_ERR(clk);
  71. goto error;
  72. }
  73. ret = pm_clk_add_clk(dev, clk);
  74. if (ret) {
  75. dev_err(dev, "failed to add clock at index %d\n", i);
  76. clk_put(clk);
  77. goto error;
  78. }
  79. }
  80. return 0;
  81. error:
  82. pm_clk_destroy(dev);
  83. return ret;
  84. }
  85. static int gic_probe(struct platform_device *pdev)
  86. {
  87. struct device *dev = &pdev->dev;
  88. const struct gic_clk_data *data;
  89. struct gic_chip_data *gic;
  90. int ret, irq;
  91. data = of_device_get_match_data(&pdev->dev);
  92. if (!data) {
  93. dev_err(&pdev->dev, "no device match found\n");
  94. return -ENODEV;
  95. }
  96. irq = irq_of_parse_and_map(dev->of_node, 0);
  97. if (!irq) {
  98. dev_err(dev, "no parent interrupt found!\n");
  99. return -EINVAL;
  100. }
  101. ret = gic_get_clocks(dev, data);
  102. if (ret)
  103. goto irq_dispose;
  104. pm_runtime_enable(dev);
  105. ret = pm_runtime_get_sync(dev);
  106. if (ret < 0)
  107. goto rpm_disable;
  108. ret = gic_of_init_child(dev, &gic, irq);
  109. if (ret)
  110. goto rpm_put;
  111. platform_set_drvdata(pdev, gic);
  112. pm_runtime_put(dev);
  113. dev_info(dev, "GIC IRQ controller registered\n");
  114. return 0;
  115. rpm_put:
  116. pm_runtime_put_sync(dev);
  117. rpm_disable:
  118. pm_runtime_disable(dev);
  119. pm_clk_destroy(dev);
  120. irq_dispose:
  121. irq_dispose_mapping(irq);
  122. return ret;
  123. }
  124. static const struct dev_pm_ops gic_pm_ops = {
  125. SET_RUNTIME_PM_OPS(gic_runtime_suspend,
  126. gic_runtime_resume, NULL)
  127. };
  128. static const char * const gic400_clocks[] = {
  129. "clk",
  130. };
  131. static const struct gic_clk_data gic400_data = {
  132. .num_clocks = ARRAY_SIZE(gic400_clocks),
  133. .clocks = gic400_clocks,
  134. };
  135. static const struct of_device_id gic_match[] = {
  136. { .compatible = "nvidia,tegra210-agic", .data = &gic400_data },
  137. {},
  138. };
  139. MODULE_DEVICE_TABLE(of, gic_match);
  140. static struct platform_driver gic_driver = {
  141. .probe = gic_probe,
  142. .driver = {
  143. .name = "gic",
  144. .of_match_table = gic_match,
  145. .pm = &gic_pm_ops,
  146. }
  147. };
  148. builtin_platform_driver(gic_driver);