Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b29e8b87 authored by Alban Bedel's avatar Alban Bedel Committed by Ralf Baechle
Browse files

MIPS: ath79: Add OF support to the IRQ controllers



Add OF support for the CPU and MISC interrupt controllers of most
supported ATH79 devices.

Signed-off-by: default avatarAlban Bedel <albeu@free.fr>
Cc: linux-mips@linux-mips.org
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent bb35586f
Loading
Loading
Loading
Loading
+86 −1
Original line number Original line Diff line number Diff line
@@ -15,7 +15,9 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/of_irq.h>
#include "../../../drivers/irqchip/irqchip.h"


#include <asm/irq_cpu.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <asm/mipsregs.h>
@@ -23,6 +25,7 @@
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include "common.h"
#include "common.h"
#include "machtypes.h"


static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
{
{
@@ -268,8 +271,90 @@ asmlinkage void plat_irq_dispatch(void)
	}
	}
}
}


#ifdef CONFIG_IRQCHIP
static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
{
	irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
	return 0;
}

static const struct irq_domain_ops misc_irq_domain_ops = {
	.xlate = irq_domain_xlate_onecell,
	.map = misc_map,
};

static int __init ath79_misc_intc_of_init(
	struct device_node *node, struct device_node *parent)
{
	void __iomem *base = ath79_reset_base;
	struct irq_domain *domain;
	int irq;

	irq = irq_of_parse_and_map(node, 0);
	if (!irq)
		panic("Failed to get MISC IRQ");

	domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
			ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL);
	if (!domain)
		panic("Failed to add MISC irqdomain");

	/* Disable and clear all interrupts */
	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);


	irq_set_chained_handler(irq, ath79_misc_irq_handler);

	return 0;
}
IRQCHIP_DECLARE(ath79_misc_intc, "qca,ar7100-misc-intc",
		ath79_misc_intc_of_init);

static int __init ar79_cpu_intc_of_init(
	struct device_node *node, struct device_node *parent)
{
	int err, i, count;

	/* Fill the irq_wb_chan table */
	count = of_count_phandle_with_args(
		node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");

	for (i = 0; i < count; i++) {
		struct of_phandle_args args;
		u32 irq = i;

		of_property_read_u32_index(
			node, "qca,ddr-wb-channel-interrupts", i, &irq);
		if (irq >= ARRAY_SIZE(irq_wb_chan))
			continue;

		err = of_parse_phandle_with_args(
			node, "qca,ddr-wb-channels",
			"#qca,ddr-wb-channel-cells",
			i, &args);
		if (err)
			return err;

		irq_wb_chan[irq] = args.args[0];
		pr_info("IRQ: Set flush channel of IRQ%d to %d\n",
			irq, args.args[0]);
	}

	return mips_cpu_irq_of_init(node, parent);
}
IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
		ar79_cpu_intc_of_init);

#endif

void __init arch_init_irq(void)
void __init arch_init_irq(void)
{
{
	if (mips_machtype == ATH79_MACH_GENERIC_OF) {
		irqchip_init();
		return;
	}

	if (soc_is_ar71xx() || soc_is_ar724x() ||
	if (soc_is_ar71xx() || soc_is_ar724x() ||
	    soc_is_ar913x() || soc_is_ar933x()) {
	    soc_is_ar913x() || soc_is_ar933x()) {
		irq_wb_chan[2] = 3;
		irq_wb_chan[2] = 3;