// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  CLPS711X IRQ driver
 *
 *  Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru>
 */

#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/slab.h>

#include <asm/exception.h>
#include <asm/mach/irq.h>

#define CLPS711X_INTSR1	(0x0240)
#define CLPS711X_INTMR1	(0x0280)
#define CLPS711X_BLEOI	(0x0600)
#define CLPS711X_MCEOI	(0x0640)
#define CLPS711X_TEOI	(0x0680)
#define CLPS711X_TC1EOI	(0x06c0)
#define CLPS711X_TC2EOI	(0x0700)
#define CLPS711X_RTCEOI	(0x0740)
#define CLPS711X_UMSEOI	(0x0780)
#define CLPS711X_COEOI	(0x07c0)
#define CLPS711X_INTSR2	(0x1240)
#define CLPS711X_INTMR2	(0x1280)
#define CLPS711X_SRXEOF	(0x1600)
#define CLPS711X_KBDEOI	(0x1700)
#define CLPS711X_INTSR3	(0x2240)
#define CLPS711X_INTMR3	(0x2280)

static const struct {
#define CLPS711X_FLAG_EN	(1 << 0)
#define CLPS711X_FLAG_FIQ	(1 << 1)
	unsigned int	flags;
	phys_addr_t	eoi;
} clps711x_irqs[] = {
	[1]	= { CLPS711X_FLAG_FIQ, CLPS711X_BLEOI, },
	[3]	= { CLPS711X_FLAG_FIQ, CLPS711X_MCEOI, },
	[4]	= { CLPS711X_FLAG_EN, CLPS711X_COEOI, },
	[5]	= { CLPS711X_FLAG_EN, },
	[6]	= { CLPS711X_FLAG_EN, },
	[7]	= { CLPS711X_FLAG_EN, },
	[8]	= { CLPS711X_FLAG_EN, CLPS711X_TC1EOI, },
	[9]	= { CLPS711X_FLAG_EN, CLPS711X_TC2EOI, },
	[10]	= { CLPS711X_FLAG_EN, CLPS711X_RTCEOI, },
	[11]	= { CLPS711X_FLAG_EN, CLPS711X_TEOI, },
	[12]	= { CLPS711X_FLAG_EN, },
	[13]	= { CLPS711X_FLAG_EN, },
	[14]	= { CLPS711X_FLAG_EN, CLPS711X_UMSEOI, },
	[15]	= { CLPS711X_FLAG_EN, CLPS711X_SRXEOF, },
	[16]	= { CLPS711X_FLAG_EN, CLPS711X_KBDEOI, },
	[17]	= { CLPS711X_FLAG_EN, },
	[18]	= { CLPS711X_FLAG_EN, },
	[28]	= { CLPS711X_FLAG_EN, },
	[29]	= { CLPS711X_FLAG_EN, },
	[32]	= { CLPS711X_FLAG_FIQ, },
};

static struct {
	void __iomem		*base;
	void __iomem		*intmr[3];
	void __iomem		*intsr[3];
	struct irq_domain	*domain;
	struct irq_domain_ops	ops;
} *clps711x_intc;

static void __exception_irq_entry clps711x_irqh(struct pt_regs *regs)
{
	u32 irqstat;

	do {
		irqstat = readw_relaxed(clps711x_intc->intmr[0]) &
			  readw_relaxed(clps711x_intc->intsr[0]);
		if (irqstat)
			generic_handle_domain_irq(clps711x_intc->domain,
						  fls(irqstat) - 1);

		irqstat = readw_relaxed(clps711x_intc->intmr[1]) &
			  readw_relaxed(clps711x_intc->intsr[1]);
		if (irqstat)
			generic_handle_domain_irq(clps711x_intc->domain,
						  fls(irqstat) - 1 + 16);
	} while (irqstat);
}

static void clps711x_intc_eoi(struct irq_data *d)
{
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	writel_relaxed(0, clps711x_intc->base + clps711x_irqs[hwirq].eoi);
}

static void clps711x_intc_mask(struct irq_data *d)
{
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	void __iomem *intmr = clps711x_intc->intmr[hwirq / 16];
	u32 tmp;

	tmp = readl_relaxed(intmr);
	tmp &= ~(1 << (hwirq % 16));
	writel_relaxed(tmp, intmr);
}

