/*
 * Hisilicon HiP04 INTC
 *
 * Copyright (C) 2002-2014 ARM Limited.
 * Copyright (c) 2013-2014 Hisilicon Ltd.
 * Copyright (c) 2013-2014 Linaro Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Interrupt architecture for the HIP04 INTC:
 *
 * o There is one Interrupt Distributor, which receives interrupts
 *   from system devices and sends them to the Interrupt Controllers.
 *
 * o There is one CPU Interface per CPU, which sends interrupts sent
 *   by the Distributor, and interrupts generated locally, to the
 *   associated CPU. The base address of the CPU interface is usually
 *   aliased so that the same address points to different chips depending
 *   on the CPU it is accessed from.
 *
 * Note that IRQs 0-31 are special - they are local to each CPU.
 * As such, the enable set/clear, pending set/clear and active bit
 * registers are banked per-cpu for these sources.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/smp.h>
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
#include <linux/cpumask.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/irqchip/arm-gic.h>

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

#include "irq-gic-common.h"
#include "irqchip.h"

#define HIP04_MAX_IRQS		510

struct hip04_irq_data {
	void __iomem *dist_base;
	void __iomem *cpu_base;
	struct irq_domain *domain;
	unsigned int nr_irqs;
};

static DEFINE_RAW_SPINLOCK(irq_controller_lock);

/*
 * The GIC mapping of CPU interfaces does not necessarily match
 * the logical CPU numbering.  Let's use a mapping as returned
 * by the GIC itself.
 */
#define NR_HIP04_CPU_IF 16
static u16 hip04_cpu_map[NR_HIP04_CPU_IF] __read_mostly;

static struct hip04_irq_data hip04_data __read_mostly;

static inline void __iomem *hip04_dist_base(struct irq_data *d)
{
	struct hip04_irq_data *hip04_data = irq_data_get_irq_chip_data(d);
	return hip04_data->dist_base;
}

static inline void __iomem *hip04_cpu_base(struct irq_data *d)
{
	struct hip04_irq_data *hip04_data = irq_data_get_irq_chip_data(d);
	return hip04_data->cpu_base;
}

static inline unsigned int hip04_irq(struct irq_data *d)
{
	return d->hwirq;
}

/*
 * Routines to acknowledge, disable and enable interrupts
 */
static void hip04_mask_irq(struct irq_data *d)
{
	u32 mask = 1 << (hip04_irq(d) % 32);

	raw_spin_lock(&irq_controller_lock);
	writel_relaxed(mask, hip04_dist_base(d) + GIC_DIST_ENABLE_CLEAR +
		       (hip04_irq(d) / 32) * 4);
	raw_spin_unlock(&irq_controller_lock);
}

static void hip04_unmask_irq(struct irq_data *d)
{
	u32 mask = 1 << (hip04_irq(d) % 32);

	raw_spin_lock(&irq_controller_lock);
	writel_relaxed(mask, hip04_dist_base(d) + GIC_DIST_ENABLE_SET +
		       (hip04_irq(d) / 32) * 4);
	raw_spin_unlock(&irq_controller_lock);
}

static void hip04_eoi_irq(struct irq_data *d)
{
	writel_relaxed(hip04_irq(d), hip04_cpu_base(d) + GIC_CPU_EOI);
}

static int hip04_irq_set_type(struct irq_data *d, unsigned int type)
{
	void __iomem *base = hip04_dist_base(d);
	unsigned int irq = hip04_irq(d);

	/* Interrupt configuration for SGIs can't be changed */
	if (irq < 16)
		return -EINVAL;

	if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
		return -EINVAL;

	raw_spin_lock(&irq_controller_lock);

	gic_configure_irq(irq, type, base, NULL);

	raw_spin_unlock(&irq_controller_lock);

	return 0;
}

#ifdef CONFIG_SMP
static int hip04_irq_set_affinity(struct irq_data *d,
				  const struct cpumask *mask_val,
				  bool force)
{
	void __iomem *reg;
	unsigned int cpu, shift = (hip04_irq(d) % 2) * 16;
	u32 val, mask, bit;

	if (!force)
		cpu = cpumask_any_and(mask_val, cpu_online_mask);
	else
		cpu = cpumask_first(mask_val);

	if (cpu >= NR_HIP04_CPU_IF || cpu >= nr_cpu_ids)
		return -EINVAL;

	raw_spin_lock(&irq_controller_lock);
	reg = hip04_dist_base(d) + GIC_DIST_TARGET + ((hip04_irq(d) * 2) & ~3);
	mask = 0xffff << shift;
	bit = hip04_cpu_map[cpu] << shift;
	val = readl_relaxed(reg) & ~mask;
	writel_relaxed(val | bit, reg);
	raw_spin_unlock(&irq_controller_lock);

	return IRQ_SET_MASK_OK;
}
#endif

