/*
 * Copyright 2008-2011 IBM Corporation.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version
 *  2 of the License, or (at your option) any later version.
 */

#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/msi.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/xics.h>

#include "wsp.h"
#include "ics.h"


/* WSP ICS */

struct wsp_ics {
	struct ics ics;
	struct device_node *dn;
	void __iomem *regs;
	spinlock_t lock;
	unsigned long *bitmap;
	u32 chip_id;
	u32 lsi_base;
	u32 lsi_count;
	u64 hwirq_start;
	u64 count;
#ifdef CONFIG_SMP
	int *hwirq_cpu_map;
#endif
};

#define to_wsp_ics(ics)	container_of(ics, struct wsp_ics, ics)

#define INT_SRC_LAYER_BUID_REG(base)	((base) + 0x00)
#define IODA_TBL_ADDR_REG(base)		((base) + 0x18)
#define IODA_TBL_DATA_REG(base)		((base) + 0x20)
#define XIVE_UPDATE_REG(base)		((base) + 0x28)
#define ICS_INT_CAPS_REG(base)		((base) + 0x30)

#define TBL_AUTO_INCREMENT	((1UL << 63) | (1UL << 15))
#define TBL_SELECT_XIST		(1UL << 48)
#define TBL_SELECT_XIVT		(1UL << 49)

#define IODA_IRQ(irq)		((irq) & (0x7FFULL))	/* HRM 5.1.3.4 */

#define XIST_REQUIRED		0x8
#define XIST_REJECTED		0x4
#define XIST_PRESENTED		0x2
#define XIST_PENDING		0x1

#define XIVE_SERVER_SHIFT	42
#define XIVE_SERVER_MASK	0xFFFFULL
#define XIVE_PRIORITY_MASK	0xFFULL
#define XIVE_PRIORITY_SHIFT	32
#define XIVE_WRITE_ENABLE	(1ULL << 63)

/*
 * The docs refer to a 6 bit field called ChipID, which consists of a
 * 3 bit NodeID and a 3 bit ChipID. On WSP the ChipID is always zero
 * so we ignore it, and every where we use "chip id" in this code we
 * mean the NodeID.
 */
#define WSP_ICS_CHIP_SHIFT		17


static struct wsp_ics *ics_list;
static int num_ics;

/* ICS Source controller accessors */

static u64 wsp_ics_get_xive(struct wsp_ics *ics, unsigned int irq)
{
	unsigned long flags;
	u64 xive;

	spin_lock_irqsave(&ics->lock, flags);
	out_be64(IODA_TBL_ADDR_REG(ics->regs), TBL_SELECT_XIVT | IODA_IRQ(irq));
	xive = in_be64(IODA_TBL_DATA_REG(ics->regs));
	spin_unlock_irqrestore(&ics->lock, flags);

	return xive;
}

static void wsp_ics_set_xive(struct wsp_ics *ics, unsigned int irq, u64 xive)
{
	xive &= ~XIVE_ADDR_MASK;
	xive |= (irq & XIVE_ADDR_MASK);
	xive |= XIVE_WRITE_ENABLE;

	out_be64(XIVE_UPDATE_REG(ics->regs), xive);
}

static u64 xive_set_server(u64 xive, unsigned int server)
{
	u64 mask = ~(XIVE_SERVER_MASK << XIVE_SERVER_SHIFT);

	xive &= mask;
	xive |= (server & XIVE_SERVER_MASK) << XIVE_SERVER_SHIFT;

	return xive;
}

static u64 xive_set_priority(u64 xive, unsigned int priority)
{
	u64 mask = ~(XIVE_PRIORITY_MASK << XIVE_PRIORITY_SHIFT);

	xive &= mask;
	xive |= (priority & XIVE_PRIORITY_MASK) << XIVE_PRIORITY_SHIFT;

	return xive;
}


