LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/4]: powerpc/cell spidernet low watermark patch.
From: Linas Vepstas @ 2006-08-18 23:29 UTC (permalink / raw)
  To: David Miller
  Cc: arnd, jklewis, linux-kernel, linuxppc-dev, netdev, Jens.Osterkamp
In-Reply-To: <20060818.155116.112621100.davem@davemloft.net>

On Fri, Aug 18, 2006 at 03:51:16PM -0700, David Miller wrote:
> I see you moving TX reclaim into tasklets and stuff.  I've vehemently
> against that because you wouldn't need it in order to move TX
> processing into software interrupts if you did it all in NAPI
> ->poll().

I don't understand what you are saying. If I call the transmit 
queue cleanup code from the poll() routine, nothing hapens, 
because the kernel does not call the poll() routine often 
enough. I've stated this several times.  

--linas

^ permalink raw reply

* Re: [PATCH 2/6]: powerpc/cell spidernet low watermark patch.
From: Arnd Bergmann @ 2006-08-18 23:09 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: akpm, James K Lewis, linux-kernel, netdev, Jeff Garzik,
	ens Osterkamp
In-Reply-To: <20060818222146.GI26889@austin.ibm.com>

T24gU2F0dXJkYXkgMTkgQXVndXN0IDIwMDYgMDA6MjEsIExpbmFzIFZlcHN0YXMgd3JvdGU6Cj4g
K6CgoKCgoKAvKiBNZWFzdXJlIHRoZSBsZW5ndGggb2YgdGhlIHF1ZXVlLiAqLwo+ICugoKCgoKCg
d2hpbGUgKGRlc2NyICE9IGNhcmQtPnR4X2NoYWluLmhlYWQpIHsKPiAroKCgoKCgoKCgoKCgoKCg
c3RhdHVzID0gZGVzY3ItPmRtYWNfY21kX3N0YXR1cyAmIFNQSURFUl9ORVRfREVTQ1JfTk9UX0lO
X1VTRTsKPiAroKCgoKCgoKCgoKCgoKCgaWYgKHN0YXR1cyA9PSBTUElERVJfTkVUX0RFU0NSX05P
VF9JTl9VU0UpCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgYnJlYWs7Cj4gK6CgoKCgoKCgoKCg
oKCgoGRlc2NyID0gZGVzY3ItPm5leHQ7Cj4gK6CgoKCgoKCgoKCgoKCgoGNudCsrOwo+ICugoKCg
oKCgfQo+ICugoKCgoKCgaWYgKGNudCA9PSAwKQo+ICugoKCgoKCgoKCgoKCgoKByZXR1cm47Cj4g
Kwo+ICugoKCgoKCgLyogU2V0IGxvdy13YXRlcm1hcmsgMy80dGgncyBvZiB0aGUgd2F5IGludG8g
dGhlIHF1ZXVlLiAqLwo+ICugoKCgoKCgZGVzY3IgPSBjYXJkLT50eF9jaGFpbi50YWlsOwo+ICug
oKCgoKCgY250ID0gKGNudCozKS80Owo+ICugoKCgoKCgZm9yIChpPTA7aTxjbnQ7IGkrKykKPiAr
oKCgoKCgoKCgoKCgoKCgZGVzY3IgPSBkZXNjci0+bmV4dDsKCkkgd29uZGVyIGlmIGNhbGxpbmcg
dGhpcyBmcmVxdWVudGx5IHJlc3VsdHMgaW4gYSBzaWduaWZpY2FudCBwcm9jZXNzaW5nCm92ZXJo
ZWFkIGluIHRoZSBDUFUuIERvZXMgdGhlIHNwaWRlcl9uZXRfc2V0X2xvd193YXRlcm1hcmsgZnVu
Y3Rpb24Kc2hvdyB1cCBpbiB5b3VyIHByb2ZpbGVzPwoKQSBtb3JlIGVmZmljaWVudCBpbXBsZW1l
bnRhdGlvbiBtaWdodCBiZSB0byBtYXJrIG9uZSBkZXNjcmlwdG9yIHRoYXQKaXMgYXQgYSBmaXhl
ZCBvZmZzZXQgZnJvbSB0aGUgVFggcXVldWUgdGFpbCwgc28gd2Ugb25seSBuZWVkIHRvIGRvCgpj
YXJkLT5sb3dfd2F0ZXJtYXJrLT5uZXh0LT5kbWFjX2NtZF9zdGF0dXMgfD0gU1BJREVSX05FVF9E
RVNDUl9UWERFU0ZMRzsKbWIoKTsKY2FyZC0+bG93X3dhdGVybWFyay0+ZG1hY19jbWRfc3RhdHVz
ICY9IH5TUElERVJfTkVUX0RFU0NSX1RYREVTRkxHOwpjYXJkLT5sb3dfd2F0ZXJtYXJrID0gY2Fy
ZC0+bG93X3dhdGVybWFyay0+bmV4dDsKCndoZW4gd2UgcXVldWUgYW5vdGhlciBmcmFtZSBmb3Ig
VFguCgoJQXJuZCA8PjwK

^ permalink raw reply

* [PATCH] Add 85xx DTS files to powerpc
From: Andy Fleming @ 2006-08-18 23:04 UTC (permalink / raw)
  To: Paul Mackerras, linuxppc-dev

Added the mpc85xx family of dts files to the powerpc tree
---
 arch/powerpc/boot/dts/mpc8540ads.dts |  257 ++++++++++++++++++++++++++++++
 arch/powerpc/boot/dts/mpc8541cds.dts |  244 +++++++++++++++++++++++++++++
 arch/powerpc/boot/dts/mpc8548cds.dts |  287 ++++++++++++++++++++++++++++++++++
 arch/powerpc/boot/dts/mpc8555cds.dts |  244 +++++++++++++++++++++++++++++
 4 files changed, 1032 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
new file mode 100644
index 0000000..93d2c2d
--- /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@2 {
+				linux,phandle = <2452002>;
+				interrupt-parent = <40000>;
+				interrupts = <37 1>;
+				reg = <2>;
+				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 = "TSEC";
+			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 = <2452002>;
+		};
+
+		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 0000000..d526397
--- /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 0000000..ec1446a
--- /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 0000000..71fea14
--- /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;
+		};
+	};
+};
-- 
2006_06_07.01.gittree_pull-dirty

^ permalink raw reply related

* [PATCH] Fix interrupts on 8540 ADS board
From: Andy Fleming @ 2006-08-18 23:03 UTC (permalink / raw)
  To: Paul Mackerras, linuxppc-dev

* Fixed 8540 ADS support for the new irq layer
* Fixed 8540 ADS support for mapping PCI interrupts
* Updated 8540 ADS to use device tree for interrupt assignment
  and sense values
