qcom-pdc.c (da3f875a4189e643f8eec7f0bffa39c90d3418c6) qcom-pdc.c (81ef8bf88065b07d597c723ca5b0f1f10a808de4)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/err.h>
7#include <linux/init.h>
8#include <linux/irq.h>
9#include <linux/irqchip.h>
10#include <linux/irqdomain.h>
11#include <linux/io.h>
12#include <linux/kernel.h>
13#include <linux/of.h>
14#include <linux/of_address.h>
15#include <linux/of_device.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/err.h>
7#include <linux/init.h>
8#include <linux/irq.h>
9#include <linux/irqchip.h>
10#include <linux/irqdomain.h>
11#include <linux/io.h>
12#include <linux/kernel.h>
13#include <linux/of.h>
14#include <linux/of_address.h>
15#include <linux/of_device.h>
16#include <linux/soc/qcom/irq.h>
16#include <linux/spinlock.h>
17#include <linux/spinlock.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/types.h>
20
21#define PDC_MAX_IRQS 168
18#include <linux/slab.h>
19#include <linux/types.h>
20
21#define PDC_MAX_IRQS 168
22#define PDC_MAX_GPIO_IRQS 256
22
23#define CLEAR_INTR(reg, intr) (reg & ~(1 << intr))
24#define ENABLE_INTR(reg, intr) (reg | (1 << intr))
25
26#define IRQ_ENABLE_BANK 0x10
27#define IRQ_i_CFG 0x110
28
23
24#define CLEAR_INTR(reg, intr) (reg & ~(1 << intr))
25#define ENABLE_INTR(reg, intr) (reg | (1 << intr))
26
27#define IRQ_ENABLE_BANK 0x10
28#define IRQ_i_CFG 0x110
29
30#define PDC_NO_PARENT_IRQ ~0UL
31
29struct pdc_pin_region {
30 u32 pin_base;
31 u32 parent_base;
32 u32 cnt;
33};
34
35static DEFINE_RAW_SPINLOCK(pdc_lock);
36static void __iomem *pdc_base;

--- 23 unchanged lines hidden (view full) ---

