Commit fbdc674b authored by Paul Burton's avatar Paul Burton Committed by Ralf Baechle
Browse files

MIPS: SEAD-3: Set interrupt-parent per-device, not at root node



The SEAD-3 board may be configured with or without a MIPS Global
Interrupt Controller (GIC). Because of this we have a device tree with a
default case of a GIC present, and code to fixup the device tree based
upon a configuration register that indicates the presence of the GIC.

In order to keep this DT fixup code simple, the interrupt-parent
property was specified at the root node of the SEAD-3 DT, allowing the
fixup code to simply change this property to the phandle of the CPU
interrupt controller if a GIC is not present & affect all
interrupt-using devices at once. This however causes a problem if we do
have a GIC & the device tree is used as-is, because the interrupt-parent
property of the root node applies to the CPU interrupt controller node.
This causes a cycle when of_irq_init() attempts to probe interrupt
controllers in order and boots fail due to a lack of configured
interrupts, with this message printed on the kernel console:

[    0.000000] OF: of_irq_init: children remain, but no parents

Fix this by removing the interrupt-parent property from the DT root node
& instead setting it for each device which uses interrupts, ensuring
that the CPU interrupt controller node has no interrupt-parent &
allowing of_irq_init() to identify it as the root interrupt controller.

Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
Reported-by: default avatarKeng Koh <keng.koh@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16187/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 032a469b
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@
	#size-cells = <1>;
	compatible = "mti,sead-3";
	model = "MIPS SEAD-3";
	interrupt-parent = <&gic>;

	chosen {
		stdout-path = "serial1:115200";
@@ -60,6 +59,7 @@
		compatible = "generic-ehci";
		reg = <0x1b200000 0x1000>;

		interrupt-parent = <&gic>;
		interrupts = <0>; /* GIC 0 or CPU 6 */

		has-transaction-translator;
@@ -222,6 +222,7 @@

		clock-frequency = <14745600>;

		interrupt-parent = <&gic>;
		interrupts = <3>; /* GIC 3 or CPU 4 */

		no-loopback-test;
@@ -236,6 +237,7 @@

		clock-frequency = <14745600>;

		interrupt-parent = <&gic>;
		interrupts = <2>; /* GIC 2 or CPU 4 */

		no-loopback-test;
@@ -246,6 +248,7 @@
		reg = <0x1f010000 0x10000>;
		reg-io-width = <4>;

		interrupt-parent = <&gic>;
		interrupts = <0>; /* GIC 0 or CPU 6 */

		phy-mode = "mii";
+20 −6
Original line number Diff line number Diff line
@@ -87,14 +87,16 @@ static __init int remove_gic(void *fdt)
		return -EINVAL;
	}

	err = fdt_setprop_u32(fdt, 0, "interrupt-parent", cpu_phandle);
	uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a");
	while (uart_off >= 0) {
		err = fdt_setprop_u32(fdt, uart_off, "interrupt-parent",
				      cpu_phandle);
		if (err) {
		pr_err("unable to set root interrupt-parent: %d\n", err);
			pr_warn("unable to set UART interrupt-parent: %d\n",
				err);
			return err;
		}

	uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a");
	while (uart_off >= 0) {
		err = fdt_setprop_u32(fdt, uart_off, "interrupts",
				      cpu_uart_int);
		if (err) {
@@ -117,6 +119,12 @@ static __init int remove_gic(void *fdt)
		return eth_off;
	}

	err = fdt_setprop_u32(fdt, eth_off, "interrupt-parent", cpu_phandle);
	if (err) {
		pr_err("unable to set ethernet interrupt-parent: %d\n", err);
		return err;
	}

	err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int);
	if (err) {
		pr_err("unable to set ethernet interrupts property: %d\n", err);
@@ -129,6 +137,12 @@ static __init int remove_gic(void *fdt)
		return ehci_off;
	}

	err = fdt_setprop_u32(fdt, ehci_off, "interrupt-parent", cpu_phandle);
	if (err) {
		pr_err("unable to set EHCI interrupt-parent: %d\n", err);
		return err;
	}

	err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int);
	if (err) {
		pr_err("unable to set EHCI interrupts property: %d\n", err);