// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2012 Freescale Semiconductor, Inc.
 *
 * Author: Varun Sethi <varun.sethi@freescale.com>
 */

#include <linux/irq.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mpic.h>

#include "mpic.h"

#define MPIC_ERR_INT_BASE	0x3900
#define MPIC_ERR_INT_EISR	0x0000
#define MPIC_ERR_INT_EIMR	0x0010

static inline u32 mpic_fsl_err_read(u32 __iomem *base, unsigned int err_reg)
{
	return in_be32(base + (err_reg >> 2));
}

static inline void mpic_fsl_err_write(u32 __iomem *base, u32 value)
{
	out_be32(base + (MPIC_ERR_INT_EIMR >> 2), value);
}

static void fsl_mpic_mask_err(struct irq_data *d)
{
	u32 eimr;
	struct mpic *mpic = irq_data_get_irq_chip_data(d);
	unsigned int src = virq_to_hw(d->irq) - mpic->err_int_vecs[0];

	eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
	eimr |= (1 << (31 - src));
	mpic_fsl_err_write(mpic->err_regs, eimr);
}

static void fsl_mpic_unmask_err(struct irq_data *d)
{
	u32 eimr;
	struct mpic *mpic = irq_data_get_irq_chip_data(d);
	unsigned int src = virq_to_hw(d->irq) - mpic->err_int_vecs[0];

	eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
	eimr &= ~(1 << (31 - src));
	mpic_fsl_err_write(mpic->err_regs, eimr);
}

static struct irq_chip fsl_mpic_err_chip = {
	.irq_disable	= fsl_mpic_mask_err,
	.irq_mask	= fsl_mpic_mask_err,
	.irq_unmask	= fsl_mpic_unmask_err,
};

int __init mpic_setup_error_int(struct mpic *mpic, int intvec)
{
	int i;

	mpic->err_regs = ioremap(mpic->paddr + MPIC_ERR_INT_BASE, 0x1000);
	if (!mpic->err_regs) {
		pr_err("could not map mpic error registers\n");
		return -ENOMEM;
	}
	mpic->hc_err = fsl_mpic_err_chip;
	mpic->hc_err.name = mpic->name;
	mpic->flags |= MPIC_FSL_HAS_EIMR;
	/* allocate interrupt vectors for error interrupts */
	for (i = MPIC_MAX_ERR - 1; i >= 0; i--)
		mpic->err_int_vecs[i] = intvec--;

	return 0;
}

int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t  hw)
{
	if ((mpic->flags & MPIC_FSL_HAS_EIMR) &&
	    (hw >= mpic->err_int_vecs[0] &&
	     hw <= mpic->err_int_vecs[MPIC_MAX_ERR - 1])) {
		WARN_ON(mpic->flags & MPIC_SECONDARY);

		pr_debug("mpic: mapping as Error Interrupt\n");
		irq_set_chip_data(virq, mpic);
		irq_set_chip_and_handler(virq, &mpic->hc_err,
					 handle_level_irq);
		return 1;
	}

	return 0;
}

static irqreturn_t fsl_error_int_handler(int irq, void *data)
{
	struct mpic *mpic = (struct mpic *) data;
	u32 eisr, eimr;
	int errint;

	eisr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EISR);
	eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);

	if (!(eisr & ~eimr))
		return IRQ_NONE;

	while (eisr) {
		int ret;
		errint = __builtin_clz(eisr);
		ret = generic_handle_domain_irq(mpic->irqhost,
						mpic->err_int_vecs[errint]);
		if (WARN_ON(ret)) {
			eimr |=  1 << (31 - errint);
			mpic_fsl_err_write(mpic->err_regs, eimr);
		}
		eisr &= ~(1 << (31 - errint));
	}

	return IRQ_HANDLED;
}

void __init mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum)
{
	unsigned int virq;
	int ret;

	virq = irq_create_mapping(mpic->irqhost, irqnum);
	if (!virq) {
		pr_err("Error interrupt setup failed\n");
		return;
	}

	/* Mask all error interrupts */
	mpic_fsl_err_write(mpic->err_regs, ~0);

	ret = request_irq(virq, fsl_error_int_handler, IRQF_NO_THREAD,
		    "mpic-error-int", mpic);
	if (ret)
		pr_err("Failed to register error interrupt handler\n");
}
