// SPDX-License-Identifier: GPL-2.0
/*
 * irqchip for the IXP4xx interrupt controller
 * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org>
 *
 * Based on arch/arm/mach-ixp4xx/common.c
 * Copyright 2002 (C) Intel Corporation
 * Copyright 2003-2004 (C) MontaVista, Software, Inc.
 * Copyright (C) Deepak Saxena <dsaxena@plexity.net>
 */
#include <linux/bitops.h>
#include <linux/gpio/driver.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/cpu.h>

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

#define IXP4XX_ICPR	0x00 /* Interrupt Status */
#define IXP4XX_ICMR	0x04 /* Interrupt Enable */
#define IXP4XX_ICLR	0x08 /* Interrupt IRQ/FIQ Select */
#define IXP4XX_ICIP	0x0C /* IRQ Status */
#define IXP4XX_ICFP	0x10 /* FIQ Status */
#define IXP4XX_ICHR	0x14 /* Interrupt Priority */
#define IXP4XX_ICIH	0x18 /* IRQ Highest Pri Int */
#define IXP4XX_ICFH	0x1C /* FIQ Highest Pri Int */

/* IXP43x and IXP46x-only */
#define	IXP4XX_ICPR2	0x20 /* Interrupt Status 2 */
#define	IXP4XX_ICMR2	0x24 /* Interrupt Enable 2 */
#define	IXP4XX_ICLR2	0x28 /* Interrupt IRQ/FIQ Select 2 */
#define IXP4XX_ICIP2	0x2C /* IRQ Status */
#define IXP4XX_ICFP2	0x30 /* FIQ Status */
#define IXP4XX_ICEEN	0x34 /* Error High Pri Enable */

/**
 * struct ixp4xx_irq - state container for the Faraday IRQ controller
 * @irqbase: IRQ controller memory base in virtual memory
 * @is_356: if this is an IXP43x, IXP45x or IX46x SoC (with 64 IRQs)
 * @irqchip: irqchip for this instance
 * @domain: IRQ domain for this instance
 */
struct ixp4xx_irq {
	void __iomem *irqbase;
	bool is_356;
	struct irq_chip irqchip;
	struct irq_domain *domain;
};

/* Local static state container */
static struct ixp4xx_irq ixirq;

/* GPIO Clocks */
#define IXP4XX_GPIO_CLK_0		14
#define IXP4XX_GPIO_CLK_1		15

static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
{
	/* All are level active high (asserted) here */
	if (type != IRQ_TYPE_LEVEL_HIGH)
		return -EINVAL;
	return 0;
}

static void ixp4xx_irq_mask(struct irq_data *d)
{
	struct ixp4xx_irq *ixi = irq_data_get_irq_chip_data(d);
	u32 val;

	if (ixi->is_356 && d->hwirq >= 32) {
		val = __raw_readl(ixi->irqbase + IXP4XX_ICMR2);
		val &= ~BIT(d->hwirq - 32);
		__raw_writel(val, ixi->irqbase + IXP4XX_ICMR2);
	} else {
		val = __raw_readl(ixi->irqbase + IXP4XX_ICMR);
		val &= ~BIT(d->hwirq);
		__raw_writel(val, ixi->irqbase + IXP4XX_ICMR);
	}
}

/*
 * Level triggered interrupts on GPIO lines can only be cleared when the
 * interrupt condition disappears.
 */
static void ixp4xx_irq_unmask(struct irq_data *d)
{
	struct ixp4xx_irq *ixi = irq_data_get_irq_chip_data(d);
	u32 val;

	if (ixi->is_356 && d->hwirq >= 32) {
		val = __raw_readl(ixi->irqbase + IXP4XX_ICMR2);
		val |= BIT(d->hwirq - 32);
		__raw_writel(val, ixi->irqbase + IXP4XX_ICMR2);
	} else {
		val = __raw_readl(ixi->irqbase + IXP4XX_ICMR);
		val |= BIT(d->hwirq);
		__raw_writel(val, ixi->irqbase + IXP4XX_ICMR);
	}
}

static asmlinkage void __exception_irq_entry
ixp4xx_handle_irq(struct pt_regs *regs)
{
	struct ixp4xx_irq *ixi = &ixirq;
	unsigned long status;
	int i;

	status = __raw_readl(ixi->irqbase + IXP4XX_ICIP);
	for_each_set_bit(i, &status, 32)
		generic_handle_domain_irq(ixi->domain, i);

	/*
	 * IXP465/IXP435 has an upper IRQ status register
	 */
	if (ixi->is_356) {
		status = __raw_readl(ixi->irqbase + IXP4XX_ICIP2);
		for_each_set_bit(i, &status, 32)
			generic_handle_domain_irq(ixi->domain, i + 32);
	}
}

