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
;
163 if (pin_out
== GPIO_NO_WAKE_IRQ
)
167 case IRQ_TYPE_EDGE_RISING
:
168 pdc_type
= PDC_EDGE_RISING
;
170 case IRQ_TYPE_EDGE_FALLING
:
171 pdc_type
= PDC_EDGE_FALLING
;
172 type
= IRQ_TYPE_EDGE_RISING
;
174 case IRQ_TYPE_EDGE_BOTH
:
175 pdc_type
= PDC_EDGE_DUAL
;
176 type
= IRQ_TYPE_EDGE_RISING
;
178 case IRQ_TYPE_LEVEL_HIGH
:
179 pdc_type
= PDC_LEVEL_HIGH
;
181 case IRQ_TYPE_LEVEL_LOW
:
182 pdc_type
= PDC_LEVEL_LOW
;
183 type
= IRQ_TYPE_LEVEL_HIGH
;
190 pdc_reg_write(IRQ_i_CFG
, pin_out
, pdc_type
);
192 return irq_chip_set_type_parent(d
, type
);
195 static struct irq_chip qcom_pdc_gic_chip
= {
197 .irq_eoi
= irq_chip_eoi_parent
,
198 .irq_mask
= qcom_pdc_gic_mask
,
199 .irq_unmask
= qcom_pdc_gic_unmask
,
200 .irq_disable
= qcom_pdc_gic_disable
,
201 .irq_enable
= qcom_pdc_gic_enable
,
202 .irq_get_irqchip_state
= qcom_pdc_gic_get_irqchip_state
,
203 .irq_set_irqchip_state
= qcom_pdc_gic_set_irqchip_state
,
204 .irq_retrigger
= irq_chip_retrigger_hierarchy
,
205 .irq_set_type
= qcom_pdc_gic_set_type
,
206 .flags
= IRQCHIP_MASK_ON_SUSPEND
|
207 IRQCHIP_SET_TYPE_MASKED
|
208 IRQCHIP_SKIP_SET_WAKE
,
209 .irq_set_vcpu_affinity
= irq_chip_set_vcpu_affinity_parent
,
210 .irq_set_affinity
= irq_chip_set_affinity_parent
,
213 static irq_hw_number_t
get_parent_hwirq(int pin
)
216 struct pdc_pin_region
*region
;
218 for (i
= 0; i
< pdc_region_cnt
; i
++) {
219 region
= &pdc_region
[i
];
220 if (pin
>= region
->pin_base
&&
221 pin
< region
->pin_base
+ region
->cnt
)
222 return (region
->parent_base
+ pin
- region
->pin_base
);
225 return PDC_NO_PARENT_IRQ
;
228 static int qcom_pdc_translate(struct irq_domain
*d
, struct irq_fwspec
*fwspec
,
229 unsigned long *hwirq
, unsigned int *type
)
231 if (is_of_node(fwspec
->fwnode
)) {
232 if (fwspec
->param_count
!= 2)
235 *hwirq
= fwspec
->param
[0];
236 *type
= fwspec
->param
[1] & IRQ_TYPE_SENSE_MASK
;
243 static int qcom_pdc_alloc(struct irq_domain
*domain
, unsigned int virq
,
244 unsigned int nr_irqs
, void *data
)
246 struct irq_fwspec
*fwspec
= data
;
247 struct irq_fwspec parent_fwspec
;
248 irq_hw_number_t hwirq
, parent_hwirq
;
252 ret
= qcom_pdc_translate(domain
, fwspec
, &hwirq
, &type
);
256 ret
= irq_domain_set_hwirq_and_chip(domain
, virq
, hwirq
,
257 &qcom_pdc_gic_chip
, NULL
);
261 parent_hwirq
= get_parent_hwirq(hwirq
);
262 if (parent_hwirq
== PDC_NO_PARENT_IRQ
)
265 if (type
& IRQ_TYPE_EDGE_BOTH
)
266 type
= IRQ_TYPE_EDGE_RISING
;
268 if (type
& IRQ_TYPE_LEVEL_MASK
)
269 type
= IRQ_TYPE_LEVEL_HIGH
;
271 parent_fwspec
.fwnode
= domain
->parent
->fwnode
;
272 parent_fwspec
.param_count
= 3;
273 parent_fwspec
.param
[0] = 0;
274 parent_fwspec
.param
[1] = parent_hwirq
;
275 parent_fwspec
.param
[2] = type
;
277 return irq_domain_alloc_irqs_parent(domain
, virq
, nr_irqs
,
281 static const struct irq_domain_ops qcom_pdc_ops
= {
282 .translate
= qcom_pdc_translate
,
283 .alloc
= qcom_pdc_alloc
,
284 .free
= irq_domain_free_irqs_common
,
287 static int qcom_pdc_gpio_alloc(struct irq_domain
*domain
, unsigned int virq
,
288 unsigned int nr_irqs
, void *data
)
290 struct irq_fwspec
*fwspec
= data
;
291 struct irq_fwspec parent_fwspec
;
292 irq_hw_number_t hwirq
, parent_hwirq
;
296 ret
= qcom_pdc_translate(domain
, fwspec
, &hwirq
, &type
);
300 ret
= irq_domain_set_hwirq_and_chip(domain
, virq
, hwirq
,
301 &qcom_pdc_gic_chip
, NULL
);
305 if (hwirq
== GPIO_NO_WAKE_IRQ
)
308 parent_hwirq
= get_parent_hwirq(hwirq
);
309 if (parent_hwirq
== PDC_NO_PARENT_IRQ
)
312 if (type
& IRQ_TYPE_EDGE_BOTH
)
313 type
= IRQ_TYPE_EDGE_RISING
;
315 if (type
& IRQ_TYPE_LEVEL_MASK
)
316 type
= IRQ_TYPE_LEVEL_HIGH
;
318 parent_fwspec
.fwnode
= domain
->parent
->fwnode
;
319 parent_fwspec
.param_count
= 3;
320 parent_fwspec
.param
[0] = 0;
321 parent_fwspec
.param
[1] = parent_hwirq
;
322 parent_fwspec
.param
[2] = type
;
324 return irq_domain_alloc_irqs_parent(domain
, virq
, nr_irqs
,
328 static int qcom_pdc_gpio_domain_select(struct irq_domain
*d
,
329 struct irq_fwspec
*fwspec
,
330 enum irq_domain_bus_token bus_token
)
332 return bus_token
== DOMAIN_BUS_WAKEUP
;
335 static const struct irq_domain_ops qcom_pdc_gpio_ops
= {
336 .select
= qcom_pdc_gpio_domain_select
,
337 .alloc
= qcom_pdc_gpio_alloc
,
338 .free
= irq_domain_free_irqs_common
,
341 static int pdc_setup_pin_mapping(struct device_node
*np
)
345 n
= of_property_count_elems_of_size(np
, "qcom,pdc-ranges", sizeof(u32
));
349 pdc_region_cnt
= n
/ 3;
350 pdc_region
= kcalloc(pdc_region_cnt
, sizeof(*pdc_region
), GFP_KERNEL
);
356 for (n
= 0; n
< pdc_region_cnt
; n
++) {
357 ret
= of_property_read_u32_index(np
, "qcom,pdc-ranges",
359 &pdc_region
[n
].pin_base
);
362 ret
= of_property_read_u32_index(np
, "qcom,pdc-ranges",
364 &pdc_region
[n
].parent_base
);
367 ret
= of_property_read_u32_index(np
, "qcom,pdc-ranges",
377 static int qcom_pdc_init(struct device_node
*node
, struct device_node
*parent
)
379 struct irq_domain
*parent_domain
, *pdc_domain
, *pdc_gpio_domain
;
382 pdc_base
= of_iomap(node
, 0);
384 pr_err("%pOF: unable to map PDC registers\n", node
);
388 parent_domain
= irq_find_host(parent
);
389 if (!parent_domain
) {
390 pr_err("%pOF: unable to find PDC's parent domain\n", node
);
395 ret
= pdc_setup_pin_mapping(node
);
397 pr_err("%pOF: failed to init PDC pin-hwirq mapping\n", node
);
401 pdc_domain
= irq_domain_create_hierarchy(parent_domain
, 0, PDC_MAX_IRQS
,
402 of_fwnode_handle(node
),
403 &qcom_pdc_ops
, NULL
);
405 pr_err("%pOF: GIC domain add failed\n", node
);
410 pdc_gpio_domain
= irq_domain_create_hierarchy(parent_domain
,
411 IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP
,
413 of_fwnode_handle(node
),
414 &qcom_pdc_gpio_ops
, NULL
);
415 if (!pdc_gpio_domain
) {
416 pr_err("%pOF: PDC domain add failed for GPIO domain\n", node
);
421 irq_domain_update_bus_token(pdc_gpio_domain
, DOMAIN_BUS_WAKEUP
);
426 irq_domain_remove(pdc_domain
);
433 IRQCHIP_DECLARE(qcom_pdc
, "qcom,pdc", qcom_pdc_init
);