// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 */

#include <linux/bitfield.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

/* FIC Registers */
#define AL_FIC_CAUSE		0x00
#define AL_FIC_SET_CAUSE	0x08
#define AL_FIC_MASK		0x10
#define AL_FIC_CONTROL		0x28

#define CONTROL_TRIGGER_RISING	BIT(3)
#define CONTROL_MASK_MSI_X	BIT(5)

#define NR_FIC_IRQS 32

MODULE_AUTHOR("Talel Shenhar");
MODULE_DESCRIPTION("Amazon's Annapurna Labs Interrupt Controller Driver");
MODULE_LICENSE("GPL v2");

enum al_fic_state {
	AL_FIC_UNCONFIGURED = 0,
	AL_FIC_CONFIGURED_LEVEL,
	AL_FIC_CONFIGURED_RISING_EDGE,
};

struct al_fic {
	void __iomem *base;
	struct irq_domain *domain;
	const char *name;
	unsigned int parent_irq;
	enum al_fic_state state;
};

static void al_fic_set_trigger(struct al_fic *fic,
			       struct irq_chip_generic *gc,
			       enum al_fic_state new_state)
{
	irq_flow_handler_t handler;
	u32 control = readl_relaxed(fic->base + AL_FIC_CONTROL);

	if (new_state == AL_FIC_CONFIGURED_LEVEL) {
		handler = handle_level_irq;
		control &= ~CONTROL_TRIGGER_RISING;
	} else {
		handler = handle_edge_irq;
		control |= CONTROL_TRIGGER_RISING;
	}
	gc->chip_types->handler = handler;
	fic->state = new_state;
	writel_relaxed(control, fic->base + AL_FIC_CONTROL);
}

static int al_fic_irq_set_type(struct irq_data *data, unsigned int flow_type)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
	struct al_fic *fic = gc->private;
	enum al_fic_state new_state;
	int ret = 0;

	irq_gc_lock(gc);

	if (((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_HIGH) &&
	    ((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_EDGE_RISING)) {
		pr_debug("fic doesn't support flow type %d\n", flow_type);
		ret = -EINVAL;
		goto err;
	}

	new_state = (flow_type & IRQ_TYPE_LEVEL_HIGH) ?
		AL_FIC_CONFIGURED_LEVEL : AL_FIC_CONFIGURED_RISING_EDGE;

	/*
	 * A given FIC instance can be either all level or all edge triggered.
	 * This is generally fixed depending on what pieces of HW it's wired up
	 * to.
	 *
	 * We configure it based on the sensitivity of the first source
	 * being setup, and reject any subsequent attempt at configuring it in a
	 * different way.
	 */
	if (fic->state == AL_FIC_UNCONFIGURED) {
		al_fic_set_trigger(fic, gc, new_state);
	} else if (fic->state != new_state) {
		pr_debug("fic %s state already configured to %d\n",
			 fic->name, fic->state);
		ret = -EINVAL;
		goto err;
	}

err:
	irq_gc_unlock(gc);

	return ret;
}

static void al_fic_irq_handler(struct irq_desc *desc)
{
	struct al_fic *fic = irq_desc_get_handler_data(desc);
	struct irq_domain *domain = fic->domain;
	struct irq_chip *irqchip = irq_desc_get_chip(desc);
	struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
	unsigned long pending;
	u32 hwirq;

	chained_irq_enter(irqchip, desc);

	pending = readl_relaxed(fic->base + AL_FIC_CAUSE);
	pending &= ~gc->mask_cache;

	for_each_set_bit(hwirq, &pending, NR_FIC_IRQS)
		generic_handle_domain_irq(domain, hwirq);

	chained_irq_exit(irqchip, desc);
}

static int al_fic_irq_retrigger(struct irq_data *data)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
	struct al_fic *fic = gc->private;

	writel_relaxed(BIT(data->hwirq), fic->base + AL_FIC_SET_CAUSE);

	return 1;
}

static int al_fic_register(struct device_node *node,
			   struct al_fic *fic)
{
	struct irq_chip_generic *gc;
	int ret;

	fic->domain = irq_domain_add_linear(node,
					    NR_FIC_IRQS,
					    &irq_generic_chip_ops,
					    fic);
	if (!fic->domain) {
		pr_err("fail to add irq domain\n");
		return -ENOMEM;
	}

