Lines Matching +full:parent +full:- +full:interrupt +full:- +full:base

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver code for Tegra's Legacy Interrupt Controller
7 * Heavily based on the original arch/arm/mach-tegra/irq.c code:
24 #include <dt-bindings/interrupt-controller/arm-gic.h>
62 { .compatible = "nvidia,tegra210-ictlr", .data = &tegra210_ictlr_soc },
63 { .compatible = "nvidia,tegra30-ictlr", .data = &tegra30_ictlr_soc },
64 { .compatible = "nvidia,tegra20-ictlr", .data = &tegra20_ictlr_soc },
69 void __iomem *base[TEGRA_MAX_NUM_ICTLRS]; member
84 void __iomem *base = (void __iomem __force *)d->chip_data; in tegra_ictlr_write_mask() local
87 mask = BIT(d->hwirq % 32); in tegra_ictlr_write_mask()
88 writel_relaxed(mask, base + reg); in tegra_ictlr_write_mask()
118 u32 irq = d->hwirq; in tegra_set_wake()
124 lic->ictlr_wake_mask[index] |= mask; in tegra_set_wake()
126 lic->ictlr_wake_mask[index] &= ~mask; in tegra_set_wake()
129 * Do *not* call into the parent, as the GIC doesn't have any in tegra_set_wake()
130 * wake-up facility... in tegra_set_wake()
142 void __iomem *ictlr = lic->base[i]; in tegra_ictlr_suspend()
144 /* Save interrupt state */ in tegra_ictlr_suspend()
145 lic->cpu_ier[i] = readl_relaxed(ictlr + ICTLR_CPU_IER); in tegra_ictlr_suspend()
146 lic->cpu_iep[i] = readl_relaxed(ictlr + ICTLR_CPU_IEP_CLASS); in tegra_ictlr_suspend()
147 lic->cop_ier[i] = readl_relaxed(ictlr + ICTLR_COP_IER); in tegra_ictlr_suspend()
148 lic->cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS); in tegra_ictlr_suspend()
157 writel_relaxed(lic->ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET); in tegra_ictlr_suspend()
171 void __iomem *ictlr = lic->base[i]; in tegra_ictlr_resume()
173 writel_relaxed(lic->cpu_iep[i], in tegra_ictlr_resume()
176 writel_relaxed(lic->cpu_ier[i], in tegra_ictlr_resume()
178 writel_relaxed(lic->cop_iep[i], in tegra_ictlr_resume()
181 writel_relaxed(lic->cop_ier[i], in tegra_ictlr_resume()
220 if (is_of_node(fwspec->fwnode)) { in tegra_ictlr_domain_translate()
221 if (fwspec->param_count != 3) in tegra_ictlr_domain_translate()
222 return -EINVAL; in tegra_ictlr_domain_translate()
225 if (fwspec->param[0] != 0) in tegra_ictlr_domain_translate()
226 return -EINVAL; in tegra_ictlr_domain_translate()
228 *hwirq = fwspec->param[1]; in tegra_ictlr_domain_translate()
229 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; in tegra_ictlr_domain_translate()
233 return -EINVAL; in tegra_ictlr_domain_translate()
242 struct tegra_ictlr_info *info = domain->host_data; in tegra_ictlr_domain_alloc()
246 if (fwspec->param_count != 3) in tegra_ictlr_domain_alloc()
247 return -EINVAL; /* Not GIC compliant */ in tegra_ictlr_domain_alloc()
248 if (fwspec->param[0] != GIC_SPI) in tegra_ictlr_domain_alloc()
249 return -EINVAL; /* No PPI should point to this domain */ in tegra_ictlr_domain_alloc()
251 hwirq = fwspec->param[1]; in tegra_ictlr_domain_alloc()
253 return -EINVAL; in tegra_ictlr_domain_alloc()
260 (void __force *)info->base[ictlr]); in tegra_ictlr_domain_alloc()
264 parent_fwspec.fwnode = domain->parent->fwnode; in tegra_ictlr_domain_alloc()
276 struct device_node *parent) in tegra_ictlr_init() argument
284 if (!parent) { in tegra_ictlr_init()
285 pr_err("%pOF: no parent, giving up\n", node); in tegra_ictlr_init()
286 return -ENODEV; in tegra_ictlr_init()
289 parent_domain = irq_find_host(parent); in tegra_ictlr_init()
291 pr_err("%pOF: unable to obtain parent domain\n", node); in tegra_ictlr_init()
292 return -ENXIO; in tegra_ictlr_init()
297 return -ENODEV; in tegra_ictlr_init()
299 soc = match->data; in tegra_ictlr_init()
303 return -ENOMEM; in tegra_ictlr_init()
306 void __iomem *base; in tegra_ictlr_init() local
308 base = of_iomap(node, i); in tegra_ictlr_init()
309 if (!base) in tegra_ictlr_init()
312 lic->base[i] = base; in tegra_ictlr_init()
315 writel_relaxed(GENMASK(31, 0), base + ICTLR_CPU_IER_CLR); in tegra_ictlr_init()
317 writel_relaxed(0, base + ICTLR_CPU_IEP_CLASS); in tegra_ictlr_init()
324 err = -ENOMEM; in tegra_ictlr_init()
328 WARN(num_ictlrs != soc->num_ictlrs, in tegra_ictlr_init()
329 "%pOF: Found %u interrupt controllers in DT; expected %u.\n", in tegra_ictlr_init()
330 node, num_ictlrs, soc->num_ictlrs); in tegra_ictlr_init()
338 err = -ENOMEM; in tegra_ictlr_init()
345 node, num_ictlrs * 32, parent); in tegra_ictlr_init()
351 iounmap(lic->base[i]); in tegra_ictlr_init()
357 IRQCHIP_DECLARE(tegra20_ictlr, "nvidia,tegra20-ictlr", tegra_ictlr_init);
358 IRQCHIP_DECLARE(tegra30_ictlr, "nvidia,tegra30-ictlr", tegra_ictlr_init);
359 IRQCHIP_DECLARE(tegra210_ictlr, "nvidia,tegra210-ictlr", tegra_ictlr_init);