/*
 * 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.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"

#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);
	int ret;

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

	/* SPIs have restrictions on the supported types */
	if (irq >= 32 && type != IRQ_TYPE_LEVEL_HIGH &&
			 type != IRQ_TYPE_EDGE_RISING)
		return -EINVAL;

	raw_spin_lock(&irq_controller_lock);

	ret = gic_configure_irq(irq, type, base, NULL);

	raw_spin_unlock(&irq_controller_lock);

	return ret;
}

#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)) {
			handle_domain_irq(hip04_data.domain, 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
	.flags			= IRQCHIP_SET_TYPE_MASKED |
				  IRQCHIP_SKIP_SET_WAKE |
				  IRQCHIP_MASK_ON_SUSPEND,
};

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] = 0xffff;

	/*
	 * 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);
