summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-08-23 21:08:12 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-08-23 21:08:12 -0700
commitccc712fe6b2acbafe9fc31f765a193e3249ca4a1 (patch)
tree9e1a4052a69203baf1e866af4536ca9ceb904fa6
parent9c637646dafd82370c284ce7fcc8b4ba2546dfb1 (diff)
parentc9169f8747bb282cbe518132bf7d49755a00b6c1 (diff)
downloadblackbird-op-linux-ccc712fe6b2acbafe9fc31f765a193e3249ca4a1.tar.gz
blackbird-op-linux-ccc712fe6b2acbafe9fc31f765a193e3249ca4a1.zip
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
-rw-r--r--arch/powerpc/boot/dts/mpc8540ads.dts257
-rw-r--r--arch/powerpc/boot/dts/mpc8541cds.dts244
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds.dts287
-rw-r--r--arch/powerpc/boot/dts/mpc8555cds.dts244
-rw-r--r--arch/powerpc/kernel/legacy_serial.c8
-rw-r--r--arch/powerpc/kernel/prom_parse.c13
-rw-r--r--arch/powerpc/kernel/time.c25
-rw-r--r--arch/powerpc/kernel/traps.c8
-rw-r--r--arch/powerpc/mm/hugetlbpage.c2
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c162
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c210
-rw-r--r--arch/powerpc/platforms/86xx/mpc8641_hpcn.h32
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c324
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c73
-rw-r--r--arch/powerpc/platforms/powermac/bootx_init.c15
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c30
-rw-r--r--arch/powerpc/sysdev/tsi108_dev.c10
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c21
-rw-r--r--include/asm-powerpc/pgalloc.h2
-rw-r--r--include/asm-powerpc/system.h9
-rw-r--r--include/asm-powerpc/tsi108.h14
-rw-r--r--include/asm-powerpc/tsi108_irq.h124
23 files changed, 1593 insertions, 522 deletions
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
new file mode 100644
index 000000000000..5f41c1f7a5f3
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -0,0 +1,257 @@
+/*
+ * MPC8540 ADS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+ model = "MPC8540ADS";
+ compatible = "MPC85xxADS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ linux,phandle = <100>;
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ linux,phandle = <200>;
+
+ PowerPC,8540@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>; // 32 bytes
+ i-cache-line-size = <20>; // 32 bytes
+ d-cache-size = <8000>; // L1, 32K
+ i-cache-size = <8000>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // 166 MHz
+ clock-frequency = <0>; // 825 MHz, from uboot
+ 32-bit;
+ linux,phandle = <201>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ linux,phandle = <300>;
+ reg = <00000000 08000000>; // 128M at 0x0
+ };
+
+ soc8540@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "soc";
+ ranges = <0 e0000000 00100000>;
+ reg = <e0000000 00100000>; // CCSRBAR 1M
+ bus-frequency = <0>;
+
+ i2c@3000 {
+ device_type = "i2c";
+ compatible = "fsl-i2c";
+ reg = <3000 100>;
+ interrupts = <1b 2>;
+ interrupt-parent = <40000>;
+ dfsrr;
+ };
+
+ mdio@24520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "gianfar";
+ reg = <24520 20>;
+ linux,phandle = <24520>;
+ ethernet-phy@0 {
+ linux,phandle = <2452000>;
+ interrupt-parent = <40000>;
+ interrupts = <35 1>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@1 {
+ linux,phandle = <2452001>;
+ interrupt-parent = <40000>;
+ interrupts = <35 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@3 {
+ linux,phandle = <2452003>;
+ interrupt-parent = <40000>;
+ interrupts = <37 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ };
+
+ ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <24000 1000>;
+ address = [ 00 E0 0C 00 73 00 ];
+ local-mac-address = [ 00 E0 0C 00 73 00 ];
+ interrupts = <d 2 e 2 12 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452000>;
+ };
+
+ ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <25000 1000>;
+ address = [ 00 E0 0C 00 73 01 ];
+ local-mac-address = [ 00 E0 0C 00 73 01 ];
+ interrupts = <13 2 14 2 18 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452001>;
+ };
+
+ ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "FEC";
+ compatible = "gianfar";
+ reg = <26000 1000>;
+ address = [ 00 E0 0C 00 73 02 ];
+ local-mac-address = [ 00 E0 0C 00 73 02 ];
+ interrupts = <19 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452003>;
+ };
+
+ serial@4500 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4500 100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <1a 2>;
+ interrupt-parent = <40000>;
+ };
+
+ serial@4600 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4600 100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <1a 2>;
+ interrupt-parent = <40000>;
+ };
+ pci@8000 {
+ linux,phandle = <8000>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x02 */
+ 1000 0 0 1 40000 31 1
+ 1000 0 0 2 40000 32 1
+ 1000 0 0 3 40000 33 1
+ 1000 0 0 4 40000 34 1
+
+ /* IDSEL 0x03 */
+ 1800 0 0 1 40000 34 1
+ 1800 0 0 2 40000 31 1
+ 1800 0 0 3 40000 32 1
+ 1800 0 0 4 40000 33 1
+
+ /* IDSEL 0x04 */
+ 2000 0 0 1 40000 33 1
+ 2000 0 0 2 40000 34 1
+ 2000 0 0 3 40000 31 1
+ 2000 0 0 4 40000 32 1
+
+ /* IDSEL 0x05 */
+ 2800 0 0 1 40000 32 1
+ 2800 0 0 2 40000 33 1
+ 2800 0 0 3 40000 34 1
+ 2800 0 0 4 40000 31 1
+
+ /* IDSEL 0x0c */
+ 6000 0 0 1 40000 31 1
+ 6000 0 0 2 40000 32 1
+ 6000 0 0 3 40000 33 1
+ 6000 0 0 4 40000 34 1
+
+ /* IDSEL 0x0d */
+ 6800 0 0 1 40000 34 1
+ 6800 0 0 2 40000 31 1
+ 6800 0 0 3 40000 32 1
+ 6800 0 0 4 40000 33 1
+
+ /* IDSEL 0x0e */
+ 7000 0 0 1 40000 33 1
+ 7000 0 0 2 40000 34 1
+ 7000 0 0 3 40000 31 1
+ 7000 0 0 4 40000 32 1
+
+ /* IDSEL 0x0f */
+ 7800 0 0 1 40000 32 1
+ 7800 0 0 2 40000 33 1
+ 7800 0 0 3 40000 34 1
+ 7800 0 0 4 40000 31 1
+
+ /* IDSEL 0x12 */
+ 9000 0 0 1 40000 31 1
+ 9000 0 0 2 40000 32 1
+ 9000 0 0 3 40000 33 1
+ 9000 0 0 4 40000 34 1
+
+ /* IDSEL 0x13 */
+ 9800 0 0 1 40000 34 1
+ 9800 0 0 2 40000 31 1
+ 9800 0 0 3 40000 32 1
+ 9800 0 0 4 40000 33 1
+
+ /* IDSEL 0x14 */
+ a000 0 0 1 40000 33 1
+ a000 0 0 2 40000 34 1
+ a000 0 0 3 40000 31 1
+ a000 0 0 4 40000 32 1
+
+ /* IDSEL 0x15 */
+ a800 0 0 1 40000 32 1
+ a800 0 0 2 40000 33 1
+ a800 0 0 3 40000 34 1
+ a800 0 0 4 40000 31 1>;
+ interrupt-parent = <40000>;
+ interrupts = <08 2>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 80000000 80000000 0 20000000
+ 01000000 0 00000000 e2000000 0 00100000>;
+ clock-frequency = <3f940aa>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <8000 1000>;
+ compatible = "85xx";
+ device_type = "pci";
+ };
+
+ pic@40000 {
+ linux,phandle = <40000>;
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <40000 40000>;
+ built-in;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ big-endian;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
new file mode 100644
index 000000000000..7be0bc659e1c
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -0,0 +1,244 @@
+/*
+ * MPC8541 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+ model = "MPC8541CDS";
+ compatible = "MPC85xxCDS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ linux,phandle = <100>;
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ linux,phandle = <200>;
+
+ PowerPC,8541@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>; // 32 bytes
+ i-cache-line-size = <20>; // 32 bytes
+ d-cache-size = <8000>; // L1, 32K
+ i-cache-size = <8000>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // 166 MHz
+ clock-frequency = <0>; // 825 MHz, from uboot
+ 32-bit;
+ linux,phandle = <201>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ linux,phandle = <300>;
+ reg = <00000000 08000000>; // 128M at 0x0
+ };
+
+ soc8541@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "soc";
+ ranges = <0 e0000000 00100000>;
+ reg = <e0000000 00100000>; // CCSRBAR 1M
+ bus-frequency = <0>;
+
+ i2c@3000 {
+ device_type = "i2c";
+ compatible = "fsl-i2c";
+ reg = <3000 100>;
+ interrupts = <1b 2>;
+ interrupt-parent = <40000>;
+ dfsrr;
+ };
+
+ mdio@24520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "gianfar";
+ reg = <24520 20>;
+ linux,phandle = <24520>;
+ ethernet-phy@0 {
+ linux,phandle = <2452000>;
+ interrupt-parent = <40000>;
+ interrupts = <35 0>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@1 {
+ linux,phandle = <2452001>;
+ interrupt-parent = <40000>;
+ interrupts = <35 0>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ };
+
+ ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <24000 1000>;
+ local-mac-address = [ 00 E0 0C 00 73 00 ];
+ interrupts = <d 2 e 2 12 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452000>;
+ };
+
+ ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <25000 1000>;
+ local-mac-address = [ 00 E0 0C 00 73 01 ];
+ interrupts = <13 2 14 2 18 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452001>;
+ };
+
+ serial@4500 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4500 100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <1a 2>;
+ interrupt-parent = <40000>;
+ };
+
+ serial@4600 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4600 100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <1a 2>;
+ interrupt-parent = <40000>;
+ };
+
+ pci@8000 {
+ linux,phandle = <8000>;
+ interrupt-map-mask = <1f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x10 */
+ 08000 0 0 1 40000 30 1
+ 08000 0 0 2 40000 31 1
+ 08000 0 0 3 40000 32 1
+ 08000 0 0 4 40000 33 1
+
+ /* IDSEL 0x11 */
+ 08800 0 0 1 40000 30 1
+ 08800 0 0 2 40000 31 1
+ 08800 0 0 3 40000 32 1
+ 08800 0 0 4 40000 33 1
+
+ /* IDSEL 0x12 (Slot 1) */
+ 09000 0 0 1 40000 30 1
+ 09000 0 0 2 40000 31 1
+ 09000 0 0 3 40000 32 1
+ 09000 0 0 4 40000 33 1
+
+ /* IDSEL 0x13 (Slot 2) */
+ 09800 0 0 1 40000 31 1
+ 09800 0 0 2 40000 32 1
+ 09800 0 0 3 40000 33 1
+ 09800 0 0 4 40000 30 1
+
+ /* IDSEL 0x14 (Slot 3) */
+ 0a000 0 0 1 40000 32 1
+ 0a000 0 0 2 40000 33 1
+ 0a000 0 0 3 40000 30 1
+ 0a000 0 0 4 40000 31 1
+
+ /* IDSEL 0x15 (Slot 4) */
+ 0a800 0 0 1 40000 33 1
+ 0a800 0 0 2 40000 30 1
+ 0a800 0 0 3 40000 31 1
+ 0a800 0 0 4 40000 32 1
+
+ /* Bus 1 (Tundra Bridge) */
+ /* IDSEL 0x12 (ISA bridge) */
+ 19000 0 0 1 40000 30 1
+ 19000 0 0 2 40000 31 1
+ 19000 0 0 3 40000 32 1
+ 19000 0 0 4 40000 33 1>;
+ interrupt-parent = <40000>;
+ interrupts = <08 2>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 80000000 80000000 0 20000000
+ 01000000 0 00000000 e2000000 0 00100000>;
+ clock-frequency = <3f940aa>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <8000 1000>;
+ compatible = "85xx";
+ device_type = "pci";
+
+ i8259@19000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ reg = <19000 0 0 0 1>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ built-in;
+ compatible = "chrp,iic";
+ big-endian;
+ interrupts = <1>;
+ interrupt-parent = <8000>;
+ };
+ };
+
+ pci@9000 {
+ linux,phandle = <9000>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x15 */
+ a800 0 0 1 40000 3b 1
+ a800 0 0 2 40000 3b 1
+ a800 0 0 3 40000 3b 1
+ a800 0 0 4 40000 3b 1>;
+ interrupt-parent = <40000>;
+ interrupts = <09 2>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 a0000000 a0000000 0 20000000
+ 01000000 0 00000000 e3000000 0 00100000>;
+ clock-frequency = <3f940aa>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <9000 1000>;
+ compatible = "85xx";
+ device_type = "pci";
+ };
+
+ pic@40000 {
+ linux,phandle = <40000>;
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <40000 40000>;
+ built-in;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ big-endian;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
new file mode 100644
index 000000000000..893d7957c174
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -0,0 +1,287 @@
+/*
+ * MPC8555 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+ model = "MPC8548CDS";
+ compatible = "MPC85xxCDS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ linux,phandle = <100>;
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ linux,phandle = <200>;
+
+ PowerPC,8548@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>; // 32 bytes
+ i-cache-line-size = <20>; // 32 bytes
+ d-cache-size = <8000>; // L1, 32K
+ i-cache-size = <8000>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // 166 MHz
+ clock-frequency = <0>; // 825 MHz, from uboot
+ 32-bit;
+ linux,phandle = <201>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ linux,phandle = <300>;
+ reg = <00000000 08000000>; // 128M at 0x0
+ };
+
+ soc8548@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "soc";
+ ranges = <0 e0000000 00100000>;
+ reg = <e0000000 00100000>; // CCSRBAR 1M
+ bus-frequency = <0>;
+
+ i2c@3000 {
+ device_type = "i2c";
+ compatible = "fsl-i2c";
+ reg = <3000 100>;
+ interrupts = <1b 2>;
+ interrupt-parent = <40000>;
+ dfsrr;
+ };
+
+ mdio@24520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "gianfar";
+ reg = <24520 20>;
+ linux,phandle = <24520>;
+ ethernet-phy@0 {
+ linux,phandle = <2452000>;
+ interrupt-parent = <40000>;
+ interrupts = <35 0>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@1 {
+ linux,phandle = <2452001>;
+ interrupt-parent = <40000>;
+ interrupts = <35 0>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+
+ ethernet-phy@2 {
+ linux,phandle = <2452002>;
+ interrupt-parent = <40000>;
+ interrupts = <35 0>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@3 {
+ linux,phandle = <2452003>;
+ interrupt-parent = <40000>;
+ interrupts = <35 0>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ };
+
+ ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <24000 1000>;
+ local-mac-address = [ 00 E0 0C 00 73 00 ];
+ interrupts = <d 2 e 2 12 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452000>;
+ };
+
+ ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <25000 1000>;
+ local-mac-address = [ 00 E0 0C 00 73 01 ];
+ interrupts = <13 2 14 2 18 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452001>;
+ };
+
+ ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <26000 1000>;
+ local-mac-address = [ 00 E0 0C 00 73 02 ];
+ interrupts = <f 2 10 2 11 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452001>;
+ };
+
+/* eTSEC 4 is currently broken
+ ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <27000 1000>;
+ local-mac-address = [ 00 E0 0C 00 73 03 ];
+ interrupts = <15 2 16 2 17 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452001>;
+ };
+ */
+
+ serial@4500 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4500 100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <1a 2>;
+ interrupt-parent = <40000>;
+ };
+
+ serial@4600 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4600 100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <1a 2>;
+ interrupt-parent = <40000>;
+ };
+
+ pci@8000 {
+ linux,phandle = <8000>;
+ interrupt-map-mask = <1f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x10 */
+ 08000 0 0 1 40000 30 1
+ 08000 0 0 2 40000 31 1
+ 08000 0 0 3 40000 32 1
+ 08000 0 0 4 40000 33 1
+
+ /* IDSEL 0x11 */
+ 08800 0 0 1 40000 30 1
+ 08800 0 0 2 40000 31 1
+ 08800 0 0 3 40000 32 1
+ 08800 0 0 4 40000 33 1
+
+ /* IDSEL 0x12 (Slot 1) */
+ 09000 0 0 1 40000 30 1
+ 09000 0 0 2 40000 31 1
+ 09000 0 0 3 40000 32 1
+ 09000 0 0 4 40000 33 1
+
+ /* IDSEL 0x13 (Slot 2) */
+ 09800 0 0 1 40000 31 1
+ 09800 0 0 2 40000 32 1
+ 09800 0 0 3 40000 33 1
+ 09800 0 0 4 40000 30 1
+
+ /* IDSEL 0x14 (Slot 3) */
+ 0a000 0 0 1 40000 32 1
+ 0a000 0 0 2 40000 33 1
+ 0a000 0 0 3 40000 30 1
+ 0a000 0 0 4 40000 31 1
+
+ /* IDSEL 0x15 (Slot 4) */
+ 0a800 0 0 1 40000 33 1
+ 0a800 0 0 2 40000 30 1
+ 0a800 0 0 3 40000 31 1
+ 0a800 0 0 4 40000 32 1
+
+ /* Bus 1 (Tundra Bridge) */
+ /* IDSEL 0x12 (ISA bridge) */
+ 19000 0 0 1 40000 30 1
+ 19000 0 0 2 40000 31 1
+ 19000 0 0 3 40000 32 1
+ 19000 0 0 4 40000 33 1>;
+ interrupt-parent = <40000>;
+ interrupts = <08 2>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 80000000 80000000 0 20000000
+ 01000000 0 00000000 e2000000 0 00100000>;
+ clock-frequency = <3f940aa>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <8000 1000>;
+ compatible = "85xx";
+ device_type = "pci";
+
+ i8259@19000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ reg = <19000 0 0 0 1>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ built-in;
+ compatible = "chrp,iic";
+ big-endian;
+ interrupts = <1>;
+ interrupt-parent = <8000>;
+ };
+ };
+
+ pci@9000 {
+ linux,phandle = <9000>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x15 */
+ a800 0 0 1 40000 3b 1
+ a800 0 0 2 40000 3b 1
+ a800 0 0 3 40000 3b 1
+ a800 0 0 4 40000 3b 1>;
+ interrupt-parent = <40000>;
+ interrupts = <09 2>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 a0000000 a0000000 0 20000000
+ 01000000 0 00000000 e3000000 0 00100000>;
+ clock-frequency = <3f940aa>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <9000 1000>;
+ compatible = "85xx";
+ device_type = "pci";
+ };
+
+ pic@40000 {
+ linux,phandle = <40000>;
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <40000 40000>;
+ built-in;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ big-endian;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
new file mode 100644
index 000000000000..118f5a887651
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -0,0 +1,244 @@
+/*
+ * MPC8555 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+ model = "MPC8555CDS";
+ compatible = "MPC85xxCDS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ linux,phandle = <100>;
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ linux,phandle = <200>;
+
+ PowerPC,8555@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>; // 32 bytes
+ i-cache-line-size = <20>; // 32 bytes
+ d-cache-size = <8000>; // L1, 32K
+ i-cache-size = <8000>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // 166 MHz
+ clock-frequency = <0>; // 825 MHz, from uboot
+ 32-bit;
+ linux,phandle = <201>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ linux,phandle = <300>;
+ reg = <00000000 08000000>; // 128M at 0x0
+ };
+
+ soc8555@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "soc";
+ ranges = <0 e0000000 00100000>;
+ reg = <e0000000 00100000>; // CCSRBAR 1M
+ bus-frequency = <0>;
+
+ i2c@3000 {
+ device_type = "i2c";
+ compatible = "fsl-i2c";
+ reg = <3000 100>;
+ interrupts = <1b 2>;
+ interrupt-parent = <40000>;
+ dfsrr;
+ };
+
+ mdio@24520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "gianfar";
+ reg = <24520 20>;
+ linux,phandle = <24520>;
+ ethernet-phy@0 {
+ linux,phandle = <2452000>;
+ interrupt-parent = <40000>;
+ interrupts = <35 0>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ ethernet-phy@1 {
+ linux,phandle = <2452001>;
+ interrupt-parent = <40000>;
+ interrupts = <35 0>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ };
+
+ ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <24000 1000>;
+ local-mac-address = [ 00 E0 0C 00 73 00 ];
+ interrupts = <0d 2 0e 2 12 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452000>;
+ };
+
+ ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <25000 1000>;
+ local-mac-address = [ 00 E0 0C 00 73 01 ];
+ interrupts = <13 2 14 2 18 2>;
+ interrupt-parent = <40000>;
+ phy-handle = <2452001>;
+ };
+
+ serial@4500 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4500 100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <1a 2>;
+ interrupt-parent = <40000>;
+ };
+
+ serial@4600 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4600 100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <1a 2>;
+ interrupt-parent = <40000>;
+ };
+
+ pci@8000 {
+ linux,phandle = <8000>;
+ interrupt-map-mask = <1f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x10 */
+ 08000 0 0 1 40000 30 1
+ 08000 0 0 2 40000 31 1
+ 08000 0 0 3 40000 32 1
+ 08000 0 0 4 40000 33 1
+
+ /* IDSEL 0x11 */
+ 08800 0 0 1 40000 30 1
+ 08800 0 0 2 40000 31 1
+ 08800 0 0 3 40000 32 1
+ 08800 0 0 4 40000 33 1
+
+ /* IDSEL 0x12 (Slot 1) */
+ 09000 0 0 1 40000 30 1
+ 09000 0 0 2 40000 31 1
+ 09000 0 0 3 40000 32 1
+ 09000 0 0 4 40000 33 1
+
+ /* IDSEL 0x13 (Slot 2) */
+ 09800 0 0 1 40000 31 1
+ 09800 0 0 2 40000 32 1
+ 09800 0 0 3 40000 33 1
+ 09800 0 0 4 40000 30 1
+
+ /* IDSEL 0x14 (Slot 3) */
+ 0a000 0 0 1 40000 32 1
+ 0a000 0 0 2 40000 33 1
+ 0a000 0 0 3 40000 30 1
+ 0a000 0 0 4 40000 31 1
+
+ /* IDSEL 0x15 (Slot 4) */
+ 0a800 0 0 1 40000 33 1
+ 0a800 0 0 2 40000 30 1
+ 0a800 0 0 3 40000 31 1
+ 0a800 0 0 4 40000 32 1
+
+ /* Bus 1 (Tundra Bridge) */
+ /* IDSEL 0x12 (ISA bridge) */
+ 19000 0 0 1 40000 30 1
+ 19000 0 0 2 40000 31 1
+ 19000 0 0 3 40000 32 1
+ 19000 0 0 4 40000 33 1>;
+ interrupt-parent = <40000>;
+ interrupts = <08 2>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 80000000 80000000 0 20000000
+ 01000000 0 00000000 e2000000 0 00100000>;
+ clock-frequency = <3f940aa>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <8000 1000>;
+ compatible = "85xx";
+ device_type = "pci";
+
+ i8259@19000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ reg = <19000 0 0 0 1>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ built-in;
+ compatible = "chrp,iic";
+ big-endian;
+ interrupts = <1>;
+ interrupt-parent = <8000>;
+ };
+ };
+
+ pci@9000 {
+ linux,phandle = <9000>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x15 */
+ a800 0 0 1 40000 3b 1
+ a800 0 0 2 40000 3b 1
+ a800 0 0 3 40000 3b 1
+ a800 0 0 4 40000 3b 1>;
+ interrupt-parent = <40000>;
+ interrupts = <09 2>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 a0000000 a0000000 0 20000000
+ 01000000 0 00000000 e3000000 0 00100000>;
+ clock-frequency = <3f940aa>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <9000 1000>;
+ compatible = "85xx";
+ device_type = "pci";
+ };
+
+ pic@40000 {
+ linux,phandle = <40000>;
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <40000 40000>;
+ built-in;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ big-endian;
+ };
+ };
+};
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 359ab89748e0..40a39291861f 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -115,6 +115,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
u64 addr;
u32 *addrp;
upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+ struct device_node *tsi = of_get_parent(np);
/* We only support ports that have a clock frequency properly
* encoded in the device-tree.
@@ -134,7 +135,10 @@ static int __init add_legacy_soc_port(struct device_node *np,
/* Add port, irq will be dealt with later. We passed a translated
* IO port value. It will be fixed up later along with the irq
*/
- return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
+ if (tsi && !strcmp(tsi->type, "tsi-bridge"))
+ return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0);
+ else
+ return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
}
static int __init add_legacy_isa_port(struct device_node *np,
@@ -464,7 +468,7 @@ static int __init serial_dev_init(void)
fixup_port_irq(i, np, port);
if (port->iotype == UPIO_PORT)
fixup_port_pio(i, np, port);
- if (port->iotype == UPIO_MEM)
+ if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
fixup_port_mmio(i, np, port);
}
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 6a7e997c401d..11052c212ad5 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -598,11 +598,6 @@ static struct device_node *of_irq_find_parent(struct device_node *child)
return p;
}
-static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
-{
- return (((pin - 1) + slot) % 4) + 1;
-}
-
/* This doesn't need to be called if you don't have any special workaround
* flags to pass
*/
@@ -891,6 +886,12 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
}
EXPORT_SYMBOL_GPL(of_irq_map_one);
+#ifdef CONFIG_PCI
+static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
+{
+ return (((pin - 1) + slot) % 4) + 1;
+}
+
int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
{
struct device_node *dn, *ppnode;
@@ -967,4 +968,4 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
return of_irq_map_raw(ppnode, &lspec, laddr, out_irq);
}
EXPORT_SYMBOL_GPL(of_irq_map_pci);
-
+#endif /* CONFIG_PCI */
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 774c0a3c5019..18e59e43d2b3 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -417,7 +417,7 @@ static __inline__ void timer_check_rtc(void)
/*
* This version of gettimeofday has microsecond resolution.
*/
-static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val)
+static inline void __do_gettimeofday(struct timeval *tv)
{
unsigned long sec, usec;
u64 tb_ticks, xsec;
@@ -431,7 +431,12 @@ static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val)
* without a divide (and in fact, without a multiply)
*/
temp_varp = do_gtod.varp;
- tb_ticks = tb_val - temp_varp->tb_orig_stamp;
+
+ /* Sampling the time base must be done after loading
+ * do_gtod.varp in order to avoid racing with update_gtod.
+ */
+ data_barrier(temp_varp);
+ tb_ticks = get_tb() - temp_varp->tb_orig_stamp;
temp_tb_to_xs = temp_varp->tb_to_xs;
temp_stamp_xsec = temp_varp->stamp_xsec;
xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs);
@@ -464,7 +469,7 @@ void do_gettimeofday(struct timeval *tv)
tv->tv_usec = usec;
return;
}
- __do_gettimeofday(tv, get_tb());
+ __do_gettimeofday(tv);
}
EXPORT_SYMBOL(do_gettimeofday);
@@ -650,6 +655,7 @@ void timer_interrupt(struct pt_regs * regs)
int next_dec;
int cpu = smp_processor_id();
unsigned long ticks;
+ u64 tb_next_jiffy;
#ifdef CONFIG_PPC32
if (atomic_read(&ppc_n_lost_interrupts) != 0)
@@ -691,11 +697,14 @@ void timer_interrupt(struct pt_regs * regs)
continue;
write_seqlock(&xtime_lock);
- tb_last_jiffy += tb_ticks_per_jiffy;
- tb_last_stamp = per_cpu(last_jiffy, cpu);
- do_timer(regs);
- timer_recalc_offset(tb_last_jiffy);
- timer_check_rtc();
+ tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
+ if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
+ tb_last_jiffy = tb_next_jiffy;
+ tb_last_stamp = per_cpu(last_jiffy, cpu);
+ do_timer(regs);
+ timer_recalc_offset(tb_last_jiffy);
+ timer_check_rtc();
+ }
write_sequnlock(&xtime_lock);
}
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index e4d1713e8aea..9b352bd0a460 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -585,14 +585,14 @@ static void parse_fpe(struct pt_regs *regs)
#define INST_MFSPR_PVR_MASK 0xfc1fffff
#define INST_DCBA 0x7c0005ec
-#define INST_DCBA_MASK 0x7c0007fe
+#define INST_DCBA_MASK 0xfc0007fe
#define INST_MCRXR 0x7c000400
-#define INST_MCRXR_MASK 0x7c0007fe
+#define INST_MCRXR_MASK 0xfc0007fe
#define INST_STRING 0x7c00042a
-#define INST_STRING_MASK 0x7c0007fe
-#define INST_STRING_GEN_MASK 0x7c00067e
+#define INST_STRING_MASK 0xfc0007fe
+#define INST_STRING_GEN_MASK 0xfc00067e
#define INST_LSWI 0x7c0004aa
#define INST_LSWX 0x7c00042a
#define INST_STSWI 0x7c0005aa
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 266b8b2ceac9..5615acc29527 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -153,7 +153,7 @@ static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp)
hpdp->pd = 0;
tlb->need_flush = 1;
pgtable_free_tlb(tlb, pgtable_free_cache(hugepte, HUGEPTE_CACHE_NUM,
- HUGEPTE_TABLE_SIZE-1));
+ PGF_CACHENUM_MASK));
}
#ifdef CONFIG_PPC_64K_PAGES
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 454fc53289ab..c3268d9877e4 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -14,7 +14,6 @@ config MPC8540_ADS
config MPC85xx_CDS
bool "Freescale MPC85xx CDS"
select DEFAULT_UIMAGE
- select PPC_I8259 if PCI
help
This option enables support for the MPC85xx CDS board
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 06a497676c99..9d2acfbbeccd 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -37,79 +37,7 @@ unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
#endif
-/*
- * Internal interrupts are all Level Sensitive, and Positive Polarity
- *
- * Note: Likely, this table and the following function should be
- * obtained and derived from the OF Device Tree.
- */
-static u_char mpc85xx_ads_openpic_initsenses[] __initdata = {
- MPC85XX_INTERNAL_IRQ_SENSES,
- 0x0, /* External 0: */
-#if defined(CONFIG_PCI)
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 0 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 1 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 2 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 4: PCI slot 3 */
-#else
- 0x0, /* External 1: */
- 0x0, /* External 2: */
- 0x0, /* External 3: */
- 0x0, /* External 4: */
-#endif
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */
- 0x0, /* External 6: */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */
- 0x0, /* External 8: */
- 0x0, /* External 9: */
- 0x0, /* External 10: */
- 0x0, /* External 11: */
-};
-
#ifdef CONFIG_PCI
-/*
- * interrupt routing
- */
-
-int
-mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
- static char pci_irq_table[][4] =
- /*
- * This is little evil, but works around the fact
- * that revA boards have IDSEL starting at 18
- * and others boards (older) start at 12
- *
- * PCI IDSEL/INTPIN->INTLINE
- * A B C D
- */
- {
- {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 2 */
- {PIRQD, PIRQA, PIRQB, PIRQC},
- {PIRQC, PIRQD, PIRQA, PIRQB},
- {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 5 */
- {0, 0, 0, 0}, /* -- */
- {0, 0, 0, 0}, /* -- */
- {0, 0, 0, 0}, /* -- */
- {0, 0, 0, 0}, /* -- */
- {0, 0, 0, 0}, /* -- */
- {0, 0, 0, 0}, /* -- */
- {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 12 */
- {PIRQD, PIRQA, PIRQB, PIRQC},
- {PIRQC, PIRQD, PIRQA, PIRQB},
- {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 15 */
- {0, 0, 0, 0}, /* -- */
- {0, 0, 0, 0}, /* -- */
- {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 18 */
- {PIRQD, PIRQA, PIRQB, PIRQC},
- {PIRQC, PIRQD, PIRQA, PIRQB},
- {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 21 */
- };
-
- const long min_idsel = 2, max_idsel = 21, irqs_per_slot = 4;
- return PCI_IRQ_TABLE_LOOKUP;
-}
-
int
mpc85xx_exclude_device(u_char bus, u_char devfn)
{
@@ -119,44 +47,63 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
return PCIBIOS_SUCCESSFUL;
}
+void __init
+mpc85xx_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+
+ for_each_pci_dev(dev)
+ pci_read_irq_line(dev);
+}
#endif /* CONFIG_PCI */
void __init mpc85xx_ads_pic_init(void)
{
- struct mpic *mpic1;
- phys_addr_t OpenPIC_PAddr;
-
- /* Determine the Physical Address of the OpenPIC regs */
- OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET;
-
- mpic1 = mpic_alloc(OpenPIC_PAddr,
- MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
- 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250,
- mpc85xx_ads_openpic_initsenses,
- sizeof(mpc85xx_ads_openpic_initsenses),
- " OpenPIC ");
- BUG_ON(mpic1 == NULL);
- mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200);
- mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280);
- mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300);
- mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380);
- mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400);
- mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480);
- mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500);
- mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580);
-
- /* dummy mappings to get to 48 */
- mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600);
- mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680);
- mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700);
- mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780);
-
- /* External ints */
- mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000);
- mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080);
- mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100);
- mpic_init(mpic1);
+ struct mpic *mpic;
+ struct resource r;
+ struct device_node *np = NULL;
+
+ np = of_find_node_by_type(np, "open-pic");
+
+ if (np == NULL) {
+ printk(KERN_ERR "Could not find open-pic node\n");
+ return;
+ }
+
+ if(of_address_to_resource(np, 0, &r)) {
+ printk(KERN_ERR "Could not map mpic register space\n");
+ of_node_put(np);
+ return;
+ }
+
+ mpic = mpic_alloc(np, r.start,
+ MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
+ 4, 0, " OpenPIC ");
+ BUG_ON(mpic == NULL);
+ of_node_put(np);
+
+ mpic_assign_isu(mpic, 0, r.start + 0x10200);
+ mpic_assign_isu(mpic, 1, r.start + 0x10280);
+ mpic_assign_isu(mpic, 2, r.start + 0x10300);
+ mpic_assign_isu(mpic, 3, r.start + 0x10380);
+ mpic_assign_isu(mpic, 4, r.start + 0x10400);
+ mpic_assign_isu(mpic, 5, r.start + 0x10480);
+ mpic_assign_isu(mpic, 6, r.start + 0x10500);
+ mpic_assign_isu(mpic, 7, r.start + 0x10580);
+
+ /* Unused on this platform (leave room for 8548) */
+ mpic_assign_isu(mpic, 8, r.start + 0x10600);
+ mpic_assign_isu(mpic, 9, r.start + 0x10680);
+ mpic_assign_isu(mpic, 10, r.start + 0x10700);
+ mpic_assign_isu(mpic, 11, r.start + 0x10780);
+
+ /* External Interrupts */
+ mpic_assign_isu(mpic, 12, r.start + 0x10000);
+ mpic_assign_isu(mpic, 13, r.start + 0x10080);
+ mpic_assign_isu(mpic, 14, r.start + 0x10100);
+
+ mpic_init(mpic);
}
/*
@@ -165,7 +112,9 @@ void __init mpc85xx_ads_pic_init(void)
static void __init mpc85xx_ads_setup_arch(void)
{
struct device_node *cpu;
+#ifdef CONFIG_PCI
struct device_node *np;
+#endif
if (ppc_md.progress)
ppc_md.progress("mpc85xx_ads_setup_arch()", 0);
@@ -186,8 +135,7 @@ static void __init mpc85xx_ads_setup_arch(void)
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
- ppc_md.pci_swizzle = common_swizzle;
- ppc_md.pci_map_irq = mpc85xx_map_irq;
+ ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup;
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
#endif
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 18e6e11f7020..1d357d32a29f 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -57,94 +57,8 @@ unsigned long isa_mem_base = 0;
static int cds_pci_slot = 2;
static volatile u8 *cadmus;
-/*
- * Internal interrupts are all Level Sensitive, and Positive Polarity
- *
- * Note: Likely, this table and the following function should be
- * obtained and derived from the OF Device Tree.
- */
-static u_char mpc85xx_cds_openpic_initsenses[] __initdata = {
- MPC85XX_INTERNAL_IRQ_SENSES,
-#if defined(CONFIG_PCI)
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Ext 0: PCI slot 0 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 1 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 2 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 3 */
-#else
- 0x0, /* External 0: */
- 0x0, /* External 1: */
- 0x0, /* External 2: */
- 0x0, /* External 3: */
-#endif
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */
- 0x0, /* External 6: */
- 0x0, /* External 7: */
- 0x0, /* External 8: */
- 0x0, /* External 9: */
- 0x0, /* External 10: */
-#ifdef CONFIG_PCI
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 11: PCI2 slot 0 */
-#else
- 0x0, /* External 11: */
-#endif
-};
-
#ifdef CONFIG_PCI
-/*
- * interrupt routing
- */
-int
-mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
- struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
-
- if (!hose->index)
- {
- /* Handle PCI1 interrupts */
- char pci_irq_table[][4] =
- /*
- * PCI IDSEL/INTPIN->INTLINE
- * A B C D
- */
-
- /* Note IRQ assignment for slots is based on which slot the elysium is
- * in -- in this setup elysium is in slot #2 (this PIRQA as first
- * interrupt on slot */
- {
- { 0, 1, 2, 3 }, /* 16 - PMC */
- { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */
- { 0, 1, 2, 3 }, /* 18 - Slot 1 */
- { 1, 2, 3, 0 }, /* 19 - Slot 2 */
- { 2, 3, 0, 1 }, /* 20 - Slot 3 */
- { 3, 0, 1, 2 }, /* 21 - Slot 4 */
- };
-
- const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4;
- int i, j;
-
- for (i = 0; i < 6; i++)
- for (j = 0; j < 4; j++)
- pci_irq_table[i][j] =
- ((pci_irq_table[i][j] + 5 -
- cds_pci_slot) & 0x3) + PIRQ0A;
-
- return PCI_IRQ_TABLE_LOOKUP;
- } else {
- /* Handle PCI2 interrupts (if we have one) */
- char pci_irq_table[][4] =
- {
- /*
- * We only have one slot and one interrupt
- * going to PIRQA - PIRQD */
- { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */
- };
-
- const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4;
-
- return PCI_IRQ_TABLE_LOOKUP;
- }
-}
#define ARCADIA_HOST_BRIDGE_IDSEL 17
#define ARCADIA_2ND_BRIDGE_IDSEL 3
@@ -210,50 +124,104 @@ mpc85xx_cds_pcibios_fixup(void)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
pci_dev_put(dev);
}
+
+ /* Now map all the PCI irqs */
+ dev = NULL;
+ for_each_pci_dev(dev)
+ pci_read_irq_line(dev);
+}
+
+#ifdef CONFIG_PPC_I8259
+#warning The i8259 PIC support is currently broken
+static void mpc85xx_8259_cascade(unsigned int irq, struct
+ irq_desc *desc, struct pt_regs *regs)
+{
+ unsigned int cascade_irq = i8259_irq(regs);
+
+ if (cascade_irq != NO_IRQ)
+ generic_handle_irq(cascade_irq, regs);
+
+ desc->chip->eoi(irq);
}
+#endif /* PPC_I8259 */
#endif /* CONFIG_PCI */
void __init mpc85xx_cds_pic_init(void)
{
- struct mpic *mpic1;
- phys_addr_t OpenPIC_PAddr;
+ struct mpic *mpic;
+ struct resource r;
+ struct device_node *np = NULL;
+ struct device_node *cascade_node = NULL;
+ int cascade_irq;
- /* Determine the Physical Address of the OpenPIC regs */
- OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET;
+ np = of_find_node_by_type(np, "open-pic");
+
+ if (np == NULL) {
+ printk(KERN_ERR "Could not find open-pic node\n");
+ return;
+ }
- mpic1 = mpic_alloc(OpenPIC_PAddr,
+ if (of_address_to_resource(np, 0, &r)) {
+ printk(KERN_ERR "Failed to map mpic register space\n");
+ of_node_put(np);
+ return;
+ }
+
+ mpic = mpic_alloc(np, r.start,
MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
- 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250,
- mpc85xx_cds_openpic_initsenses,
- sizeof(mpc85xx_cds_openpic_initsenses), " OpenPIC ");
- BUG_ON(mpic1 == NULL);
- mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200);
- mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280);
- mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300);
- mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380);
- mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400);
- mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480);
- mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500);
- mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580);
-
- /* dummy mappings to get to 48 */
- mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600);
- mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680);
- mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700);
- mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780);
-
- /* External ints */
- mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000);
- mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080);
- mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100);
-
- mpic_init(mpic1);
+ 4, 0, " OpenPIC ");
+ BUG_ON(mpic == NULL);
+
+ /* Return the mpic node */
+ of_node_put(np);
+
+ mpic_assign_isu(mpic, 0, r.start + 0x10200);
+ mpic_assign_isu(mpic, 1, r.start + 0x10280);
+ mpic_assign_isu(mpic, 2, r.start + 0x10300);
+ mpic_assign_isu(mpic, 3, r.start + 0x10380);
+ mpic_assign_isu(mpic, 4, r.start + 0x10400);
+ mpic_assign_isu(mpic, 5, r.start + 0x10480);
+ mpic_assign_isu(mpic, 6, r.start + 0x10500);
+ mpic_assign_isu(mpic, 7, r.start + 0x10580);
+
+ /* Used only for 8548 so far, but no harm in
+ * allocating them for everyone */
+ mpic_assign_isu(mpic, 8, r.start + 0x10600);
+ mpic_assign_isu(mpic, 9, r.start + 0x10680);
+ mpic_assign_isu(mpic, 10, r.start + 0x10700);
+ mpic_assign_isu(mpic, 11, r.start + 0x10780);
+
+ /* External Interrupts */
+ mpic_assign_isu(mpic, 12, r.start + 0x10000);
+ mpic_assign_isu(mpic, 13, r.start + 0x10080);
+ mpic_assign_isu(mpic, 14, r.start + 0x10100);
+
+ mpic_init(mpic);
+
+#ifdef CONFIG_PPC_I8259
+ /* Initialize the i8259 controller */
+ for_each_node_by_type(np, "interrupt-controller")
+ if (device_is_compatible(np, "chrp,iic")) {
+ cascade_node = np;
+ break;
+ }
+
+ if (cascade_node == NULL) {
+ printk(KERN_DEBUG "Could not find i8259 PIC\n");
+ return;
+ }
-#ifdef CONFIG_PCI
- mpic_setup_cascade(PIRQ0A, i8259_irq_cascade, NULL);
+ cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+ if (cascade_irq == NO_IRQ) {
+ printk(KERN_ERR "Failed to map cascade interrupt\n");
+ return;
+ }
- i8259_init(0,0);
-#endif
+ i8259_init(cascade_node, 0);
+ of_node_put(cascade_node);
+
+ set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade);
+#endif /* CONFIG_PPC_I8259 */
}
@@ -298,8 +266,6 @@ mpc85xx_cds_setup_arch(void)
add_bridge(np);
ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
- ppc_md.pci_swizzle = common_swizzle;
- ppc_md.pci_map_irq = mpc85xx_map_irq;
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
#endif
diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h
index 5d2bcf78cef7..41e554c4af94 100644
--- a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h
+++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h
@@ -16,38 +16,6 @@
#include <linux/init.h>
-/* PCI interrupt controller */
-#define PIRQA 3
-#define PIRQB 4
-#define PIRQC 5
-#define PIRQD 6
-#define PIRQ7 7
-#define PIRQE 9
-#define PIRQF 10
-#define PIRQG 11
-#define PIRQH 12
-
-/* PCI-Express memory map */
-#define MPC86XX_PCIE_LOWER_IO 0x00000000
-#define MPC86XX_PCIE_UPPER_IO 0x00ffffff
-
-#define MPC86XX_PCIE_LOWER_MEM 0x80000000
-#define MPC86XX_PCIE_UPPER_MEM 0x9fffffff
-
-#define MPC86XX_PCIE_IO_BASE 0xe2000000
-#define MPC86XX_PCIE_MEM_OFFSET 0x00000000
-
-#define MPC86XX_PCIE_IO_SIZE 0x01000000
-
-#define PCIE1_CFG_ADDR_OFFSET (0x8000)
-#define PCIE1_CFG_DATA_OFFSET (0x8004)
-
-#define PCIE2_CFG_ADDR_OFFSET (0x9000)
-#define PCIE2_CFG_DATA_OFFSET (0x9004)
-
-#define MPC86xx_PCIE_OFFSET PCIE1_CFG_ADDR_OFFSET
-#define MPC86xx_PCIE_SIZE (0x1000)
-
#define MPC86XX_RSTCR_OFFSET (0xe00b0) /* Reset Control Register */
#endif /* __MPC8641_HPCN_H__ */
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index ebae73eb0063..146da3001c67 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -37,6 +37,14 @@
#include "mpc86xx.h"
#include "mpc8641_hpcn.h"
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(KERN_ERR fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
+
#ifndef CONFIG_PCI
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
@@ -44,205 +52,215 @@ unsigned long pci_dram_offset = 0;
#endif
-/*
- * Internal interrupts are all Level Sensitive, and Positive Polarity
- */
-
-static u_char mpc86xx_hpcn_openpic_initsenses[] __initdata = {
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: Reserved */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: MCM */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCIE1 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: PCIE2 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: Reserved */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: Reserved */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: DUART2 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 1 Transmit */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 1 Receive */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: TSEC 3 transmit */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: TSEC 3 receive */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: TSEC 3 error */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 1 Receive/Transmit Error */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 2 Transmit */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 2 Receive */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: TSEC 4 transmit */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: TSEC 4 receive */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: TSEC 4 error */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 2 Receive/Transmit Error */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART1 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 32: SRIO error/write-port unit */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 33: SRIO outbound doorbell */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 34: SRIO inbound doorbell */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 35: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 36: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 37: SRIO outbound message unit 1 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 38: SRIO inbound message unit 1 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 39: SRIO outbound message unit 2 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 40: SRIO inbound message unit 2 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 41: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 42: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 43: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 44: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 45: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 46: Unused */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 47: Unused */
- 0x0, /* External 0: */
- 0x0, /* External 1: */
- 0x0, /* External 2: */
- 0x0, /* External 3: */
- 0x0, /* External 4: */
- 0x0, /* External 5: */
- 0x0, /* External 6: */
- 0x0, /* External 7: */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: Pixis FPGA */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 9: ULI 8259 INTR Cascade */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 10: Quad ETH PHY */
- 0x0, /* External 11: */
- 0x0,
- 0x0,
- 0x0,
- 0x0,
-};
-
+static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs)
+{
+ unsigned int cascade_irq = i8259_irq(regs);
+ if (cascade_irq != NO_IRQ)
+ generic_handle_irq(cascade_irq, regs);
+ desc->chip->eoi(irq);
+}
void __init
mpc86xx_hpcn_init_irq(void)
{
struct mpic *mpic1;
+ struct device_node *np, *cascade_node = NULL;
+ int cascade_irq;
phys_addr_t openpic_paddr;
+ np = of_find_node_by_type(NULL, "open-pic");
+ if (np == NULL)
+ return;
+
/* Determine the Physical Address of the OpenPIC regs */
openpic_paddr = get_immrbase() + MPC86xx_OPENPIC_OFFSET;
/* Alloc mpic structure and per isu has 16 INT entries. */
- mpic1 = mpic_alloc(openpic_paddr,
+ mpic1 = mpic_alloc(np, openpic_paddr,
MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
- 16, MPC86xx_OPENPIC_IRQ_OFFSET, 0, 250,
- mpc86xx_hpcn_openpic_initsenses,
- sizeof(mpc86xx_hpcn_openpic_initsenses),
+ 16, NR_IRQS - 4,
" MPIC ");
BUG_ON(mpic1 == NULL);
+ mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10000);
+
/* 48 Internal Interrupts */
- mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10200);
- mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10400);
- mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10600);
+ mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10200);
+ mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10400);
+ mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10600);
- /* 16 External interrupts */
- mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10000);
+ /* 16 External interrupts
+ * Moving them from [0 - 15] to [64 - 79]
+ */
+ mpic_assign_isu(mpic1, 4, openpic_paddr + 0x10000);
mpic_init(mpic1);
#ifdef CONFIG_PCI
- mpic_setup_cascade(MPC86xx_IRQ_EXT9, i8259_irq_cascade, NULL);
- i8259_init(0, I8259_OFFSET);
-#endif
-}
+ /* Initialize i8259 controller */
+ for_each_node_by_type(np, "interrupt-controller")
+ if (device_is_compatible(np, "chrp,iic")) {
+ cascade_node = np;
+ break;
+ }
+ if (cascade_node == NULL) {
+ printk(KERN_DEBUG "mpc86xxhpcn: no ISA interrupt controller\n");
+ return;
+ }
+ cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+ if (cascade_irq == NO_IRQ) {
+ printk(KERN_ERR "mpc86xxhpcn: failed to map cascade interrupt");
+ return;
+ }
+ DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq);
+ i8259_init(cascade_node, 0);
+ set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade);
+#endif
+}
#ifdef CONFIG_PCI
-/*
- * interrupt routing
- */
-int
-mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH};
+const unsigned char uli1575_irq_route_table[16] = {
+ 0, /* 0: Reserved */
+ 0x8, /* 1: 0b1000 */
+ 0, /* 2: Reserved */
+ 0x2, /* 3: 0b0010 */
+ 0x4, /* 4: 0b0100 */
+ 0x5, /* 5: 0b0101 */
+ 0x7, /* 6: 0b0111 */
+ 0x6, /* 7: 0b0110 */
+ 0, /* 8: Reserved */
+ 0x1, /* 9: 0b0001 */
+ 0x3, /* 10: 0b0011 */
+ 0x9, /* 11: 0b1001 */
+ 0xb, /* 12: 0b1011 */
+ 0, /* 13: Reserved */
+ 0xd, /* 14, 0b1101 */
+ 0xf, /* 15, 0b1111 */
+};
+
+static int __devinit
+get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin)
{
- static char pci_irq_table[][4] = {
- /*
- * PCI IDSEL/INTPIN->INTLINE
- * A B C D
- */
- {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 17 -- PCI Slot 1 */
- {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 18 -- PCI Slot 2 */
- {0, 0, 0, 0}, /* IDSEL 19 */
- {0, 0, 0, 0}, /* IDSEL 20 */
- {0, 0, 0, 0}, /* IDSEL 21 */
- {0, 0, 0, 0}, /* IDSEL 22 */
- {0, 0, 0, 0}, /* IDSEL 23 */
- {0, 0, 0, 0}, /* IDSEL 24 */
- {0, 0, 0, 0}, /* IDSEL 25 */
- {PIRQD, PIRQA, PIRQB, PIRQC}, /* IDSEL 26 -- PCI Bridge*/
- {PIRQC, 0, 0, 0}, /* IDSEL 27 -- LAN */
- {PIRQE, PIRQF, PIRQH, PIRQ7}, /* IDSEL 28 -- USB 1.1 */
- {PIRQE, PIRQF, PIRQG, 0}, /* IDSEL 29 -- Audio & Modem */
- {PIRQH, 0, 0, 0}, /* IDSEL 30 -- LPC & PMU*/
- {PIRQD, 0, 0, 0}, /* IDSEL 31 -- ATA */
- };
-
- const long min_idsel = 17, max_idsel = 31, irqs_per_slot = 4;
- return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET;
+ struct of_irq oirq;
+ u32 laddr[3];
+ struct device_node *hosenode = hose ? hose->arch_data : NULL;
+
+ if (!hosenode) return -EINVAL;
+
+ laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8);
+ laddr[1] = laddr[2] = 0;
+ of_irq_map_raw(hosenode, &pin, laddr, &oirq);
+ DBG("mpc86xx_hpcn: pci irq addr %x, slot %d, pin %d, irq %d\n",
+ laddr[0], slot, pin, oirq.specifier[0]);
+ return oirq.specifier[0];
}
-static void __devinit quirk_ali1575(struct pci_dev *dev)
+static void __devinit quirk_uli1575(struct pci_dev *dev)
{
unsigned short temp;
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ unsigned char irq2pin[16];
+ unsigned long pirq_map_word = 0;
+ u32 irq;
+ int i;
/*
- * ALI1575 interrupts route table setup:
+ * ULI1575 interrupts route setup
+ */
+ memset(irq2pin, 0, 16); /* Initialize default value 0 */
+
+ /*
+ * PIRQA -> PIRQD mapping read from OF-tree
+ *
+ * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD
+ * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA
+ */
+ for (i = 0; i < 4; i++){
+ irq = get_pci_irq_from_of(hose, 17, i + 1);
+ if (irq > 0 && irq < 16)
+ irq2pin[irq] = PIRQA + i;
+ else
+ printk(KERN_WARNING "ULI1575 device"
+ "(slot %d, pin %d) irq %d is invalid.\n",
+ 17, i, irq);
+ }
+
+ /*
+ * PIRQE -> PIRQF mapping set manually
*
* IRQ pin IRQ#
- * PIRQA ---- 3
- * PIRQB ---- 4
- * PIRQC ---- 5
- * PIRQD ---- 6
* PIRQE ---- 9
* PIRQF ---- 10
* PIRQG ---- 11
* PIRQH ---- 12
- *
- * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD
- * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA
*/
- pci_write_config_dword(dev, 0x48, 0xb9317542);
+ for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i;
+
+ /* Set IRQ-PIRQ Mapping to ULI1575 */
+ for (i = 0; i < 16; i++)
+ if (irq2pin[i])
+ pirq_map_word |= (uli1575_irq_route_table[i] & 0xf)
+ << ((irq2pin[i] - PIRQA) * 4);
- /* USB 1.1 OHCI controller 1, interrupt: PIRQE */
- pci_write_config_byte(dev, 0x86, 0x0c);
+ /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */
+ DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n",
+ pirq_map_word);
+ pci_write_config_dword(dev, 0x48, pirq_map_word);
- /* USB 1.1 OHCI controller 2, interrupt: PIRQF */
- pci_write_config_byte(dev, 0x87, 0x0d);
+#define ULI1575_SET_DEV_IRQ(slot, pin, reg) \
+ do { \
+ int irq; \
+ irq = get_pci_irq_from_of(hose, slot, pin); \
+ if (irq > 0 && irq < 16) \
+ pci_write_config_byte(dev, reg, irq2pin[irq]); \
+ else \
+ printk(KERN_WARNING "ULI1575 device" \
+ "(slot %d, pin %d) irq %d is invalid.\n", \
+ slot, pin, irq); \
+ } while(0)
- /* USB 1.1 OHCI controller 3, interrupt: PIRQH */
- pci_write_config_byte(dev, 0x88, 0x0f);
+ /* USB 1.1 OHCI controller 1, slot 28, pin 1 */
+ ULI1575_SET_DEV_IRQ(28, 1, 0x86);
- /* USB 2.0 controller, interrupt: PIRQ7 */
- pci_write_config_byte(dev, 0x74, 0x06);
+ /* USB 1.1 OHCI controller 2, slot 28, pin 2 */
+ ULI1575_SET_DEV_IRQ(28, 2, 0x87);
- /* Audio controller, interrupt: PIRQE */
- pci_write_config_byte(dev, 0x8a, 0x0c);
+ /* USB 1.1 OHCI controller 3, slot 28, pin 3 */
+ ULI1575_SET_DEV_IRQ(28, 3, 0x88);
- /* Modem controller, interrupt: PIRQF */
- pci_write_config_byte(dev, 0x8b, 0x0d);
+ /* USB 2.0 controller, slot 28, pin 4 */
+ irq = get_pci_irq_from_of(hose, 28, 4);
+ if (irq >= 0 && irq <=15)
+ pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]);
- /* HD audio controller, interrupt: PIRQG */
- pci_write_config_byte(dev, 0x8c, 0x0e);
+ /* Audio controller, slot 29, pin 1 */
+ ULI1575_SET_DEV_IRQ(29, 1, 0x8a);
- /* Serial ATA interrupt: PIRQD */
- pci_write_config_byte(dev, 0x8d, 0x0b);
+ /* Modem controller, slot 29, pin 2 */
+ ULI1575_SET_DEV_IRQ(29, 2, 0x8b);
- /* SMB interrupt: PIRQH */
- pci_write_config_byte(dev, 0x8e, 0x0f);
+ /* HD audio controller, slot 29, pin 3 */
+ ULI1575_SET_DEV_IRQ(29, 3, 0x8c);
- /* PMU ACPI SCI interrupt: PIRQH */
- pci_write_config_byte(dev, 0x8f, 0x0f);
+ /* SMB interrupt: slot 30, pin 1 */
+ ULI1575_SET_DEV_IRQ(30, 1, 0x8e);
+
+ /* PMU ACPI SCI interrupt: slot 30, pin 2 */
+ ULI1575_SET_DEV_IRQ(30, 2, 0x8f);
+
+ /* Serial ATA interrupt: slot 31, pin 1 */
+ ULI1575_SET_DEV_IRQ(31, 1, 0x8d);
/* Primary PATA IDE IRQ: 14
* Secondary PATA IDE IRQ: 15
*/
- pci_write_config_byte(dev, 0x44, 0x3d);
- pci_write_config_byte(dev, 0x75, 0x0f);
+ pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]);
+ pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]);
/* Set IRQ14 and IRQ15 to legacy IRQs */
pci_read_config_word(dev, 0x46, &temp);
@@ -264,6 +282,8 @@ static void __devinit quirk_ali1575(struct pci_dev *dev)
*/
outb(0xfa, 0x4d0);
outb(0x1e, 0x4d1);
+
+#undef ULI1575_SET_DEV_IRQ
}
static void __devinit quirk_uli5288(struct pci_dev *dev)
@@ -306,7 +326,7 @@ static void __devinit early_uli5249(struct pci_dev *dev)
dev->class |= 0x1;
}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
@@ -337,8 +357,6 @@ mpc86xx_hpcn_setup_arch(void)
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
- ppc_md.pci_swizzle = common_swizzle;
- ppc_md.pci_map_irq = mpc86xx_map_irq;
ppc_md.pci_exclude_device = mpc86xx_exclude_device;
#endif
@@ -377,6 +395,15 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_file *m)
}
+void __init mpc86xx_hpcn_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+
+ for_each_pci_dev(dev)
+ pci_read_irq_line(dev);
+}
+
+
/*
* Called very early, device-tree isn't unflattened
*/
@@ -431,6 +458,7 @@ define_machine(mpc86xx_hpcn) {
.setup_arch = mpc86xx_hpcn_setup_arch,
.init_IRQ = mpc86xx_hpcn_init_irq,
.show_cpuinfo = mpc86xx_hpcn_show_cpuinfo,
+ .pcibios_fixup = mpc86xx_hpcn_pcibios_fixup,
.get_irq = mpic_get_irq,
.restart = mpc86xx_restart,
.time_init = mpc86xx_time_init,
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index d7a4fc7ca238..ed00ed2455dd 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -1,7 +1,7 @@
/*
* mpc7448_hpc2.c
*
- * Board setup routines for the Freescale Taiga platform
+ * Board setup routines for the Freescale mpc7448hpc2(taiga) platform
*
* Author: Jacob Pan
* jacob.pan@freescale.com
@@ -12,10 +12,10 @@
*
* Copyright 2004-2006 Freescale Semiconductor, Inc.
*
- * This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
*/
#include <linux/config.h>
@@ -62,43 +62,8 @@ pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
extern int tsi108_setup_pci(struct device_node *dev);
extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
extern void tsi108_pci_int_init(void);
-extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused);
-
-/*
- * Define all of the IRQ senses and polarities. Taken from the
- * mpc7448hpc manual.
- * Note: Likely, this table and the following function should be
- * obtained and derived from the OF Device Tree.
- */
-
-static u_char mpc7448_hpc2_pic_initsenses[] __initdata = {
- /* External on-board sources */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[0] XINT0 from FPGA */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[1] XINT1 from FPGA */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[2] PHY_INT from both GIGE */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[3] RESERVED */
- /* Internal Tsi108/109 interrupt sources */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA0 */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA1 */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA2 */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA3 */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART0 */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART1 */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* I2C */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* GPIO */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE0 */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE1 */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* HLP */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* SDC */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Processor IF */
- (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
- (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* PCI/X block */
-};
+extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs);
int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
{
@@ -229,6 +194,8 @@ static void __init mpc7448_hpc2_init_IRQ(void)
{
struct mpic *mpic;
phys_addr_t mpic_paddr = 0;
+ unsigned int cascade_pci_irq;
+ struct device_node *tsi_pci;
struct device_node *tsi_pic;
tsi_pic = of_find_node_by_type(NULL, "open-pic");
@@ -246,24 +213,31 @@ static void __init mpc7448_hpc2_init_IRQ(void)
DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__,
(u32) mpic_paddr);
- mpic = mpic_alloc(mpic_paddr,
+ mpic = mpic_alloc(tsi_pic, mpic_paddr,
MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108),
0, /* num_sources used */
- TSI108_IRQ_BASE,
0, /* num_sources used */
- NR_IRQS - 4 /* XXXX */,
- mpc7448_hpc2_pic_initsenses,
- sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC");
+ "Tsi108_PIC");
BUG_ON(mpic == NULL); /* XXXX */
-
mpic_init(mpic);
- mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic);
+
+ tsi_pci = of_find_node_by_type(NULL, "pci");
+ if (tsi_pci == 0) {
+ printk("%s: No tsi108 pci node found !\n", __FUNCTION__);
+ return;
+ }
+
+ cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
+ set_irq_data(cascade_pci_irq, mpic);
+ set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+
tsi108_pci_int_init();
/* Configure MPIC outputs to CPU0 */
tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
+ of_node_put(tsi_pic);
}
void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
@@ -320,6 +294,7 @@ static int mpc7448_machine_check_exception(struct pt_regs *regs)
return 0;
}
+
define_machine(mpc7448_hpc2){
.name = "MPC7448 HPC2",
.probe = mpc7448_hpc2_probe,
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index 6a026c733f6a..9d73d0234c5d 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -411,8 +411,15 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
DBG("End of boot params: %x\n", mem_end);
rsvmap[0] = mem_start;
rsvmap[1] = mem_end;
- rsvmap[2] = 0;
- rsvmap[3] = 0;
+ if (bootx_info->ramDisk) {
+ rsvmap[2] = ((unsigned long)bootx_info) + bootx_info->ramDisk;
+ rsvmap[3] = rsvmap[2] + bootx_info->ramDiskSize;
+ rsvmap[4] = 0;
+ rsvmap[5] = 0;
+ } else {
+ rsvmap[2] = 0;
+ rsvmap[3] = 0;
+ }
return (unsigned long)hdr;
}
@@ -543,12 +550,12 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
*/
if (bi->version < 5) {
space = bi->deviceTreeOffset + bi->deviceTreeSize;
- if (bi->ramDisk)
+ if (bi->ramDisk >= space)
space = bi->ramDisk + bi->ramDiskSize;
} else
space = bi->totalParamsSize;
- bootx_printf("Total space used by parameters & ramdisk: %x \n", space);
+ bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space);
/* New BootX will have flushed all TLBs and enters kernel with
* MMU switched OFF, so this should not be useful anymore.
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 12b65609c072..ef10bcf2d943 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -85,11 +85,8 @@ static int __init gfar_mdio_of_init(void)
mdio_data.irq[k] = -1;
while ((child = of_get_next_child(np, child)) != NULL) {
- if (child->n_intrs) {
- u32 *id =
- (u32 *) get_property(child, "reg", NULL);
- mdio_data.irq[*id] = child->intrs[0].line;
- }
+ u32 *id = get_property(child, "reg", NULL);
+ mdio_data.irq[*id] = irq_of_parse_and_map(child, 0);
}
ret =
@@ -131,6 +128,7 @@ static int __init gfar_of_init(void)
char *model;
void *mac_addr;
phandle *ph;
+ int n_res = 1;
memset(r, 0, sizeof(r));
memset(&gfar_data, 0, sizeof(gfar_data));
@@ -139,8 +137,7 @@ static int __init gfar_of_init(void)
if (ret)
goto err;
- r[1].start = np->intrs[0].line;
- r[1].end = np->intrs[0].line;
+ r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
r[1].flags = IORESOURCE_IRQ;
model = get_property(np, "model", NULL);
@@ -150,19 +147,19 @@ static int __init gfar_of_init(void)
r[1].name = gfar_tx_intr;
r[2].name = gfar_rx_intr;
- r[2].start = np->intrs[1].line;
- r[2].end = np->intrs[1].line;
+ r[2].start = r[2].end = irq_of_parse_and_map(np, 1);
r[2].flags = IORESOURCE_IRQ;
r[3].name = gfar_err_intr;
- r[3].start = np->intrs[2].line;
- r[3].end = np->intrs[2].line;
+ r[3].start = r[3].end = irq_of_parse_and_map(np, 2);
r[3].flags = IORESOURCE_IRQ;
+
+ n_res += 2;
}
gfar_dev =
platform_device_register_simple("fsl-gianfar", i, &r[0],
- np->n_intrs + 1);
+ n_res + 1);
if (IS_ERR(gfar_dev)) {
ret = PTR_ERR(gfar_dev);
@@ -259,8 +256,7 @@ static int __init fsl_i2c_of_init(void)
if (ret)
goto err;
- r[1].start = np->intrs[0].line;
- r[1].end = np->intrs[0].line;
+ r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
r[1].flags = IORESOURCE_IRQ;
i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
@@ -396,8 +392,7 @@ static int __init fsl_usb_of_init(void)
if (ret)
goto err;
- r[1].start = np->intrs[0].line;
- r[1].end = np->intrs[0].line;
+ r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
r[1].flags = IORESOURCE_IRQ;
usb_dev_mph =
@@ -445,8 +440,7 @@ static int __init fsl_usb_of_init(void)
if (ret)
goto unreg_mph;
- r[1].start = np->intrs[0].line;
- r[1].end = np->intrs[0].line;
+ r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
r[1].flags = IORESOURCE_IRQ;
usb_dev_dr =
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
index 26a0cc820cde..f3038461d4c0 100644
--- a/arch/powerpc/sysdev/tsi108_dev.c
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -93,13 +93,15 @@ static int __init tsi108_eth_of_init(void)
goto err;
r[1].name = "tx";
- r[1].start = np->intrs[0].line;
- r[1].end = np->intrs[0].line;
+ r[1].start = irq_of_parse_and_map(np, 0);
+ r[1].end = irq_of_parse_and_map(np, 0);
r[1].flags = IORESOURCE_IRQ;
+ DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
+ __FUNCTION__,r[1].name, r[1].start, r[1].end);
tsi_eth_dev =
platform_device_register_simple("tsi-ethernet", i, &r[0],
- np->n_intrs + 1);
+ 1);
if (IS_ERR(tsi_eth_dev)) {
ret = PTR_ERR(tsi_eth_dev);
@@ -127,7 +129,7 @@ static int __init tsi108_eth_of_init(void)
tsi_eth_data.regs = r[0].start;
tsi_eth_data.phyregs = res.start;
tsi_eth_data.phy = *phy_id;
- tsi_eth_data.irq_num = np->intrs[0].line;
+ tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0);
of_node_put(phy);
ret =
platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 3265d54c82ed..2ab06ed3ae73 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -26,7 +26,6 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
-
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -228,7 +227,7 @@ int __init tsi108_setup_pci(struct device_node *dev)
(hose)->ops = &tsi108_direct_pci_ops;
- printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. "
+ printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. "
"Firmware bus number: %d->%d\n",
rsrc.start, hose->first_busno, hose->last_busno);
@@ -278,7 +277,7 @@ static void init_pci_source(void)
mb();
}
-static inline int get_pci_source(void)
+static inline unsigned int get_pci_source(void)
{
u_int temp = 0;
int irq = -1;
@@ -371,12 +370,12 @@ static void tsi108_pci_irq_end(u_int irq)
* Interrupt controller descriptor for cascaded PCI interrupt controller.
*/
-struct hw_interrupt_type tsi108_pci_irq = {
+static struct irq_chip tsi108_pci_irq = {
.typename = "tsi108_PCI_int",
- .enable = tsi108_pci_irq_enable,
- .disable = tsi108_pci_irq_disable,
+ .mask = tsi108_pci_irq_disable,
.ack = tsi108_pci_irq_ack,
.end = tsi108_pci_irq_end,
+ .unmask = tsi108_pci_irq_enable,
};
/*
@@ -399,14 +398,18 @@ void __init tsi108_pci_int_init(void)
DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
for (i = 0; i < NUM_PCI_IRQS; i++) {
- irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq;
+ irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq;
irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL;
}
init_pci_source();
}
-int tsi108_irq_cascade(struct pt_regs *regs, void *unused)
+void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs)
{
- return get_pci_source();
+ unsigned int cascade_irq = get_pci_source();
+ if (cascade_irq != NO_IRQ)
+ generic_handle_irq(cascade_irq, regs);
+ desc->chip->eoi(irq);
}
diff --git a/include/asm-powerpc/pgalloc.h b/include/asm-powerpc/pgalloc.h
index 9f0917c68659..ae63db7b3e7d 100644
--- a/include/asm-powerpc/pgalloc.h
+++ b/include/asm-powerpc/pgalloc.h
@@ -117,7 +117,7 @@ static inline void pte_free(struct page *ptepage)
pte_free_kernel(page_address(ptepage));
}
-#define PGF_CACHENUM_MASK 0xf
+#define PGF_CACHENUM_MASK 0x3
typedef struct pgtable_free {
unsigned long val;
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 7307aa775671..4c9f5229e833 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -53,6 +53,15 @@
#define smp_read_barrier_depends() do { } while(0)
#endif /* CONFIG_SMP */
+/*
+ * This is a barrier which prevents following instructions from being
+ * started until the value of the argument x is known. For example, if
+ * x is a variable loaded from memory, this prevents following
+ * instructions from being executed until the load has been performed.
+ */
+#define data_barrier(x) \
+ asm volatile("twi 0,%0,0; isync" : : "r" (x) : "memory");
+
struct task_struct;
struct pt_regs;
diff --git a/include/asm-powerpc/tsi108.h b/include/asm-powerpc/tsi108.h
index c4c278d72f71..2c702d35a7cf 100644
--- a/include/asm-powerpc/tsi108.h
+++ b/include/asm-powerpc/tsi108.h
@@ -1,16 +1,18 @@
/*
- * include/asm-ppc/tsi108.h
- *
* common routine and memory layout for Tundra TSI108(Grendel) host bridge
* memory controller.
*
* Author: Jacob Pan (jacob.pan@freescale.com)
* Alex Bounine (alexandreb@tundra.com)
- * 2004 (c) Freescale Semiconductor Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
+ *
+ * Copyright 2004-2006 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
*/
+
#ifndef __PPC_KERNEL_TSI108_H
#define __PPC_KERNEL_TSI108_H
diff --git a/include/asm-powerpc/tsi108_irq.h b/include/asm-powerpc/tsi108_irq.h
new file mode 100644
index 000000000000..3e4d04effa57
--- /dev/null
+++ b/include/asm-powerpc/tsi108_irq.h
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2005 Tundra Semiconductor Corp.
+ * Alex Bounine, <alexandreb at tundra.com).
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * definitions for interrupt controller initialization and external interrupt
+ * demultiplexing on TSI108EMU/SVB boards.
+ */
+
+#ifndef _ASM_PPC_TSI108_IRQ_H
+#define _ASM_PPC_TSI108_IRQ_H
+
+/*
+ * Tsi108 interrupts
+ */
+#ifndef TSI108_IRQ_REG_BASE
+#define TSI108_IRQ_REG_BASE 0
+#endif
+
+#define TSI108_IRQ(x) (TSI108_IRQ_REG_BASE + (x))
+
+#define TSI108_MAX_VECTORS (36 + 4) /* 36 sources + PCI INT demux */
+#define MAX_TASK_PRIO 0xF
+
+#define TSI108_IRQ_SPURIOUS (TSI108_MAX_VECTORS)
+
+#define DEFAULT_PRIO_LVL 10 /* initial priority level */
+
+/* Interrupt vectors assignment to external and internal
+ * sources of requests. */
+
+/* EXTERNAL INTERRUPT SOURCES */
+
+#define IRQ_TSI108_EXT_INT0 TSI108_IRQ(0) /* External Source at INT[0] */
+#define IRQ_TSI108_EXT_INT1 TSI108_IRQ(1) /* External Source at INT[1] */
+#define IRQ_TSI108_EXT_INT2 TSI108_IRQ(2) /* External Source at INT[2] */
+#define IRQ_TSI108_EXT_INT3 TSI108_IRQ(3) /* External Source at INT[3] */
+
+/* INTERNAL INTERRUPT SOURCES */
+
+#define IRQ_TSI108_RESERVED0 TSI108_IRQ(4) /* Reserved IRQ */
+#define IRQ_TSI108_RESERVED1 TSI108_IRQ(5) /* Reserved IRQ */
+#define IRQ_TSI108_RESERVED2 TSI108_IRQ(6) /* Reserved IRQ */
+#define IRQ_TSI108_RESERVED3 TSI108_IRQ(7) /* Reserved IRQ */
+#define IRQ_TSI108_DMA0 TSI108_IRQ(8) /* DMA0 */
+#define IRQ_TSI108_DMA1 TSI108_IRQ(9) /* DMA1 */
+#define IRQ_TSI108_DMA2 TSI108_IRQ(10) /* DMA2 */
+#define IRQ_TSI108_DMA3 TSI108_IRQ(11) /* DMA3 */
+#define IRQ_TSI108_UART0 TSI108_IRQ(12) /* UART0 */
+#define IRQ_TSI108_UART1 TSI108_IRQ(13) /* UART1 */
+#define IRQ_TSI108_I2C TSI108_IRQ(14) /* I2C */
+#define IRQ_TSI108_GPIO TSI108_IRQ(15) /* GPIO */
+#define IRQ_TSI108_GIGE0 TSI108_IRQ(16) /* GIGE0 */
+#define IRQ_TSI108_GIGE1 TSI108_IRQ(17) /* GIGE1 */
+#define IRQ_TSI108_RESERVED4 TSI108_IRQ(18) /* Reserved IRQ */
+#define IRQ_TSI108_HLP TSI108_IRQ(19) /* HLP */
+#define IRQ_TSI108_SDRAM TSI108_IRQ(20) /* SDC */
+#define IRQ_TSI108_PROC_IF TSI108_IRQ(21) /* Processor IF */
+#define IRQ_TSI108_RESERVED5 TSI108_IRQ(22) /* Reserved IRQ */
+#define IRQ_TSI108_PCI TSI108_IRQ(23) /* PCI/X block */
+
+#define IRQ_TSI108_MBOX0 TSI108_IRQ(24) /* Mailbox 0 register */
+#define IRQ_TSI108_MBOX1 TSI108_IRQ(25) /* Mailbox 1 register */
+#define IRQ_TSI108_MBOX2 TSI108_IRQ(26) /* Mailbox 2 register */
+#define IRQ_TSI108_MBOX3 TSI108_IRQ(27) /* Mailbox 3 register */
+
+#define IRQ_TSI108_DBELL0 TSI108_IRQ(28) /* Doorbell 0 */
+#define IRQ_TSI108_DBELL1 TSI108_IRQ(29) /* Doorbell 1 */
+#define IRQ_TSI108_DBELL2 TSI108_IRQ(30) /* Doorbell 2 */
+#define IRQ_TSI108_DBELL3 TSI108_IRQ(31) /* Doorbell 3 */
+
+#define IRQ_TSI108_TIMER0 TSI108_IRQ(32) /* Global Timer 0 */
+#define IRQ_TSI108_TIMER1 TSI108_IRQ(33) /* Global Timer 1 */
+#define IRQ_TSI108_TIMER2 TSI108_IRQ(34) /* Global Timer 2 */
+#define IRQ_TSI108_TIMER3 TSI108_IRQ(35) /* Global Timer 3 */
+
+/*
+ * PCI bus INTA# - INTD# lines demultiplexor
+ */
+#define IRQ_PCI_INTAD_BASE TSI108_IRQ(36)
+#define IRQ_PCI_INTA (IRQ_PCI_INTAD_BASE + 0)
+#define IRQ_PCI_INTB (IRQ_PCI_INTAD_BASE + 1)
+#define IRQ_PCI_INTC (IRQ_PCI_INTAD_BASE + 2)
+#define IRQ_PCI_INTD (IRQ_PCI_INTAD_BASE + 3)
+#define NUM_PCI_IRQS (4)
+
+/* number of entries in vector dispatch table */
+#define IRQ_TSI108_TAB_SIZE (TSI108_MAX_VECTORS + 1)
+
+/* Mapping of MPIC outputs to processors' interrupt pins */
+
+#define IDIR_INT_OUT0 0x1
+#define IDIR_INT_OUT1 0x2
+#define IDIR_INT_OUT2 0x4
+#define IDIR_INT_OUT3 0x8
+
+/*---------------------------------------------------------------
+ * IRQ line configuration parameters */
+
+/* Interrupt delivery modes */
+typedef enum {
+ TSI108_IRQ_DIRECTED,
+ TSI108_IRQ_DISTRIBUTED,
+} TSI108_IRQ_MODE;
+#endif /* _ASM_PPC_TSI108_IRQ_H */
OpenPOWER on IntegriCloud