static void clps711x_intc_unmask(struct irq_data *d)
{
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	void __iomem *intmr = clps711x_intc->intmr[hwirq / 16];
	u32 tmp;

	tmp = readl_relaxed(intmr);
	tmp |= 1 << (hwirq % 16);
	writel_relaxed(tmp, intmr);
}

static struct irq_chip clps711x_intc_chip = {
	.name		= "clps711x-intc",
	.irq_eoi	= clps711x_intc_eoi,
	.irq_mask	= clps711x_intc_mask,
	.irq_unmask	= clps711x_intc_unmask,
};

static int __init clps711x_intc_irq_map(struct irq_domain *h, unsigned int virq,
					irq_hw_number_t hw)
{
	irq_flow_handler_t handler = handle_level_irq;
	unsigned int flags = 0;

	if (!clps711x_irqs[hw].flags)
		return 0;

	if (clps711x_irqs[hw].flags & CLPS711X_FLAG_FIQ) {
		handler = handle_bad_irq;
		flags |= IRQ_NOAUTOEN;
	} else if (clps711x_irqs[hw].eoi) {
		handler = handle_fasteoi_irq;
	}

	/* Clear down pending interrupt */
	if (clps711x_irqs[hw].eoi)
		writel_relaxed(0, clps711x_intc->base + clps711x_irqs[hw].eoi);

	irq_set_chip_and_handler(virq, &clps711x_intc_chip, handler);
	irq_modify_status(virq, IRQ_NOPROBE, flags);

	return 0;
}

static int __init _clps711x_intc_init(struct device_node *np,
				      phys_addr_t base, resource_size_t size)
{
	int err;

	clps711x_intc = kzalloc(sizeof(*clps711x_intc), GFP_KERNEL);
	if (!clps711x_intc)
		return -ENOMEM;

	clps711x_intc->base = ioremap(base, size);
	if (!clps711x_intc->base) {
		err = -ENOMEM;
		goto out_kfree;
	}

	clps711x_intc->intsr[0] = clps711x_intc->base + CLPS711X_INTSR1;
	clps711x_intc->intmr[0] = clps711x_intc->base + CLPS711X_INTMR1;
	clps711x_intc->intsr[1] = clps711x_intc->base + CLPS711X_INTSR2;
	clps711x_intc->intmr[1] = clps711x_intc->base + CLPS711X_INTMR2;
	clps711x_intc->intsr[2] = clps711x_intc->base + CLPS711X_INTSR3;
	clps711x_intc->intmr[2] = clps711x_intc->base + CLPS711X_INTMR3;

	/* Mask all interrupts */
	writel_relaxed(0, clps711x_intc->intmr[0]);
	writel_relaxed(0, clps711x_intc->intmr[1]);
	writel_relaxed(0, clps711x_intc->intmr[2]);

	err = irq_alloc_descs(-1, 0, ARRAY_SIZE(clps711x_irqs), numa_node_id());
	if (err < 0)
		goto out_iounmap;

	clps711x_intc->ops.map = clps711x_intc_irq_map;
	clps711x_intc->ops.xlate = irq_domain_xlate_onecell;
	clps711x_intc->domain =
		irq_domain_add_legacy(np, ARRAY_SIZE(clps711x_irqs),
				      0, 0, &clps711x_intc->ops, NULL);
	if (!clps711x_intc->domain) {
		err = -ENOMEM;
		goto out_irqfree;
	}

	irq_set_default_host(clps711x_intc->domain);
	set_handle_irq(clps711x_irqh);

#ifdef CONFIG_FIQ
	init_FIQ(0);
#endif

	return 0;

out_irqfree:
	irq_free_descs(0, ARRAY_SIZE(clps711x_irqs));

out_iounmap:
	iounmap(clps711x_intc->base);

out_kfree:
	kfree(clps711x_intc);

	return err;
}

static int __init clps711x_intc_init_dt(struct device_node *np,
					struct device_node *parent)
{
	struct resource res;
	int err;

	err = of_address_to_resource(np, 0, &res);
	if (err)
		return err;

	return _clps711x_intc_init(np, res.start, resource_size(&res));
}
IRQCHIP_DECLARE(clps711x, "cirrus,ep7209-intc", clps711x_intc_init_dt);