60 enable = pdc_reg_read(IRQ_ENABLE_BANK, index);
61 enable = on ? ENABLE_INTR(enable, mask) : CLEAR_INTR(enable, mask);
62 pdc_reg_write(IRQ_ENABLE_BANK, index, enable);
63 raw_spin_unlock(&pdc_lock);
64}
65
66static void qcom_pdc_gic_disable(struct irq_data *d)
67{
32struct pdc_pin_region {
33 u32 pin_base;
34 u32 parent_base;
35 u32 cnt;
36};
37
38static DEFINE_RAW_SPINLOCK(pdc_lock);
39static void __iomem *pdc_base;

--- 23 unchanged lines hidden (view full) ---

63 enable = pdc_reg_read(IRQ_ENABLE_BANK, index);
64 enable = on ? ENABLE_INTR(enable, mask) : CLEAR_INTR(enable, mask);
65 pdc_reg_write(IRQ_ENABLE_BANK, index, enable);
66 raw_spin_unlock(&pdc_lock);
67}
68
69static void qcom_pdc_gic_disable(struct irq_data *d)
70{
71 if (d->hwirq == GPIO_NO_WAKE_IRQ)
72 return;
73
68 pdc_enable_intr(d, false);
69 irq_chip_disable_parent(d);
70}
71
72static void qcom_pdc_gic_enable(struct irq_data *d)
73{
74 pdc_enable_intr(d, false);
75 irq_chip_disable_parent(d);
76}
77
78static void qcom_pdc_gic_enable(struct irq_data *d)
79{
80 if (d->hwirq == GPIO_NO_WAKE_IRQ)
81 return;
82
74 pdc_enable_intr(d, true);
75 irq_chip_enable_parent(d);
76}
77
78static void qcom_pdc_gic_mask(struct irq_data *d)
79{
83 pdc_enable_intr(d, true);
84 irq_chip_enable_parent(d);
85}
86
87static void qcom_pdc_gic_mask(struct irq_data *d)
88{
89 if (d->hwirq == GPIO_NO_WAKE_IRQ)
90 return;
91
80 irq_chip_mask_parent(d);
81}
82
83static void qcom_pdc_gic_unmask(struct irq_data *d)
84{
92 irq_chip_mask_parent(d);
93}
94
95static void qcom_pdc_gic_unmask(struct irq_data *d)
96{
97 if (d->hwirq == GPIO_NO_WAKE_IRQ)
98 return;
99
85 irq_chip_unmask_parent(d);
86}
87
88/*
89 * GIC does not handle falling edge or active low. To allow falling edge and
90 * active low interrupts to be handled at GIC, PDC has an inverter that inverts
91 * falling edge into a rising edge and active low into an active high.
92 * For the inverter to work, the polarity bit in the IRQ_CONFIG register has to

--- 26 unchanged lines hidden (view full) ---

119 * If @type is level, then forward that as level high as PDC
120 * takes care of converting falling edge to rising edge signal
121 */
122static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
123{
124 int pin_out = d->hwirq;
125 enum pdc_irq_config_bits pdc_type;
126
100 irq_chip_unmask_parent(d);
101}
102
103/*
104 * GIC does not handle falling edge or active low. To allow falling edge and
105 * active low interrupts to be handled at GIC, PDC has an inverter that inverts
106 * falling edge into a rising edge and active low into an active high.
107 * For the inverter to work, the polarity bit in the IRQ_CONFIG register has to

--- 26 unchanged lines hidden (view full) ---

134 * If @type is level, then forward that as level high as PDC
135 * takes care of converting falling edge to rising edge signal
136 */
137static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
138{
139 int pin_out = d->hwirq;
140 enum pdc_irq_config_bits pdc_type;
141
142 if (pin_out == GPIO_NO_WAKE_IRQ)
143 return 0;
144
127 switch (type) {
128 case IRQ_TYPE_EDGE_RISING:
129 pdc_type = PDC_EDGE_RISING;
130 break;
131 case IRQ_TYPE_EDGE_FALLING:
132 pdc_type = PDC_EDGE_FALLING;
133 type = IRQ_TYPE_EDGE_RISING;
134 break;

--- 41 unchanged lines hidden (view full) ---

176
177 for (i = 0; i < pdc_region_cnt; i++) {
178 region = &pdc_region[i];
179 if (pin >= region->pin_base &&
180 pin < region->pin_base + region->cnt)
181 return (region->parent_base + pin - region->pin_base);
182 }
183
145 switch (type) {
146 case IRQ_TYPE_EDGE_RISING:
147 pdc_type = PDC_EDGE_RISING;
148 break;
149 case IRQ_TYPE_EDGE_FALLING:
150 pdc_type = PDC_EDGE_FALLING;
151 type = IRQ_TYPE_EDGE_RISING;
152 break;

--- 41 unchanged lines hidden (view full) ---

194
195 for (i = 0; i < pdc_region_cnt; i++) {
196 region = &pdc_region[i];
197 if (pin >= region->pin_base &&
198 pin < region->pin_base + region->cnt)
199 return (region->parent_base + pin - region->pin_base);
200 }
201
184 WARN_ON(1);
185 return ~0UL;
202 return PDC_NO_PARENT_IRQ;
186}
187
188static int qcom_pdc_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
189 unsigned long *hwirq, unsigned int *type)
190{
191 if (is_of_node(fwspec->fwnode)) {
192 if (fwspec->param_count != 2)
193 return -EINVAL;

--- 12 unchanged lines hidden (view full) ---

206 struct irq_fwspec *fwspec = data;
207 struct irq_fwspec parent_fwspec;
208 irq_hw_number_t hwirq, parent_hwirq;
209 unsigned int type;
210 int ret;
211
212 ret = qcom_pdc_translate(domain, fwspec, &hwirq, &type);
213 if (ret)
203}
204
205static int qcom_pdc_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
206 unsigned long *hwirq, unsigned int *type)
207{
208 if (is_of_node(fwspec->fwnode)) {
209 if (fwspec->param_count != 2)
210 return -EINVAL;

--- 12 unchanged lines hidden (view full) ---

223 struct irq_fwspec *fwspec = data;
224 struct irq_fwspec parent_fwspec;
225 irq_hw_number_t hwirq, parent_hwirq;
226 unsigned int type;
227 int ret;
228
229 ret = qcom_pdc_translate(domain, fwspec, &hwirq, &type);
230 if (ret)
214 return -EINVAL;
231 return ret;
215
232
216 parent_hwirq = get_parent_hwirq(hwirq);
217 if (parent_hwirq == ~0UL)
218 return -EINVAL;
219
220 ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
221 &qcom_pdc_gic_chip, NULL);
222 if (ret)
223 return ret;
224
233 ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
234 &qcom_pdc_gic_chip, NULL);
235 if (ret)
236 return ret;
237
238 parent_hwirq = get_parent_hwirq(hwirq);
239 if (parent_hwirq == PDC_NO_PARENT_IRQ)
240 return 0;
241
225 if (type & IRQ_TYPE_EDGE_BOTH)
226 type = IRQ_TYPE_EDGE_RISING;
227
228 if (type & IRQ_TYPE_LEVEL_MASK)
229 type = IRQ_TYPE_LEVEL_HIGH;
230
231 parent_fwspec.fwnode = domain->parent->fwnode;
232 parent_fwspec.param_count = 3;

--- 6 unchanged lines hidden (view full) ---

239}
240
241static const struct irq_domain_ops qcom_pdc_ops = {
242 .translate = qcom_pdc_translate,
243 .alloc = qcom_pdc_alloc,
244 .free = irq_domain_free_irqs_common,
245};
246
242 if (type & IRQ_TYPE_EDGE_BOTH)
243 type = IRQ_TYPE_EDGE_RISING;
244
245 if (type & IRQ_TYPE_LEVEL_MASK)
246 type = IRQ_TYPE_LEVEL_HIGH;
247
248 parent_fwspec.fwnode = domain->parent->fwnode;
249 parent_fwspec.param_count = 3;

