// SPDX-License-Identifier: GPL-2.0
/*
 * StarFive JH8100 External Interrupt Controller driver
 *
 * Copyright (C) 2023 StarFive Technology Co., Ltd.
 *
 * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
 */

#define pr_fmt(fmt) "irq-starfive-jh8100: " fmt

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/reset.h>
#include <linux/spinlock.h>

#define STARFIVE_INTC_SRC0_CLEAR	0x10
#define STARFIVE_INTC_SRC0_MASK		0x14
#define STARFIVE_INTC_SRC0_INT		0x1c

#define STARFIVE_INTC_SRC_IRQ_NUM	32

struct starfive_irq_chip {
	void __iomem		*base;
	struct irq_domain	*domain;
	raw_spinlock_t		lock;
};

static void starfive_intc_bit_set(struct starfive_irq_chip *irqc,
				  u32 reg, u32 bit_mask)
{
	u32 value;

	value = ioread32(irqc->base + reg);
	value |= bit_mask;
	iowrite32(value, irqc->base + reg);
}

static void starfive_intc_bit_clear(struct starfive_irq_chip *irqc,
				    u32 reg, u32 bit_mask)
{
	u32 value;

	value = ioread32(irqc->base + reg);
	value &= ~bit_mask;
	iowrite32(value, irqc->base + reg);
}

static void starfive_intc_unmask(struct irq_data *d)
{
	struct starfive_irq_chip *irqc = irq_data_get_irq_chip_data(d);

	raw_spin_lock(&irqc->lock);
	starfive_intc_bit_clear(irqc, STARFIVE_INTC_SRC0_MASK, BIT(d->hwirq));
	raw_spin_unlock(&irqc->lock);
}

static void starfive_intc_mask(struct irq_data *d)
{
	struct starfive_irq_chip *irqc = irq_data_get_irq_chip_data(d);

	raw_spin_lock(&irqc->lock);
	starfive_intc_bit_set(irqc, STARFIVE_INTC_SRC0_MASK, BIT(d->hwirq));
	raw_spin_unlock(&irqc->lock);
}

static struct irq_chip intc_dev = {
	.name		= "StarFive JH8100 INTC",
	.irq_unmask	= starfive_intc_unmask,
	.irq_mask	= starfive_intc_mask,
};

static int starfive_intc_map(struct irq_domain *d, unsigned int irq,
			     irq_hw_number_t hwirq)
{
	irq_domain_set_info(d, irq, hwirq, &intc_dev, d->host_data,
			    handle_level_irq, NULL, NULL);

	return 0;
}

static const struct irq_domain_ops starfive_intc_domain_ops = {
	.xlate	= irq_domain_xlate_onecell,
	.map	= starfive_intc_map,
};

static void starfive_intc_irq_handler(struct irq_desc *desc)
{
	struct starfive_irq_chip *irqc = irq_data_get_irq_handler_data(&desc->irq_data);
	struct irq_chip *chip = irq_desc_get_chip(desc);
	unsigned long value;
	int hwirq;

	chained_irq_enter(chip, desc);

	value = ioread32(irqc->base + STARFIVE_INTC_SRC0_INT);
	while (value) {
		hwirq = ffs(value) - 1;

		generic_handle_domain_irq(irqc->domain, hwirq);

		starfive_intc_bit_set(irqc, STARFIVE_INTC_SRC0_CLEAR, BIT(hwirq));
		starfive_intc_bit_clear(irqc, STARFIVE_INTC_SRC0_CLEAR, BIT(hwirq));

		__clear_bit(hwirq, &value);
	}

	chained_irq_exit(chip, desc);
}

static int __init starfive_intc_init(struct device_node *intc,
				     struct device_node *parent)
{
	struct starfive_irq_chip *irqc;
	struct reset_control *rst;
	struct clk *clk;
	int parent_irq;
	int ret;

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

	irqc->base = of_iomap(intc, 0);
	if (!irqc->base) {
		pr_err("Unable to map registers\n");
		ret = -ENXIO;
		goto err_free;
	}

	rst = of_reset_control_get_exclusive(intc, NULL);
	if (IS_ERR(rst)) {
		pr_err("Unable to get reset control %pe\n", rst);
		ret = PTR_ERR(rst);
		goto err_unmap;
	}

	clk = of_clk_get(intc, 0);
	if (IS_ERR(clk)) {
		pr_err("Unable to get clock %pe\n", clk);
		ret = PTR_ERR(clk);
		goto err_reset_put;
	}

	ret = reset_control_deassert(rst);
	if (ret)
		goto err_clk_put;

	ret = clk_prepare_enable(clk);
	if (ret)
		goto err_reset_assert;

	raw_spin_lock_init(&irqc->lock);

	irqc->domain = irq_domain_add_linear(intc, STARFIVE_INTC_SRC_IRQ_NUM,
					     &starfive_intc_domain_ops, irqc);
	if (!irqc->domain) {
		pr_err("Unable to create IRQ domain\n");
		ret = -EINVAL;
		goto err_clk_disable;
	}

	parent_irq = of_irq_get(intc, 0);
	if (parent_irq < 0) {
		pr_err("Failed to get main IRQ: %d\n", parent_irq);
		ret = parent_irq;
		goto err_remove_domain;
	}

	irq_set_chained_handler_and_data(parent_irq, starfive_intc_irq_handler,
					 irqc);

	pr_info("Interrupt controller register, nr_irqs %d\n",
		STARFIVE_INTC_SRC_IRQ_NUM);

	return 0;

err_remove_domain:
	irq_domain_remove(irqc->domain);
err_clk_disable:
	clk_disable_unprepare(clk);
err_reset_assert:
	reset_control_assert(rst);
err_clk_put:
	clk_put(clk);
err_reset_put:
	reset_control_put(rst);
err_unmap:
	iounmap(irqc->base);
err_free:
	kfree(irqc);
	return ret;
}

IRQCHIP_PLATFORM_DRIVER_BEGIN(starfive_intc)
IRQCHIP_MATCH("starfive,jh8100-intc", starfive_intc_init)
IRQCHIP_PLATFORM_DRIVER_END(starfive_intc)

MODULE_DESCRIPTION("StarFive JH8100 External Interrupt Controller");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