static int ixp4xx_irq_domain_translate(struct irq_domain *domain,
				       struct irq_fwspec *fwspec,
				       unsigned long *hwirq,
				       unsigned int *type)
{
	/* We support standard DT translation */
	if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
		*hwirq = fwspec->param[0];
		*type = fwspec->param[1];
		return 0;
	}

	if (is_fwnode_irqchip(fwspec->fwnode)) {
		if (fwspec->param_count != 2)
			return -EINVAL;
		*hwirq = fwspec->param[0];
		*type = fwspec->param[1];
		WARN_ON(*type == IRQ_TYPE_NONE);
		return 0;
	}

	return -EINVAL;
}

static int ixp4xx_irq_domain_alloc(struct irq_domain *d,
				   unsigned int irq, unsigned int nr_irqs,
				   void *data)
{
	struct ixp4xx_irq *ixi = d->host_data;
	irq_hw_number_t hwirq;
	unsigned int type = IRQ_TYPE_NONE;
	struct irq_fwspec *fwspec = data;
	int ret;
	int i;

	ret = ixp4xx_irq_domain_translate(d, fwspec, &hwirq, &type);
	if (ret)
		return ret;

	for (i = 0; i < nr_irqs; i++) {
		/*
		 * TODO: after converting IXP4xx to only device tree, set
		 * handle_bad_irq as default handler and assume all consumers
		 * call .set_type() as this is provided in the second cell in
		 * the device tree phandle.
		 */
		irq_domain_set_info(d,
				    irq + i,
				    hwirq + i,
				    &ixi->irqchip,
				    ixi,
				    handle_level_irq,
				    NULL, NULL);
		irq_set_probe(irq + i);
	}

	return 0;
}

/*
 * This needs to be a hierarchical irqdomain to work well with the
 * GPIO irqchip (which is lower in the hierarchy)
 */
static const struct irq_domain_ops ixp4xx_irqdomain_ops = {
	.translate = ixp4xx_irq_domain_translate,
	.alloc = ixp4xx_irq_domain_alloc,
	.free = irq_domain_free_irqs_common,
};

/**
 * ixp4x_irq_setup() - Common setup code for the IXP4xx interrupt controller
 * @ixi: State container
 * @irqbase: Virtual memory base for the interrupt controller
 * @fwnode: Corresponding fwnode abstraction for this controller
 * @is_356: if this is an IXP43x, IXP45x or IXP46x SoC variant
 */
static int __init ixp4xx_irq_setup(struct ixp4xx_irq *ixi,
				   void __iomem *irqbase,
				   struct fwnode_handle *fwnode,
				   bool is_356)
{
	int nr_irqs;

	ixi->irqbase = irqbase;
	ixi->is_356 = is_356;

	/* Route all sources to IRQ instead of FIQ */
	__raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR);

	/* Disable all interrupts */
	__raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR);

	if (is_356) {
		/* Route upper 32 sources to IRQ instead of FIQ */
		__raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR2);

		/* Disable upper 32 interrupts */
		__raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR2);

		nr_irqs = 64;
	} else {
		nr_irqs = 32;
	}

	ixi->irqchip.name = "IXP4xx";
	ixi->irqchip.irq_mask = ixp4xx_irq_mask;
	ixi->irqchip.irq_unmask	= ixp4xx_irq_unmask;
	ixi->irqchip.irq_set_type = ixp4xx_set_irq_type;

	ixi->domain = irq_domain_create_linear(fwnode, nr_irqs,
					       &ixp4xx_irqdomain_ops,
					       ixi);
	if (!ixi->domain) {
		pr_crit("IXP4XX: can not add primary irqdomain\n");
		return -ENODEV;
	}

	set_handle_irq(ixp4xx_handle_irq);

	return 0;
}

static int __init ixp4xx_of_init_irq(struct device_node *np,
				     struct device_node *parent)
{
	struct ixp4xx_irq *ixi = &ixirq;
	void __iomem *base;
	struct fwnode_handle *fwnode;
	bool is_356;
	int ret;

	base = of_iomap(np, 0);
	if (!base) {
		pr_crit("IXP4XX: could not ioremap interrupt controller\n");
		return -ENODEV;
	}
	fwnode = of_node_to_fwnode(np);

	/* These chip variants have 64 interrupts */
	is_356 = of_device_is_compatible(np, "intel,ixp43x-interrupt") ||
		of_device_is_compatible(np, "intel,ixp45x-interrupt") ||
		of_device_is_compatible(np, "intel,ixp46x-interrupt");

	ret = ixp4xx_irq_setup(ixi, base, fwnode, is_356);
	if (ret)
		pr_crit("IXP4XX: failed to set up irqchip\n");

	return ret;
}
IRQCHIP_DECLARE(ixp42x, "intel,ixp42x-interrupt",
		ixp4xx_of_init_irq);
IRQCHIP_DECLARE(ixp43x, "intel,ixp43x-interrupt",
		ixp4xx_of_init_irq);
IRQCHIP_DECLARE(ixp45x, "intel,ixp45x-interrupt",
		ixp4xx_of_init_irq);
IRQCHIP_DECLARE(ixp46x, "intel,ixp46x-interrupt",
		ixp4xx_of_init_irq);