static void __exception_irq_entry hip04_handle_irq(struct pt_regs *regs)
{
	u32 irqstat, irqnr;
	void __iomem *cpu_base = hip04_data.cpu_base;

	do {
		irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
		irqnr = irqstat & GICC_IAR_INT_ID_MASK;

		if (likely(irqnr > 15 && irqnr <= HIP04_MAX_IRQS)) {
			irqnr = irq_find_mapping(hip04_data.domain, irqnr);
			handle_IRQ(irqnr, regs);
			continue;
		}
		if (irqnr < 16) {
			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
#ifdef CONFIG_SMP
			handle_IPI(irqnr, regs);
#endif
			continue;
		}
		break;
	} while (1);
}

static struct irq_chip hip04_irq_chip = {
	.name			= "HIP04 INTC",
	.irq_mask		= hip04_mask_irq,
	.irq_unmask		= hip04_unmask_irq,
	.irq_eoi		= hip04_eoi_irq,
	.irq_set_type		= hip04_irq_set_type,
#ifdef CONFIG_SMP
	.irq_set_affinity	= hip04_irq_set_affinity,
#endif
};

static u16 hip04_get_cpumask(struct hip04_irq_data *intc)
{
	void __iomem *base = intc->dist_base;
	u32 mask, i;

	for (i = mask = 0; i < 32; i += 2) {
		mask = readl_relaxed(base + GIC_DIST_TARGET + i * 2);
		mask |= mask >> 16;
		if (mask)
			break;
	}

	if (!mask)
		pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");

	return mask;
}

static void __init hip04_irq_dist_init(struct hip04_irq_data *intc)
{
	unsigned int i;
	u32 cpumask;
	unsigned int nr_irqs = intc->nr_irqs;
	void __iomem *base = intc->dist_base;

	writel_relaxed(0, base + GIC_DIST_CTRL);

	/*
	 * Set all global interrupts to this CPU only.
	 */
	cpumask = hip04_get_cpumask(intc);
	cpumask |= cpumask << 16;
	for (i = 32; i < nr_irqs; i += 2)
		writel_relaxed(cpumask, base + GIC_DIST_TARGET + ((i * 2) & ~3));

	gic_dist_config(base, nr_irqs, NULL);

	writel_relaxed(1, base + GIC_DIST_CTRL);
}

static void hip04_irq_cpu_init(struct hip04_irq_data *intc)
{
	void __iomem *dist_base = intc->dist_base;
	void __iomem *base = intc->cpu_base;
	unsigned int cpu_mask, cpu = smp_processor_id();
	int i;

	/*
	 * Get what the GIC says our CPU mask is.
	 */
	BUG_ON(cpu >= NR_HIP04_CPU_IF);
	cpu_mask = hip04_get_cpumask(intc);
	hip04_cpu_map[cpu] = cpu_mask;

	/*
	 * Clear our mask from the other map entries in case they're
	 * still undefined.
	 */
	for (i = 0; i < NR_HIP04_CPU_IF; i++)
		if (i != cpu)
			hip04_cpu_map[i] &= ~cpu_mask;

	gic_cpu_config(dist_base, NULL);

	writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
	writel_relaxed(1, base + GIC_CPU_CTRL);
}

#ifdef CONFIG_SMP
static void hip04_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
	int cpu;
	unsigned long flags, map = 0;

	raw_spin_lock_irqsave(&irq_controller_lock, flags);

	/* Convert our logical CPU mask into a physical one. */
	for_each_cpu(cpu, mask)
		map |= hip04_cpu_map[cpu];

	/*
	 * Ensure that stores to Normal memory are visible to the
	 * other CPUs before they observe us issuing the IPI.
	 */
	dmb(ishst);

	/* this always happens on GIC0 */
	writel_relaxed(map << 8 | irq, hip04_data.dist_base + GIC_DIST_SOFTINT);

	raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
}
#endif

