forked from luck/tmp_suning_uos_patched
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: Paul Burton <paul.burton@imgtec.com> Reported-by: Keng Koh <keng.koh@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/16187/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
032a469b1e
commit
fbdc674ba3
|
@ -11,7 +11,6 @@ / {
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "mti,sead-3";
|
compatible = "mti,sead-3";
|
||||||
model = "MIPS SEAD-3";
|
model = "MIPS SEAD-3";
|
||||||
interrupt-parent = <&gic>;
|
|
||||||
|
|
||||||
chosen {
|
chosen {
|
||||||
stdout-path = "serial1:115200";
|
stdout-path = "serial1:115200";
|
||||||
|
@ -60,6 +59,7 @@ ehci@1b200000 {
|
||||||
compatible = "generic-ehci";
|
compatible = "generic-ehci";
|
||||||
reg = <0x1b200000 0x1000>;
|
reg = <0x1b200000 0x1000>;
|
||||||
|
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
interrupts = <0>; /* GIC 0 or CPU 6 */
|
interrupts = <0>; /* GIC 0 or CPU 6 */
|
||||||
|
|
||||||
has-transaction-translator;
|
has-transaction-translator;
|
||||||
|
@ -222,6 +222,7 @@ uart0: uart@1f000900 {
|
||||||
|
|
||||||
clock-frequency = <14745600>;
|
clock-frequency = <14745600>;
|
||||||
|
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
interrupts = <3>; /* GIC 3 or CPU 4 */
|
interrupts = <3>; /* GIC 3 or CPU 4 */
|
||||||
|
|
||||||
no-loopback-test;
|
no-loopback-test;
|
||||||
|
@ -236,6 +237,7 @@ uart1: uart@1f000800 {
|
||||||
|
|
||||||
clock-frequency = <14745600>;
|
clock-frequency = <14745600>;
|
||||||
|
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
interrupts = <2>; /* GIC 2 or CPU 4 */
|
interrupts = <2>; /* GIC 2 or CPU 4 */
|
||||||
|
|
||||||
no-loopback-test;
|
no-loopback-test;
|
||||||
|
@ -246,6 +248,7 @@ eth@1f010000 {
|
||||||
reg = <0x1f010000 0x10000>;
|
reg = <0x1f010000 0x10000>;
|
||||||
reg-io-width = <4>;
|
reg-io-width = <4>;
|
||||||
|
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
interrupts = <0>; /* GIC 0 or CPU 6 */
|
interrupts = <0>; /* GIC 0 or CPU 6 */
|
||||||
|
|
||||||
phy-mode = "mii";
|
phy-mode = "mii";
|
||||||
|
|
|
@ -87,14 +87,16 @@ static __init int remove_gic(void *fdt)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fdt_setprop_u32(fdt, 0, "interrupt-parent", cpu_phandle);
|
|
||||||
if (err) {
|
|
||||||
pr_err("unable to set root interrupt-parent: %d\n", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a");
|
uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a");
|
||||||
while (uart_off >= 0) {
|
while (uart_off >= 0) {
|
||||||
|
err = fdt_setprop_u32(fdt, uart_off, "interrupt-parent",
|
||||||
|
cpu_phandle);
|
||||||
|
if (err) {
|
||||||
|
pr_warn("unable to set UART interrupt-parent: %d\n",
|
||||||
|
err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
err = fdt_setprop_u32(fdt, uart_off, "interrupts",
|
err = fdt_setprop_u32(fdt, uart_off, "interrupts",
|
||||||
cpu_uart_int);
|
cpu_uart_int);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -117,6 +119,12 @@ static __init int remove_gic(void *fdt)
|
||||||
return eth_off;
|
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);
|
err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("unable to set ethernet interrupts property: %d\n", 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;
|
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);
|
err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("unable to set EHCI interrupts property: %d\n", err);
|
pr_err("unable to set EHCI interrupts property: %d\n", err);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user