/*
 * Copyright (C) 2016 Marvell
 *
 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
 *
 * 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.
 */

#define pr_fmt(fmt) "GIC-ODMI: " fmt

#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/msi.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>

#define GICP_ODMIN_SET			0x40
#define   GICP_ODMI_INT_NUM_SHIFT	12
#define GICP_ODMIN_GM_EP_R0		0x110
#define GICP_ODMIN_GM_EP_R1		0x114
#define GICP_ODMIN_GM_EA_R0		0x108
#define GICP_ODMIN_GM_EA_R1		0x118

/*
 * We don't support the group events, so we simply have 8 interrupts
 * per frame.
 */
#define NODMIS_SHIFT		3
#define NODMIS_PER_FRAME	(1 << NODMIS_SHIFT)
#define NODMIS_MASK		(NODMIS_PER_FRAME - 1)

struct odmi_data {
	struct resource res;
	void __iomem *base;
	unsigned int spi_base;
};

static struct odmi_data *odmis;
static unsigned long *odmis_bm;
static unsigned int odmis_count;

/* Protects odmis_bm */
static DEFINE_SPINLOCK(odmis_bm_lock);

static void odmi_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
{
	struct odmi_data *odmi;
	phys_addr_t addr;
	unsigned int odmin;

	if (WARN_ON(d->hwirq >= odmis_count * NODMIS_PER_FRAME))
		return;

	odmi = &odmis[d->hwirq >> NODMIS_SHIFT];
	odmin = d->hwirq & NODMIS_MASK;

	addr = odmi->res.start + GICP_ODMIN_SET;

	msg->address_hi = upper_32_bits(addr);
	msg->address_lo = lower_32_bits(addr);
	msg->data = odmin << GICP_ODMI_INT_NUM_SHIFT;
}

static struct irq_chip odmi_irq_chip = {
	.name			= "ODMI",
	.irq_mask		= irq_chip_mask_parent,
	.irq_unmask		= irq_chip_unmask_parent,
	.irq_eoi		= irq_chip_eoi_parent,
	.irq_set_affinity	= irq_chip_set_affinity_parent,
	.irq_compose_msi_msg	= odmi_compose_msi_msg,
};

static int odmi_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
				 unsigned int nr_irqs, void *args)
{
	struct odmi_data *odmi = NULL;
	struct irq_fwspec fwspec;
	struct irq_data *d;
	unsigned int hwirq, odmin;
	int ret;

	spin_lock(&odmis_bm_lock);
	hwirq = find_first_zero_bit(odmis_bm, NODMIS_PER_FRAME * odmis_count);
	if (hwirq >= NODMIS_PER_FRAME * odmis_count) {
		spin_unlock(&odmis_bm_lock);
		return -ENOSPC;
	}

	__set_bit(hwirq, odmis_bm);
	spin_unlock(&odmis_bm_lock);

	odmi = &odmis[hwirq >> NODMIS_SHIFT];
	odmin = hwirq & NODMIS_MASK;

	fwspec.fwnode = domain->parent->fwnode;
	fwspec.param_count = 3;
	fwspec.param[0] = GIC_SPI;
	fwspec.param[1] = odmi->spi_base - 32 + odmin;
	fwspec.param[2] = IRQ_TYPE_EDGE_RISING;

	ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
	if (ret) {
		pr_err("Cannot allocate parent IRQ\n");
		spin_lock(&odmis_bm_lock);
		__clear_bit(odmin, odmis_bm);
		spin_unlock(&odmis_bm_lock);
		return ret;
	}

	/* Configure the interrupt line to be edge */
	d = irq_domain_get_irq_data(domain->parent, virq);
	d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING);

	irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
				      &odmi_irq_chip, NULL);

	return 0;
}

static void odmi_irq_domain_free(struct irq_domain *domain,
				 unsigned int virq, unsigned int nr_irqs)
{
	struct irq_data *d = irq_domain_get_irq_data(domain, virq);

	if (d->hwirq >= odmis_count * NODMIS_PER_FRAME) {
		pr_err("Failed to teardown msi. Invalid hwirq %lu\n", d->hwirq);
		return;
	}

	irq_domain_free_irqs_parent(domain, virq, nr_irqs);

	/* Actually free the MSI */
	spin_lock(&odmis_bm_lock);
	__clear_bit(d->hwirq, odmis_bm);
	spin_unlock(&odmis_bm_lock);
}

static const struct irq_domain_ops odmi_domain_ops = {
	.alloc	= odmi_irq_domain_alloc,
	.free	= odmi_irq_domain_free,
};

static struct irq_chip odmi_msi_irq_chip = {
	.name	= "ODMI",
};

static struct msi_domain_ops odmi_msi_ops = {
};

static struct msi_domain_info odmi_msi_domain_info = {
	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
	.ops	= &odmi_msi_ops,
	.chip	= &odmi_msi_irq_chip,
};

static int __init mvebu_odmi_init(struct device_node *node,
				  struct device_node *parent)
{
	struct irq_domain *inner_domain, *plat_domain;
	int ret, i;

	if (of_property_read_u32(node, "marvell,odmi-frames", &odmis_count))
		return -EINVAL;

	odmis = kcalloc(odmis_count, sizeof(struct odmi_data), GFP_KERNEL);
	if (!odmis)
		return -ENOMEM;

	odmis_bm = bitmap_zalloc(odmis_count * NODMIS_PER_FRAME, GFP_KERNEL);
	if (!odmis_bm) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	for (i = 0; i < odmis_count; i++) {
		struct odmi_data *odmi = &odmis[i];

		ret = of_address_to_resource(node, i, &odmi->res);
		if (ret)
			goto err_unmap;

		odmi->base = of_io_request_and_map(node, i, "odmi");
		if (IS_ERR(odmi->base)) {
			ret = PTR_ERR(odmi->base);
			goto err_unmap;
		}

		if (of_property_read_u32_index(node, "marvell,spi-base",
					       i, &odmi->spi_base)) {
			ret = -EINVAL;
			goto err_unmap;
		}
	}

	inner_domain = irq_domain_create_linear(of_node_to_fwnode(node),
						odmis_count * NODMIS_PER_FRAME,
						&odmi_domain_ops, NULL);
	if (!inner_domain) {
		ret = -ENOMEM;
		goto err_unmap;
	}

	inner_domain->parent = irq_find_host(parent);

	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node),
						     &odmi_msi_domain_info,
						     inner_domain);
	if (!plat_domain) {
		ret = -ENOMEM;
		goto err_remove_inner;
	}

	return 0;

err_remove_inner:
	irq_domain_remove(inner_domain);
err_unmap:
	for (i = 0; i < odmis_count; i++) {
		struct odmi_data *odmi = &odmis[i];

		if (odmi->base && !IS_ERR(odmi->base))
			iounmap(odmis[i].base);
	}
	bitmap_free(odmis_bm);
err_alloc:
	kfree(odmis);
	return ret;
}

IRQCHIP_DECLARE(mvebu_odmi, "marvell,odmi-controller", mvebu_odmi_init);
