// SPDX-License-Identifier: GPL-2.0
/*
 * Loongson LPC Interrupt Controller support
 *
 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
 */

#define pr_fmt(fmt) "lpc: " fmt

#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>

/* Registers */
#define LPC_INT_CTL		0x00
#define LPC_INT_ENA		0x04
#define LPC_INT_STS		0x08
#define LPC_INT_CLR		0x0c
#define LPC_INT_POL		0x10
#define LPC_COUNT		16

/* LPC_INT_CTL */
#define LPC_INT_CTL_EN		BIT(31)

struct pch_lpc {
	void __iomem		*base;
	struct irq_domain	*lpc_domain;
	raw_spinlock_t		lpc_lock;
	u32			saved_reg_ctl;
	u32			saved_reg_ena;
	u32			saved_reg_pol;
};

struct fwnode_handle *pch_lpc_handle;

static void lpc_irq_ack(struct irq_data *d)
{
	unsigned long flags;
	struct pch_lpc *priv = d->domain->host_data;

	raw_spin_lock_irqsave(&priv->lpc_lock, flags);
	writel(0x1 << d->hwirq, priv->base + LPC_INT_CLR);
	raw_spin_unlock_irqrestore(&priv->lpc_lock, flags);
}

static void lpc_irq_mask(struct irq_data *d)
{
	unsigned long flags;
	struct pch_lpc *priv = d->domain->host_data;

	raw_spin_lock_irqsave(&priv->lpc_lock, flags);
	writel(readl(priv->base + LPC_INT_ENA) & (~(0x1 << (d->hwirq))),
			priv->base + LPC_INT_ENA);
	raw_spin_unlock_irqrestore(&priv->lpc_lock, flags);
}

static void lpc_irq_unmask(struct irq_data *d)
{
	unsigned long flags;
	struct pch_lpc *priv = d->domain->host_data;

	raw_spin_lock_irqsave(&priv->lpc_lock, flags);
	writel(readl(priv->base + LPC_INT_ENA) | (0x1 << (d->hwirq)),
			priv->base + LPC_INT_ENA);
	raw_spin_unlock_irqrestore(&priv->lpc_lock, flags);
}

static int lpc_irq_set_type(struct irq_data *d, unsigned int type)
{
	u32 val;
	u32 mask = 0x1 << (d->hwirq);
	struct pch_lpc *priv = d->domain->host_data;

	if (!(type & IRQ_TYPE_LEVEL_MASK))
		return 0;

	val = readl(priv->base + LPC_INT_POL);

	if (type == IRQ_TYPE_LEVEL_HIGH)
		val |= mask;
	else
		val &= ~mask;

	writel(val, priv->base + LPC_INT_POL);

	return 0;
}

static const struct irq_chip pch_lpc_irq_chip = {
	.name			= "PCH LPC",
	.irq_mask		= lpc_irq_mask,
	.irq_unmask		= lpc_irq_unmask,
	.irq_ack		= lpc_irq_ack,
	.irq_set_type		= lpc_irq_set_type,
	.flags			= IRQCHIP_SKIP_SET_WAKE,
};

static void lpc_irq_dispatch(struct irq_desc *desc)
{
	u32 pending, bit;
	struct irq_chip *chip = irq_desc_get_chip(desc);
	struct pch_lpc *priv = irq_desc_get_handler_data(desc);

	chained_irq_enter(chip, desc);

	pending = readl(priv->base + LPC_INT_ENA);
	pending &= readl(priv->base + LPC_INT_STS);
	if (!pending)
		spurious_interrupt();

	while (pending) {
		bit = __ffs(pending);

		generic_handle_domain_irq(priv->lpc_domain, bit);
		pending &= ~BIT(bit);
	}
	chained_irq_exit(chip, desc);
}

static int pch_lpc_map(struct irq_domain *d, unsigned int irq,
			irq_hw_number_t hw)
{
	irq_set_chip_and_handler(irq, &pch_lpc_irq_chip, handle_level_irq);
	return 0;
}

static const struct irq_domain_ops pch_lpc_domain_ops = {
	.map 		= pch_lpc_map,
	.translate	= irq_domain_translate_twocell,
};

static void pch_lpc_reset(struct pch_lpc *priv)
{
	/* Enable the LPC interrupt, bit31: en  bit30: edge */
	writel(LPC_INT_CTL_EN, priv->base + LPC_INT_CTL);
	writel(0, priv->base + LPC_INT_ENA);
	/* Clear all 18-bit interrpt bit */
	writel(GENMASK(17, 0), priv->base + LPC_INT_CLR);
}

static int pch_lpc_disabled(struct pch_lpc *priv)
{
	return (readl(priv->base + LPC_INT_ENA) == 0xffffffff) &&
			(readl(priv->base + LPC_INT_STS) == 0xffffffff);
}

int __init pch_lpc_acpi_init(struct irq_domain *parent,
					struct acpi_madt_lpc_pic *acpi_pchlpc)
{
	int parent_irq;
	struct pch_lpc *priv;
	struct irq_fwspec fwspec;
	struct fwnode_handle *irq_handle;

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

	raw_spin_lock_init(&priv->lpc_lock);

	priv->base = ioremap(acpi_pchlpc->address, acpi_pchlpc->size);
	if (!priv->base)
		goto free_priv;

	if (pch_lpc_disabled(priv)) {
		pr_err("Failed to get LPC status\n");
		goto iounmap_base;
	}

	irq_handle = irq_domain_alloc_named_fwnode("lpcintc");
	if (!irq_handle) {
		pr_err("Unable to allocate domain handle\n");
		goto iounmap_base;
	}

	priv->lpc_domain = irq_domain_create_linear(irq_handle, LPC_COUNT,
					&pch_lpc_domain_ops, priv);
	if (!priv->lpc_domain) {
		pr_err("Failed to create IRQ domain\n");
		goto free_irq_handle;
	}
	pch_lpc_reset(priv);

	fwspec.fwnode = parent->fwnode;
	fwspec.param[0] = acpi_pchlpc->cascade + GSI_MIN_PCH_IRQ;
	fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH;
	fwspec.param_count = 2;
	parent_irq = irq_create_fwspec_mapping(&fwspec);
	irq_set_chained_handler_and_data(parent_irq, lpc_irq_dispatch, priv);

	pch_lpc_handle = irq_handle;
	return 0;

free_irq_handle:
	irq_domain_free_fwnode(irq_handle);
iounmap_base:
	iounmap(priv->base);
free_priv:
	kfree(priv);

	return -ENOMEM;
}