static int hip04_irq_domain_map(struct irq_domain *d, unsigned int irq,
				irq_hw_number_t hw)
{
	if (hw < 32) {
		irq_set_percpu_devid(irq);
		irq_set_chip_and_handler(irq, &hip04_irq_chip,
					 handle_percpu_devid_irq);
		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
	} else {
		irq_set_chip_and_handler(irq, &hip04_irq_chip,
					 handle_fasteoi_irq);
		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
	}
	irq_set_chip_data(irq, d->host_data);
	return 0;
}

static int hip04_irq_domain_xlate(struct irq_domain *d,
				  struct device_node *controller,
				  const u32 *intspec, unsigned int intsize,
				  unsigned long *out_hwirq,
				  unsigned int *out_type)
{
	unsigned long ret = 0;

	if (d->of_node != controller)
		return -EINVAL;
	if (intsize < 3)
		return -EINVAL;

	/* Get the interrupt number and add 16 to skip over SGIs */
	*out_hwirq = intspec[1] + 16;

	/* For SPIs, we need to add 16 more to get the irq ID number */
	if (!intspec[0])
		*out_hwirq += 16;

	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;

	return ret;
}

#ifdef CONFIG_SMP
static int hip04_irq_secondary_init(struct notifier_block *nfb,
				    unsigned long action,
				    void *hcpu)
{
	if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
		hip04_irq_cpu_init(&hip04_data);
	return NOTIFY_OK;
}

/*
 * Notifier for enabling the INTC CPU interface. Set an arbitrarily high
 * priority because the GIC needs to be up before the ARM generic timers.
 */
static struct notifier_block hip04_irq_cpu_notifier = {
	.notifier_call	= hip04_irq_secondary_init,
	.priority	= 100,
};
#endif

static const struct irq_domain_ops hip04_irq_domain_ops = {
	.map	= hip04_irq_domain_map,
	.xlate	= hip04_irq_domain_xlate,
};

static int __init
hip04_of_init(struct device_node *node, struct device_node *parent)
{
	irq_hw_number_t hwirq_base = 16;
	int nr_irqs, irq_base, i;

	if (WARN_ON(!node))
		return -ENODEV;

	hip04_data.dist_base = of_iomap(node, 0);
	WARN(!hip04_data.dist_base, "fail to map hip04 intc dist registers\n");

	hip04_data.cpu_base = of_iomap(node, 1);
	WARN(!hip04_data.cpu_base, "unable to map hip04 intc cpu registers\n");

	/*
	 * Initialize the CPU interface map to all CPUs.
	 * It will be refined as each CPU probes its ID.
	 */
	for (i = 0; i < NR_HIP04_CPU_IF; i++)
		hip04_cpu_map[i] = 0xff;

	/*
	 * Find out how many interrupts are supported.
	 * The HIP04 INTC only supports up to 510 interrupt sources.
	 */
	nr_irqs = readl_relaxed(hip04_data.dist_base + GIC_DIST_CTR) & 0x1f;
	nr_irqs = (nr_irqs + 1) * 32;
	if (nr_irqs > HIP04_MAX_IRQS)
		nr_irqs = HIP04_MAX_IRQS;
	hip04_data.nr_irqs = nr_irqs;

	nr_irqs -= hwirq_base; /* calculate # of irqs to allocate */

	irq_base = irq_alloc_descs(-1, hwirq_base, nr_irqs, numa_node_id());
	if (IS_ERR_VALUE(irq_base)) {
		pr_err("failed to allocate IRQ numbers\n");
		return -EINVAL;
	}

	hip04_data.domain = irq_domain_add_legacy(node, nr_irqs, irq_base,
						  hwirq_base,
						  &hip04_irq_domain_ops,
						  &hip04_data);

	if (WARN_ON(!hip04_data.domain))
		return -EINVAL;

#ifdef CONFIG_SMP
	set_smp_cross_call(hip04_raise_softirq);
	register_cpu_notifier(&hip04_irq_cpu_notifier);
#endif
	set_handle_irq(hip04_handle_irq);

	hip04_irq_dist_init(&hip04_data);
	hip04_irq_cpu_init(&hip04_data);

	return 0;
}
IRQCHIP_DECLARE(hip04_intc, "hisilicon,hip04-intc", hip04_of_init);
