linux/drivers/irqchip/irq-ingenic.c
Linus Torvalds bf4afc53b7 Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
This was done entirely with mindless brute force, using

    git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
        xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'

to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.

Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.

For the same reason the 'flex' versions will be done as a separate
conversion.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21 17:09:51 -08:00

160 lines
3.9 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* Ingenic XBurst platform IRQ support
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/irqchip.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/io.h>
struct ingenic_intc_data {
void __iomem *base;
struct irq_domain *domain;
unsigned num_chips;
};
#define JZ_REG_INTC_STATUS 0x00
#define JZ_REG_INTC_MASK 0x04
#define JZ_REG_INTC_SET_MASK 0x08
#define JZ_REG_INTC_CLEAR_MASK 0x0c
#define JZ_REG_INTC_PENDING 0x10
#define CHIP_SIZE 0x20
static irqreturn_t intc_cascade(int irq, void *data)
{
struct ingenic_intc_data *intc = irq_get_handler_data(irq);
struct irq_domain *domain = intc->domain;
struct irq_chip_generic *gc;
uint32_t pending;
unsigned i;
for (i = 0; i < intc->num_chips; i++) {
gc = irq_get_domain_generic_chip(domain, i * 32);
pending = irq_reg_readl(gc, JZ_REG_INTC_PENDING);
if (!pending)
continue;
while (pending) {
int bit = __fls(pending);
generic_handle_domain_irq(domain, bit + (i * 32));
pending &= ~BIT(bit);
}
}
return IRQ_HANDLED;
}
static int __init ingenic_intc_of_init(struct device_node *node,
unsigned num_chips)
{
struct ingenic_intc_data *intc;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
struct irq_domain *domain;
int parent_irq, err = 0;
unsigned i;
intc = kzalloc_obj(*intc);
if (!intc) {
err = -ENOMEM;
goto out_err;
}
parent_irq = irq_of_parse_and_map(node, 0);
if (!parent_irq) {
err = -EINVAL;
goto out_free;
}
err = irq_set_handler_data(parent_irq, intc);
if (err)
goto out_unmap_irq;
intc->num_chips = num_chips;
intc->base = of_iomap(node, 0);
if (!intc->base) {
err = -ENODEV;
goto out_unmap_irq;
}
domain = irq_domain_create_linear(of_fwnode_handle(node), num_chips * 32,
&irq_generic_chip_ops, NULL);
if (!domain) {
err = -ENOMEM;
goto out_unmap_base;
}
intc->domain = domain;
err = irq_alloc_domain_generic_chips(domain, 32, 1, "INTC",
handle_level_irq, 0,
IRQ_NOPROBE | IRQ_LEVEL, 0);
if (err)
goto out_domain_remove;
for (i = 0; i < num_chips; i++) {
gc = irq_get_domain_generic_chip(domain, i * 32);
gc->wake_enabled = IRQ_MSK(32);
gc->reg_base = intc->base + (i * CHIP_SIZE);
ct = gc->chip_types;
ct->regs.enable = JZ_REG_INTC_CLEAR_MASK;
ct->regs.disable = JZ_REG_INTC_SET_MASK;
ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
ct->chip.irq_mask = irq_gc_mask_disable_reg;
ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
ct->chip.irq_set_wake = irq_gc_set_wake;
ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND;
/* Mask all irqs */
irq_reg_writel(gc, IRQ_MSK(32), JZ_REG_INTC_SET_MASK);
}
if (request_irq(parent_irq, intc_cascade, IRQF_NO_SUSPEND,
"SoC intc cascade interrupt", NULL))
pr_err("Failed to register SoC intc cascade interrupt\n");
return 0;
out_domain_remove:
irq_domain_remove(domain);
out_unmap_base:
iounmap(intc->base);
out_unmap_irq:
irq_dispose_mapping(parent_irq);
out_free:
kfree(intc);
out_err:
return err;
}
static int __init intc_1chip_of_init(struct device_node *node,
struct device_node *parent)
{
return ingenic_intc_of_init(node, 1);
}
IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", intc_1chip_of_init);
IRQCHIP_DECLARE(jz4725b_intc, "ingenic,jz4725b-intc", intc_1chip_of_init);
static int __init intc_2chip_of_init(struct device_node *node,
struct device_node *parent)
{
return ingenic_intc_of_init(node, 2);
}
IRQCHIP_DECLARE(jz4760_intc, "ingenic,jz4760-intc", intc_2chip_of_init);
IRQCHIP_DECLARE(jz4770_intc, "ingenic,jz4770-intc", intc_2chip_of_init);
IRQCHIP_DECLARE(jz4775_intc, "ingenic,jz4775-intc", intc_2chip_of_init);
IRQCHIP_DECLARE(jz4780_intc, "ingenic,jz4780-intc", intc_2chip_of_init);