// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Interrupt management for most GSC and related devices.
 *
 * (c) Copyright 1999 Alex deVries for The Puffin Group
 * (c) Copyright 1999 Grant Grundler for Hewlett-Packard
 * (c) Copyright 1999 Matthew Wilcox
 * (c) Copyright 2000 Helge Deller
 * (c) Copyright 2001 Matthew Wilcox for Hewlett-Packard
 */

#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/types.h>

#include <asm/hardware.h>
#include <asm/io.h>

#include "gsc.h"

#undef DEBUG

#ifdef DEBUG
#define DEBPRINTK printk
#else
#define DEBPRINTK(x,...)
#endif

int gsc_alloc_irq(struct gsc_irq *i)
{
	int irq = txn_alloc_irq(GSC_EIM_WIDTH);
	if (irq < 0) {
		printk("cannot get irq\n");
		return irq;
	}

	i->txn_addr = txn_alloc_addr(irq);
	i->txn_data = txn_alloc_data(irq);
	i->irq = irq;

	return irq;
}

int gsc_claim_irq(struct gsc_irq *i, int irq)
{
	int c = irq;

	irq += CPU_IRQ_BASE; /* virtualize the IRQ first */

	irq = txn_claim_irq(irq);
	if (irq < 0) {
		printk("cannot claim irq %d\n", c);
		return irq;
	}

	i->txn_addr = txn_alloc_addr(irq);
	i->txn_data = txn_alloc_data(irq);
	i->irq = irq;

	return irq;
}

EXPORT_SYMBOL(gsc_alloc_irq);
EXPORT_SYMBOL(gsc_claim_irq);

/* Common interrupt demultiplexer used by Asp, Lasi & Wax.  */
irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev)
{
	unsigned long irr;
	struct gsc_asic *gsc_asic = dev;

	irr = gsc_readl(gsc_asic->hpa + OFFSET_IRR);
	if (irr == 0)
		return IRQ_NONE;

	DEBPRINTK("%s intr, mask=0x%x\n", gsc_asic->name, irr);

	do {
		int local_irq = __ffs(irr);
		unsigned int irq = gsc_asic->global_irq[local_irq];
		generic_handle_irq(irq);
		irr &= ~(1 << local_irq);
	} while (irr);

	return IRQ_HANDLED;
}

int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit)
{
	int local_irq;

	for (local_irq = 0; local_irq < limit; local_irq++) {
		if (global_irqs[local_irq] == irq)
			return local_irq;
	}

	return NO_IRQ;
}

static void gsc_asic_mask_irq(struct irq_data *d)
{
	struct gsc_asic *irq_dev = irq_data_get_irq_chip_data(d);
	int local_irq = gsc_find_local_irq(d->irq, irq_dev->global_irq, 32);
	u32 imr;

	DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, d->irq,
			irq_dev->name, imr);

	/* Disable the IRQ line by clearing the bit in the IMR */
	imr = gsc_readl(irq_dev->hpa + OFFSET_IMR);
	imr &= ~(1 << local_irq);
	gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
}

static void gsc_asic_unmask_irq(struct irq_data *d)
{
	struct gsc_asic *irq_dev = irq_data_get_irq_chip_data(d);
	int local_irq = gsc_find_local_irq(d->irq, irq_dev->global_irq, 32);
	u32 imr;

	DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, d->irq,
			irq_dev->name, imr);

	/* Enable the IRQ line by setting the bit in the IMR */
	imr = gsc_readl(irq_dev->hpa + OFFSET_IMR);
	imr |= 1 << local_irq;
	gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
	/*
	 * FIXME: read IPR to make sure the IRQ isn't already pending.
	 *   If so, we need to read IRR and manually call do_irq().
	 */
}

#ifdef CONFIG_SMP
static int gsc_set_affinity_irq(struct irq_data *d, const struct cpumask *dest,
				bool force)
{
	struct gsc_asic *gsc_dev = irq_data_get_irq_chip_data(d);
	struct cpumask tmask;
	int cpu_irq;

	if (!cpumask_and(&tmask, dest, cpu_online_mask))
		return -EINVAL;

	cpu_irq = cpu_check_affinity(d, &tmask);
	if (cpu_irq < 0)
		return cpu_irq;

	gsc_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq);
	gsc_dev->eim = ((u32) gsc_dev->gsc_irq.txn_addr) | gsc_dev->gsc_irq.txn_data;

	/* switch IRQ's for devices below LASI/WAX to other CPU */
	/* ASP chip (svers 0x70) does not support reprogramming */
	if (gsc_dev->gsc->id.sversion != 0x70)
		gsc_writel(gsc_dev->eim, gsc_dev->hpa + OFFSET_IAR);

	irq_data_update_effective_affinity(d, &tmask);

	return IRQ_SET_MASK_OK;
}
#endif


static struct irq_chip gsc_asic_interrupt_type = {
	.name		=	"GSC-ASIC",
	.irq_unmask	=	gsc_asic_unmask_irq,
	.irq_mask	=	gsc_asic_mask_irq,
#ifdef CONFIG_SMP
	.irq_set_affinity =	gsc_set_affinity_irq,
#endif
};

int gsc_assign_irq(struct irq_chip *type, void *data)
{
	static int irq = GSC_IRQ_BASE;

	if (irq > GSC_IRQ_MAX)
		return NO_IRQ;

	irq_set_chip_and_handler(irq, type, handle_simple_irq);
	irq_set_chip_data(irq, data);

	return irq++;
}

void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp)
{
	int irq = asic->global_irq[local_irq];
	
	if (irq <= 0) {
		irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic);
		if (irq == NO_IRQ)
			return;

		asic->global_irq[local_irq] = irq;
	}
	*irqp = irq;
}

struct gsc_fixup_struct {
	void (*choose_irq)(struct parisc_device *, void *);
	void *ctrl;
};

static int gsc_fixup_irqs_callback(struct device *dev, void *data)
{
	struct parisc_device *padev = to_parisc_device(dev);
	struct gsc_fixup_struct *gf = data;

	/* work-around for 715/64 and others which have parent
	   at path [5] and children at path [5/0/x] */
	if (padev->id.hw_type == HPHW_FAULTY)
		gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq);
	gf->choose_irq(padev, gf->ctrl);

	return 0;
}

void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
			void (*choose_irq)(struct parisc_device *, void *))
{
	struct gsc_fixup_struct data = {
		.choose_irq	= choose_irq,
		.ctrl		= ctrl,
	};

	device_for_each_child(&parent->dev, &data, gsc_fixup_irqs_callback);
}

int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
{
	struct resource *res;
	int i;

	gsc_asic->gsc = parent;

	/* Initialise local irq -> global irq mapping */
	for (i = 0; i < 32; i++) {
		gsc_asic->global_irq[i] = NO_IRQ;
	}

	/* allocate resource region */
	res = request_mem_region(gsc_asic->hpa, 0x100000, gsc_asic->name);
	if (res) {
		res->flags = IORESOURCE_MEM; 	/* do not mark it busy ! */
	}

#if 0
	printk(KERN_WARNING "%s IRQ %d EIM 0x%x", gsc_asic->name,
			parent->irq, gsc_asic->eim);
	if (gsc_readl(gsc_asic->hpa + OFFSET_IMR))
		printk("  IMR is non-zero! (0x%x)",
				gsc_readl(gsc_asic->hpa + OFFSET_IMR));
	printk("\n");
#endif

	return 0;
}
