Lines Matching +full:parent +full:- +full:interrupt +full:- +full:base
1 // SPDX-License-Identifier: GPL-2.0+
3 * Actions Semi Owl SoCs SIRQ interrupt controller driver
6 * David Liu <liuwei@actions-semi.com>
14 #include <linux/interrupt.h>
19 #include <dt-bindings/interrupt-controller/arm-gic.h>
37 /* S900 SIRQ control register offsets, relative to controller base address */
45 /* INTC_EXTCTL reg offsets relative to controller base address */
51 void __iomem *base; member
98 val = readl_relaxed(data->base + data->params->reg_offset[index]); in owl_sirq_read_extctl()
99 if (data->params->reg_shared) in owl_sirq_read_extctl()
110 if (data->params->reg_shared) { in owl_sirq_write_extctl()
111 val = readl_relaxed(data->base + data->params->reg_offset[index]); in owl_sirq_write_extctl()
116 writel_relaxed(extctl, data->base + data->params->reg_offset[index]); in owl_sirq_write_extctl()
125 raw_spin_lock_irqsave(&d->lock, flags); in owl_sirq_clear_set_extctl()
130 raw_spin_unlock_irqrestore(&d->lock, flags); in owl_sirq_clear_set_extctl()
138 * Software must clear external interrupt pending, when interrupt type in owl_sirq_eoi()
143 data->hwirq); in owl_sirq_eoi()
152 owl_sirq_clear_set_extctl(chip_data, INTC_EXTCTL_EN, 0, data->hwirq); in owl_sirq_mask()
160 owl_sirq_clear_set_extctl(chip_data, 0, INTC_EXTCTL_EN, data->hwirq); in owl_sirq_unmask()
190 return -EINVAL; in owl_sirq_set_type()
194 data->hwirq); in owl_sirq_set_type()
200 .name = "owl-sirq",
216 if (!is_of_node(fwspec->fwnode)) in owl_sirq_domain_translate()
217 return -EINVAL; in owl_sirq_domain_translate()
219 if (fwspec->param_count != 2 || fwspec->param[0] >= NUM_SIRQ) in owl_sirq_domain_translate()
220 return -EINVAL; in owl_sirq_domain_translate()
222 *hwirq = fwspec->param[0]; in owl_sirq_domain_translate()
223 *type = fwspec->param[1]; in owl_sirq_domain_translate()
231 struct owl_sirq_chip_data *chip_data = domain->host_data; in owl_sirq_domain_alloc()
239 return -EINVAL; in owl_sirq_domain_alloc()
256 return -EINVAL; in owl_sirq_domain_alloc()
262 parent_fwspec.fwnode = domain->parent->fwnode; in owl_sirq_domain_alloc()
265 parent_fwspec.param[1] = chip_data->ext_irqs[hwirq]; in owl_sirq_domain_alloc()
279 struct device_node *parent) in owl_sirq_init() argument
285 parent_domain = irq_find_host(parent); in owl_sirq_init()
287 pr_err("%pOF: failed to find sirq parent domain\n", node); in owl_sirq_init()
288 return -ENXIO; in owl_sirq_init()
293 return -ENOMEM; in owl_sirq_init()
295 raw_spin_lock_init(&chip_data->lock); in owl_sirq_init()
297 chip_data->params = params; in owl_sirq_init()
299 chip_data->base = of_iomap(node, 0); in owl_sirq_init()
300 if (!chip_data->base) { in owl_sirq_init()
302 ret = -ENXIO; in owl_sirq_init()
311 pr_err("%pOF: failed to parse interrupt %d\n", node, i); in owl_sirq_init()
316 ret = -EINVAL; in owl_sirq_init()
320 chip_data->ext_irqs[i] = irq.args[1]; in owl_sirq_init()
322 /* Set 24MHz external interrupt clock freq */ in owl_sirq_init()
330 ret = -ENOMEM; in owl_sirq_init()
337 iounmap(chip_data->base); in owl_sirq_init()
345 struct device_node *parent) in owl_sirq_s500_of_init() argument
347 return owl_sirq_init(&owl_sirq_s500_params, node, parent); in owl_sirq_s500_of_init()
350 IRQCHIP_DECLARE(owl_sirq_s500, "actions,s500-sirq", owl_sirq_s500_of_init);
351 IRQCHIP_DECLARE(owl_sirq_s700, "actions,s700-sirq", owl_sirq_s500_of_init);
354 struct device_node *parent) in owl_sirq_s900_of_init() argument
356 return owl_sirq_init(&owl_sirq_s900_params, node, parent); in owl_sirq_s900_of_init()
359 IRQCHIP_DECLARE(owl_sirq_s900, "actions,s900-sirq", owl_sirq_s900_of_init);