#ifdef CONFIG_SMP
/* Find logical CPUs within mask on a given chip and store result in ret */
void cpus_on_chip(int chip_id, cpumask_t *mask, cpumask_t *ret)
{
	int cpu, chip;
	struct device_node *cpu_dn, *dn;
	const u32 *prop;

	cpumask_clear(ret);
	for_each_cpu(cpu, mask) {
		cpu_dn = of_get_cpu_node(cpu, NULL);
		if (!cpu_dn)
			continue;

		prop = of_get_property(cpu_dn, "at-node", NULL);
		if (!prop) {
			of_node_put(cpu_dn);
			continue;
		}

		dn = of_find_node_by_phandle(*prop);
		of_node_put(cpu_dn);

		chip = wsp_get_chip_id(dn);
		if (chip == chip_id)
			cpumask_set_cpu(cpu, ret);

		of_node_put(dn);
	}
}

/* Store a suitable CPU to handle a hwirq in the ics->hwirq_cpu_map cache */
static int cache_hwirq_map(struct wsp_ics *ics, unsigned int hwirq,
			   const cpumask_t *affinity)
{
	cpumask_var_t avail, newmask;
	int ret = -ENOMEM, cpu, cpu_rover = 0, target;
	int index = hwirq - ics->hwirq_start;
	unsigned int nodeid;

	BUG_ON(index < 0 || index >= ics->count);

	if (!ics->hwirq_cpu_map)
		return -ENOMEM;

	if (!distribute_irqs) {
		ics->hwirq_cpu_map[hwirq - ics->hwirq_start] = xics_default_server;
		return 0;
	}

	/* Allocate needed CPU masks */
	if (!alloc_cpumask_var(&avail, GFP_KERNEL))
		goto ret;
	if (!alloc_cpumask_var(&newmask, GFP_KERNEL))
		goto freeavail;

	/* Find PBus attached to the source of this IRQ */
	nodeid = (hwirq >> WSP_ICS_CHIP_SHIFT) & 0x3; /* 12:14 */

	/* Find CPUs that could handle this IRQ */
	if (affinity)
		cpumask_and(avail, cpu_online_mask, affinity);
	else
		cpumask_copy(avail, cpu_online_mask);

	/* Narrow selection down to logical CPUs on the same chip */
	cpus_on_chip(nodeid, avail, newmask);

	/* Ensure we haven't narrowed it down to 0 */
	if (unlikely(cpumask_empty(newmask))) {
		if (unlikely(cpumask_empty(avail))) {
			ret = -1;
			goto out;
		}
		cpumask_copy(newmask, avail);
	}

	/* Choose a CPU out of those we narrowed it down to in round robin */
	target = hwirq % cpumask_weight(newmask);
	for_each_cpu(cpu, newmask) {
		if (cpu_rover++ >= target) {
			ics->hwirq_cpu_map[index] = get_hard_smp_processor_id(cpu);
			ret = 0;
			goto out;
		}
	}

	/* Shouldn't happen */
	WARN_ON(1);

out:
	free_cpumask_var(newmask);
freeavail:
	free_cpumask_var(avail);
ret:
	if (ret < 0) {
		ics->hwirq_cpu_map[index] = cpumask_first(cpu_online_mask);
		pr_warning("Error, falling hwirq 0x%x routing back to CPU %i\n",
			   hwirq, ics->hwirq_cpu_map[index]);
	}
	return ret;
}

static void alloc_irq_map(struct wsp_ics *ics)
{
	int i;

	ics->hwirq_cpu_map = kmalloc(sizeof(int) * ics->count, GFP_KERNEL);
	if (!ics->hwirq_cpu_map) {
		pr_warning("Allocate hwirq_cpu_map failed, "
			   "IRQ balancing disabled\n");
		return;
	}

	for (i=0; i < ics->count; i++)
		ics->hwirq_cpu_map[i] = xics_default_server;
}