---

Ok.  Many, many apologies for the previous patch.  *This* patch is 
tested on a fresh tree.  The arguments for it going in from before still 
apply, though.  The current mainline for 2.6.18 doesn't build, let alone 
boot, so we *need* this patch to go in, as well as the CDS patch from 
before.

 arch/powerpc/platforms/85xx/mpc85xx_ads.c |  162 ++++++++++-------------------
 1 files changed, 55 insertions(+), 107 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index d0cfcdb..cae6b73 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_cha
 		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 @@ #ifdef CONFIG_PCI
 	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
 
-- 
2006_06_07.01.gittree_pull-dirty

^ permalink raw reply related

* Re: [PATCH 5/6]: powerpc/cell spidernet bottom half
From: Arnd Bergmann @ 2006-08-18 23:03 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: akpm, James K Lewis, linux-kernel, netdev, Jeff Garzik,
	ens Osterkamp
In-Reply-To: <20060818222657.GL26889@austin.ibm.com>

On Saturday 19 August 2006 00:26, Linas Vepstas wrote:
> The recent set of low-waterark patches for the spider result in a
> significant amount of computing being done in an interrupt context.
> This patch moves this to a "bottom half" aka work queue, so that
> the code runs in a normal kernel context. Curiously, this seems to 
> result in a performance boost of about 5% for large packets.

I guess this one still needs some work. We already have a bottom
half mechanism in the network layer, using the NAPI poll function
that is strongly serialized.

Linas, you wrote that you have tried doing the TX descriptor cleanup
in dev->poll(), but I think you missed the point that this function
needs should then be scheduled whenever necessary.

This seems a little strange, but I think what we need to do is in the
low-watermark interrupt call netif_rx_schedule(netdev) in order to
arrange for the ->poll function to be called in the next softirq.

Someone should probably document that in 
Documentation/networking/NAPI_HOWTO.txt, I might end up doing that
once we get it right for spidernet.

	Arnd <><

^ permalink raw reply

* Re: [PATCH 4/6]: powerpc/cell spidernet ethtool -i version number info.
From: Arnd Bergmann @ 2006-08-18 22:56 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: akpm, James K Lewis, linux-kernel, netdev, Jeff Garzik,
	ens Osterkamp
In-Reply-To: <20060818222500.GK26889@austin.ibm.com>

On Saturday 19 August 2006 00:25, Linas Vepstas wrote:
> This patch adds version information as reported by=20
> ethtool -i to the Spidernet driver.

Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

except for

> @@ -2293,6 +2294,8 @@ static struct pci_driver spider_net_driv
> =A0 */
> =A0static int __init spider_net_init(void)
> =A0{
> +=A0=A0=A0=A0=A0=A0=A0printk("spidernet Version %s.\n",VERSION);
> +

This printk is missing a level (KERN_INFO or similar). Moreover,
it is rather strange for a driver to print a message when no
device is actually used by it. I'd rather drop the version
printk completely, but I know that Jim has strong feelings about
what to do with version information. I suggest that if we decide
to keep something like that in the driver, it should be printed
in spider_net_probe().

	Arnd <><

^ permalink raw reply

* Re: [PATCH 2/4]: powerpc/cell spidernet low watermark patch.
From: David Miller @ 2006-08-18 22:51 UTC (permalink / raw)
  To: linas; +Cc: arnd, jklewis, linux-kernel, linuxppc-dev, netdev, Jens.Osterkamp
In-Reply-To: <20060818224618.GN26889@austin.ibm.com>

From: linas@austin.ibm.com (Linas Vepstas)
Date: Fri, 18 Aug 2006 17:46:18 -0500

> > We're not saying to use the RX interrupt as the trigger for
> > RX and TX work.  Rather, either of RX or TX interrupt will
> > schedule the NAPI poll.
> 
> And, for a lark, this is exactly what I did. Just to see.
> Because there are so few ack packets, there are very few 
> RX interrupts -- not enough to get NAPI to actually keep
> the device busy.

You're misreading me.  TX interrupts are intended to be "enabled" and
trigger NAPI polls.  TX IRQ enabled, enabled :-)

If you want to eliminate them if the kernel keeps hopping into
the ->hard_start_xmit() via hw interrupt mitigation or whatever,
that's fine.  But if you do need to do TX interrupt processing,
do it in NAPI ->poll().

> I'm somewhat disoriened from this conversation. Its presumably
> clear that low-watermark mechanisms are superior to NAPI. 
> >From what I gather, NAPI was invented to deal with cheap 
> or low-function hardware; it adds nothing to this particular
> situation. Why are we talking about this?

NAPI is meant to give fairness to all devices receiving packets
in the system, particularly in times of high load or overload.

And equally importantly, it allows you to run the majority of your
interrupt handler in software IRQ context.  This allows not only your
locking to be simpler, but it also allows things like oprofile to
monitor almost your entire IRQ processing path even with just timer
interrupt based oprofile profiling.

I see you moving TX reclaim into tasklets and stuff.  I've vehemently
against that because you wouldn't need it in order to move TX
processing into software interrupts if you did it all in NAPI
->poll().

^ permalink raw reply

* Re: [PATCH 1/6]: powerpc/cell spidernet burst alignment patch
From: Arnd Bergmann @ 2006-08-18 22:51 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: akpm, James K Lewis, linux-kernel, netdev, Jeff Garzik,
	ens Osterkamp
In-Reply-To: <20060818222038.GH26889@austin.ibm.com>

On Saturday 19 August 2006 00:20, Linas Vepstas wrote:
> This patch increases the Burst Address alignment from 64 to 1024 in the
> Spidernet driver. This improves transmit performance for arge packets
> from about 100Mbps to 300-400Mbps.

Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

^ permalink raw reply

* Re: [PATCH 2/4]: powerpc/cell spidernet low watermark patch.
From: Linas Vepstas @ 2006-08-18 22:46 UTC (permalink / raw)
  To: David Miller
  Cc: arnd, jklewis, linux-kernel, linuxppc-dev, netdev, Jens.Osterkamp
In-Reply-To: <20060818.142513.29571851.davem@davemloft.net>

On Fri, Aug 18, 2006 at 02:25:13PM -0700, David Miller wrote:
> From: linas@austin.ibm.com (Linas Vepstas)
> Date: Fri, 18 Aug 2006 14:23:56 -0500
> 
> > On Thu, Aug 17, 2006 at 01:43:40AM +0200, Benjamin Herrenschmidt wrote:
> > > 
> > > Sounds good (without actually looking at the code though :), that was a
> > > long required improvement to that driver. Also, we should probably look
> > > into using NAPI polling for tx completion queue as well, no ?
> > 
> > Just for a lark, I tried using NAPI polling, while disabling all TX
> > interrupts. Performance was a disaster: 8Mbits/sec, fom which I conclude
> > that the tcp ack packets do not flow back fast enough to allw reliance
> > on NAPI polling for transmit.
> 
> The idea is to use NAPI polling with TX interrupts disabled.

