/*
 * Synopsys DW APB ICTL irqchip driver.
 *
 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 *
 * based on GPL'ed 2.6 kernel sources
 *  (c) Marvell International Ltd.
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

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

#define APB_INT_ENABLE_L	0x00
#define APB_INT_ENABLE_H	0x04
#define APB_INT_MASK_L		0x08
#define APB_INT_MASK_H		0x0c
#define APB_INT_FINALSTATUS_L	0x30
#define APB_INT_FINALSTATUS_H	0x34
#define APB_INT_BASE_OFFSET	0x04

/* irq domain of the primary interrupt controller. */
static struct irq_domain *dw_apb_ictl_irq_domain;

static void __irq_entry dw_apb_ictl_handle_irq(struct pt_regs *regs)
{
	struct irq_domain *d = dw_apb_ictl_irq_domain;
	int n;

	for (n = 0; n < d->revmap_size; n += 32) {
		struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, n);
		u32 stat = readl_relaxed(gc->reg_base + APB_INT_FINALSTATUS_L);

		while (stat) {
			u32 hwirq = ffs(stat) - 1;

			generic_handle_domain_irq(d, hwirq);
			stat &= ~BIT(hwirq);
		}
	}
}

static void dw_apb_ictl_handle_irq_cascaded(struct irq_desc *desc)
{
	struct irq_domain *d = irq_desc_get_handler_data(desc);
	struct irq_chip *chip = irq_desc_get_chip(desc);
	int n;

	chained_irq_enter(chip, desc);

	for (n = 0; n < d->revmap_size; n += 32) {
		struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, n);
		u32 stat = readl_relaxed(gc->reg_base + APB_INT_FINALSTATUS_L);

		while (stat) {
			u32 hwirq = ffs(stat) - 1;
			generic_handle_domain_irq(d, gc->irq_base + hwirq);

			stat &= ~BIT(hwirq);
		}
	}

	chained_irq_exit(chip, desc);
}

static int dw_apb_ictl_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
				unsigned int nr_irqs, void *arg)
{
	int i, ret;
	irq_hw_number_t hwirq;
	unsigned int type = IRQ_TYPE_NONE;
	struct irq_fwspec *fwspec = arg;

	ret = irq_domain_translate_onecell(domain, fwspec, &hwirq, &type);
	if (ret)
		return ret;

	for (i = 0; i < nr_irqs; i++)
		irq_map_generic_chip(domain, virq + i, hwirq + i);

	return 0;
}

static const struct irq_domain_ops dw_apb_ictl_irq_domain_ops = {
	.translate = irq_domain_translate_onecell,
	.alloc = dw_apb_ictl_irq_domain_alloc,
	.free = irq_domain_free_irqs_top,
};

#ifdef CONFIG_PM
static void dw_apb_ictl_resume(struct irq_data *d)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct irq_chip_type *ct = irq_data_get_chip_type(d);

	irq_gc_lock(gc);
	writel_relaxed(~0, gc->reg_base + ct->regs.enable);
	writel_relaxed(*ct->mask_cache, gc->reg_base + ct->regs.mask);
	irq_gc_unlock(gc);
}
#else
#define dw_apb_ictl_resume	NULL
#endif /* CONFIG_PM */

static int __init dw_apb_ictl_init(struct device_node *np,
				   struct device_node *parent)
{
	const struct irq_domain_ops *domain_ops;
	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
	struct resource r;
	struct irq_domain *domain;
	struct irq_chip_generic *gc;
	void __iomem *iobase;
	int ret, nrirqs, parent_irq, i;
	u32 reg;

	if (!parent) {
		/* Used as the primary interrupt controller */
		parent_irq = 0;
		domain_ops = &dw_apb_ictl_irq_domain_ops;
	} else {
		/* Map the parent interrupt for the chained handler */
		parent_irq = irq_of_parse_and_map(np, 0);
		if (parent_irq <= 0) {
			pr_err("%pOF: unable to parse irq\n", np);
			return -EINVAL;
		}
		domain_ops = &irq_generic_chip_ops;
	}

	ret = of_address_to_resource(np, 0, &r);
	if (ret) {
		pr_err("%pOF: unable to get resource\n", np);
		return ret;
	}

	if (!request_mem_region(r.start, resource_size(&r), np->full_name)) {
		pr_err("%pOF: unable to request mem region\n", np);
		return -ENOMEM;
	}

	iobase = ioremap(r.start, resource_size(&r));
	if (!iobase) {
		pr_err("%pOF: unable to map resource\n", np);
		ret = -ENOMEM;
		goto err_release;
	}

	/*
	 * DW IP can be configured to allow 2-64 irqs. We can determine
	 * the number of irqs supported by writing into enable register
	 * and look for bits not set, as corresponding flip-flops will
	 * have been removed by synthesis tool.
	 */

	/* mask and enable all interrupts */
	writel_relaxed(~0, iobase + APB_INT_MASK_L);
	writel_relaxed(~0, iobase + APB_INT_MASK_H);
	writel_relaxed(~0, iobase + APB_INT_ENABLE_L);
	writel_relaxed(~0, iobase + APB_INT_ENABLE_H);

	reg = readl_relaxed(iobase + APB_INT_ENABLE_H);
	if (reg)
		nrirqs = 32 + fls(reg);
	else
		nrirqs = fls(readl_relaxed(iobase + APB_INT_ENABLE_L));

	domain = irq_domain_add_linear(np, nrirqs, domain_ops, NULL);
	if (!domain) {
		pr_err("%pOF: unable to add irq domain\n", np);
		ret = -ENOMEM;
		goto err_unmap;
	}

	ret = irq_alloc_domain_generic_chips(domain, 32, 1, np->name,
					     handle_level_irq, clr, 0,
					     IRQ_GC_INIT_MASK_CACHE);
	if (ret) {
		pr_err("%pOF: unable to alloc irq domain gc\n", np);
		goto err_unmap;
	}

	for (i = 0; i < DIV_ROUND_UP(nrirqs, 32); i++) {
		gc = irq_get_domain_generic_chip(domain, i * 32);
		gc->reg_base = iobase + i * APB_INT_BASE_OFFSET;
		gc->chip_types[0].regs.mask = APB_INT_MASK_L;
		gc->chip_types[0].regs.enable = APB_INT_ENABLE_L;
		gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
		gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
		gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume;
	}

	if (parent_irq) {
		irq_set_chained_handler_and_data(parent_irq,
				dw_apb_ictl_handle_irq_cascaded, domain);
	} else {
		dw_apb_ictl_irq_domain = domain;
		set_handle_irq(dw_apb_ictl_handle_irq);
	}

	return 0;

err_unmap:
	iounmap(iobase);
err_release:
	release_mem_region(r.start, resource_size(&r));
	return ret;
}
IRQCHIP_DECLARE(dw_apb_ictl,
		"snps,dw-apb-ictl", dw_apb_ictl_init);