static int get_irq_server(struct wsp_ics *ics, unsigned int hwirq)
{
	int index = hwirq - ics->hwirq_start;

	BUG_ON(index < 0 || index >= ics->count);

	if (!ics->hwirq_cpu_map)
		return xics_default_server;

	return ics->hwirq_cpu_map[index];
}
#else /* !CONFIG_SMP */
static int cache_hwirq_map(struct wsp_ics *ics, unsigned int hwirq,
			   const cpumask_t *affinity)
{
	return 0;
}

static int get_irq_server(struct wsp_ics *ics, unsigned int hwirq)
{
	return xics_default_server;
}

static void alloc_irq_map(struct wsp_ics *ics) { }
#endif

static void wsp_chip_unmask_irq(struct irq_data *d)
{
	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
	struct wsp_ics *ics;
	int server;
	u64 xive;

	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
		return;

	ics = d->chip_data;
	if (WARN_ON(!ics))
		return;

	server = get_irq_server(ics, hw_irq);

	xive = wsp_ics_get_xive(ics, hw_irq);
	xive = xive_set_server(xive, server);
	xive = xive_set_priority(xive, DEFAULT_PRIORITY);
	wsp_ics_set_xive(ics, hw_irq, xive);
}

static unsigned int wsp_chip_startup(struct irq_data *d)
{
	/* unmask it */
	wsp_chip_unmask_irq(d);
	return 0;
}

static void wsp_mask_real_irq(unsigned int hw_irq, struct wsp_ics *ics)
{
	u64 xive;

	if (hw_irq == XICS_IPI)
		return;

	if (WARN_ON(!ics))
		return;
	xive = wsp_ics_get_xive(ics, hw_irq);
	xive = xive_set_server(xive, xics_default_server);
	xive = xive_set_priority(xive, LOWEST_PRIORITY);
	wsp_ics_set_xive(ics, hw_irq, xive);
}

static void wsp_chip_mask_irq(struct irq_data *d)
{
	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
	struct wsp_ics *ics = d->chip_data;

	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
		return;

	wsp_mask_real_irq(hw_irq, ics);
}

static int wsp_chip_set_affinity(struct irq_data *d,
				 const struct cpumask *cpumask, bool force)
{
	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
	struct wsp_ics *ics;
	int ret;
	u64 xive;

	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
		return -1;

	ics = d->chip_data;
	if (WARN_ON(!ics))
		return -1;
	xive = wsp_ics_get_xive(ics, hw_irq);

	/*
	 * For the moment only implement delivery to all cpus or one cpu.
	 * Get current irq_server for the given irq
	 */
	ret = cache_hwirq_map(ics, hw_irq, cpumask);
	if (ret == -1) {
		char cpulist[128];
		cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
		pr_warning("%s: No online cpus in the mask %s for irq %d\n",
			   __func__, cpulist, d->irq);
		return -1;
	} else if (ret == -ENOMEM) {
		pr_warning("%s: Out of memory\n", __func__);
		return -1;
	}

	xive = xive_set_server(xive, get_irq_server(ics, hw_irq));
	wsp_ics_set_xive(ics, hw_irq, xive);

	return IRQ_SET_MASK_OK;
}

static struct irq_chip wsp_irq_chip = {
	.name = "WSP ICS",
	.irq_startup		= wsp_chip_startup,
	.irq_mask		= wsp_chip_mask_irq,
	.irq_unmask		= wsp_chip_unmask_irq,
	.irq_set_affinity	= wsp_chip_set_affinity
};

static int wsp_ics_host_match(struct ics *ics, struct device_node *dn)
{
	/* All ICSs in the system implement a global irq number space,
	 * so match against them all. */
	return of_device_is_compatible(dn, "ibm,ppc-xics");
}

static int wsp_ics_match_hwirq(struct wsp_ics *wsp_ics, unsigned int hwirq)
{
	if (hwirq >= wsp_ics->hwirq_start &&
	    hwirq <  wsp_ics->hwirq_start + wsp_ics->count)
		return 1;

	return 0;
}