--- 6 unchanged lines hidden (view full) ---

256}
257
258static const struct irq_domain_ops qcom_pdc_ops = {
259 .translate = qcom_pdc_translate,
260 .alloc = qcom_pdc_alloc,
261 .free = irq_domain_free_irqs_common,
262};
263
264static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq,
265 unsigned int nr_irqs, void *data)
266{
267 struct irq_fwspec *fwspec = data;
268 struct irq_fwspec parent_fwspec;
269 irq_hw_number_t hwirq, parent_hwirq;
270 unsigned int type;
271 int ret;
272
273 ret = qcom_pdc_translate(domain, fwspec, &hwirq, &type);
274 if (ret)
275 return ret;
276
277 ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
278 &qcom_pdc_gic_chip, NULL);
279 if (ret)
280 return ret;
281
282 if (hwirq == GPIO_NO_WAKE_IRQ)
283 return 0;
284
285 parent_hwirq = get_parent_hwirq(hwirq);
286 if (parent_hwirq == PDC_NO_PARENT_IRQ)
287 return 0;
288
289 if (type & IRQ_TYPE_EDGE_BOTH)
290 type = IRQ_TYPE_EDGE_RISING;
291
292 if (type & IRQ_TYPE_LEVEL_MASK)
293 type = IRQ_TYPE_LEVEL_HIGH;
294
295 parent_fwspec.fwnode = domain->parent->fwnode;
296 parent_fwspec.param_count = 3;
297 parent_fwspec.param[0] = 0;
298 parent_fwspec.param[1] = parent_hwirq;
299 parent_fwspec.param[2] = type;
300
301 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
302 &parent_fwspec);
303}
304
305static int qcom_pdc_gpio_domain_select(struct irq_domain *d,
306 struct irq_fwspec *fwspec,
307 enum irq_domain_bus_token bus_token)
308{
309 return bus_token == DOMAIN_BUS_WAKEUP;
310}
311
312static const struct irq_domain_ops qcom_pdc_gpio_ops = {
313 .select = qcom_pdc_gpio_domain_select,
314 .alloc = qcom_pdc_gpio_alloc,
315 .free = irq_domain_free_irqs_common,
316};
317
247static int pdc_setup_pin_mapping(struct device_node *np)
248{
249 int ret, n;
250
251 n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32));
252 if (n <= 0 || n % 3)
253 return -EINVAL;
254