The idea of a low-watermark mark interrupt is that there are *zero*
interrupts, as long as the kernel keeps feeding packets to the device.

In my last email to you, I attached a real-life vmstat trace 
showing exactly zero interrupts over a two minute period. 

However, the zero-interrupt scenario only occurs if the kernel
is actually feeding packets to the driver.  If the socket beffers
are small, then the app blocks, the kernel is idle, and there
are not enough tcp ack packets coming back the other way to 
actually get the NAPI polling to keep the adapter fed.

> We're not saying to use the RX interrupt as the trigger for
> RX and TX work.  Rather, either of RX or TX interrupt will
> schedule the NAPI poll.

And, for a lark, this is exactly what I did. Just to see.
Because there are so few ack packets, there are very few 
RX interrupts -- not enough to get NAPI to actually keep
the device busy.

------
I'm somewhat disoriened from this conversation. Its presumably
clear that low-watermark mechanisms are superior to NAPI. 
>From what I gather, NAPI was invented to deal with cheap 
or low-function hardware; it adds nothing to this particular
situation. Why are we talking about this?

--linas

^ permalink raw reply

* [PATCH 6/6]:  powerpc/cell spidernet refine locking
From: Linas Vepstas @ 2006-08-18 22:29 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: akpm, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev, ens Osterkamp
In-Reply-To: <20060818220700.GG26889@austin.ibm.com>



The transmit side of the spider ethernet driver currently
places locks around some very large chunks of code. This
results in a fair amount of lock contention is some cases. 
This patch makes the locks much more fine-grained, protecting
only the cirtical sections. One lock is used to protect 
three locations: the queue head and tail pointers, and the 
queue low-watermark location.

This, with the previous patches, result in the following 
performance, using netperf, averaged over 5 minute runs:

pkt size    rate
--------    ----
1500        804 Mbits/sec
 800        701 Mbits/sec
 600        600 Mbits/sec
 300        280 Mbits/sec
  60         60 Mbits/sec


Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: Utz Bacher <utz.bacher@de.ibm.com>
Cc: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>