	ret = irq_alloc_domain_generic_chips(fic->domain,
					     NR_FIC_IRQS,
					     1, fic->name,
					     handle_level_irq,
					     0, 0, IRQ_GC_INIT_MASK_CACHE);
	if (ret) {
		pr_err("fail to allocate generic chip (%d)\n", ret);
		goto err_domain_remove;
	}

	gc = irq_get_domain_generic_chip(fic->domain, 0);
	gc->reg_base = fic->base;
	gc->chip_types->regs.mask = AL_FIC_MASK;
	gc->chip_types->regs.ack = AL_FIC_CAUSE;
	gc->chip_types->chip.irq_mask = irq_gc_mask_set_bit;
	gc->chip_types->chip.irq_unmask = irq_gc_mask_clr_bit;
	gc->chip_types->chip.irq_ack = irq_gc_ack_clr_bit;
	gc->chip_types->chip.irq_set_type = al_fic_irq_set_type;
	gc->chip_types->chip.irq_retrigger = al_fic_irq_retrigger;
	gc->chip_types->chip.flags = IRQCHIP_SKIP_SET_WAKE;
	gc->private = fic;

	irq_set_chained_handler_and_data(fic->parent_irq,
					 al_fic_irq_handler,
					 fic);
	return 0;

err_domain_remove:
	irq_domain_remove(fic->domain);

	return ret;
}

/*
 * al_fic_wire_init() - initialize and configure fic in wire mode
 * @of_node: optional pointer to interrupt controller's device tree node.
 * @base: mmio to fic register
 * @name: name of the fic
 * @parent_irq: interrupt of parent
 *
 * This API will configure the fic hardware to to work in wire mode.
 * In wire mode, fic hardware is generating a wire ("wired") interrupt.
 * Interrupt can be generated based on positive edge or level - configuration is
 * to be determined based on connected hardware to this fic.
 */
static struct al_fic *al_fic_wire_init(struct device_node *node,
				       void __iomem *base,
				       const char *name,
				       unsigned int parent_irq)
{
	struct al_fic *fic;
	int ret;
	u32 control = CONTROL_MASK_MSI_X;

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

	fic->base = base;
	fic->parent_irq = parent_irq;
	fic->name = name;

	/* mask out all interrupts */
	writel_relaxed(0xFFFFFFFF, fic->base + AL_FIC_MASK);

	/* clear any pending interrupt */
	writel_relaxed(0, fic->base + AL_FIC_CAUSE);

	writel_relaxed(control, fic->base + AL_FIC_CONTROL);

	ret = al_fic_register(node, fic);
	if (ret) {
		pr_err("fail to register irqchip\n");
		goto err_free;
	}

	pr_debug("%s initialized successfully in Legacy mode (parent-irq=%u)\n",
		 fic->name, parent_irq);

	return fic;

err_free:
	kfree(fic);
	return ERR_PTR(ret);
}

static int __init al_fic_init_dt(struct device_node *node,
				 struct device_node *parent)
{
	int ret;
	void __iomem *base;
	unsigned int parent_irq;
	struct al_fic *fic;

	if (!parent) {
		pr_err("%s: unsupported - device require a parent\n",
		       node->name);
		return -EINVAL;
	}

	base = of_iomap(node, 0);
	if (!base) {
		pr_err("%s: fail to map memory\n", node->name);
		return -ENOMEM;
	}

	parent_irq = irq_of_parse_and_map(node, 0);
	if (!parent_irq) {
		pr_err("%s: fail to map irq\n", node->name);
		ret = -EINVAL;
		goto err_unmap;
	}

	fic = al_fic_wire_init(node,
			       base,
			       node->name,
			       parent_irq);
	if (IS_ERR(fic)) {
		pr_err("%s: fail to initialize irqchip (%lu)\n",
		       node->name,
		       PTR_ERR(fic));
		ret = PTR_ERR(fic);
		goto err_irq_dispose;
	}

	return 0;

err_irq_dispose:
	irq_dispose_mapping(parent_irq);
err_unmap:
	iounmap(base);

	return ret;
}

IRQCHIP_DECLARE(al_fic, "amazon,al-fic", al_fic_init_dt);
