// SPDX-License-Identifier: GPL-2.0-only
/*
 * Broadcom BCM7038 style Level 1 interrupt controller driver
 *
 * Copyright (C) 2014 Broadcom Corporation
 * Author: Kevin Cernekee
 */

#define pr_fmt(fmt)	KBUILD_MODNAME	": " fmt

#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/types.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/syscore_ops.h>

#define IRQS_PER_WORD		32
#define REG_BYTES_PER_IRQ_WORD	(sizeof(u32) * 4)
#define MAX_WORDS		8

struct bcm7038_l1_cpu;

struct bcm7038_l1_chip {
	raw_spinlock_t		lock;
	unsigned int		n_words;
	struct irq_domain	*domain;
	struct bcm7038_l1_cpu	*cpus[NR_CPUS];
#ifdef CONFIG_PM_SLEEP
	struct list_head	list;
	u32			wake_mask[MAX_WORDS];
#endif
	u32			irq_fwd_mask[MAX_WORDS];
	u8			affinity[MAX_WORDS * IRQS_PER_WORD];
};

struct bcm7038_l1_cpu {
	void __iomem		*map_base;
	u32			mask_cache[0];
};

/*
 * STATUS/MASK_STATUS/MASK_SET/MASK_CLEAR are packed one right after another:
 *
 * 7038:
 *   0x1000_1400: W0_STATUS
 *   0x1000_1404: W1_STATUS
 *   0x1000_1408: W0_MASK_STATUS
 *   0x1000_140c: W1_MASK_STATUS
 *   0x1000_1410: W0_MASK_SET
 *   0x1000_1414: W1_MASK_SET
 *   0x1000_1418: W0_MASK_CLEAR
 *   0x1000_141c: W1_MASK_CLEAR
 *
 * 7445:
 *   0xf03e_1500: W0_STATUS
 *   0xf03e_1504: W1_STATUS
 *   0xf03e_1508: W2_STATUS
 *   0xf03e_150c: W3_STATUS
 *   0xf03e_1510: W4_STATUS
 *   0xf03e_1514: W0_MASK_STATUS
 *   0xf03e_1518: W1_MASK_STATUS
 *   [...]
 */

static inline unsigned int reg_status(struct bcm7038_l1_chip *intc,
				      unsigned int word)
{
	return (0 * intc->n_words + word) * sizeof(u32);
}

static inline unsigned int reg_mask_status(struct bcm7038_l1_chip *intc,
					   unsigned int word)
{
	return (1 * intc->n_words + word) * sizeof(u32);
}

static inline unsigned int reg_mask_set(struct bcm7038_l1_chip *intc,
					unsigned int word)
{
	return (2 * intc->n_words + word) * sizeof(u32);
}

static inline unsigned int reg_mask_clr(struct bcm7038_l1_chip *intc,
					unsigned int word)
{
	return (3 * intc->n_words + word) * sizeof(u32);
}

static inline u32 l1_readl(void __iomem *reg)
{
	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
		return ioread32be(reg);
	else
		return readl(reg);
}

static inline void l1_writel(u32 val, void __iomem *reg)
{
	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
		iowrite32be(val, reg);
	else
		writel(val, reg);
}

static void bcm7038_l1_irq_handle(struct irq_desc *desc)
{
	struct bcm7038_l1_chip *intc = irq_desc_get_handler_data(desc);
	struct bcm7038_l1_cpu *cpu;
	struct irq_chip *chip = irq_desc_get_chip(desc);
	unsigned int idx;

#ifdef CONFIG_SMP
	cpu = intc->cpus[cpu_logical_map(smp_processor_id())];
#else
	cpu = intc->cpus[0];
#endif

	chained_irq_enter(chip, desc);

	for (idx = 0; idx < intc->n_words; idx++) {
		int base = idx * IRQS_PER_WORD;
		unsigned long pending, flags;
		int hwirq;

		raw_spin_lock_irqsave(&intc->lock, flags);
		pending = l1_readl(cpu->map_base + reg_status(intc, idx)) &
			  ~cpu->mask_cache[idx];
		raw_spin_unlock_irqrestore(&intc->lock, flags);

		for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
			generic_handle_irq(irq_find_mapping(intc->domain,
							    base + hwirq));
		}
	}

	chained_irq_exit(chip, desc);
}

static void __bcm7038_l1_unmask(struct irq_data *d, unsigned int cpu_idx)
{
	struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
	u32 word = d->hwirq / IRQS_PER_WORD;
	u32 mask = BIT(d->hwirq % IRQS_PER_WORD);

	intc->cpus[cpu_idx]->mask_cache[word] &= ~mask;
	l1_writel(mask, intc->cpus[cpu_idx]->map_base +
			reg_mask_clr(intc, word));
}

static void __bcm7038_l1_mask(struct irq_data *d, unsigned int cpu_idx)
{
	struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
	u32 word = d->hwirq / IRQS_PER_WORD;
	u32 mask = BIT(d->hwirq % IRQS_PER_WORD);

	intc->cpus[cpu_idx]->mask_cache[word] |= mask;
	l1_writel(mask, intc->cpus[cpu_idx]->map_base +
			reg_mask_set(intc, word));
}

