// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2024 Inochi Amaoto <inochiama@gmail.com>
 */

#define pr_fmt(fmt) "thead-c900-aclint-sswi: " fmt
#include <linux/cpu.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/smp.h>
#include <linux/string_choices.h>
#include <asm/sbi.h>
#include <asm/vendorid_list.h>

#define THEAD_ACLINT_xSWI_REGISTER_SIZE		4

#define THEAD_C9XX_CSR_SXSTATUS			0x5c0
#define THEAD_C9XX_SXSTATUS_CLINTEE		BIT(17)

static int sswi_ipi_virq __ro_after_init;
static DEFINE_PER_CPU(void __iomem *, sswi_cpu_regs);

static void thead_aclint_sswi_ipi_send(unsigned int cpu)
{
	writel(0x1, per_cpu(sswi_cpu_regs, cpu));
}

static void thead_aclint_sswi_ipi_clear(void)
{
	writel_relaxed(0x0, this_cpu_read(sswi_cpu_regs));
}

static void thead_aclint_sswi_ipi_handle(struct irq_desc *desc)
{
	struct irq_chip *chip = irq_desc_get_chip(desc);

	chained_irq_enter(chip, desc);

	csr_clear(CSR_IP, IE_SIE);
	thead_aclint_sswi_ipi_clear();

	ipi_mux_process();

	chained_irq_exit(chip, desc);
}

static int thead_aclint_sswi_starting_cpu(unsigned int cpu)
{
	enable_percpu_irq(sswi_ipi_virq, irq_get_trigger_type(sswi_ipi_virq));

	return 0;
}

static int thead_aclint_sswi_dying_cpu(unsigned int cpu)
{
	thead_aclint_sswi_ipi_clear();

	disable_percpu_irq(sswi_ipi_virq);

	return 0;
}

static int __init thead_aclint_sswi_parse_irq(struct fwnode_handle *fwnode,
					      void __iomem *reg)
{
	struct of_phandle_args parent;
	unsigned long hartid;
	u32 contexts, i;
	int rc, cpu;

	contexts = of_irq_count(to_of_node(fwnode));
	if (!(contexts)) {
		pr_err("%pfwP: no ACLINT SSWI context available\n", fwnode);
		return -EINVAL;
	}

	for (i = 0; i < contexts; i++) {
		rc = of_irq_parse_one(to_of_node(fwnode), i, &parent);
		if (rc)
			return rc;

		rc = riscv_of_parent_hartid(parent.np, &hartid);
		if (rc)
			return rc;

		if (parent.args[0] != RV_IRQ_SOFT)
			return -ENOTSUPP;

		cpu = riscv_hartid_to_cpuid(hartid);

		per_cpu(sswi_cpu_regs, cpu) = reg + i * THEAD_ACLINT_xSWI_REGISTER_SIZE;
	}

	pr_info("%pfwP: register %u CPU%s\n", fwnode, contexts, str_plural(contexts));

	return 0;
}

static int __init thead_aclint_sswi_probe(struct fwnode_handle *fwnode)
{
	struct irq_domain *domain;
	void __iomem *reg;
	int virq, rc;

	/* If it is T-HEAD CPU, check whether SSWI is enabled */
	if (riscv_cached_mvendorid(0) == THEAD_VENDOR_ID &&
	    !(csr_read(THEAD_C9XX_CSR_SXSTATUS) & THEAD_C9XX_SXSTATUS_CLINTEE))
		return -ENOTSUPP;

	if (!is_of_node(fwnode))
		return -EINVAL;

	reg = of_iomap(to_of_node(fwnode), 0);
	if (!reg)
		return -ENOMEM;

	/* Parse SSWI setting */
	rc = thead_aclint_sswi_parse_irq(fwnode, reg);
	if (rc < 0)
		return rc;

	/* If mulitple SSWI devices are present, do not register irq again */
	if (sswi_ipi_virq)
		return 0;

	/* Find riscv intc domain and create IPI irq mapping */
	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
	if (!domain) {
		pr_err("%pfwP: Failed to find INTC domain\n", fwnode);
		return -ENOENT;
	}

	sswi_ipi_virq = irq_create_mapping(domain, RV_IRQ_SOFT);
	if (!sswi_ipi_virq) {
		pr_err("unable to create ACLINT SSWI IRQ mapping\n");
		return -ENOMEM;
	}

	/* Register SSWI irq and handler */
	virq = ipi_mux_create(BITS_PER_BYTE, thead_aclint_sswi_ipi_send);
	if (virq <= 0) {
		pr_err("unable to create muxed IPIs\n");
		irq_dispose_mapping(sswi_ipi_virq);
		return virq < 0 ? virq : -ENOMEM;
	}

	irq_set_chained_handler(sswi_ipi_virq, thead_aclint_sswi_ipi_handle);

	cpuhp_setup_state(CPUHP_AP_IRQ_THEAD_ACLINT_SSWI_STARTING,
			  "irqchip/thead-aclint-sswi:starting",
			  thead_aclint_sswi_starting_cpu,
			  thead_aclint_sswi_dying_cpu);

	riscv_ipi_set_virq_range(virq, BITS_PER_BYTE);

	/* Announce that SSWI is providing IPIs */
	pr_info("providing IPIs using THEAD ACLINT SSWI\n");

	return 0;
}

static int __init thead_aclint_sswi_early_probe(struct device_node *node,
						struct device_node *parent)
{
	return thead_aclint_sswi_probe(&node->fwnode);
}
IRQCHIP_DECLARE(thead_aclint_sswi, "thead,c900-aclint-sswi", thead_aclint_sswi_early_probe);
