Lines Matching +full:loongson +full:- +full:2 +full:k
1 // SPDX-License-Identifier: GPL-2.0
4 * Loongson Local IO Interrupt Controller support
20 #include <loongson.h>
22 #include <asm/loongson.h>
25 #include "irq-loongson.h"
38 * LIOINTC_REG_INTC_POL register is only valid for Loongson-2K series, and
39 * Loongson-3 series behave as noops.
75 struct irq_chip_generic *gc = handler->priv->gc; in liointc_chained_handle_irq()
81 pending = readl(handler->priv->core_isr[core]); in liointc_chained_handle_irq()
85 if (handler->priv->has_lpc_irq_errata && in liointc_chained_handle_irq()
86 (handler->parent_int_map & gc->mask_cache & in liointc_chained_handle_irq()
96 generic_handle_domain_irq(gc->domain, bit); in liointc_chained_handle_irq()
108 writel(readl(gc->reg_base + offset) | mask, in liointc_set_bit()
109 gc->reg_base + offset); in liointc_set_bit()
111 writel(readl(gc->reg_base + offset) & ~mask, in liointc_set_bit()
112 gc->reg_base + offset); in liointc_set_bit()
118 u32 mask = data->mask; in liointc_set_type()
141 return -EINVAL; in liointc_set_type()
151 struct liointc_priv *priv = gc->private; in liointc_suspend()
153 priv->int_pol = readl(gc->reg_base + LIOINTC_REG_INTC_POL); in liointc_suspend()
154 priv->int_edge = readl(gc->reg_base + LIOINTC_REG_INTC_EDGE); in liointc_suspend()
159 struct liointc_priv *priv = gc->private; in liointc_resume()
165 writel(0xffffffff, gc->reg_base + LIOINTC_REG_INTC_DISABLE); in liointc_resume()
168 writeb(priv->map_cache[i], gc->reg_base + i); in liointc_resume()
169 writel(priv->int_pol, gc->reg_base + LIOINTC_REG_INTC_POL); in liointc_resume()
170 writel(priv->int_edge, gc->reg_base + LIOINTC_REG_INTC_EDGE); in liointc_resume()
172 writel(gc->mask_cache, gc->reg_base + LIOINTC_REG_INTC_ENABLE); in liointc_resume()
186 return -EINVAL; in liointc_domain_xlate()
187 *out_hwirq = intspec[0] - GSI_MIN_CPU_IRQ; in liointc_domain_xlate()
215 return -ENOMEM; in liointc_init()
222 priv->core_isr[i] = base + LIOINTC_REG_INTC_STATUS(i); in liointc_init()
225 priv->handler[i].parent_int_map = parent_int_map[i]; in liointc_init()
230 "reg-names", core_reg_names[i]); in liointc_init()
235 priv->core_isr[i] = of_iomap(node, index); in liointc_init()
238 if (!priv->core_isr[0]) in liointc_init()
250 pr_err("loongson-liointc: cannot add IRQ domain\n"); in liointc_init()
255 (node ? node->full_name : "LIOINTC"), in liointc_init()
258 pr_err("loongson-liointc: unable to register IRQ domain\n"); in liointc_init()
270 u32 pending = priv->handler[i].parent_int_map; in liointc_init()
275 priv->map_cache[bit] = BIT(i) << LIOINTC_SHIFT_INTx; in liointc_init()
282 priv->map_cache[i] |= BIT(loongson_sysconf.boot_cpu_id); in liointc_init()
283 writeb(priv->map_cache[i], base + i); in liointc_init()
287 gc->private = priv; in liointc_init()
288 gc->reg_base = base; in liointc_init()
289 gc->domain = domain; in liointc_init()
290 gc->suspend = liointc_suspend; in liointc_init()
291 gc->resume = liointc_resume; in liointc_init()
293 ct = gc->chip_types; in liointc_init()
294 ct->regs.enable = LIOINTC_REG_INTC_ENABLE; in liointc_init()
295 ct->regs.disable = LIOINTC_REG_INTC_DISABLE; in liointc_init()
296 ct->chip.irq_unmask = irq_gc_unmask_enable_reg; in liointc_init()
297 ct->chip.irq_mask = irq_gc_mask_disable_reg; in liointc_init()
298 ct->chip.irq_mask_ack = irq_gc_mask_disable_reg; in liointc_init()
299 ct->chip.irq_set_type = liointc_set_type; in liointc_init()
300 ct->chip.flags = IRQCHIP_SKIP_SET_WAKE; in liointc_init()
302 gc->mask_cache = 0; in liointc_init()
303 priv->gc = gc; in liointc_init()
309 priv->handler[i].priv = priv; in liointc_init()
311 liointc_chained_handle_irq, &priv->handler[i]); in liointc_init()
324 return -EINVAL; in liointc_init()
336 if (!of_device_is_compatible(node, "loongson,liointc-2.0")) { in liointc_of_init()
340 index = of_property_match_string(node, "reg-names", "main"); in liointc_of_init()
341 revision = 2; in liointc_of_init()
345 return -EINVAL; in liointc_of_init()
353 return -ENODEV; in liointc_of_init()
356 "loongson,parent_int_map", in liointc_of_init()
361 pr_err("loongson-liointc: No parent_int_map\n"); in liointc_of_init()
362 return -ENODEV; in liointc_of_init()
373 IRQCHIP_DECLARE(loongson_liointc_1_0, "loongson,liointc-1.0", liointc_of_init);
374 IRQCHIP_DECLARE(loongson_liointc_1_0a, "loongson,liointc-1.0a", liointc_of_init);
375 IRQCHIP_DECLARE(loongson_liointc_2_0, "loongson,liointc-2.0", liointc_of_init);
405 parent_int_map[0] = acpi_liointc->cascade_map[0]; in liointc_acpi_init()
406 parent_int_map[1] = acpi_liointc->cascade_map[1]; in liointc_acpi_init()
408 parent_irq[0] = irq_create_mapping(parent, acpi_liointc->cascade[0]); in liointc_acpi_init()
409 parent_irq[1] = irq_create_mapping(parent, acpi_liointc->cascade[1]); in liointc_acpi_init()
411 domain_handle = irq_domain_alloc_fwnode(&acpi_liointc->address); in liointc_acpi_init()
414 return -ENOMEM; in liointc_acpi_init()
417 ret = liointc_init(acpi_liointc->address, acpi_liointc->size, in liointc_acpi_init()