static void bcm7038_l1_unmask(struct irq_data *d)
{
	struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
	unsigned long flags;

	raw_spin_lock_irqsave(&intc->lock, flags);
	__bcm7038_l1_unmask(d, intc->affinity[d->hwirq]);
	raw_spin_unlock_irqrestore(&intc->lock, flags);
}

static void bcm7038_l1_mask(struct irq_data *d)
{
	struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
	unsigned long flags;

	raw_spin_lock_irqsave(&intc->lock, flags);
	__bcm7038_l1_mask(d, intc->affinity[d->hwirq]);
	raw_spin_unlock_irqrestore(&intc->lock, flags);
}

static int bcm7038_l1_set_affinity(struct irq_data *d,
				   const struct cpumask *dest,
				   bool force)
{
	struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
	unsigned long flags;
	irq_hw_number_t hw = d->hwirq;
	u32 word = hw / IRQS_PER_WORD;
	u32 mask = BIT(hw % IRQS_PER_WORD);
	unsigned int first_cpu = cpumask_any_and(dest, cpu_online_mask);
	bool was_disabled;

	raw_spin_lock_irqsave(&intc->lock, flags);

	was_disabled = !!(intc->cpus[intc->affinity[hw]]->mask_cache[word] &
			  mask);
	__bcm7038_l1_mask(d, intc->affinity[hw]);
	intc->affinity[hw] = first_cpu;
	if (!was_disabled)
		__bcm7038_l1_unmask(d, first_cpu);

	raw_spin_unlock_irqrestore(&intc->lock, flags);
	irq_data_update_effective_affinity(d, cpumask_of(first_cpu));

	return 0;
}

#ifdef CONFIG_SMP
static void bcm7038_l1_cpu_offline(struct irq_data *d)
{
	struct cpumask *mask = irq_data_get_affinity_mask(d);
	int cpu = smp_processor_id();
	cpumask_t new_affinity;

	/* This CPU was not on the affinity mask */
	if (!cpumask_test_cpu(cpu, mask))
		return;

	if (cpumask_weight(mask) > 1) {
		/*
		 * Multiple CPU affinity, remove this CPU from the affinity
		 * mask
		 */
		cpumask_copy(&new_affinity, mask);
		cpumask_clear_cpu(cpu, &new_affinity);
	} else {
		/* Only CPU, put on the lowest online CPU */
		cpumask_clear(&new_affinity);
		cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
	}
	irq_set_affinity_locked(d, &new_affinity, false);
}
#endif

static int __init bcm7038_l1_init_one(struct device_node *dn,
				      unsigned int idx,
				      struct bcm7038_l1_chip *intc)
{
	struct resource res;
	resource_size_t sz;
	struct bcm7038_l1_cpu *cpu;
	unsigned int i, n_words, parent_irq;
	int ret;

	if (of_address_to_resource(dn, idx, &res))
		return -EINVAL;
	sz = resource_size(&res);
	n_words = sz / REG_BYTES_PER_IRQ_WORD;

	if (n_words > MAX_WORDS)
		return -EINVAL;
	else if (!intc->n_words)
		intc->n_words = n_words;
	else if (intc->n_words != n_words)
		return -EINVAL;

	ret = of_property_read_u32_array(dn , "brcm,int-fwd-mask",
					 intc->irq_fwd_mask, n_words);
	if (ret != 0 && ret != -EINVAL) {
		/* property exists but has the wrong number of words */
		pr_err("invalid brcm,int-fwd-mask property\n");
		return -EINVAL;
	}

	cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
					GFP_KERNEL);
	if (!cpu)
		return -ENOMEM;

	cpu->map_base = ioremap(res.start, sz);
	if (!cpu->map_base)
		return -ENOMEM;

	for (i = 0; i < n_words; i++) {
		l1_writel(~intc->irq_fwd_mask[i],
			  cpu->map_base + reg_mask_set(intc, i));
		l1_writel(intc->irq_fwd_mask[i],
			  cpu->map_base + reg_mask_clr(intc, i));
		cpu->mask_cache[i] = ~intc->irq_fwd_mask[i];
	}

	parent_irq = irq_of_parse_and_map(dn, idx);
	if (!parent_irq) {
		pr_err("failed to map parent interrupt %d\n", parent_irq);
		return -EINVAL;
	}

	if (of_property_read_bool(dn, "brcm,irq-can-wake"))
		enable_irq_wake(parent_irq);

	irq_set_chained_handler_and_data(parent_irq, bcm7038_l1_irq_handle,
					 intc);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
/*
 * We keep a list of bcm7038_l1_chip used for suspend/resume. This hack is
 * used because the struct chip_type suspend/resume hooks are not called
 * unless chip_type is hooked onto a generic_chip. Since this driver does
 * not use generic_chip, we need to manually hook our resume/suspend to
 * syscore_ops.
 */
static LIST_HEAD(bcm7038_l1_intcs_list);
static DEFINE_RAW_SPINLOCK(bcm7038_l1_intcs_lock);

