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

Commit 50246787 authored by Darren Stevens's avatar Darren Stevens Committed by Michael Ellerman
Browse files

powerpc/pasemi: Fix Nemo SB600 i8259 interrupts.



The device tree on the Nemo passes all of the i8259 interrupts with
numbers between 212 and 222, and points their interrupt-parent property
to the pasemi-opic, requiring custom patches to the kernel. Fix the
values so that they can be controlled by the generic ppc i8259 code.

Signed-off-by: default avatarDarren Stevens <darren@stevens-zone.net>
[mpe: Rework deeply nested if and boundary checks]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 88c13e2f
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
@@ -2644,6 +2644,70 @@ static void __init fixup_device_tree_efika(void)
#define fixup_device_tree_efika()
#endif

#ifdef CONFIG_PPC_PASEMI_NEMO
/*
 * CFE supplied on Nemo is broken in several ways, biggest
 * problem is that it reassigns ISA interrupts to unused mpic ints.
 * Add an interrupt-controller property for the io-bridge to use
 * and correct the ints so we can attach them to an irq_domain
 */
static void __init fixup_device_tree_pasemi(void)
{
	u32 interrupts[2], parent, rval, val = 0;
	char *name, *pci_name;
	phandle iob, node;

	/* Find the root pci node */
	name = "/pxp@0,e0000000";
	iob = call_prom("finddevice", 1, 1, ADDR(name));
	if (!PHANDLE_VALID(iob))
		return;

	/* check if interrupt-controller node set yet */
	if (prom_getproplen(iob, "interrupt-controller") !=PROM_ERROR)
		return;

	prom_printf("adding interrupt-controller property for SB600...\n");

	prom_setprop(iob, name, "interrupt-controller", &val, 0);

	pci_name = "/pxp@0,e0000000/pci@11";
	node = call_prom("finddevice", 1, 1, ADDR(pci_name));
	parent = ADDR(iob);

	for( ; prom_next_node(&node); ) {
		/* scan each node for one with an interrupt */
		if (!PHANDLE_VALID(node))
			continue;

		rval = prom_getproplen(node, "interrupts");
		if (rval == 0 || rval == PROM_ERROR)
			continue;

		prom_getprop(node, "interrupts", &interrupts, sizeof(interrupts));
		if ((interrupts[0] < 212) || (interrupts[0] > 222))
			continue;

		/* found a node, update both interrupts and interrupt-parent */
		if ((interrupts[0] >= 212) && (interrupts[0] <= 215))
			interrupts[0] -= 203;
		if ((interrupts[0] >= 216) && (interrupts[0] <= 220))
			interrupts[0] -= 213;
		if (interrupts[0] == 221)
			interrupts[0] = 14;
		if (interrupts[0] == 222)
			interrupts[0] = 8;

		prom_setprop(node, pci_name, "interrupts", interrupts,
					sizeof(interrupts));
		prom_setprop(node, pci_name, "interrupt-parent", &parent,
					sizeof(parent));
	}
}
#else	/* !CONFIG_PPC_PASEMI_NEMO */
static inline void fixup_device_tree_pasemi(void) { }
#endif

static void __init fixup_device_tree(void)
{
	fixup_device_tree_maple();
@@ -2651,6 +2715,7 @@ static void __init fixup_device_tree(void)
	fixup_device_tree_chrp();
	fixup_device_tree_pmac();
	fixup_device_tree_efika();
	fixup_device_tree_pasemi();
}

static void __init prom_find_boot_cpu(void)