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