static int wsp_ics_map(struct ics *ics, unsigned int virq)
{
	struct wsp_ics *wsp_ics = to_wsp_ics(ics);
	unsigned int hw_irq = virq_to_hw(virq);
	unsigned long flags;

	if (!wsp_ics_match_hwirq(wsp_ics, hw_irq))
		return -ENOENT;

	irq_set_chip_and_handler(virq, &wsp_irq_chip, handle_fasteoi_irq);

	irq_set_chip_data(virq, wsp_ics);

	spin_lock_irqsave(&wsp_ics->lock, flags);
	bitmap_allocate_region(wsp_ics->bitmap, hw_irq - wsp_ics->hwirq_start, 0);
	spin_unlock_irqrestore(&wsp_ics->lock, flags);

	return 0;
}

static void wsp_ics_mask_unknown(struct ics *ics, unsigned long hw_irq)
{
	struct wsp_ics *wsp_ics = to_wsp_ics(ics);

	if (!wsp_ics_match_hwirq(wsp_ics, hw_irq))
		return;

	pr_err("%s: IRQ %lu (real) is invalid, disabling it.\n", __func__, hw_irq);
	wsp_mask_real_irq(hw_irq, wsp_ics);
}

static long wsp_ics_get_server(struct ics *ics, unsigned long hw_irq)
{
	struct wsp_ics *wsp_ics = to_wsp_ics(ics);

	if (!wsp_ics_match_hwirq(wsp_ics, hw_irq))
		return -ENOENT;

	return get_irq_server(wsp_ics, hw_irq);
}

/* HW Number allocation API */

static struct wsp_ics *wsp_ics_find_dn_ics(struct device_node *dn)
{
	struct device_node *iparent;
	int i;

	iparent = of_irq_find_parent(dn);
	if (!iparent) {
		pr_err("wsp_ics: Failed to find interrupt parent!\n");
		return NULL;
	}

	for(i = 0; i < num_ics; i++) {
		if(ics_list[i].dn == iparent)
			break;
	}

	if (i >= num_ics) {
		pr_err("wsp_ics: Unable to find parent bitmap!\n");
		return NULL;
	}

	return &ics_list[i];
}

int wsp_ics_alloc_irq(struct device_node *dn, int num)
{
	struct wsp_ics *ics;
	int order, offset;

	ics = wsp_ics_find_dn_ics(dn);
	if (!ics)
		return -ENODEV;

	/* Fast, but overly strict if num isn't a power of two */
	order = get_count_order(num);

	spin_lock_irq(&ics->lock);
	offset = bitmap_find_free_region(ics->bitmap, ics->count, order);
	spin_unlock_irq(&ics->lock);

	if (offset < 0)
		return offset;

	return offset + ics->hwirq_start;
}

void wsp_ics_free_irq(struct device_node *dn, unsigned int irq)
{
	struct wsp_ics *ics;

	ics = wsp_ics_find_dn_ics(dn);
	if (WARN_ON(!ics))
		return;

	spin_lock_irq(&ics->lock);
	bitmap_release_region(ics->bitmap, irq, 0);
	spin_unlock_irq(&ics->lock);
}

/* Initialisation */

static int __init wsp_ics_bitmap_setup(struct wsp_ics *ics,
				      struct device_node *dn)
{
	int len, i, j, size;
	u32 start, count;
	const u32 *p;

	size = BITS_TO_LONGS(ics->count) * sizeof(long);
	ics->bitmap = kzalloc(size, GFP_KERNEL);
	if (!ics->bitmap) {
		pr_err("wsp_ics: ENOMEM allocating IRQ bitmap!\n");
		return -ENOMEM;
	}

	spin_lock_init(&ics->lock);

	p = of_get_property(dn, "available-ranges", &len);
	if (!p || !len) {
		/* FIXME this should be a WARN() once mambo is updated */
		pr_err("wsp_ics: No available-ranges defined for %s\n",
			dn->full_name);
		return 0;
	}

	if (len % (2 * sizeof(u32)) != 0) {
		/* FIXME this should be a WARN() once mambo is updated */
		pr_err("wsp_ics: Invalid available-ranges for %s\n",
			dn->full_name);
		return 0;
	}

