1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
7 #include <linux/init.h>
8 #include <linux/interrupt.h>
10 #include <linux/irqchip.h>
11 #include <linux/irqdomain.h>
13 #include <linux/kernel.h>
15 #include <linux/of_address.h>
16 #include <linux/of_device.h>
17 #include <linux/soc/qcom/irq.h>
18 #include <linux/spinlock.h>
19 #include <linux/slab.h>
20 #include <linux/types.h>
22 #define PDC_MAX_IRQS 168
23 #define PDC_MAX_GPIO_IRQS 256
25 #define CLEAR_INTR(reg, intr) (reg & ~(1 << intr))
26 #define ENABLE_INTR(reg, intr) (reg | (1 << intr))
28 #define IRQ_ENABLE_BANK 0x10
29 #define IRQ_i_CFG 0x110
31 #define PDC_NO_PARENT_IRQ ~0UL
33 struct pdc_pin_region
{
39 static DEFINE_RAW_SPINLOCK(pdc_lock
);
40 static void __iomem
*pdc_base
;
41 static struct pdc_pin_region
*pdc_region
;
42 static int pdc_region_cnt
;
44 static void pdc_reg_write(int reg
, u32 i
, u32 val
)
46 writel_relaxed(val
, pdc_base
+ reg
+ i
* sizeof(u32
));
49 static u32
pdc_reg_read(int reg
, u32 i
)
51 return readl_relaxed(pdc_base
+ reg
+ i
* sizeof(u32
));
54 static int qcom_pdc_gic_get_irqchip_state(struct irq_data
*d
,
55 enum irqchip_irq_state which
,
58 if (d
->hwirq
== GPIO_NO_WAKE_IRQ
)
61 return irq_chip_get_parent_state(d
, which
, state
);
64 static int qcom_pdc_gic_set_irqchip_state(struct irq_data
*d
,
65 enum irqchip_irq_state which
,
68 if (d
->hwirq
== GPIO_NO_WAKE_IRQ
)
71 return irq_chip_set_parent_state(d
, which
, value
);
74 static void pdc_enable_intr(struct irq_data
*d
, bool on
)
76 int pin_out
= d
->hwirq
;
83 raw_spin_lock(&pdc_lock
);
84 enable
= pdc_reg_read(IRQ_ENABLE_BANK
, index
);
85 enable
= on
? ENABLE_INTR(enable
, mask
) : CLEAR_INTR(enable
, mask
);
86 pdc_reg_write(IRQ_ENABLE_BANK
, index
, enable
);
87 raw_spin_unlock(&pdc_lock
);
90 static void qcom_pdc_gic_disable(struct irq_data
*d
)
92 if (d
->hwirq
== GPIO_NO_WAKE_IRQ
)
95 pdc_enable_intr(d
, false);
96 irq_chip_disable_parent(d
);
99 static void qcom_pdc_gic_enable(struct irq_data
*d
)
101 if (d
->hwirq
== GPIO_NO_WAKE_IRQ
)
104 pdc_enable_intr(d
, true);
105 irq_chip_enable_parent(d
);
108 static void qcom_pdc_gic_mask(struct irq_data
*d
)
110 if (d
->hwirq
== GPIO_NO_WAKE_IRQ
)
113 irq_chip_mask_parent(d
);
116 static void qcom_pdc_gic_unmask(struct irq_data
*d
)
118 if (d
->hwirq
== GPIO_NO_WAKE_IRQ
)
121 irq_chip_unmask_parent(d
);
125 * GIC does not handle falling edge or active low. To allow falling edge and
126 * active low interrupts to be handled at GIC, PDC has an inverter that inverts
127 * falling edge into a rising edge and active low into an active high.
128 * For the inverter to work, the polarity bit in the IRQ_CONFIG register has to
129 * set as per the table below.
130 * Level sensitive active low LOW
131 * Rising edge sensitive NOT USED
132 * Falling edge sensitive LOW
133 * Dual Edge sensitive NOT USED
134 * Level sensitive active High HIGH
135 * Falling Edge sensitive NOT USED
136 * Rising edge sensitive HIGH
137 * Dual Edge sensitive HIGH
139 enum pdc_irq_config_bits
{
140 PDC_LEVEL_LOW
= 0b000,
141 PDC_EDGE_FALLING
= 0b010,
142 PDC_LEVEL_HIGH
= 0b100,
143 PDC_EDGE_RISING
= 0b110,
144 PDC_EDGE_DUAL
= 0b111,
148 * qcom_pdc_gic_set_type: Configure PDC for the interrupt
150 * @d: the interrupt data
151 * @type: the interrupt type
153 * If @type is edge triggered, forward that as Rising edge as PDC
154 * takes care of converting falling edge to rising edge signal
155 * If @type is level, then forward that as level high as PDC
156 * takes care of converting falling edge to rising edge signal
158 static int qcom_pdc_gic_set_type(struct irq_data
*d
, unsigned int type
)
160 int pin_out
= d
->hwirq
;
161 enum pdc_irq_config_bits pdc_type
;
162 enum pdc_irq_config_bits old_pdc_type
;
165 if (pin_out
== GPIO_NO_WAKE_IRQ
)
169 case IRQ_TYPE_EDGE_RISING
:
170 pdc_type
= PDC_EDGE_RISING
;
172 case IRQ_TYPE_EDGE_FALLING
:
173 pdc_type
= PDC_EDGE_FALLING
;
174 type
= IRQ_TYPE_EDGE_RISING
;
176 case IRQ_TYPE_EDGE_BOTH
:
177 pdc_type
= PDC_EDGE_DUAL
;
178 type
= IRQ_TYPE_EDGE_RISING
;
180 case IRQ_TYPE_LEVEL_HIGH
:
181 pdc_type
= PDC_LEVEL_HIGH
;
183 case IRQ_TYPE_LEVEL_LOW
:
184 pdc_type
= PDC_LEVEL_LOW
;
185 type
= IRQ_TYPE_LEVEL_HIGH
;
192 old_pdc_type
= pdc_reg_read(IRQ_i_CFG
, pin_out
);
193 pdc_reg_write(IRQ_i_CFG
, pin_out
, pdc_type
);
195 ret
= irq_chip_set_type_parent(d
, type
);
200 * When we change types the PDC can give a phantom interrupt.
201 * Clear it. Specifically the phantom shows up when reconfiguring
202 * polarity of interrupt without changing the state of the signal
203 * but let's be consistent and clear it always.
205 * Doing this works because we have IRQCHIP_SET_TYPE_MASKED so the
206 * interrupt will be cleared before the rest of the system sees it.
208 if (old_pdc_type
!= pdc_type
)
209 irq_chip_set_parent_state(d
, IRQCHIP_STATE_PENDING
, false);
214 static struct irq_chip qcom_pdc_gic_chip
= {
216 .irq_eoi
= irq_chip_eoi_parent
,
217 .irq_mask
= qcom_pdc_gic_mask
,
218 .irq_unmask
= qcom_pdc_gic_unmask
,
219 .irq_disable
= qcom_pdc_gic_disable
,
220 .irq_enable
= qcom_pdc_gic_enable
,
221 .irq_get_irqchip_state
= qcom_pdc_gic_get_irqchip_state
,
222 .irq_set_irqchip_state
= qcom_pdc_gic_set_irqchip_state
,
223 .irq_retrigger
= irq_chip_retrigger_hierarchy
,
224 .irq_set_type
= qcom_pdc_gic_set_type
,
225 .flags
= IRQCHIP_MASK_ON_SUSPEND
|
226 IRQCHIP_SET_TYPE_MASKED
|
227 IRQCHIP_SKIP_SET_WAKE
|
228 IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND
,
229 .irq_set_vcpu_affinity
= irq_chip_set_vcpu_affinity_parent
,
230 .irq_set_affinity
= irq_chip_set_affinity_parent
,
233 static irq_hw_number_t
get_parent_hwirq(int pin
)
236 struct pdc_pin_region
*region
;
238 for (i
= 0; i
< pdc_region_cnt
; i
++) {
239 region
= &pdc_region
[i
];
240 if (pin
>= region
->pin_base
&&
241 pin
< region
->pin_base
+ region
->cnt
)
242 return (region
->parent_base
+ pin
- region
->pin_base
);
245 return PDC_NO_PARENT_IRQ
;
248 static int qcom_pdc_translate(struct irq_domain
*d
, struct irq_fwspec
*fwspec
,
249 unsigned long *hwirq
, unsigned int *type
)
251 if (is_of_node(fwspec
->fwnode
)) {
252 if (fwspec
->param_count
!= 2)
255 *hwirq
= fwspec
->param
[0];
256 *type
= fwspec
->param
[1] & IRQ_TYPE_SENSE_MASK
;
263 static int qcom_pdc_alloc(struct irq_domain
*domain
, unsigned int virq
,
264 unsigned int nr_irqs
, void *data
)
266 struct irq_fwspec
*fwspec
= data
;
267 struct irq_fwspec parent_fwspec
;
268 irq_hw_number_t hwirq
, parent_hwirq
;
272 ret
= qcom_pdc_translate(domain
, fwspec
, &hwirq
, &type
);
276 ret
= irq_domain_set_hwirq_and_chip(domain
, virq
, hwirq
,
277 &qcom_pdc_gic_chip
, NULL
);
281 parent_hwirq
= get_parent_hwirq(hwirq
);
282 if (parent_hwirq
== PDC_NO_PARENT_IRQ
)
285 if (type
& IRQ_TYPE_EDGE_BOTH
)
286 type
= IRQ_TYPE_EDGE_RISING
;
288 if (type
& IRQ_TYPE_LEVEL_MASK
)
289 type
= IRQ_TYPE_LEVEL_HIGH
;
291 parent_fwspec
.fwnode
= domain
->parent
->fwnode
;
292 parent_fwspec
.param_count
= 3;
293 parent_fwspec
.param
[0] = 0;
294 parent_fwspec
.param
[1] = parent_hwirq
;
295 parent_fwspec
.param
[2] = type
;
297 return irq_domain_alloc_irqs_parent(domain
, virq
, nr_irqs
,
301 static const struct irq_domain_ops qcom_pdc_ops
= {
302 .translate
= qcom_pdc_translate
,
303 .alloc
= qcom_pdc_alloc
,
304 .free
= irq_domain_free_irqs_common
,
307 static int qcom_pdc_gpio_alloc(struct irq_domain
*domain
, unsigned int virq
,
308 unsigned int nr_irqs
, void *data
)
310 struct irq_fwspec
*fwspec
= data
;
311 struct irq_fwspec parent_fwspec
;
312 irq_hw_number_t hwirq
, parent_hwirq
;
316 ret
= qcom_pdc_translate(domain
, fwspec
, &hwirq
, &type
);
320 ret
= irq_domain_set_hwirq_and_chip(domain
, virq
, hwirq
,
321 &qcom_pdc_gic_chip
, NULL
);
325 if (hwirq
== GPIO_NO_WAKE_IRQ
)
328 parent_hwirq
= get_parent_hwirq(hwirq
);
329 if (parent_hwirq
== PDC_NO_PARENT_IRQ
)
332 if (type
& IRQ_TYPE_EDGE_BOTH
)
333 type
= IRQ_TYPE_EDGE_RISING
;
335 if (type
& IRQ_TYPE_LEVEL_MASK
)
336 type
= IRQ_TYPE_LEVEL_HIGH
;
338 parent_fwspec
.fwnode
= domain
->parent
->fwnode
;
339 parent_fwspec
.param_count
= 3;
340 parent_fwspec
.param
[0] = 0;
341 parent_fwspec
.param
[1] = parent_hwirq
;
342 parent_fwspec
.param
[2] = type
;
344 return irq_domain_alloc_irqs_parent(domain
, virq
, nr_irqs
,
348 static int qcom_pdc_gpio_domain_select(struct irq_domain
*d
,
349 struct irq_fwspec
*fwspec
,
350 enum irq_domain_bus_token bus_token
)
352 return bus_token
== DOMAIN_BUS_WAKEUP
;
355 static const struct irq_domain_ops qcom_pdc_gpio_ops
= {
356 .select
= qcom_pdc_gpio_domain_select
,
357 .alloc
= qcom_pdc_gpio_alloc
,
358 .free
= irq_domain_free_irqs_common
,
361 static int pdc_setup_pin_mapping(struct device_node
*np
)
364 u32 irq_index
, reg_index
, val
;
366 n
= of_property_count_elems_of_size(np
, "qcom,pdc-ranges", sizeof(u32
));
370 pdc_region_cnt
= n
/ 3;
371 pdc_region
= kcalloc(pdc_region_cnt
, sizeof(*pdc_region
), GFP_KERNEL
);
377 for (n
= 0; n
< pdc_region_cnt
; n
++) {
378 ret
= of_property_read_u32_index(np
, "qcom,pdc-ranges",
380 &pdc_region
[n
].pin_base
);
383 ret
= of_property_read_u32_index(np
, "qcom,pdc-ranges",
385 &pdc_region
[n
].parent_base
);
388 ret
= of_property_read_u32_index(np
, "qcom,pdc-ranges",
394 for (i
= 0; i
< pdc_region
[n
].cnt
; i
++) {
395 reg_index
= (i
+ pdc_region
[n
].pin_base
) >> 5;
396 irq_index
= (i
+ pdc_region
[n
].pin_base
) & 0x1f;
397 val
= pdc_reg_read(IRQ_ENABLE_BANK
, reg_index
);
398 val
&= ~BIT(irq_index
);
399 pdc_reg_write(IRQ_ENABLE_BANK
, reg_index
, val
);
406 static int qcom_pdc_init(struct device_node
*node
, struct device_node
*parent
)
408 struct irq_domain
*parent_domain
, *pdc_domain
, *pdc_gpio_domain
;
411 pdc_base
= of_iomap(node
, 0);
413 pr_err("%pOF: unable to map PDC registers\n", node
);
417 parent_domain
= irq_find_host(parent
);
418 if (!parent_domain
) {
419 pr_err("%pOF: unable to find PDC's parent domain\n", node
);
424 ret
= pdc_setup_pin_mapping(node
);
426 pr_err("%pOF: failed to init PDC pin-hwirq mapping\n", node
);
430 pdc_domain
= irq_domain_create_hierarchy(parent_domain
, 0, PDC_MAX_IRQS
,
431 of_fwnode_handle(node
),
432 &qcom_pdc_ops
, NULL
);
434 pr_err("%pOF: GIC domain add failed\n", node
);
439 pdc_gpio_domain
= irq_domain_create_hierarchy(parent_domain
,
440 IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP
,
442 of_fwnode_handle(node
),
443 &qcom_pdc_gpio_ops
, NULL
);
444 if (!pdc_gpio_domain
) {
445 pr_err("%pOF: PDC domain add failed for GPIO domain\n", node
);
450 irq_domain_update_bus_token(pdc_gpio_domain
, DOMAIN_BUS_WAKEUP
);
455 irq_domain_remove(pdc_domain
);
462 IRQCHIP_DECLARE(qcom_pdc
, "qcom,pdc", qcom_pdc_init
);