--- 22 unchanged lines hidden (view full) ---

277 return ret;
278 }
279
280 return 0;
281}
282
283static int qcom_pdc_init(struct device_node *node, struct device_node *parent)
284{
318static int pdc_setup_pin_mapping(struct device_node *np)
319{
320 int ret, n;
321
322 n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32));
323 if (n <= 0 || n % 3)
324 return -EINVAL;
325

--- 22 unchanged lines hidden (view full) ---

348 return ret;
349 }
350
351 return 0;
352}
353
354static int qcom_pdc_init(struct device_node *node, struct device_node *parent)
355{
285 struct irq_domain *parent_domain, *pdc_domain;
356 struct irq_domain *parent_domain, *pdc_domain, *pdc_gpio_domain;
286 int ret;
287
288 pdc_base = of_iomap(node, 0);
289 if (!pdc_base) {
290 pr_err("%pOF: unable to map PDC registers\n", node);
291 return -ENXIO;
292 }
293

--- 14 unchanged lines hidden (view full) ---

308 of_fwnode_handle(node),
309 &qcom_pdc_ops, NULL);
310 if (!pdc_domain) {
311 pr_err("%pOF: GIC domain add failed\n", node);
312 ret = -ENOMEM;
313 goto fail;
314 }
315
357 int ret;
358
359 pdc_base = of_iomap(node, 0);
360 if (!pdc_base) {
361 pr_err("%pOF: unable to map PDC registers\n", node);
362 return -ENXIO;
363 }
364

--- 14 unchanged lines hidden (view full) ---

379 of_fwnode_handle(node),
380 &qcom_pdc_ops, NULL);
381 if (!pdc_domain) {
382 pr_err("%pOF: GIC domain add failed\n", node);
383 ret = -ENOMEM;
384 goto fail;
385 }
386
387 pdc_gpio_domain = irq_domain_create_hierarchy(parent_domain,
388 IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP,
389 PDC_MAX_GPIO_IRQS,
390 of_fwnode_handle(node),
391 &qcom_pdc_gpio_ops, NULL);
392 if (!pdc_gpio_domain) {
393 pr_err("%pOF: PDC domain add failed for GPIO domain\n", node);
394 ret = -ENOMEM;
395 goto remove;
396 }
397
398 irq_domain_update_bus_token(pdc_gpio_domain, DOMAIN_BUS_WAKEUP);
399
316 return 0;
317
400 return 0;
401
402remove:
403 irq_domain_remove(pdc_domain);
318fail:
319 kfree(pdc_region);
320 iounmap(pdc_base);
321 return ret;
322}
323
324IRQCHIP_DECLARE(qcom_pdc, "qcom,pdc", qcom_pdc_init);
404fail:
405 kfree(pdc_region);
406 iounmap(pdc_base);
407 return ret;
408}
409
410IRQCHIP_DECLARE(qcom_pdc, "qcom,pdc", qcom_pdc_init);