	bitmap_fill(ics->bitmap, ics->count);

	for (i = 0; i < len / sizeof(u32); i += 2) {
		start = of_read_number(p + i, 1);
		count = of_read_number(p + i + 1, 1);

		pr_devel("%s: start: %d count: %d\n", __func__, start, count);

		if ((start + count) > (ics->hwirq_start + ics->count) ||
		     start < ics->hwirq_start) {
			pr_err("wsp_ics: Invalid range! -> %d to %d\n",
					start, start + count);
			break;
		}

		for (j = 0; j < count; j++)
			bitmap_release_region(ics->bitmap,
				(start + j) - ics->hwirq_start, 0);
	}

	/* Ensure LSIs are not available for allocation */
	bitmap_allocate_region(ics->bitmap, ics->lsi_base,
			       get_count_order(ics->lsi_count));

	return 0;
}

static int __init wsp_ics_setup(struct wsp_ics *ics, struct device_node *dn)
{
	u32 lsi_buid, msi_buid, msi_base, msi_count;
	void __iomem *regs;
	const u32 *p;
	int rc, len, i;
	u64 caps, buid;

	p = of_get_property(dn, "interrupt-ranges", &len);
	if (!p || len < (2 * sizeof(u32))) {
		pr_err("wsp_ics: No/bad interrupt-ranges found on %s\n",
			dn->full_name);
		return -ENOENT;
	}

	if (len > (2 * sizeof(u32))) {
		pr_err("wsp_ics: Multiple ics ranges not supported.\n");
		return -EINVAL;
	}

	regs = of_iomap(dn, 0);
	if (!regs) {
		pr_err("wsp_ics: of_iomap(%s) failed\n", dn->full_name);
		return -ENXIO;
	}

	ics->hwirq_start = of_read_number(p, 1);
	ics->count = of_read_number(p + 1, 1);
	ics->regs = regs;

	ics->chip_id = wsp_get_chip_id(dn);
	if (WARN_ON(ics->chip_id < 0))
		ics->chip_id = 0;

	/* Get some informations about the critter */
	caps = in_be64(ICS_INT_CAPS_REG(ics->regs));
	buid = in_be64(INT_SRC_LAYER_BUID_REG(ics->regs));
	ics->lsi_count = caps >> 56;
	msi_count = (caps >> 44) & 0x7ff;

	/* Note: LSI BUID is 9 bits, but really only 3 are BUID and the
	 * rest is mixed in the interrupt number. We store the whole
	 * thing though
	 */
	lsi_buid = (buid >> 48) & 0x1ff;
	ics->lsi_base = (ics->chip_id << WSP_ICS_CHIP_SHIFT) | lsi_buid << 5;
	msi_buid = (buid >> 37) & 0x7;
	msi_base = (ics->chip_id << WSP_ICS_CHIP_SHIFT) | msi_buid << 11;

	pr_info("wsp_ics: Found %s\n", dn->full_name);
	pr_info("wsp_ics:    irq range : 0x%06llx..0x%06llx\n",
		ics->hwirq_start, ics->hwirq_start + ics->count - 1);
	pr_info("wsp_ics:    %4d LSIs : 0x%06x..0x%06x\n",
		ics->lsi_count, ics->lsi_base,
		ics->lsi_base + ics->lsi_count - 1);
	pr_info("wsp_ics:    %4d MSIs : 0x%06x..0x%06x\n",
		msi_count, msi_base,
		msi_base + msi_count - 1);

	/* Let's check the HW config is sane */
	if (ics->lsi_base < ics->hwirq_start ||
	    (ics->lsi_base + ics->lsi_count) > (ics->hwirq_start + ics->count))
		pr_warning("wsp_ics: WARNING ! LSIs out of interrupt-ranges !\n");
	if (msi_base < ics->hwirq_start ||
	    (msi_base + msi_count) > (ics->hwirq_start + ics->count))
		pr_warning("wsp_ics: WARNING ! MSIs out of interrupt-ranges !\n");

	/* We don't check for overlap between LSI and MSI, which will happen
	 * if we use the same BUID, I'm not sure yet how legit that is.
	 */

	rc = wsp_ics_bitmap_setup(ics, dn);
	if (rc) {
		iounmap(regs);
		return rc;
	}

	ics->dn = of_node_get(dn);
	alloc_irq_map(ics);

	for(i = 0; i < ics->count; i++)
		wsp_mask_real_irq(ics->hwirq_start + i, ics);

	ics->ics.map = wsp_ics_map;
	ics->ics.mask_unknown = wsp_ics_mask_unknown;
	ics->ics.get_server = wsp_ics_get_server;
	ics->ics.host_match = wsp_ics_host_match;

	xics_register_ics(&ics->ics);

	return 0;
}

