0073-pinctrl-qom-use-scm_call-to-route-GPIO-irq-to-Apps.patch 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. From 2034addc7e193dc81d7ca60d8884832751b76758 Mon Sep 17 00:00:00 2001
  2. From: Ajay Kishore <[email protected]>
  3. Date: Tue, 24 Jan 2017 14:14:16 +0530
  4. Subject: pinctrl: qcom: use scm_call to route GPIO irq to Apps
  5. For IPQ806x targets, TZ protects the registers that are used to
  6. configure the routing of interrupts to a target processor.
  7. To resolve this, this patch uses scm call to route GPIO interrupts
  8. to application processor. Also the scm call interface is changed.
  9. Change-Id: Ib6c06829d04bc8c20483c36e63da92e26cdef9ce
  10. Signed-off-by: Ajay Kishore <[email protected]>
  11. ---
  12. drivers/firmware/qcom_scm-32.c | 17 +++++++++++++++++
  13. drivers/firmware/qcom_scm-64.c | 9 +++++++++
  14. drivers/firmware/qcom_scm.c | 13 +++++++++++++
  15. drivers/firmware/qcom_scm.h | 8 ++++++++
  16. drivers/pinctrl/qcom/pinctrl-msm.c | 34 ++++++++++++++++++++++++++++------
  17. include/linux/qcom_scm.h | 3 ++-
  18. 6 files changed, 77 insertions(+), 7 deletions(-)
  19. --- a/drivers/firmware/qcom_scm-32.c
  20. +++ b/drivers/firmware/qcom_scm-32.c
  21. @@ -561,6 +561,24 @@ int __qcom_scm_pas_mss_reset(struct devi
  22. return ret ? : le32_to_cpu(out);
  23. }
  24. +int __qcom_scm_pinmux_read(u32 svc_id, u32 cmd_id, u32 arg1)
  25. +{
  26. + s32 ret;
  27. +
  28. + ret = qcom_scm_call_atomic1(svc_id, cmd_id, arg1);
  29. +
  30. + return ret;
  31. +}
  32. +
  33. +int __qcom_scm_pinmux_write(u32 svc_id, u32 cmd_id, u32 arg1, u32 arg2)
  34. +{
  35. + s32 ret;
  36. +
  37. + ret = qcom_scm_call_atomic2(svc_id, cmd_id, arg1, arg2);
  38. +
  39. + return ret;
  40. +}
  41. +
  42. int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
  43. {
  44. struct {
  45. --- a/drivers/firmware/qcom_scm-64.c
  46. +++ b/drivers/firmware/qcom_scm-64.c
  47. @@ -366,6 +366,16 @@ int __qcom_scm_pas_mss_reset(struct devi
  48. return ret ? : res.a1;
  49. }
  50. +int __qcom_scm_pinmux_read(u32 svc_id, u32 cmd_id, u32 arg1)
  51. +{
  52. + return -ENOTSUPP;
  53. +}
  54. +
  55. +int __qcom_scm_pinmux_write(u32 svc_id, u32 cmd_id, u32 arg1, u32 arg2)
  56. +{
  57. + return -ENOTSUPP;
  58. +}
  59. +
  60. int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
  61. {
  62. struct qcom_scm_desc desc = {0};
  63. --- a/drivers/firmware/qcom_scm.c
  64. +++ b/drivers/firmware/qcom_scm.c
  65. @@ -470,3 +470,16 @@ static int __init qcom_scm_init(void)
  66. return platform_driver_register(&qcom_scm_driver);
  67. }
  68. subsys_initcall(qcom_scm_init);
  69. +
  70. +int qcom_scm_pinmux_read(u32 arg1)
  71. +{
  72. + return __qcom_scm_pinmux_read(SCM_SVC_IO_ACCESS, SCM_IO_READ, arg1);
  73. +}
  74. +EXPORT_SYMBOL(qcom_scm_pinmux_read);
  75. +
  76. +int qcom_scm_pinmux_write(u32 arg1, u32 arg2)
  77. +{
  78. + return __qcom_scm_pinmux_write(SCM_SVC_IO_ACCESS, SCM_IO_WRITE,
  79. + arg1, arg2);
  80. +}
  81. +EXPORT_SYMBOL(qcom_scm_pinmux_write);
  82. --- a/drivers/firmware/qcom_scm.h
  83. +++ b/drivers/firmware/qcom_scm.h
  84. @@ -58,6 +58,13 @@ extern int __qcom_scm_pas_auth_and_rese
  85. extern int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral);
  86. extern int __qcom_scm_pas_mss_reset(struct device *dev, bool reset);
  87. +#define SCM_IO_READ 1
  88. +#define SCM_IO_WRITE 2
  89. +#define SCM_SVC_IO_ACCESS 0x5
  90. +
  91. +s32 __qcom_scm_pinmux_read(u32 svc_id, u32 cmd_id, u32 arg1);
  92. +s32 __qcom_scm_pinmux_write(u32 svc_id, u32 cmd_id, u32 arg1, u32 arg2);
  93. +
  94. /* common error codes */
  95. #define QCOM_SCM_V2_EBUSY -12
  96. #define QCOM_SCM_ENOMEM -5
  97. --- a/drivers/pinctrl/qcom/pinctrl-msm.c
  98. +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
  99. @@ -30,7 +30,8 @@
  100. #include <linux/reboot.h>
  101. #include <linux/pm.h>
  102. #include <linux/log2.h>
  103. -
  104. +#include <linux/qcom_scm.h>
  105. +#include <linux/io.h>
  106. #include "../core.h"
  107. #include "../pinconf.h"
  108. #include "pinctrl-msm.h"
  109. @@ -646,6 +647,9 @@ static void msm_gpio_irq_ack(struct irq_
  110. const struct msm_pingroup *g;
  111. unsigned long flags;
  112. u32 val;
  113. + u32 addr;
  114. + int ret;
  115. + const __be32 *reg;
  116. g = &pctrl->soc->groups[d->hwirq];
  117. @@ -684,11 +688,30 @@ static int msm_gpio_irq_set_type(struct
  118. else
  119. clear_bit(d->hwirq, pctrl->dual_edge_irqs);
  120. + int ret = of_device_is_compatible(pctrl->dev->of_node,
  121. + "qcom,ipq8064-pinctrl");
  122. /* Route interrupts to application cpu */
  123. - val = readl(pctrl->regs + g->intr_target_reg);
  124. - val &= ~(7 << g->intr_target_bit);
  125. - val |= g->intr_target_kpss_val << g->intr_target_bit;
  126. - writel(val, pctrl->regs + g->intr_target_reg);
  127. + if (!ret) {
  128. + val = readl(pctrl->regs + g->intr_target_reg);
  129. + val &= ~(7 << g->intr_target_bit);
  130. + val |= g->intr_target_kpss_val << g->intr_target_bit;
  131. + writel(val, pctrl->regs + g->intr_target_reg);
  132. + } else {
  133. + const __be32 *reg = of_get_property(pctrl->dev->of_node, "reg", NULL);
  134. + if (reg) {
  135. + u32 addr = be32_to_cpup(reg) + g->intr_target_reg;
  136. + val = qcom_scm_pinmux_read(addr);
  137. + __iormb();
  138. +
  139. + val &= ~(7 << g->intr_target_bit);
  140. + val |= g->intr_target_kpss_val << g->intr_target_bit;
  141. +
  142. + __iowmb();
  143. + ret = qcom_scm_pinmux_write(addr, val);
  144. + if (ret)
  145. + pr_err("\n Routing interrupts to Apps proc failed");
  146. + }
  147. + }
  148. /* Update configuration for gpio.
  149. * RAW_STATUS_EN is left on for all gpio irqs. Due to the
  150. @@ -962,4 +985,3 @@ int msm_pinctrl_remove(struct platform_d
  151. return 0;
  152. }
  153. EXPORT_SYMBOL(msm_pinctrl_remove);
  154. -
  155. --- a/include/linux/qcom_scm.h
  156. +++ b/include/linux/qcom_scm.h
  157. @@ -43,6 +43,8 @@ extern int qcom_scm_set_remote_state(u32
  158. extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
  159. extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
  160. extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
  161. +extern s32 qcom_scm_pinmux_read(u32 arg1);
  162. +extern s32 qcom_scm_pinmux_write(u32 arg1, u32 arg2);
  163. #else
  164. static inline
  165. int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
  166. @@ -73,5 +75,7 @@ qcom_scm_set_remote_state(u32 state,u32
  167. static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return -ENODEV; }
  168. static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) { return -ENODEV; }
  169. static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) { return -ENODEV; }
  170. +extern s32 qcom_scm_pinmux_read(u32 arg1) { return -ENODEV; }
  171. +extern s32 qcom_scm_pinmux_write(u32 arg1, u32 arg2) { return -ENODEV; }
  172. #endif
  173. #endif