ipa_smp2p.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
  3. * Copyright (C) 2019-2022 Linaro Ltd.
  4. */
  5. #include <linux/types.h>
  6. #include <linux/device.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/notifier.h>
  9. #include <linux/panic_notifier.h>
  10. #include <linux/pm_runtime.h>
  11. #include <linux/soc/qcom/smem.h>
  12. #include <linux/soc/qcom/smem_state.h>
  13. #include "ipa_smp2p.h"
  14. #include "ipa.h"
  15. #include "ipa_uc.h"
  16. /**
  17. * DOC: IPA SMP2P communication with the modem
  18. *
  19. * SMP2P is a primitive communication mechanism available between the AP and
  20. * the modem. The IPA driver uses this for two purposes: to enable the modem
  21. * to state that the GSI hardware is ready to use; and to communicate the
  22. * state of IPA power in the event of a crash.
  23. *
  24. * GSI needs to have early initialization completed before it can be used.
  25. * This initialization is done either by Trust Zone or by the modem. In the
  26. * latter case, the modem uses an SMP2P interrupt to tell the AP IPA driver
  27. * when the GSI is ready to use.
  28. *
  29. * The modem is also able to inquire about the current state of IPA
  30. * power by trigging another SMP2P interrupt to the AP. We communicate
  31. * whether power is enabled using two SMP2P state bits--one to indicate
  32. * the power state (on or off), and a second to indicate the power state
  33. * bit is valid. The modem will poll the valid bit until it is set, and
  34. * at that time records whether the AP has IPA power enabled.
  35. *
  36. * Finally, if the AP kernel panics, we update the SMP2P state bits even if
  37. * we never receive an interrupt from the modem requesting this.
  38. */
  39. /**
  40. * struct ipa_smp2p - IPA SMP2P information
  41. * @ipa: IPA pointer
  42. * @valid_state: SMEM state indicating enabled state is valid
  43. * @enabled_state: SMEM state to indicate power is enabled
  44. * @valid_bit: Valid bit in 32-bit SMEM state mask
  45. * @enabled_bit: Enabled bit in 32-bit SMEM state mask
  46. * @enabled_bit: Enabled bit in 32-bit SMEM state mask
  47. * @clock_query_irq: IPA interrupt triggered by modem for power query
  48. * @setup_ready_irq: IPA interrupt triggered by modem to signal GSI ready
  49. * @power_on: Whether IPA power is on
  50. * @notified: Whether modem has been notified of power state
  51. * @setup_disabled: Whether setup ready interrupt handler is disabled
  52. * @mutex: Mutex protecting ready-interrupt/shutdown interlock
  53. * @panic_notifier: Panic notifier structure
  54. */
  55. struct ipa_smp2p {
  56. struct ipa *ipa;
  57. struct qcom_smem_state *valid_state;
  58. struct qcom_smem_state *enabled_state;
  59. u32 valid_bit;
  60. u32 enabled_bit;
  61. u32 clock_query_irq;
  62. u32 setup_ready_irq;
  63. bool power_on;
  64. bool notified;
  65. bool setup_disabled;
  66. struct mutex mutex;
  67. struct notifier_block panic_notifier;
  68. };
  69. /**
  70. * ipa_smp2p_notify() - use SMP2P to tell modem about IPA power state
  71. * @smp2p: SMP2P information
  72. *
  73. * This is called either when the modem has requested it (by triggering
  74. * the modem power query IPA interrupt) or whenever the AP is shutting down
  75. * (via a panic notifier). It sets the two SMP2P state bits--one saying
  76. * whether the IPA power is on, and the other indicating the first bit
  77. * is valid.
  78. */
  79. static void ipa_smp2p_notify(struct ipa_smp2p *smp2p)
  80. {
  81. struct device *dev;
  82. u32 value;
  83. u32 mask;
  84. if (smp2p->notified)
  85. return;
  86. dev = &smp2p->ipa->pdev->dev;
  87. smp2p->power_on = pm_runtime_get_if_active(dev, true) > 0;
  88. /* Signal whether the IPA power is enabled */
  89. mask = BIT(smp2p->enabled_bit);
  90. value = smp2p->power_on ? mask : 0;
  91. qcom_smem_state_update_bits(smp2p->enabled_state, mask, value);
  92. /* Now indicate that the enabled flag is valid */
  93. mask = BIT(smp2p->valid_bit);
  94. value = mask;
  95. qcom_smem_state_update_bits(smp2p->valid_state, mask, value);
  96. smp2p->notified = true;
  97. }
  98. /* Threaded IRQ handler for modem "ipa-clock-query" SMP2P interrupt */
  99. static irqreturn_t ipa_smp2p_modem_clk_query_isr(int irq, void *dev_id)
  100. {
  101. struct ipa_smp2p *smp2p = dev_id;
  102. ipa_smp2p_notify(smp2p);
  103. return IRQ_HANDLED;
  104. }
  105. static int ipa_smp2p_panic_notifier(struct notifier_block *nb,
  106. unsigned long action, void *data)
  107. {
  108. struct ipa_smp2p *smp2p;
  109. smp2p = container_of(nb, struct ipa_smp2p, panic_notifier);
  110. ipa_smp2p_notify(smp2p);
  111. if (smp2p->power_on)
  112. ipa_uc_panic_notifier(smp2p->ipa);
  113. return NOTIFY_DONE;
  114. }
  115. static int ipa_smp2p_panic_notifier_register(struct ipa_smp2p *smp2p)
  116. {
  117. /* IPA panic handler needs to run before modem shuts down */
  118. smp2p->panic_notifier.notifier_call = ipa_smp2p_panic_notifier;
  119. smp2p->panic_notifier.priority = INT_MAX; /* Do it early */
  120. return atomic_notifier_chain_register(&panic_notifier_list,
  121. &smp2p->panic_notifier);
  122. }
  123. static void ipa_smp2p_panic_notifier_unregister(struct ipa_smp2p *smp2p)
  124. {
  125. atomic_notifier_chain_unregister(&panic_notifier_list,
  126. &smp2p->panic_notifier);
  127. }
  128. /* Threaded IRQ handler for modem "ipa-setup-ready" SMP2P interrupt */
  129. static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id)
  130. {
  131. struct ipa_smp2p *smp2p = dev_id;
  132. struct device *dev;
  133. int ret;
  134. /* Ignore any (spurious) interrupts received after the first */
  135. if (smp2p->ipa->setup_complete)
  136. return IRQ_HANDLED;
  137. /* Power needs to be active for setup */
  138. dev = &smp2p->ipa->pdev->dev;
  139. ret = pm_runtime_get_sync(dev);
  140. if (ret < 0) {
  141. dev_err(dev, "error %d getting power for setup\n", ret);
  142. goto out_power_put;
  143. }
  144. /* An error here won't cause driver shutdown, so warn if one occurs */
  145. ret = ipa_setup(smp2p->ipa);
  146. WARN(ret != 0, "error %d from ipa_setup()\n", ret);
  147. out_power_put:
  148. pm_runtime_mark_last_busy(dev);
  149. (void)pm_runtime_put_autosuspend(dev);
  150. return IRQ_HANDLED;
  151. }
  152. /* Initialize SMP2P interrupts */
  153. static int ipa_smp2p_irq_init(struct ipa_smp2p *smp2p, const char *name,
  154. irq_handler_t handler)
  155. {
  156. struct device *dev = &smp2p->ipa->pdev->dev;
  157. unsigned int irq;
  158. int ret;
  159. ret = platform_get_irq_byname(smp2p->ipa->pdev, name);
  160. if (ret <= 0)
  161. return ret ? : -EINVAL;
  162. irq = ret;
  163. ret = request_threaded_irq(irq, NULL, handler, 0, name, smp2p);
  164. if (ret) {
  165. dev_err(dev, "error %d requesting \"%s\" IRQ\n", ret, name);
  166. return ret;
  167. }
  168. return irq;
  169. }
  170. static void ipa_smp2p_irq_exit(struct ipa_smp2p *smp2p, u32 irq)
  171. {
  172. free_irq(irq, smp2p);
  173. }
  174. /* Drop the power reference if it was taken in ipa_smp2p_notify() */
  175. static void ipa_smp2p_power_release(struct ipa *ipa)
  176. {
  177. struct device *dev = &ipa->pdev->dev;
  178. if (!ipa->smp2p->power_on)
  179. return;
  180. pm_runtime_mark_last_busy(dev);
  181. (void)pm_runtime_put_autosuspend(dev);
  182. ipa->smp2p->power_on = false;
  183. }
  184. /* Initialize the IPA SMP2P subsystem */
  185. int ipa_smp2p_init(struct ipa *ipa, bool modem_init)
  186. {
  187. struct qcom_smem_state *enabled_state;
  188. struct device *dev = &ipa->pdev->dev;
  189. struct qcom_smem_state *valid_state;
  190. struct ipa_smp2p *smp2p;
  191. u32 enabled_bit;
  192. u32 valid_bit;
  193. int ret;
  194. valid_state = qcom_smem_state_get(dev, "ipa-clock-enabled-valid",
  195. &valid_bit);
  196. if (IS_ERR(valid_state))
  197. return PTR_ERR(valid_state);
  198. if (valid_bit >= 32) /* BITS_PER_U32 */
  199. return -EINVAL;
  200. enabled_state = qcom_smem_state_get(dev, "ipa-clock-enabled",
  201. &enabled_bit);
  202. if (IS_ERR(enabled_state))
  203. return PTR_ERR(enabled_state);
  204. if (enabled_bit >= 32) /* BITS_PER_U32 */
  205. return -EINVAL;
  206. smp2p = kzalloc(sizeof(*smp2p), GFP_KERNEL);
  207. if (!smp2p)
  208. return -ENOMEM;
  209. smp2p->ipa = ipa;
  210. /* These fields are needed by the power query interrupt
  211. * handler, so initialize them now.
  212. */
  213. mutex_init(&smp2p->mutex);
  214. smp2p->valid_state = valid_state;
  215. smp2p->valid_bit = valid_bit;
  216. smp2p->enabled_state = enabled_state;
  217. smp2p->enabled_bit = enabled_bit;
  218. /* We have enough information saved to handle notifications */
  219. ipa->smp2p = smp2p;
  220. ret = ipa_smp2p_irq_init(smp2p, "ipa-clock-query",
  221. ipa_smp2p_modem_clk_query_isr);
  222. if (ret < 0)
  223. goto err_null_smp2p;
  224. smp2p->clock_query_irq = ret;
  225. ret = ipa_smp2p_panic_notifier_register(smp2p);
  226. if (ret)
  227. goto err_irq_exit;
  228. if (modem_init) {
  229. /* Result will be non-zero (negative for error) */
  230. ret = ipa_smp2p_irq_init(smp2p, "ipa-setup-ready",
  231. ipa_smp2p_modem_setup_ready_isr);
  232. if (ret < 0)
  233. goto err_notifier_unregister;
  234. smp2p->setup_ready_irq = ret;
  235. }
  236. return 0;
  237. err_notifier_unregister:
  238. ipa_smp2p_panic_notifier_unregister(smp2p);
  239. err_irq_exit:
  240. ipa_smp2p_irq_exit(smp2p, smp2p->clock_query_irq);
  241. err_null_smp2p:
  242. ipa->smp2p = NULL;
  243. mutex_destroy(&smp2p->mutex);
  244. kfree(smp2p);
  245. return ret;
  246. }
  247. void ipa_smp2p_exit(struct ipa *ipa)
  248. {
  249. struct ipa_smp2p *smp2p = ipa->smp2p;
  250. if (smp2p->setup_ready_irq)
  251. ipa_smp2p_irq_exit(smp2p, smp2p->setup_ready_irq);
  252. ipa_smp2p_panic_notifier_unregister(smp2p);
  253. ipa_smp2p_irq_exit(smp2p, smp2p->clock_query_irq);
  254. /* We won't get notified any more; drop power reference (if any) */
  255. ipa_smp2p_power_release(ipa);
  256. ipa->smp2p = NULL;
  257. mutex_destroy(&smp2p->mutex);
  258. kfree(smp2p);
  259. }
  260. void ipa_smp2p_irq_disable_setup(struct ipa *ipa)
  261. {
  262. struct ipa_smp2p *smp2p = ipa->smp2p;
  263. if (!smp2p->setup_ready_irq)
  264. return;
  265. mutex_lock(&smp2p->mutex);
  266. if (!smp2p->setup_disabled) {
  267. disable_irq(smp2p->setup_ready_irq);
  268. smp2p->setup_disabled = true;
  269. }
  270. mutex_unlock(&smp2p->mutex);
  271. }
  272. /* Reset state tracking whether we have notified the modem */
  273. void ipa_smp2p_notify_reset(struct ipa *ipa)
  274. {
  275. struct ipa_smp2p *smp2p = ipa->smp2p;
  276. u32 mask;
  277. if (!smp2p->notified)
  278. return;
  279. ipa_smp2p_power_release(ipa);
  280. /* Reset the power enabled valid flag */
  281. mask = BIT(smp2p->valid_bit);
  282. qcom_smem_state_update_bits(smp2p->valid_state, mask, 0);
  283. /* Mark the power disabled for good measure... */
  284. mask = BIT(smp2p->enabled_bit);
  285. qcom_smem_state_update_bits(smp2p->enabled_state, mask, 0);
  286. smp2p->notified = false;
  287. }