// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for MIPS Goldfish Programmable Interrupt Controller.
 *
 * Author: Miodrag Dinic <miodrag.dinic@mips.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#define GFPIC_NR_IRQS			32

/* 8..39 Cascaded Goldfish PIC interrupts */
#define GFPIC_IRQ_BASE			8

#define GFPIC_REG_IRQ_PENDING		0x04
#define GFPIC_REG_IRQ_DISABLE_ALL	0x08
#define GFPIC_REG_IRQ_DISABLE		0x0c
#define GFPIC_REG_IRQ_ENABLE		0x10

struct goldfish_pic_data {
	void __iomem *base;
	struct irq_domain *irq_domain;
};

static void goldfish_pic_cascade(struct irq_desc *desc)
{
	struct goldfish_pic_data *gfpic = irq_desc_get_handler_data(desc);
	struct irq_chip *host_chip = irq_desc_get_chip(desc);
	u32 pending, hwirq;

	chained_irq_enter(host_chip, desc);

	pending = readl(gfpic->base + GFPIC_REG_IRQ_PENDING);
	while (pending) {
		hwirq = __fls(pending);
		generic_handle_domain_irq(gfpic->irq_domain, hwirq);
		pending &= ~(1 << hwirq);
	}

	chained_irq_exit(host_chip, desc);
}

static const struct irq_domain_ops goldfish_irq_domain_ops = {
	.xlate = irq_domain_xlate_onecell,
};

static int __init goldfish_pic_of_init(struct device_node *of_node,
				       struct device_node *parent)
{
	struct goldfish_pic_data *gfpic;
	struct irq_chip_generic *gc;
	struct irq_chip_type *ct;
	unsigned int parent_irq;
	int ret = 0;

	gfpic = kzalloc(sizeof(*gfpic), GFP_KERNEL);
	if (!gfpic) {
		ret = -ENOMEM;
		goto out_err;
	}

	parent_irq = irq_of_parse_and_map(of_node, 0);
	if (!parent_irq) {
		pr_err("Failed to map parent IRQ!\n");
		ret = -EINVAL;
		goto out_free;
	}

	gfpic->base = of_iomap(of_node, 0);
	if (!gfpic->base) {
		pr_err("Failed to map base address!\n");
		ret = -ENOMEM;
		goto out_unmap_irq;
	}

	/* Mask interrupts. */
	writel(1, gfpic->base + GFPIC_REG_IRQ_DISABLE_ALL);

	gc = irq_alloc_generic_chip("GFPIC", 1, GFPIC_IRQ_BASE, gfpic->base,
				    handle_level_irq);
	if (!gc) {
		pr_err("Failed to allocate chip structures!\n");
		ret = -ENOMEM;
		goto out_iounmap;
	}

	ct = gc->chip_types;
	ct->regs.enable = GFPIC_REG_IRQ_ENABLE;
	ct->regs.disable = GFPIC_REG_IRQ_DISABLE;
	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
	ct->chip.irq_mask = irq_gc_mask_disable_reg;

	irq_setup_generic_chip(gc, IRQ_MSK(GFPIC_NR_IRQS), 0,
			       IRQ_NOPROBE | IRQ_LEVEL, 0);

	gfpic->irq_domain = irq_domain_add_legacy(of_node, GFPIC_NR_IRQS,
						  GFPIC_IRQ_BASE, 0,
						  &goldfish_irq_domain_ops,
						  NULL);
	if (!gfpic->irq_domain) {
		pr_err("Failed to add irqdomain!\n");
		ret = -ENOMEM;
		goto out_destroy_generic_chip;
	}

	irq_set_chained_handler_and_data(parent_irq,
					 goldfish_pic_cascade, gfpic);

	pr_info("Successfully registered.\n");
	return 0;

out_destroy_generic_chip:
	irq_destroy_generic_chip(gc, IRQ_MSK(GFPIC_NR_IRQS),
				 IRQ_NOPROBE | IRQ_LEVEL, 0);
out_iounmap:
	iounmap(gfpic->base);
out_unmap_irq:
	irq_dispose_mapping(parent_irq);
out_free:
	kfree(gfpic);
out_err:
	pr_err("Failed to initialize! (errno = %d)\n", ret);
	return ret;
}

IRQCHIP_DECLARE(google_gf_pic, "google,goldfish-pic", goldfish_pic_of_init);