----
 drivers/net/spider_net.c |   77 ++++++++++++++++++++---------------------------
 drivers/net/spider_net.h |    2 -
 2 files changed, 35 insertions(+), 44 deletions(-)

Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.c	2006-08-15 14:28:56.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.c	2006-08-15 14:29:36.000000000 -0500
@@ -644,8 +644,9 @@ static int
 spider_net_prepare_tx_descr(struct spider_net_card *card,
 			    struct sk_buff *skb)
 {
-	struct spider_net_descr *descr = card->tx_chain.head;
+	struct spider_net_descr *descr;
 	dma_addr_t buf;
+	unsigned long flags;
 
 	buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
 	if (buf == DMA_ERROR_CODE) {
@@ -655,6 +656,10 @@ spider_net_prepare_tx_descr(struct spide
 		return -ENOMEM;
 	}
 
+	spin_lock_irqsave(&card->tx_chain.lock, flags);
+	descr = card->tx_chain.head;
+	card->tx_chain.head = card->tx_chain.head->next;
+
 	descr->buf_addr = buf;
 	descr->buf_size = skb->len;
 	descr->next_descr_addr = 0;
@@ -663,6 +668,8 @@ spider_net_prepare_tx_descr(struct spide
 
 	descr->dmac_cmd_status =
 			SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS;
+	spin_unlock_irqrestore(&card->tx_chain.lock, flags);
+
 	if (skb->protocol == htons(ETH_P_IP))
 		switch (skb->nh.iph->protocol) {
 		case IPPROTO_TCP:
@@ -673,37 +680,16 @@ spider_net_prepare_tx_descr(struct spide
 			break;
 		}
 
+	/* Chain the bus address, so that the DMA engine finds this descr. */
 	descr->prev->next_descr_addr = descr->bus_addr;
 
 	return 0;
 }
 
-/**
- * spider_net_release_tx_descr - processes a used tx descriptor
- * @card: card structure
- * @descr: descriptor to release
- *
- * releases a used tx descriptor (unmapping, freeing of skb)
- */
-static inline void
-spider_net_release_tx_descr(struct spider_net_card *card)
-{
-	struct spider_net_descr *descr = card->tx_chain.tail;
-	struct sk_buff *skb;
-
-	card->tx_chain.tail = card->tx_chain.tail->next;
-	descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE;
-
-	/* unmap the skb */
-	skb = descr->skb;
-	pci_unmap_single(card->pdev, descr->buf_addr, skb->len,
-			PCI_DMA_TODEVICE);
-	dev_kfree_skb_any(skb);
-}
-
 static void
 spider_net_set_low_watermark(struct spider_net_card *card)
 {
+	unsigned long flags;
 	int status;
 	int cnt=0;
 	int i;
@@ -727,11 +713,13 @@ spider_net_set_low_watermark(struct spid
 		descr = descr->next;
 
 	/* Set the new watermark, clear the old wtermark */
+	spin_lock_irqsave(&card->tx_chain.lock, flags);
 	descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG;
 	if (card->low_watermark && card->low_watermark != descr)
 		card->low_watermark->dmac_cmd_status =
 		     card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG;
 	card->low_watermark = descr;
+	spin_unlock_irqrestore(&card->tx_chain.lock, flags);
 }
 
 /**
@@ -750,22 +738,30 @@ static int
 spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
 {
 	struct spider_net_descr_chain *chain = &card->tx_chain;
+	struct spider_net_descr *descr;
+	struct sk_buff *skb;
+	u32 buf_addr;
+	unsigned long flags;
 	int status;
 	int rc=0;
 
 	spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR);
 
 	while (chain->tail != chain->head) {
-		status = spider_net_get_descr_status(chain->tail);
+		spin_lock_irqsave(&chain->lock, flags);
+		descr = chain->tail;
+
+		status = spider_net_get_descr_status(descr);
 		switch (status) {
 		case SPIDER_NET_DESCR_COMPLETE:
 			card->netdev_stats.tx_packets++;
-			card->netdev_stats.tx_bytes += chain->tail->skb->len;
+			card->netdev_stats.tx_bytes += descr->skb->len;
 			break;
 
 		case SPIDER_NET_DESCR_CARDOWNED:
 			if (!brutal) {
 				rc = 1;
+				spin_unlock_irqrestore(&chain->lock, flags);
 				goto done;
 			}
 			/* fallthrough, if we release the descriptors
@@ -785,9 +781,19 @@ spider_net_release_tx_chain(struct spide
 		default:
 			card->netdev_stats.tx_dropped++;
 			rc = 1;
+			spin_unlock_irqrestore(&chain->lock, flags);
 			goto done;
 		}
-		spider_net_release_tx_descr(card);
+
+		chain->tail = chain->tail->next;
+		descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE;
+		skb = descr->skb;
+		buf_addr = descr->buf_addr;
+		spin_unlock_irqrestore(&chain->lock, flags);
+
+		/* unmap the skb */
+		pci_unmap_single(card->pdev, buf_addr, skb->len, PCI_DMA_TODEVICE);
+		dev_kfree_skb_any(skb);
 	}
 done:
 	if (rc == 1)
@@ -844,11 +850,8 @@ spider_net_xmit(struct sk_buff *skb, str
 	struct spider_net_card *card = netdev_priv(netdev);
 	struct spider_net_descr_chain *chain = &card->tx_chain;
 	struct spider_net_descr *descr = chain->head;
-	unsigned long flags;
 	int result;
 
-	spin_lock_irqsave(&chain->lock, flags);
-
 	spider_net_release_tx_chain(card, 0);
 
 	if (chain->head->next == chain->tail->prev) {
@@ -869,12 +872,9 @@ spider_net_xmit(struct sk_buff *skb, str
 	}
 
 	result = NETDEV_TX_OK;
-
 	spider_net_kick_tx_dma(card);
-	card->tx_chain.head = card->tx_chain.head->next;
 
 out:
-	spin_unlock_irqrestore(&chain->lock, flags);
 	netif_wake_queue(netdev);
 	return result;
 }
@@ -891,17 +891,11 @@ out:
 static void
 spider_net_cleanup_tx_ring(struct spider_net_card *card)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&card->tx_chain.lock, flags);
-
 	if ((spider_net_release_tx_chain(card, 0) != 0) &&
 	    (card->netdev->flags & IFF_UP)) {
 		spider_net_kick_tx_dma(card);
 		netif_wake_queue(card->netdev);
 	}
-
-	spin_unlock_irqrestore(&card->tx_chain.lock, flags);
 }
 
 static void
@@ -1932,10 +1926,7 @@ spider_net_stop(struct net_device *netde
 	spider_net_disable_rxdmac(card);
 
 	/* release chains */
-	if (spin_trylock(&card->tx_chain.lock)) {
-		spider_net_release_tx_chain(card, 1);
-		spin_unlock(&card->tx_chain.lock);
-	}
+	spider_net_release_tx_chain(card, 1);
 
 	spider_net_free_chain(card, &card->tx_chain);
 	spider_net_free_chain(card, &card->rx_chain);
Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.h
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.h	2006-08-15 14:28:56.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.h	2006-08-15 14:29:36.000000000 -0500
@@ -24,7 +24,7 @@
 #ifndef _SPIDER_NET_H
 #define _SPIDER_NET_H
 
-#define VERSION "1.1 B"
+#define VERSION "1.1 C"
 
 #include "sungem_phy.h"
 

^ permalink raw reply

* [PATCH 5/6]: powerpc/cell spidernet bottom half
From: Linas Vepstas @ 2006-08-18 22:26 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: akpm, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev, ens Osterkamp
In-Reply-To: <20060818220700.GG26889@austin.ibm.com>


The recent set of low-waterark patches for the spider result in a
significant amount of computing being done in an interrupt context.
This patch moves this to a "bottom half" aka work queue, so that
the code runs in a normal kernel context. Curiously, this seems to 
result in a performance boost of about 5% for large packets.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: Utz Bacher <utz.bacher@de.ibm.com>
Cc: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>

----
 drivers/net/spider_net.c |   21 +++++++++++++++------
 drivers/net/spider_net.h |    4 +++-
 2 files changed, 18 insertions(+), 7 deletions(-)

Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.c	2006-08-15 14:25:50.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.c	2006-08-15 14:28:56.000000000 -0500
@@ -883,9 +883,10 @@ out:
  * spider_net_cleanup_tx_ring - cleans up the TX ring
  * @card: card structure
  *
- * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use
- * interrupts to cleanup our TX ring) and returns sent packets to the stack
- * by freeing them
+ * spider_net_cleanup_tx_ring is called by either the tx_timer
+ * or from a work-queue scheduled by the tx-empty interrupt.
+ * This routine releases resources associted with transmitted
+ * packets, including updating the queue tail pointer.
  */
 static void
 spider_net_cleanup_tx_ring(struct spider_net_card *card)
@@ -895,12 +896,20 @@ spider_net_cleanup_tx_ring(struct spider
 	spin_lock_irqsave(&card->tx_chain.lock, flags);
 
 	if ((spider_net_release_tx_chain(card, 0) != 0) &&
-	    (card->netdev->flags & IFF_UP))
+	    (card->netdev->flags & IFF_UP)) {
 		spider_net_kick_tx_dma(card);
+		netif_wake_queue(card->netdev);
+	}
 
 	spin_unlock_irqrestore(&card->tx_chain.lock, flags);
 }
 
+static void
+spider_net_tx_cleanup_task(void * data)
+{
+	spider_net_cleanup_tx_ring((struct spider_net_card *) data);
+}
+
 /**
  * spider_net_do_ioctl - called for device ioctls
  * @netdev: interface device structure
@@ -1499,8 +1508,7 @@ spider_net_interrupt(int irq, void *ptr,
 		netif_rx_schedule(netdev);
 	}
 	if (status_reg & SPIDER_NET_TXINT ) {
-		spider_net_cleanup_tx_ring(card);
-		netif_wake_queue(netdev);
+		schedule_work(&card->tx_cleanup_task);
 	}
 
 	if (status_reg & SPIDER_NET_ERRINT )
@@ -2117,6 +2125,7 @@ spider_net_alloc_card(void)
 	card->netdev = netdev;
 	card->msg_enable = SPIDER_NET_DEFAULT_MSG;
 	INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task, netdev);
+	INIT_WORK(&card->tx_cleanup_task, spider_net_tx_cleanup_task, card);
 	init_waitqueue_head(&card->waitq);
 	atomic_set(&card->tx_timeout_task_counter, 0);
 
Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.h
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.h	2006-08-15 14:25:50.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.h	2006-08-15 14:28:56.000000000 -0500
@@ -24,7 +24,7 @@
 #ifndef _SPIDER_NET_H
 #define _SPIDER_NET_H
 
-#define VERSION "1.1 A"
+#define VERSION "1.1 B"
 
 #include "sungem_phy.h"
 
@@ -441,6 +441,8 @@ struct spider_net_card {
 	atomic_t tx_timeout_task_counter;
 	wait_queue_head_t waitq;
 
+	struct work_struct tx_cleanup_task;
+
 	/* for ethtool */
 	int msg_enable;
 

^ permalink raw reply

* [PATCH 4/6]: powerpc/cell spidernet ethtool -i version number info.
From: Linas Vepstas @ 2006-08-18 22:25 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: akpm, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev, ens Osterkamp
In-Reply-To: <20060818220700.GG26889@austin.ibm.com>



This patch adds version information as reported by 
ethtool -i to the Spidernet driver.

From: James K Lewis <jklewis@us.ibm.com>
Signed-off-by: James K Lewis <jklewis@us.ibm.com>
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: Utz Bacher <utz.bacher@de.ibm.com>
Cc: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>

----
 drivers/net/spider_net.c         |    3 +++
 drivers/net/spider_net.h         |    2 ++
 drivers/net/spider_net_ethtool.c |    2 +-
 3 files changed, 6 insertions(+), 1 deletion(-)

Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.c	2006-08-11 11:34:16.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.c	2006-08-11 11:38:48.000000000 -0500
@@ -55,6 +55,7 @@ MODULE_AUTHOR("Utz Bacher <utz.bacher@de
 	      "<Jens.Osterkamp@de.ibm.com>");
 MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(VERSION);
 
 static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT;
 static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT;
@@ -2293,6 +2294,8 @@ static struct pci_driver spider_net_driv
  */
 static int __init spider_net_init(void)
 {
+	printk("spidernet Version %s.\n",VERSION);
+
 	if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) {
 		rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN;
 		pr_info("adjusting rx descriptors to %i.\n", rx_descriptors);
Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.h
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.h	2006-08-11 11:19:47.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.h	2006-08-11 11:38:48.000000000 -0500
@@ -24,6 +24,8 @@
 #ifndef _SPIDER_NET_H
 #define _SPIDER_NET_H
 
+#define VERSION "1.1 A"
+
 #include "sungem_phy.h"
 
 extern int spider_net_stop(struct net_device *netdev);
Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net_ethtool.c
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net_ethtool.c	2006-06-17 20:49:35.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net_ethtool.c	2006-08-11 11:38:48.000000000 -0500
@@ -55,7 +55,7 @@ spider_net_ethtool_get_drvinfo(struct ne
 	/* clear and fill out info */
 	memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
 	strncpy(drvinfo->driver, spider_net_driver_name, 32);
-	strncpy(drvinfo->version, "0.1", 32);
+	strncpy(drvinfo->version, VERSION, 32);
 	strcpy(drvinfo->fw_version, "no information");
 	strncpy(drvinfo->bus_info, pci_name(card->pdev), 32);
 }

^ permalink raw reply

* [PATCH 3/6]: powerpc/cell spidernet stop error printing patch.
From: Linas Vepstas @ 2006-08-18 22:23 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: akpm, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev, ens Osterkamp
In-Reply-To: <20060818220700.GG26889@austin.ibm.com>



Turn off mis-interpretation of the queue-empty interrupt
status bit as an error. This bit is set as a part of 
the previous low-watermark patch.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: James K Lewis <jklewis@us.ibm.com>
Cc: Utz Bacher <utz.bacher@de.ibm.com>
Cc: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.c	2006-08-11 11:23:24.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.c	2006-08-11 11:34:16.000000000 -0500
@@ -1275,12 +1275,15 @@ spider_net_handle_error_irq(struct spide
 	case SPIDER_NET_PHYINT:
 	case SPIDER_NET_GMAC2INT:
 	case SPIDER_NET_GMAC1INT:
-	case SPIDER_NET_GIPSINT:
 	case SPIDER_NET_GFIFOINT:
 	case SPIDER_NET_DMACINT:
 	case SPIDER_NET_GSYSINT:
 		break; */
 
+	case SPIDER_NET_GIPSINT:
+		show_error = 0;
+		break;
+
 	case SPIDER_NET_GPWOPCMPINT:
 		/* PHY write operation completed */
 		show_error = 0;
@@ -1339,9 +1342,10 @@ spider_net_handle_error_irq(struct spide
 	case SPIDER_NET_GDTDCEINT:
 		/* chain end. If a descriptor should be sent, kick off
 		 * tx dma
-		if (card->tx_chain.tail == card->tx_chain.head)
+		if (card->tx_chain.tail != card->tx_chain.head)
 			spider_net_kick_tx_dma(card);
-		show_error = 0; */
+		*/
+		show_error = 0;
 		break;
 
 	/* case SPIDER_NET_G1TMCNTINT: not used. print a message */
@@ -1455,8 +1459,9 @@ spider_net_handle_error_irq(struct spide
 	}
 
 	if ((show_error) && (netif_msg_intr(card)))
-		pr_err("Got error interrupt, GHIINT0STS = 0x%08x, "
+		pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, "
 		       "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n",
+		       card->netdev->name,
 		       status_reg, error_reg1, error_reg2);
 
 	/* clear interrupt sources */

^ permalink raw reply

* [PATCH 2/6]: powerpc/cell spidernet low watermark patch.
From: Linas Vepstas @ 2006-08-18 22:21 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: akpm, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev, ens Osterkamp
In-Reply-To: <20060818220700.GG26889@austin.ibm.com>



Implement basic low-watermark support for the transmit queue.
Hardware low-watermarks allow a properly configured kernel
to continously stream data to a device and not have to handle 
any interrupts at all in doing so. Correct zero-interrupt
operation can be actually observed for this driver, when the 
socket buffer is made large enough.

The basic idea of a low-watermark interrupt is as follows.
The device driver queues up a bunch of packets for the hardware
to transmit, and then kicks the hardware to get it started.
As the hardware drains the queue of pending, untransmitted 
packets, the device driver will want to know when the queue
is almost empty, so that it can queue some more packets.

If the queue drains down to the low waterark, then an interrupt
will be generated. However, if the kernel/driver continues 
to add enough packets to keep the queue partially filled,
no interrupt will actually be generated, and the hardware 
can continue streaming packets indefinitely in this mode.

The impelmentation is done by setting the DESCR_TXDESFLG flag 
in one of the packets. When the hardware sees this flag, it will 
interrupt the device driver. Because this flag is on a fixed
packet, rather than at  fixed location in the queue, the
code below needs to move the flag as more packets are
queued up. This implementation attempts to keep the flag 
at about 1/4 from "empty".

This patch boosts driver performance from about 
300-400Mbps for 1500 byte packets, to about 710-740Mbps.


Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: James K Lewis <jklewis@us.ibm.com>
Cc: Utz Bacher <utz.bacher@de.ibm.com>
Cc: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |   56 ++++++++++++++++++++++++++++++++++++++++++-----
 drivers/net/spider_net.h |    6 +++--
 2 files changed, 55 insertions(+), 7 deletions(-)

Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.c	2006-08-07 14:39:38.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.c	2006-08-11 11:23:24.000000000 -0500
@@ -700,6 +700,39 @@ spider_net_release_tx_descr(struct spide
 	dev_kfree_skb_any(skb);
 }
 
+static void
+spider_net_set_low_watermark(struct spider_net_card *card)
+{
+	int status;
+	int cnt=0;
+	int i;
+	struct spider_net_descr *descr = card->tx_chain.tail;
+
+	/* Measure the length of the queue. */
+	while (descr != card->tx_chain.head) {
+		status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE;
+		if (status == SPIDER_NET_DESCR_NOT_IN_USE)
+			break;
+		descr = descr->next;
+		cnt++;
+	}
+	if (cnt == 0)
+		return;
+
+	/* Set low-watermark 3/4th's of the way into the queue. */
+	descr = card->tx_chain.tail;
+	cnt = (cnt*3)/4;
+	for (i=0;i<cnt; i++)
+		descr = descr->next;
+
+	/* Set the new watermark, clear the old wtermark */
+	descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG;
+	if (card->low_watermark && card->low_watermark != descr)
+		card->low_watermark->dmac_cmd_status =
+		     card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG;
+	card->low_watermark = descr;
+}
+
 /**
  * spider_net_release_tx_chain - processes sent tx descriptors
  * @card: adapter structure
@@ -717,6 +750,7 @@ spider_net_release_tx_chain(struct spide
 {
 	struct spider_net_descr_chain *chain = &card->tx_chain;
 	int status;
+	int rc=0;
 
 	spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR);
 
@@ -729,8 +763,10 @@ spider_net_release_tx_chain(struct spide
 			break;
 
 		case SPIDER_NET_DESCR_CARDOWNED:
-			if (!brutal)
-				return 1;
+			if (!brutal) {
+				rc = 1;
+				goto done;
+			}
 			/* fallthrough, if we release the descriptors
 			 * brutally (then we don't care about
 			 * SPIDER_NET_DESCR_CARDOWNED) */
@@ -747,12 +783,15 @@ spider_net_release_tx_chain(struct spide
 
 		default:
 			card->netdev_stats.tx_dropped++;
-			return 1;
+			rc = 1;
+			goto done;
 		}
 		spider_net_release_tx_descr(card);
 	}
-
-	return 0;
+done:
+	if (rc == 1)
+		spider_net_set_low_watermark(card);
+	return rc;
 }
 
 /**
@@ -1453,6 +1492,10 @@ spider_net_interrupt(int irq, void *ptr,
 		spider_net_rx_irq_off(card);
 		netif_rx_schedule(netdev);
 	}
+	if (status_reg & SPIDER_NET_TXINT ) {
+		spider_net_cleanup_tx_ring(card);
+		netif_wake_queue(netdev);
+	}
 
 	if (status_reg & SPIDER_NET_ERRINT )
 		spider_net_handle_error_irq(card, status_reg);
@@ -1615,6 +1658,9 @@ spider_net_open(struct net_device *netde
 			card->descr,
 			PCI_DMA_TODEVICE, tx_descriptors))
 		goto alloc_tx_failed;
+
+	card->low_watermark = NULL;
+
 	if (spider_net_init_chain(card, &card->rx_chain,
 			card->descr + tx_descriptors,
 			PCI_DMA_FROMDEVICE, rx_descriptors))
Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.h
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.h	2006-08-11 11:09:57.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.h	2006-08-11 11:19:47.000000000 -0500
@@ -47,7 +47,7 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_TX_DESCRIPTORS_MIN		16
 #define SPIDER_NET_TX_DESCRIPTORS_MAX		512
 
-#define SPIDER_NET_TX_TIMER			20
+#define SPIDER_NET_TX_TIMER			(HZ/5)
 
 #define SPIDER_NET_RX_CSUM_DEFAULT		1
 
@@ -209,7 +209,7 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_DMA_RX_FEND_VALUE	0x00030003
 /* to set TX_DMA_EN */
 #define SPIDER_NET_TX_DMA_EN		0x80000000
-#define SPIDER_NET_GDTDCEIDIS		0x00000302
+#define SPIDER_NET_GDTDCEIDIS		0x00000300
 #define SPIDER_NET_DMA_TX_VALUE		SPIDER_NET_TX_DMA_EN | \
 					SPIDER_NET_GDTDCEIDIS
 #define SPIDER_NET_DMA_TX_FEND_VALUE	0x00030003
@@ -349,6 +349,7 @@ enum spider_net_int2_status {
 #define SPIDER_NET_DESCR_FORCE_END		0x50000000 /* used in rx and tx */
 #define SPIDER_NET_DESCR_CARDOWNED		0xA0000000 /* used in rx and tx */
 #define SPIDER_NET_DESCR_NOT_IN_USE		0xF0000000
+#define SPIDER_NET_DESCR_TXDESFLG		0x00800000
 
 struct spider_net_descr {
 	/* as defined by the hardware */
@@ -424,6 +425,7 @@ struct spider_net_card {
 
 	struct spider_net_descr_chain tx_chain;
 	struct spider_net_descr_chain rx_chain;
+	struct spider_net_descr *low_watermark;
 
 	struct net_device_stats netdev_stats;
 

^ permalink raw reply

* [PATCH 1/6]: powerpc/cell spidernet burst alignment patch
From: Linas Vepstas @ 2006-08-18 22:20 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: akpm, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev, ens Osterkamp
In-Reply-To: <20060818220700.GG26889@austin.ibm.com>



This patch increases the Burst Address alignment from 64 to 1024 in the
Spidernet driver. This improves transmit performance for arge packets
from about 100Mbps to 300-400Mbps.

From: James K Lewis <jklewis@us.ibm.com>
Signed-off-by: James K Lewis <jklewis@us.ibm.com>
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: Utz Bacher <utz.bacher@de.ibm.com>
Cc: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6.18-rc3-mm2/drivers/net/spider_net.h
===================================================================
--- linux-2.6.18-rc3-mm2.orig/drivers/net/spider_net.h	2006-08-07 14:37:10.000000000 -0500
+++ linux-2.6.18-rc3-mm2/drivers/net/spider_net.h	2006-08-11 11:09:57.000000000 -0500
@@ -209,7 +209,7 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_DMA_RX_FEND_VALUE	0x00030003
 /* to set TX_DMA_EN */
 #define SPIDER_NET_TX_DMA_EN		0x80000000
-#define SPIDER_NET_GDTDCEIDIS		0x00000002
+#define SPIDER_NET_GDTDCEIDIS		0x00000302
 #define SPIDER_NET_DMA_TX_VALUE		SPIDER_NET_TX_DMA_EN | \
 					SPIDER_NET_GDTDCEIDIS
 #define SPIDER_NET_DMA_TX_FEND_VALUE	0x00030003

^ permalink raw reply

* [PATCH 0/6]:  powerpc/cell spidernet ethernet driver update
From: Linas Vepstas @ 2006-08-18 22:07 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: akpm, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev, ens Osterkamp


Jeff,

Can you apply and forward upstream the following series of patches?
This is the same set of patches I sent only a few days ago; however,
it appears that I failed to cc you on some of them, and I failed to
ask anyone in particular to actually apply them. So I'm asking now. :-)

The maintainership of the spidernet driver is transitioning from
Utz Bacher and Jens Osterkamp to Jim Lewis; you should be receiving
a patch to the MAINTAINERS file from Jim, noting this, shortly.  
I suspect that neither Utz nor Jens will be ack'ing or nack'ing 
these patches unless prodded; let me know if you want some particlar
ack from someone before you apply these. (BenH and Arnd Bergmann
are the ones who usually keep us honest about these things.)

Although these are based on a week-old mm tree, they should 
apply cleanly just about anywhere, as there has been little/no 
change to this code base in a long while. 

The patches bring the transmit performance of the driver up
to a decent level, as reviewed in greter detail in the patch
descriptions.

--linas

^ permalink raw reply

* Re: [PATCH 0/6] bootwrapper: arch/powerpc/boot code reorg patches
From: Mark A. Greer @ 2006-08-18 21:46 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: linuxppc-dev
In-Reply-To: <1155670626.6338.3.camel@basalt.austin.ibm.com>

On Tue, Aug 15, 2006 at 02:37:06PM -0500, Hollis Blanchard wrote:
> On Tue, 2006-08-08 at 12:14 -0700, Mark A. Greer wrote:
> > Just a note that I will respin my patches to address all of your
> > comments.  However, it looks like the fdt code is going to change
> > to use code from a common source base.  I'm going to wait until
> > that has settled and then I'll modify the code and repost the patches.
> 
> By the way, I don't expect the (ft_build.h) interface to change much
> from what I emailed last week. So I think it's safe to build on top of
> those.
> 
> The only addition I'd like to make is creating an ft_set_prop() that
> will handle resizing the tree for you. With that change, you wouldn't
> ft_get_prop() and then write directly to that pointer (as is done
> currently).
> 
> I'm still waiting to hear the outcome of Matt's patches. I don't need
> them, but if u-boot does then I'll have to merge them into the
> standalone code.

Another note.  Hollis and I have been talking some more and may change
some code.  IOW, I'm still going to wait a bit to see what comes out of
it before respining the patches.

Mark

^ permalink raw reply

* Re: [PATCH 0/6] bootwrapper: arch/powerpc/boot code reorg patches
From: Jon Loeliger @ 2006-08-18 21:41 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linuxppc-dev
In-Reply-To: <20060818214649.GA30418@mag.az.mvista.com>

On Fri, 2006-08-18 at 16:46, Mark A. Greer wrote:

> > I'm still waiting to hear the outcome of Matt's patches. I don't need
> > them, but if u-boot does then I'll have to merge them into the
> > standalone code.
> 
> Another note.  Hollis and I have been talking some more and may change
> some code.  IOW, I'm still going to wait a bit to see what comes out of
> it before respining the patches.
> 
> Mark

As a point of information, the current 8641 HPCN tree
fully depends on Matt's patches in U-Boot.  The U-Boot
with these patches in it can be found on jdl.com.

Thanks,
jdl

^ permalink raw reply

* Re: [PATCH 2/4]: powerpc/cell spidernet low watermark patch.
From: David Miller @ 2006-08-18 21:25 UTC (permalink / raw)
  To: linas; +Cc: arnd, jklewis, linux-kernel, linuxppc-dev, netdev, Jens.Osterkamp
In-Reply-To: <20060818192356.GD26889@austin.ibm.com>

From: linas@austin.ibm.com (Linas Vepstas)
Date: Fri, 18 Aug 2006 14:23:56 -0500

> On Thu, Aug 17, 2006 at 01:43:40AM +0200, Benjamin Herrenschmidt wrote:
> > 
> > Sounds good (without actually looking at the code though :), that was a
> > long required improvement to that driver. Also, we should probably look
> > into using NAPI polling for tx completion queue as well, no ?
> 
> Just for a lark, I tried using NAPI polling, while disabling all TX
> interrupts. Performance was a disaster: 8Mbits/sec, fom which I conclude
> that the tcp ack packets do not flow back fast enough to allw reliance
> on NAPI polling for transmit.

The idea is to use NAPI polling with TX interrupts disabled.

We're not saying to use the RX interrupt as the trigger for
RX and TX work.  Rather, either of RX or TX interrupt will
schedule the NAPI poll.

^ permalink raw reply

* Re: [PATCH] Fix IRQ handling on MPC8540 ADS
From: Andy Fleming @ 2006-08-18 20:48 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <44E608F3.4060505@ru.mvista.com>


On Aug 18, 2006, at 13:37, Sergei Shtylyov wrote:

> Hello.
>
> Andy Fleming wrote:
>> * Fixed IRQ handling for the 85xx ADS boards so it uses the new
>>   generic irq stuff
>> * Fixed PCI IRQ mapping so it comes from the device tree
>
>    NAK. The kernel doesn't build with this patch. I'm getting this:
>
>   CC      arch/powerpc/platforms/85xx/mpc85xx_ads.o
> arch/powerpc/platforms/85xx/mpc85xx_ads.c: In function  
> `mpc85xx_ads_pic_init':
> arch/powerpc/platforms/85xx/mpc85xx_ads.c:76: warning: implicit  
> declaration of
> function `of_put_node'
>
>   and then finally:

Argh.  In my rush to get these patches out, I neglected to test the  
8540 ADS, and forgot that I added a few lines for "robustness".  I  
will fix and resubmit after testing.

>
>   LD      .tmp_vmlinux1
> arch/powerpc/platforms/built-in.o(.init.text+0x26c): In function  
> `mpc85xx_ads_pic_init':
> arch/powerpc/platforms/85xx/mpc85xx_ads.c:84: undefined reference  
> to `of_put_node'
> arch/powerpc/platforms/built-in.o(.init.text+0x404):arch/powerpc/ 
> platforms/85xx/mpc85xx_ads.c:76: undefined reference to `of_put_node'
> make: *** [.tmp_vmlinux1] Error 1
>
>    There's no such function in the kernel -- it actually aclled  
> of_node_put(). I can post an updated patch after testing (if it  
> succeeds) if you like...
>
>> This patch *really* needs to go in before 2.6.18 is final, else  
>> 2.6.18 doesn't build for 85xx.
>
>    Looks like it's a bit crude yet to be committed...

Agreed, though it's actually no worse than the current mainline!

>
>> Thanks,
>> Andy
>
> WBR, Sergei

^ permalink raw reply

* Re: [PATCH] powerpc: emulate power5 popcntb instruction
From: Kumar Gala @ 2006-08-18 19:42 UTC (permalink / raw)
  To: will_schmidt; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1155924687.9659.25.camel@farscape.rchland.ibm.com>

>
> +static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
> +{
> +	u32 ra,rs;
> +	unsigned long tmp;
> +
> +	ra = (instword >> 16) & 0x1f;
> +	rs = (instword >> 21) & 0x1f;
> +
> +	tmp = regs->gpr[rs];
> +	tmp = tmp - ((tmp >> 1) & 0x5555555555555555);
> +	tmp = (tmp & 0x3333333333333333) + ((tmp >> 2) &  
> 0x3333333333333333);
> +	tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0f;
> +	regs->gpr[ra] = tmp;
> +
> +	return 0;
> +}

This is going to give warnings on ppc32 kernel compiles, maybe  
something like:

(unsigned long) 0x5555555555555555ull

- kumar

^ permalink raw reply

* [PATCH] [POWERPC] Rewrite the PPC 86xx IRQ handling to use Flat Device Tree
From: Jon Loeliger @ 2006-08-18 19:30 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev@ozlabs.org, Jon Loeliger
In-Reply-To: <17637.1235.223857.925995@cargo.ozlabs.ibm.com>


IRQ setup now comes from the Flat Device Tree and use the new generic
IRQ code.  Fixed the fsl_soc.c IRQ OF interrupt node parsing.
Removed some unused MPC86xx macro definition.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
(cherry picked from 919fede6edab94cccb3ca8c1c0b32fa62c9369a5 commit)
---

On Thu, 2006-08-17 at 19:07, Paul Mackerras wrote:
> The "Allow MPC8641 HPCN to build with CONFIG_PCI disabled too" patch
> depends on your "Rewrite the PPC 86xx IRQ handling to use Flat Device
> Tree" which isn't in the queue for 2.6.18, and doesn't apply for
> 2.6.18 since it depends on the constifying of get_property.

Paul,

This is the same patch from three weeks ago, cherry-picked out
of your master branch with the constification problem resolved
so that it will apply directly to your merge branch.

Without this patch, 86xx won't even build in 2.6.18 due
to the IRQ new world order.

Thanks,
jdl


 arch/powerpc/platforms/86xx/mpc8641_hpcn.h |   32 ---
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |  324 +++++++++++++++-------------
 arch/powerpc/sysdev/fsl_soc.c              |   30 +--
 3 files changed, 188 insertions(+), 198 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h
index 5d2bcf7..41e554c 100644
--- a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h
+++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h
@@ -16,38 +16,6 @@ #define __MPC8641_HPCN_H__
 
 #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 ebae73e..146da30 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -37,6 +37,14 @@ #include <sysdev/fsl_soc.h>
 #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(stru
 	 */
 	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(stru
 	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 @@ #ifdef CONFIG_PCI
 	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_fil
 }
 
 
+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/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 12b6560..ef10bcf 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 =
-- 
2006_06_07.01.gittree_pull-dirty

^ permalink raw reply related

* Re: [PATCH] Fix IRQ handling on MPC8540 ADS
From: Sergei Shtylyov @ 2006-08-18 19:33 UTC (permalink / raw)
  To: Andy Fleming; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <44E608F3.4060505@ru.mvista.com>

Hello.

Sergei Shtylyov wrote:

>>* Fixed IRQ handling for the 85xx ADS boards so it uses the new
>>  generic irq stuff
>>* Fixed PCI IRQ mapping so it comes from the device tree

>     NAK. The kernel doesn't build with this patch. I'm getting this:

>    CC      arch/powerpc/platforms/85xx/mpc85xx_ads.o
> arch/powerpc/platforms/85xx/mpc85xx_ads.c: In function `mpc85xx_ads_pic_init':
> arch/powerpc/platforms/85xx/mpc85xx_ads.c:76: warning: implicit declaration of
> function `of_put_node'

>    and then finally:

>    LD      .tmp_vmlinux1
> arch/powerpc/platforms/built-in.o(.init.text+0x26c): In function 
> `mpc85xx_ads_pic_init':
> arch/powerpc/platforms/85xx/mpc85xx_ads.c:84: undefined reference to `of_put_node'
> arch/powerpc/platforms/built-in.o(.init.text+0x404):arch/powerpc/platforms/85xx/mpc85xx_ads.c:76: 
> undefined reference to `of_put_node'
> make: *** [.tmp_vmlinux1] Error 1
> 
>     There's no such function in the kernel -- it actually aclled 
> of_node_put(). I can post an updated patch after testing (if it succeeds) if 
> you like...

    Alas, the patched kernel didn't boot further than the early startup 
messages (after I've updated U-Boot with the correct PIC device type).

>>This patch *really* needs to go in before 2.6.18 is final, else 2.6.18 
>>doesn't build for 85xx.

>     Looks like it's a bit crude yet to be committed...

    Not even compile tested. :-/

WBR, Sergei

^ permalink raw reply

* Re: [PATCH] PURR should use correct cpu feature bit
From: Michael Neuling @ 2006-08-18 19:32 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: linuxppc-dev, paulus
In-Reply-To: <20060818184821.GC27947@krispykreme>

> Now we have a PURR cpu feature bit, we should use it in sysfs code.

Snap... Paulus has this in his tree for 2.6.19

http://git.kernel.org/git/?p=linux/kernel/git/paulus/powerpc.git;a=commit;h=afd05423e02bc7391a7489b686ba1e166b6e8349

Mikey

^ permalink raw reply

* Re: [PATCH] powerpc: emulate power5 popcntb instruction
From: Kumar Gala @ 2006-08-18 19:30 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200608182105.45264.arnd@arndb.de>


On Aug 18, 2006, at 2:05 PM, Arnd Bergmann wrote:

> On Friday 18 August 2006 20:11, Will Schmidt wrote:
>> +#define INST_POPCNTB           0x7c0000f4
>> +
>
>> +       /* Emulate the popcntb (Population Count Bytes)  
>> instruction. */
>> +       if ((instword & INST_POPCNTB) == INST_POPCNTB) {
>> +               return emulate_popcntb_inst(regs, instword);
>> +       }
>> +
>
> Is that the right check? The other similar traps check against a
> mask of 0x7c0007fe.

I agree with Arnd here, its better to check with a larger mask to  
ensure that bits that should be '0' in the minor opcode are.

For example, if you had an instruction that was 0x7c0000f7 it would  
match.

- kumar

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox