// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Aspeed AST24XX, AST25XX, and AST26XX SCU Interrupt Controller
 * Copyright 2019 IBM Corporation
 *
 * Eddie James <eajames@linux.ibm.com>
 */

#include <linux/bitops.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/mfd/syscon.h>
#include <linux/of_irq.h>
#include <linux/regmap.h>

#define ASPEED_SCU_IC_REG		0x018
#define ASPEED_SCU_IC_SHIFT		0
#define ASPEED_SCU_IC_ENABLE		GENMASK(6, ASPEED_SCU_IC_SHIFT)
#define ASPEED_SCU_IC_NUM_IRQS		7
#define ASPEED_SCU_IC_STATUS_SHIFT	16

#define ASPEED_AST2600_SCU_IC0_REG	0x560
#define ASPEED_AST2600_SCU_IC0_SHIFT	0
#define ASPEED_AST2600_SCU_IC0_ENABLE	\
	GENMASK(5, ASPEED_AST2600_SCU_IC0_SHIFT)
#define ASPEED_AST2600_SCU_IC0_NUM_IRQS	6

#define ASPEED_AST2600_SCU_IC1_REG	0x570
#define ASPEED_AST2600_SCU_IC1_SHIFT	4
#define ASPEED_AST2600_SCU_IC1_ENABLE	\
	GENMASK(5, ASPEED_AST2600_SCU_IC1_SHIFT)
#define ASPEED_AST2600_SCU_IC1_NUM_IRQS	2

struct aspeed_scu_ic {
	unsigned long irq_enable;
	unsigned long irq_shift;
	unsigned int num_irqs;
	unsigned int reg;
	struct regmap *scu;
	struct irq_domain *irq_domain;
};

static void aspeed_scu_ic_irq_handler(struct irq_desc *desc)
{
	unsigned int sts;
	unsigned long bit;
	unsigned long enabled;
	unsigned long max;
	unsigned long status;
	struct aspeed_scu_ic *scu_ic = irq_desc_get_handler_data(desc);
	struct irq_chip *chip = irq_desc_get_chip(desc);
	unsigned int mask = scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT;

	chained_irq_enter(chip, desc);

	/*
	 * The SCU IC has just one register to control its operation and read
	 * status. The interrupt enable bits occupy the lower 16 bits of the
	 * register, while the interrupt status bits occupy the upper 16 bits.
	 * The status bit for a given interrupt is always 16 bits shifted from
	 * the enable bit for the same interrupt.
	 * Therefore, perform the IRQ operations in the enable bit space by
	 * shifting the status down to get the mapping and then back up to
	 * clear the bit.
	 */
	regmap_read(scu_ic->scu, scu_ic->reg, &sts);
	enabled = sts & scu_ic->irq_enable;
	status = (sts >> ASPEED_SCU_IC_STATUS_SHIFT) & enabled;

	bit = scu_ic->irq_shift;
	max = scu_ic->num_irqs + bit;

	for_each_set_bit_from(bit, &status, max) {
		generic_handle_domain_irq(scu_ic->irq_domain,
					  bit - scu_ic->irq_shift);

		regmap_write_bits(scu_ic->scu, scu_ic->reg, mask,
				  BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT));
	}

	chained_irq_exit(chip, desc);
}

static void aspeed_scu_ic_irq_mask(struct irq_data *data)
{
	struct aspeed_scu_ic *scu_ic = irq_data_get_irq_chip_data(data);
	unsigned int mask = BIT(data->hwirq + scu_ic->irq_shift) |
		(scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT);

	/*
	 * Status bits are cleared by writing 1. In order to prevent the mask
	 * operation from clearing the status bits, they should be under the
	 * mask and written with 0.
	 */
	regmap_update_bits(scu_ic->scu, scu_ic->reg, mask, 0);
}

static void aspeed_scu_ic_irq_unmask(struct irq_data *data)
{
	struct aspeed_scu_ic *scu_ic = irq_data_get_irq_chip_data(data);
	unsigned int bit = BIT(data->hwirq + scu_ic->irq_shift);
	unsigned int mask = bit |
		(scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT);

	/*
	 * Status bits are cleared by writing 1. In order to prevent the unmask
	 * operation from clearing the status bits, they should be under the
	 * mask and written with 0.
	 */
	regmap_update_bits(scu_ic->scu, scu_ic->reg, mask, bit);
}

static int aspeed_scu_ic_irq_set_affinity(struct irq_data *data,
					  const struct cpumask *dest,
					  bool force)
{
	return -EINVAL;
}

static struct irq_chip aspeed_scu_ic_chip = {
	.name			= "aspeed-scu-ic",
	.irq_mask		= aspeed_scu_ic_irq_mask,
	.irq_unmask		= aspeed_scu_ic_irq_unmask,
	.irq_set_affinity	= aspeed_scu_ic_irq_set_affinity,
};

static int aspeed_scu_ic_map(struct irq_domain *domain, unsigned int irq,
			     irq_hw_number_t hwirq)
{
	irq_set_chip_and_handler(irq, &aspeed_scu_ic_chip, handle_level_irq);
	irq_set_chip_data(irq, domain->host_data);

	return 0;
}

static const struct irq_domain_ops aspeed_scu_ic_domain_ops = {
	.map = aspeed_scu_ic_map,
};

static int aspeed_scu_ic_of_init_common(struct aspeed_scu_ic *scu_ic,
					struct device_node *node)
{
	int irq;
	int rc = 0;

	if (!node->parent) {
		rc = -ENODEV;
		goto err;
	}

	scu_ic->scu = syscon_node_to_regmap(node->parent);
	if (IS_ERR(scu_ic->scu)) {
		rc = PTR_ERR(scu_ic->scu);
		goto err;
	}

	irq = irq_of_parse_and_map(node, 0);
	if (!irq) {
		rc = -EINVAL;
		goto err;
	}

	scu_ic->irq_domain = irq_domain_add_linear(node, scu_ic->num_irqs,
						   &aspeed_scu_ic_domain_ops,
						   scu_ic);
	if (!scu_ic->irq_domain) {
		rc = -ENOMEM;
		goto err;
	}

	irq_set_chained_handler_and_data(irq, aspeed_scu_ic_irq_handler,
					 scu_ic);

	return 0;

err:
	kfree(scu_ic);

	return rc;
}

static int __init aspeed_scu_ic_of_init(struct device_node *node,
					struct device_node *parent)
{
	struct aspeed_scu_ic *scu_ic = kzalloc(sizeof(*scu_ic), GFP_KERNEL);

	if (!scu_ic)
		return -ENOMEM;

	scu_ic->irq_enable = ASPEED_SCU_IC_ENABLE;
	scu_ic->irq_shift = ASPEED_SCU_IC_SHIFT;
	scu_ic->num_irqs = ASPEED_SCU_IC_NUM_IRQS;
	scu_ic->reg = ASPEED_SCU_IC_REG;

	return aspeed_scu_ic_of_init_common(scu_ic, node);
}

static int __init aspeed_ast2600_scu_ic0_of_init(struct device_node *node,
						 struct device_node *parent)
{
	struct aspeed_scu_ic *scu_ic = kzalloc(sizeof(*scu_ic), GFP_KERNEL);

	if (!scu_ic)
		return -ENOMEM;

	scu_ic->irq_enable = ASPEED_AST2600_SCU_IC0_ENABLE;
	scu_ic->irq_shift = ASPEED_AST2600_SCU_IC0_SHIFT;
	scu_ic->num_irqs = ASPEED_AST2600_SCU_IC0_NUM_IRQS;
	scu_ic->reg = ASPEED_AST2600_SCU_IC0_REG;

	return aspeed_scu_ic_of_init_common(scu_ic, node);
}

static int __init aspeed_ast2600_scu_ic1_of_init(struct device_node *node,
						 struct device_node *parent)
{
	struct aspeed_scu_ic *scu_ic = kzalloc(sizeof(*scu_ic), GFP_KERNEL);

	if (!scu_ic)
		return -ENOMEM;

	scu_ic->irq_enable = ASPEED_AST2600_SCU_IC1_ENABLE;
	scu_ic->irq_shift = ASPEED_AST2600_SCU_IC1_SHIFT;
	scu_ic->num_irqs = ASPEED_AST2600_SCU_IC1_NUM_IRQS;
	scu_ic->reg = ASPEED_AST2600_SCU_IC1_REG;

	return aspeed_scu_ic_of_init_common(scu_ic, node);
}

IRQCHIP_DECLARE(ast2400_scu_ic, "aspeed,ast2400-scu-ic", aspeed_scu_ic_of_init);
IRQCHIP_DECLARE(ast2500_scu_ic, "aspeed,ast2500-scu-ic", aspeed_scu_ic_of_init);
IRQCHIP_DECLARE(ast2600_scu_ic0, "aspeed,ast2600-scu-ic0",
		aspeed_ast2600_scu_ic0_of_init);
IRQCHIP_DECLARE(ast2600_scu_ic1, "aspeed,ast2600-scu-ic1",
		aspeed_ast2600_scu_ic1_of_init);