static int bcm7038_l1_suspend(void)
{
	struct bcm7038_l1_chip *intc;
	int boot_cpu, word;
	u32 val;

	/* Wakeup interrupt should only come from the boot cpu */
	boot_cpu = cpu_logical_map(0);

	list_for_each_entry(intc, &bcm7038_l1_intcs_list, list) {
		for (word = 0; word < intc->n_words; word++) {
			val = intc->wake_mask[word] | intc->irq_fwd_mask[word];
			l1_writel(~val,
				intc->cpus[boot_cpu]->map_base + reg_mask_set(intc, word));
			l1_writel(val,
				intc->cpus[boot_cpu]->map_base + reg_mask_clr(intc, word));
		}
	}

	return 0;
}

static void bcm7038_l1_resume(void)
{
	struct bcm7038_l1_chip *intc;
	int boot_cpu, word;

	boot_cpu = cpu_logical_map(0);

	list_for_each_entry(intc, &bcm7038_l1_intcs_list, list) {
		for (word = 0; word < intc->n_words; word++) {
			l1_writel(intc->cpus[boot_cpu]->mask_cache[word],
				intc->cpus[boot_cpu]->map_base + reg_mask_set(intc, word));
			l1_writel(~intc->cpus[boot_cpu]->mask_cache[word],
				intc->cpus[boot_cpu]->map_base + reg_mask_clr(intc, word));
		}
	}
}

static struct syscore_ops bcm7038_l1_syscore_ops = {
	.suspend	= bcm7038_l1_suspend,
	.resume		= bcm7038_l1_resume,
};

static int bcm7038_l1_set_wake(struct irq_data *d, unsigned int on)
{
	struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
	unsigned long flags;
	u32 word = d->hwirq / IRQS_PER_WORD;
	u32 mask = BIT(d->hwirq % IRQS_PER_WORD);

	raw_spin_lock_irqsave(&intc->lock, flags);
	if (on)
		intc->wake_mask[word] |= mask;
	else
		intc->wake_mask[word] &= ~mask;
	raw_spin_unlock_irqrestore(&intc->lock, flags);

	return 0;
}
#endif

static struct irq_chip bcm7038_l1_irq_chip = {
	.name			= "bcm7038-l1",
	.irq_mask		= bcm7038_l1_mask,
	.irq_unmask		= bcm7038_l1_unmask,
	.irq_set_affinity	= bcm7038_l1_set_affinity,
#ifdef CONFIG_SMP
	.irq_cpu_offline	= bcm7038_l1_cpu_offline,
#endif
#ifdef CONFIG_PM_SLEEP
	.irq_set_wake		= bcm7038_l1_set_wake,
#endif
};

static int bcm7038_l1_map(struct irq_domain *d, unsigned int virq,
			  irq_hw_number_t hw_irq)
{
	struct bcm7038_l1_chip *intc = d->host_data;
	u32 mask = BIT(hw_irq % IRQS_PER_WORD);
	u32 word = hw_irq / IRQS_PER_WORD;

	if (intc->irq_fwd_mask[word] & mask)
		return -EPERM;

	irq_set_chip_and_handler(virq, &bcm7038_l1_irq_chip, handle_level_irq);
	irq_set_chip_data(virq, d->host_data);
	irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
	return 0;
}

static const struct irq_domain_ops bcm7038_l1_domain_ops = {
	.xlate			= irq_domain_xlate_onecell,
	.map			= bcm7038_l1_map,
};

int __init bcm7038_l1_of_init(struct device_node *dn,
			      struct device_node *parent)
{
	struct bcm7038_l1_chip *intc;
	int idx, ret;

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

	raw_spin_lock_init(&intc->lock);
	for_each_possible_cpu(idx) {
		ret = bcm7038_l1_init_one(dn, idx, intc);
		if (ret < 0) {
			if (idx)
				break;
			pr_err("failed to remap intc L1 registers\n");
			goto out_free;
		}
	}

	intc->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * intc->n_words,
					     &bcm7038_l1_domain_ops,
					     intc);
	if (!intc->domain) {
		ret = -ENOMEM;
		goto out_unmap;
	}

#ifdef CONFIG_PM_SLEEP
	/* Add bcm7038_l1_chip into a list */
	raw_spin_lock(&bcm7038_l1_intcs_lock);
	list_add_tail(&intc->list, &bcm7038_l1_intcs_list);
	raw_spin_unlock(&bcm7038_l1_intcs_lock);

	if (list_is_singular(&bcm7038_l1_intcs_list))
		register_syscore_ops(&bcm7038_l1_syscore_ops);
#endif

	pr_info("registered BCM7038 L1 intc (%pOF, IRQs: %d)\n",
		dn, IRQS_PER_WORD * intc->n_words);

	return 0;

out_unmap:
	for_each_possible_cpu(idx) {
		struct bcm7038_l1_cpu *cpu = intc->cpus[idx];

		if (cpu) {
			if (cpu->map_base)
				iounmap(cpu->map_base);
			kfree(cpu);
		}
	}
out_free:
	kfree(intc);
	return ret;
}

IRQCHIP_DECLARE(bcm7038_l1, "brcm,bcm7038-l1-intc", bcm7038_l1_of_init);
