200-ARM-at91-pm-check-for-different-controllers-in-at91_.patch 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. From 0c4cbd38a705bdeab11de4c84ad0ce8c3de8a81d Mon Sep 17 00:00:00 2001
  2. From: Claudiu Beznea <[email protected]>
  3. Date: Thu, 15 Apr 2021 13:49:50 +0300
  4. Subject: [PATCH 200/247] ARM: at91: pm: check for different controllers in
  5. at91_pm_modes_init()
  6. at91_pm_modes_init() checks for proper nodes in device tree and maps
  7. them accordingly. Up to SAMA7G5 all AT91 SoCs had the same mapping
  8. b/w power saving modes and different controllers needed in the
  9. final/first steps of suspend/resume. SAMA7G5 is not aligned with the
  10. old SoCs thus the code is adapted for this. This patch prepares
  11. the field for next commits.
  12. Signed-off-by: Claudiu Beznea <[email protected]>
  13. Signed-off-by: Nicolas Ferre <[email protected]>
  14. Link: https://lore.kernel.org/r/[email protected]
  15. ---
  16. arch/arm/mach-at91/pm.c | 143 +++++++++++++++++++++++++---------------
  17. 1 file changed, 91 insertions(+), 52 deletions(-)
  18. diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
  19. index a060bec77f20..e9f9fb410761 100644
  20. --- a/arch/arm/mach-at91/pm.c
  21. +++ b/arch/arm/mach-at91/pm.c
  22. @@ -57,6 +57,18 @@ struct at91_soc_pm {
  23. struct at91_pm_data data;
  24. };
  25. +/**
  26. + * enum at91_pm_iomaps: IOs that needs to be mapped for different PM modes
  27. + * @AT91_PM_IOMAP_SHDWC: SHDWC controller
  28. + * @AT91_PM_IOMAP_SFRBU: SFRBU controller
  29. + */
  30. +enum at91_pm_iomaps {
  31. + AT91_PM_IOMAP_SHDWC,
  32. + AT91_PM_IOMAP_SFRBU,
  33. +};
  34. +
  35. +#define AT91_PM_IOMAP(name) BIT(AT91_PM_IOMAP_##name)
  36. +
  37. static struct at91_soc_pm soc_pm = {
  38. .data = {
  39. .standby_mode = AT91_PM_STANDBY,
  40. @@ -671,24 +683,15 @@ static int __init at91_pm_backup_init(void)
  41. if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
  42. return 0;
  43. - np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
  44. - if (!np) {
  45. - pr_warn("%s: failed to find sfrbu!\n", __func__);
  46. - return ret;
  47. - }
  48. -
  49. - soc_pm.data.sfrbu = of_iomap(np, 0);
  50. - of_node_put(np);
  51. -
  52. np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam");
  53. if (!np)
  54. - goto securam_fail_no_ref_dev;
  55. + return ret;
  56. pdev = of_find_device_by_node(np);
  57. of_node_put(np);
  58. if (!pdev) {
  59. pr_warn("%s: failed to find securam device!\n", __func__);
  60. - goto securam_fail_no_ref_dev;
  61. + return ret;
  62. }
  63. sram_pool = gen_pool_get(&pdev->dev, NULL);
  64. @@ -712,64 +715,92 @@ static int __init at91_pm_backup_init(void)
  65. securam_fail:
  66. put_device(&pdev->dev);
  67. -securam_fail_no_ref_dev:
  68. - iounmap(soc_pm.data.sfrbu);
  69. - soc_pm.data.sfrbu = NULL;
  70. return ret;
  71. }
  72. -static void __init at91_pm_use_default_mode(int pm_mode)
  73. -{
  74. - if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)
  75. - return;
  76. -
  77. - if (soc_pm.data.standby_mode == pm_mode)
  78. - soc_pm.data.standby_mode = AT91_PM_ULP0;
  79. - if (soc_pm.data.suspend_mode == pm_mode)
  80. - soc_pm.data.suspend_mode = AT91_PM_ULP0;
  81. -}
  82. -
  83. static const struct of_device_id atmel_shdwc_ids[] = {
  84. { .compatible = "atmel,sama5d2-shdwc" },
  85. { .compatible = "microchip,sam9x60-shdwc" },
  86. { /* sentinel. */ }
  87. };
  88. -static void __init at91_pm_modes_init(void)
  89. +static void __init at91_pm_modes_init(const u32 *maps, int len)
  90. {
  91. struct device_node *np;
  92. - int ret;
  93. + int ret, mode;
  94. - if (!at91_is_pm_mode_active(AT91_PM_BACKUP) &&
  95. - !at91_is_pm_mode_active(AT91_PM_ULP1))
  96. - return;
  97. + ret = at91_pm_backup_init();
  98. + if (ret) {
  99. + if (soc_pm.data.standby_mode == AT91_PM_BACKUP)
  100. + soc_pm.data.standby_mode = AT91_PM_ULP0;
  101. + if (soc_pm.data.suspend_mode == AT91_PM_BACKUP)
  102. + soc_pm.data.suspend_mode = AT91_PM_ULP0;
  103. + }
  104. - np = of_find_matching_node(NULL, atmel_shdwc_ids);
  105. - if (!np) {
  106. - pr_warn("%s: failed to find shdwc!\n", __func__);
  107. - goto ulp1_default;
  108. + if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC) ||
  109. + maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC)) {
  110. + np = of_find_matching_node(NULL, atmel_shdwc_ids);
  111. + if (!np) {
  112. + pr_warn("%s: failed to find shdwc!\n", __func__);
  113. +
  114. + /* Use ULP0 if it doesn't needs SHDWC.*/
  115. + if (!(maps[AT91_PM_ULP0] & AT91_PM_IOMAP(SHDWC)))
  116. + mode = AT91_PM_ULP0;
  117. + else
  118. + mode = AT91_PM_STANDBY;
  119. +
  120. + if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC))
  121. + soc_pm.data.standby_mode = mode;
  122. + if (maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC))
  123. + soc_pm.data.suspend_mode = mode;
  124. + } else {
  125. + soc_pm.data.shdwc = of_iomap(np, 0);
  126. + of_node_put(np);
  127. + }
  128. }
  129. - soc_pm.data.shdwc = of_iomap(np, 0);
  130. - of_node_put(np);
  131. + if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU) ||
  132. + maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU)) {
  133. + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
  134. + if (!np) {
  135. + pr_warn("%s: failed to find sfrbu!\n", __func__);
  136. +
  137. + /*
  138. + * Use ULP0 if it doesn't need SHDWC or if SHDWC
  139. + * was already located.
  140. + */
  141. + if (!(maps[AT91_PM_ULP0] & AT91_PM_IOMAP(SHDWC)) ||
  142. + soc_pm.data.shdwc)
  143. + mode = AT91_PM_ULP0;
  144. + else
  145. + mode = AT91_PM_STANDBY;
  146. +
  147. + if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU))
  148. + soc_pm.data.standby_mode = mode;
  149. + if (maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU))
  150. + soc_pm.data.suspend_mode = mode;
  151. + } else {
  152. + soc_pm.data.sfrbu = of_iomap(np, 0);
  153. + of_node_put(np);
  154. + }
  155. + }
  156. - ret = at91_pm_backup_init();
  157. - if (ret) {
  158. - if (!at91_is_pm_mode_active(AT91_PM_ULP1))
  159. - goto unmap;
  160. - else
  161. - goto backup_default;
  162. + /* Unmap all unnecessary. */
  163. + if (soc_pm.data.shdwc &&
  164. + !(maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC) ||
  165. + maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC))) {
  166. + iounmap(soc_pm.data.shdwc);
  167. + soc_pm.data.shdwc = NULL;
  168. }
  169. - return;
  170. + if (soc_pm.data.sfrbu &&
  171. + !(maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU) ||
  172. + maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU))) {
  173. + iounmap(soc_pm.data.sfrbu);
  174. + soc_pm.data.sfrbu = NULL;
  175. + }
  176. -unmap:
  177. - iounmap(soc_pm.data.shdwc);
  178. - soc_pm.data.shdwc = NULL;
  179. -ulp1_default:
  180. - at91_pm_use_default_mode(AT91_PM_ULP1);
  181. -backup_default:
  182. - at91_pm_use_default_mode(AT91_PM_BACKUP);
  183. + return;
  184. }
  185. struct pmc_info {
  186. @@ -936,13 +967,16 @@ void __init sam9x60_pm_init(void)
  187. static const int modes[] __initconst = {
  188. AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
  189. };
  190. + static const int iomaps[] __initconst = {
  191. + [AT91_PM_ULP1] = AT91_PM_IOMAP(SHDWC),
  192. + };
  193. int ret;
  194. if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
  195. return;
  196. at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
  197. - at91_pm_modes_init();
  198. + at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
  199. ret = at91_dt_ramc();
  200. if (ret)
  201. return;
  202. @@ -999,13 +1033,18 @@ void __init sama5d2_pm_init(void)
  203. AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
  204. AT91_PM_BACKUP,
  205. };
  206. + static const u32 iomaps[] __initconst = {
  207. + [AT91_PM_ULP1] = AT91_PM_IOMAP(SHDWC),
  208. + [AT91_PM_BACKUP] = AT91_PM_IOMAP(SHDWC) |
  209. + AT91_PM_IOMAP(SFRBU),
  210. + };
  211. int ret;
  212. if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
  213. return;
  214. at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
  215. - at91_pm_modes_init();
  216. + at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
  217. ret = at91_dt_ramc();
  218. if (ret)
  219. return;
  220. --
  221. 2.32.0