static void __init wsp_ics_set_default_server(void)
{
	struct device_node *np;
	u32 hwid;

	/* Find the server number for the boot cpu. */
	np = of_get_cpu_node(boot_cpuid, NULL);
	BUG_ON(!np);

	hwid = get_hard_smp_processor_id(boot_cpuid);

	pr_info("wsp_ics: default server is %#x, CPU %s\n", hwid, np->full_name);
	xics_default_server = hwid;

	of_node_put(np);
}

static int __init wsp_ics_init(void)
{
	struct device_node *dn;
	struct wsp_ics *ics;
	int rc, found;

	wsp_ics_set_default_server();

	found = 0;
	for_each_compatible_node(dn, NULL, "ibm,ppc-xics")
		found++;

	if (found == 0) {
		pr_err("wsp_ics: No ICS's found!\n");
		return -ENODEV;
	}

	ics_list = kmalloc(sizeof(*ics) * found, GFP_KERNEL);
	if (!ics_list) {
		pr_err("wsp_ics: No memory for structs.\n");
		return -ENOMEM;
	}

	num_ics = 0;
	ics = ics_list;
	for_each_compatible_node(dn, NULL, "ibm,wsp-xics") {
		rc = wsp_ics_setup(ics, dn);
		if (rc == 0) {
			ics++;
			num_ics++;
		}
	}

	if (found != num_ics) {
		pr_err("wsp_ics: Failed setting up %d ICS's\n",
			found - num_ics);
		return -1;
	}

	return 0;
}

void __init wsp_init_irq(void)
{
	wsp_ics_init();
	xics_init();

	/* We need to patch our irq chip's EOI to point to the right ICP */
	wsp_irq_chip.irq_eoi = icp_ops->eoi;
}

#ifdef CONFIG_PCI_MSI
static void wsp_ics_msi_unmask_irq(struct irq_data *d)
{
	wsp_chip_unmask_irq(d);
	unmask_msi_irq(d);
}

static unsigned int wsp_ics_msi_startup(struct irq_data *d)
{
	wsp_ics_msi_unmask_irq(d);
	return 0;
}

static void wsp_ics_msi_mask_irq(struct irq_data *d)
{
	mask_msi_irq(d);
	wsp_chip_mask_irq(d);
}

/*
 * we do it this way because we reassinge default EOI handling in
 * irq_init() above
 */
static void wsp_ics_eoi(struct irq_data *data)
{
	wsp_irq_chip.irq_eoi(data);
}

static struct irq_chip wsp_ics_msi = {
	.name = "WSP ICS MSI",
	.irq_startup = wsp_ics_msi_startup,
	.irq_mask = wsp_ics_msi_mask_irq,
	.irq_unmask = wsp_ics_msi_unmask_irq,
	.irq_eoi = wsp_ics_eoi,
	.irq_set_affinity = wsp_chip_set_affinity
};

void wsp_ics_set_msi_chip(unsigned int irq)
{
	irq_set_chip(irq, &wsp_ics_msi);
}

void wsp_ics_set_std_chip(unsigned int irq)
{
	irq_set_chip(irq, &wsp_irq_chip);
}
#endif /* CONFIG_PCI_MSI */
