From 7ab413f9fd0c4845e1595001d9f9b890a43ee8fe Mon Sep 17 00:00:00 2001
From: Imre Kaloz <kaloz@openwrt.org>
Date: Mon, 28 Jan 2008 23:44:06 +0000
Subject: [PATCH] add upstream git patch for arch/powerpc

SVN-Revision: 10300
---
 .../patches-2.6.24/700-powerpc_git.patch      | 71515 ++++++++++++++++
 1 file changed, 71515 insertions(+)
 create mode 100644 target/linux/generic-2.6/patches-2.6.24/700-powerpc_git.patch

diff --git a/target/linux/generic-2.6/patches-2.6.24/700-powerpc_git.patch b/target/linux/generic-2.6/patches-2.6.24/700-powerpc_git.patch
new file mode 100644
index 0000000000..75c8c2edc3
--- /dev/null
+++ b/target/linux/generic-2.6/patches-2.6.24/700-powerpc_git.patch
@@ -0,0 +1,71515 @@
+diff -x .git -x .gitignore -Nur linux-2.6.24/Documentation/kernel-parameters.txt powerpc.git/Documentation/kernel-parameters.txt
+--- linux-2.6.24/Documentation/kernel-parameters.txt	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/Documentation/kernel-parameters.txt	2008-01-28 20:25:33.000000000 +0100
+@@ -686,6 +686,7 @@
+ 			See Documentation/isdn/README.HiSax.
+ 
+ 	hugepages=	[HW,X86-32,IA-64] Maximal number of HugeTLB pages.
++	hugepagesz=	[HW,IA-64,PPC] The size of the HugeTLB pages.
+ 
+ 	i8042.direct	[HW] Put keyboard port into non-translated mode
+ 	i8042.dumbkbd	[HW] Pretend that controller can only read data from
+diff -x .git -x .gitignore -Nur linux-2.6.24/Documentation/powerpc/00-INDEX powerpc.git/Documentation/powerpc/00-INDEX
+--- linux-2.6.24/Documentation/powerpc/00-INDEX	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/Documentation/powerpc/00-INDEX	2008-01-28 20:25:33.000000000 +0100
+@@ -28,3 +28,6 @@
+ 	- info on sound support under Linux/PPC
+ zImage_layout.txt
+ 	- info on the kernel images for Linux/PPC
++qe_firmware.txt
++	- describes the layout of firmware binaries for the Freescale QUICC
++	  Engine and the code that parses and uploads the microcode therein.
+diff -x .git -x .gitignore -Nur linux-2.6.24/Documentation/powerpc/booting-without-of.txt powerpc.git/Documentation/powerpc/booting-without-of.txt
+--- linux-2.6.24/Documentation/powerpc/booting-without-of.txt	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/Documentation/powerpc/booting-without-of.txt	2008-01-28 20:25:33.000000000 +0100
+@@ -52,7 +52,11 @@
+       i) Freescale QUICC Engine module (QE)
+       j) CFI or JEDEC memory-mapped NOR flash
+       k) Global Utilities Block
+-      l) Xilinx IP cores
++      l) Freescale Communications Processor Module
++      m) Chipselect/Local Bus
++      n) 4xx/Axon EMAC ethernet nodes
++      o) Xilinx IP cores
++      p) Freescale Synchronous Serial Interface
+ 
+   VII - Specifying interrupt information for devices
+     1) interrupts property
+@@ -671,10 +675,10 @@
+ 
+ In general, the format of an address for a device is defined by the
+ parent bus type, based on the #address-cells and #size-cells
+-property. In the absence of such a property, the parent's parent
+-values are used, etc... The kernel requires the root node to have
+-those properties defining addresses format for devices directly mapped
+-on the processor bus.
++properties.  Note that the parent's parent definitions of #address-cells
++and #size-cells are not inhereted so every node with children must specify
++them.  The kernel requires the root node to have those properties defining
++addresses format for devices directly mapped on the processor bus.
+ 
+ Those 2 properties define 'cells' for representing an address and a
+ size. A "cell" is a 32-bit number. For example, if both contain 2
+@@ -711,13 +715,14 @@
+ like address space bits, you'll have to add a bus translator to the
+ prom_parse.c file of the recent kernels for your bus type.
+ 
+-The "reg" property only defines addresses and sizes (if #size-cells
+-is non-0) within a given bus. In order to translate addresses upward
++The "reg" property only defines addresses and sizes (if #size-cells is
++non-0) within a given bus. In order to translate addresses upward
+ (that is into parent bus addresses, and possibly into CPU physical
+ addresses), all busses must contain a "ranges" property. If the
+ "ranges" property is missing at a given level, it's assumed that
+-translation isn't possible. The format of the "ranges" property for a
+-bus is a list of:
++translation isn't possible, i.e., the registers are not visible on the
++parent bus.  The format of the "ranges" property for a bus is a list
++of:
+ 
+ 	bus address, parent bus address, size
+ 
+@@ -735,6 +740,10 @@
+ 1/1 format, unless the processor supports physical addresses greater
+ than 32-bits, in which case a 2/1 format is recommended.
+ 
++Alternatively, the "ranges" property may be empty, indicating that the
++registers are visible on the parent bus using an identity mapping
++translation.  In other words, the parent bus address space is the same
++as the child bus address space.
+ 
+ 2) Note about "compatible" properties
+ -------------------------------------
+@@ -1218,16 +1227,14 @@
+ 
+   Required properties:
+     - reg : Offset and length of the register set for the device
+-    - device_type : Should be "mdio"
+     - compatible : Should define the compatible device type for the
+-      mdio.  Currently, this is most likely to be "gianfar"
++      mdio.  Currently, this is most likely to be "fsl,gianfar-mdio"
+ 
+   Example:
+ 
+ 	mdio@24520 {
+ 		reg = <24520 20>;
+-		device_type = "mdio"; 
+-		compatible = "gianfar";
++		compatible = "fsl,gianfar-mdio";
+ 
+ 		ethernet-phy@0 {
+ 			......
+@@ -1254,6 +1261,10 @@
+       services interrupts for this device.
+     - phy-handle : The phandle for the PHY connected to this ethernet
+       controller.
++    - fixed-link : <a b c d e> where a is emulated phy id - choose any,
++      but unique to the all specified fixed-links, b is duplex - 0 half,
++      1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no
++      pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause.
+ 
+   Recommended properties:
+ 
+@@ -1408,7 +1419,6 @@
+ 
+    Example multi port host USB controller device node :
+ 	usb@22000 {
+-	        device_type = "usb";
+ 		compatible = "fsl-usb2-mph";
+ 		reg = <22000 1000>;
+ 		#address-cells = <1>;
+@@ -1422,7 +1432,6 @@
+ 
+    Example dual role USB controller device node :
+ 	usb@23000 {
+-		device_type = "usb";
+ 		compatible = "fsl-usb2-dr";
+ 		reg = <23000 1000>;
+ 		#address-cells = <1>;
+@@ -1586,7 +1595,6 @@
+    iii) USB (Universal Serial Bus Controller)
+ 
+    Required properties:
+-   - device_type : should be "usb".
+    - compatible : could be "qe_udc" or "fhci-hcd".
+    - mode : the could be "host" or "slave".
+    - reg : Offset and length of the register set for the device
+@@ -1600,7 +1608,6 @@
+ 
+    Example(slave):
+ 	usb@6c0 {
+-		device_type = "usb";
+ 		compatible = "qe_udc";
+ 		reg = <6c0 40>;
+ 		interrupts = <8b 0>;
+@@ -1613,7 +1620,7 @@
+ 
+    Required properties:
+    - device_type : should be "network", "hldc", "uart", "transparent"
+-    "bisync" or "atm".
++     "bisync", "atm", or "serial".
+    - compatible : could be "ucc_geth" or "fsl_atm" and so on.
+    - model : should be "UCC".
+    - device-id : the ucc number(1-8), corresponding to UCCx in UM.
+@@ -1626,6 +1633,26 @@
+    - interrupt-parent : the phandle for the interrupt controller that
+      services interrupts for this device.
+    - pio-handle : The phandle for the Parallel I/O port configuration.
++   - port-number : for UART drivers, the port number to use, between 0 and 3.
++     This usually corresponds to the /dev/ttyQE device, e.g. <0> = /dev/ttyQE0.
++     The port number is added to the minor number of the device.  Unlike the
++     CPM UART driver, the port-number is required for the QE UART driver.
++   - soft-uart : for UART drivers, if specified this means the QE UART device
++     driver should use "Soft-UART" mode, which is needed on some SOCs that have
++     broken UART hardware.  Soft-UART is provided via a microcode upload.
++   - rx-clock-name: the UCC receive clock source
++     "none": clock source is disabled
++     "brg1" through "brg16": clock source is BRG1-BRG16, respectively
++     "clk1" through "clk24": clock source is CLK1-CLK24, respectively
++   - tx-clock-name: the UCC transmit clock source
++     "none": clock source is disabled
++     "brg1" through "brg16": clock source is BRG1-BRG16, respectively
++     "clk1" through "clk24": clock source is CLK1-CLK24, respectively
++   The following two properties are deprecated.  rx-clock has been replaced
++   with rx-clock-name, and tx-clock has been replaced with tx-clock-name.
++   Drivers that currently use the deprecated properties should continue to
++   do so, in order to support older device trees, but they should be updated
++   to check for the new properties first.
+    - rx-clock : represents the UCC receive clock source.
+      0x00 : clock source is disabled;
+      0x1~0x10 : clock source is BRG1~BRG16 respectively;
+@@ -1772,6 +1799,32 @@
+ 		};
+ 	};
+ 
++   viii) Uploaded QE firmware
++
++	 If a new firwmare has been uploaded to the QE (usually by the
++	 boot loader), then a 'firmware' child node should be added to the QE
++	 node.  This node provides information on the uploaded firmware that
++	 device drivers may need.
++
++	 Required properties:
++	 - id: The string name of the firmware.  This is taken from the 'id'
++	       member of the qe_firmware structure of the uploaded firmware.
++	       Device drivers can search this string to determine if the
++	       firmware they want is already present.
++	 - extended-modes: The Extended Modes bitfield, taken from the
++			   firmware binary.  It is a 64-bit number represented
++			   as an array of two 32-bit numbers.
++	 - virtual-traps: The virtual traps, taken from the firmware binary.
++			  It is an array of 8 32-bit numbers.
++
++	 Example:
++
++		firmware {
++			id = "Soft-UART";
++			extended-modes = <0 0>;
++			virtual-traps = <0 0 0 0 0 0 0 0>;
++		}
++
+    j) CFI or JEDEC memory-mapped NOR flash
+ 
+     Flash chips (Memory Technology Devices) are often used for solid state
+@@ -2075,8 +2128,7 @@
+ 
+    Example:
+ 	localbus@f0010100 {
+-		compatible = "fsl,mpc8272ads-localbus",
+-		             "fsl,mpc8272-localbus",
++		compatible = "fsl,mpc8272-localbus",
+ 		             "fsl,pq2-localbus";
+ 		#address-cells = <2>;
+ 		#size-cells = <1>;
+@@ -2254,7 +2306,7 @@
+ 			   available.
+ 			   For Axon: 0x0000012a
+ 
+-   l) Xilinx IP cores
++   o) Xilinx IP cores
+ 
+    The Xilinx EDK toolchain ships with a set of IP cores (devices) for use
+    in Xilinx Spartan and Virtex FPGAs.  The devices cover the whole range
+@@ -2276,7 +2328,7 @@
+    properties of the device node.  In general, device nodes for IP-cores
+    will take the following form:
+ 
+-	(name)@(base-address) {
++	(name): (generic-name)@(base-address) {
+ 		compatible = "xlnx,(ip-core-name)-(HW_VER)"
+ 			     [, (list of compatible devices), ...];
+ 		reg = <(baseaddr) (size)>;
+@@ -2286,6 +2338,9 @@
+ 		xlnx,(parameter2) = <(int-value)>;
+ 	};
+ 
++	(generic-name):   an open firmware-style name that describes the
++			generic class of device.  Preferably, this is one word, such
++			as 'serial' or 'ethernet'.
+ 	(ip-core-name):	the name of the ip block (given after the BEGIN
+ 			directive in system.mhs).  Should be in lowercase
+ 			and all underscores '_' converted to dashes '-'.
+@@ -2294,9 +2349,9 @@
+ 			dropped from the parameter name, the name is converted
+ 			to lowercase and all underscore '_' characters are
+ 			converted to dashes '-'.
+-	(baseaddr):	the C_BASEADDR parameter.
++	(baseaddr):	the baseaddr parameter value (often named C_BASEADDR).
+ 	(HW_VER):	from the HW_VER parameter.
+-	(size):		equals C_HIGHADDR - C_BASEADDR + 1
++	(size):		the address range size (often C_HIGHADDR - C_BASEADDR + 1).
+ 
+    Typically, the compatible list will include the exact IP core version
+    followed by an older IP core version which implements the same
+@@ -2326,11 +2381,11 @@
+ 
+    becomes the following device tree node:
+ 
+-	opb-uartlite-0@ec100000 {
++	opb_uartlite_0: serial@ec100000 {
+ 		device_type = "serial";
+ 		compatible = "xlnx,opb-uartlite-1.00.b";
+ 		reg = <ec100000 10000>;
+-		interrupt-parent = <&opb-intc>;
++		interrupt-parent = <&opb_intc_0>;
+ 		interrupts = <1 0>; // got this from the opb_intc parameters
+ 		current-speed = <d#115200>;	// standard serial device prop
+ 		clock-frequency = <d#50000000>;	// standard serial device prop
+@@ -2339,16 +2394,19 @@
+ 		xlnx,use-parity = <0>;
+ 	};
+ 
+-   Some IP cores actually implement 2 or more logical devices.  In this case,
+-   the device should still describe the whole IP core with a single node
+-   and add a child node for each logical device.  The ranges property can
+-   be used to translate from parent IP-core to the registers of each device.
+-   (Note: this makes the assumption that both logical devices have the same
+-   bus binding.  If this is not true, then separate nodes should be used for
+-   each logical device).  The 'cell-index' property can be used to enumerate
+-   logical devices within an IP core.  For example, the following is the
+-   system.mhs entry for the dual ps2 controller found on the ml403 reference
+-   design.
++   Some IP cores actually implement 2 or more logical devices.  In
++   this case, the device should still describe the whole IP core with
++   a single node and add a child node for each logical device.  The
++   ranges property can be used to translate from parent IP-core to the
++   registers of each device.  In addition, the parent node should be
++   compatible with the bus type 'xlnx,compound', and should contain
++   #address-cells and #size-cells, as with any other bus.  (Note: this
++   makes the assumption that both logical devices have the same bus
++   binding.  If this is not true, then separate nodes should be used
++   for each logical device).  The 'cell-index' property can be used to
++   enumerate logical devices within an IP core.  For example, the
++   following is the system.mhs entry for the dual ps2 controller found
++   on the ml403 reference design.
+ 
+ 	BEGIN opb_ps2_dual_ref
+ 		PARAMETER INSTANCE = opb_ps2_dual_ref_0
+@@ -2370,21 +2428,24 @@
+ 
+    It would result in the following device tree nodes:
+ 
+-	opb_ps2_dual_ref_0@a9000000 {
++	opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		compatible = "xlnx,compound";
+ 		ranges = <0 a9000000 2000>;
+ 		// If this device had extra parameters, then they would
+ 		// go here.
+ 		ps2@0 {
+ 			compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
+ 			reg = <0 40>;
+-			interrupt-parent = <&opb-intc>;
++			interrupt-parent = <&opb_intc_0>;
+ 			interrupts = <3 0>;
+ 			cell-index = <0>;
+ 		};
+ 		ps2@1000 {
+ 			compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
+ 			reg = <1000 40>;
+-			interrupt-parent = <&opb-intc>;
++			interrupt-parent = <&opb_intc_0>;
+ 			interrupts = <3 0>;
+ 			cell-index = <0>;
+ 		};
+@@ -2447,17 +2508,18 @@
+ 
+    Gives this device tree (some properties removed for clarity):
+ 
+-	plb-v34-0 {
++	plb@0 {
+ 		#address-cells = <1>;
+ 		#size-cells = <1>;
++		compatible = "xlnx,plb-v34-1.02.a";
+ 		device_type = "ibm,plb";
+ 		ranges; // 1:1 translation
+ 
+-		plb-bram-if-cntrl-0@ffff0000 {
++		plb_bram_if_cntrl_0: bram@ffff0000 {
+ 			reg = <ffff0000 10000>;
+ 		}
+ 
+-		opb-v20-0 {
++		opb@20000000 {
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+ 			ranges = <20000000 20000000 20000000
+@@ -2465,11 +2527,11 @@
+ 				  80000000 80000000 40000000
+ 				  c0000000 c0000000 20000000>;
+ 
+-			opb-uart16550-0@a0000000 {
++			opb_uart16550_0: serial@a0000000 {
+ 				reg = <a00000000 2000>;
+ 			};
+ 
+-			opb-intc-0@d1000fc0 {
++			opb_intc_0: interrupt-controller@d1000fc0 {
+ 				reg = <d1000fc0 20>;
+ 			};
+ 		};
+@@ -2514,6 +2576,46 @@
+       Requred properties:
+        - current-speed : Baud rate of uartlite
+ 
++    p) Freescale Synchronous Serial Interface
++
++       The SSI is a serial device that communicates with audio codecs.  It can
++       be programmed in AC97, I2S, left-justified, or right-justified modes.
++
++       Required properties:
++       - compatible	  : compatible list, containing "fsl,ssi"
++       - cell-index	  : the SSI, <0> = SSI1, <1> = SSI2, and so on
++       - reg		  : offset and length of the register set for the device
++       - interrupts	  : <a b> where a is the interrupt number and b is a
++                            field that represents an encoding of the sense and
++			    level information for the interrupt.  This should be
++			    encoded based on the information in section 2)
++			    depending on the type of interrupt controller you
++			    have.
++       - interrupt-parent : the phandle for the interrupt controller that
++                            services interrupts for this device.
++       - fsl,mode	  : the operating mode for the SSI interface
++			    "i2s-slave" - I2S mode, SSI is clock slave
++			    "i2s-master" - I2S mode, SSI is clock master
++			    "lj-slave" - left-justified mode, SSI is clock slave
++			    "lj-master" - l.j. mode, SSI is clock master
++			    "rj-slave" - right-justified mode, SSI is clock slave
++			    "rj-master" - r.j., SSI is clock master
++			    "ac97-slave" - AC97 mode, SSI is clock slave
++			    "ac97-master" - AC97 mode, SSI is clock master
++
++       Optional properties:
++       - codec-handle	  : phandle to a 'codec' node that defines an audio
++			    codec connected to this SSI.  This node is typically
++			    a child of an I2C or other control node.
++
++       Child 'codec' node required properties:
++       - compatible	  : compatible list, contains the name of the codec
++
++       Child 'codec' node optional properties:
++       - clock-frequency  : The frequency of the input clock, which typically
++                            comes from an on-board dedicated oscillator.
++
++
+    More devices will be defined as this spec matures.
+ 
+ VII - Specifying interrupt information for devices
+diff -x .git -x .gitignore -Nur linux-2.6.24/Documentation/powerpc/qe_firmware.txt powerpc.git/Documentation/powerpc/qe_firmware.txt
+--- linux-2.6.24/Documentation/powerpc/qe_firmware.txt	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/Documentation/powerpc/qe_firmware.txt	2008-01-28 20:25:33.000000000 +0100
+@@ -0,0 +1,295 @@
++	   Freescale QUICC Engine Firmware Uploading
++	   -----------------------------------------
++
++(c) 2007 Timur Tabi <timur at freescale.com>,
++    Freescale Semiconductor
++
++Table of Contents
++=================
++
++  I - Software License for Firmware
++
++  II - Microcode Availability
++
++  III - Description and Terminology
++
++  IV - Microcode Programming Details
++
++  V - Firmware Structure Layout
++
++  VI - Sample Code for Creating Firmware Files
++
++Revision Information
++====================
++
++November 30, 2007: Rev 1.0 - Initial version
++
++I - Software License for Firmware
++=================================
++
++Each firmware file comes with its own software license.  For information on
++the particular license, please see the license text that is distributed with
++the firmware.
++
++II - Microcode Availability
++===========================
++
++Firmware files are distributed through various channels.  Some are available on
++http://opensource.freescale.com.  For other firmware files, please contact
++your Freescale representative or your operating system vendor.
++
++III - Description and Terminology
++================================
++
++In this document, the term 'microcode' refers to the sequence of 32-bit
++integers that compose the actual QE microcode.
++
++The term 'firmware' refers to a binary blob that contains the microcode as
++well as other data that
++
++	1) describes the microcode's purpose
++	2) describes how and where to upload the microcode
++	3) specifies the values of various registers
++	4) includes additional data for use by specific device drivers
++
++Firmware files are binary files that contain only a firmware.
++
++IV - Microcode Programming Details
++===================================
++
++The QE architecture allows for only one microcode present in I-RAM for each
++RISC processor.  To replace any current microcode, a full QE reset (which
++disables the microcode) must be performed first.
++
++QE microcode is uploaded using the following procedure:
++
++1) The microcode is placed into I-RAM at a specific location, using the
++   IRAM.IADD and IRAM.IDATA registers.
++
++2) The CERCR.CIR bit is set to 0 or 1, depending on whether the firmware
++   needs split I-RAM.  Split I-RAM is only meaningful for SOCs that have
++   QEs with multiple RISC processors, such as the 8360.  Splitting the I-RAM
++   allows each processor to run a different microcode, effectively creating an
++   asymmetric multiprocessing (AMP) system.
++
++3) The TIBCR trap registers are loaded with the addresses of the trap handlers
++   in the microcode.
++
++4) The RSP.ECCR register is programmed with the value provided.
++
++5) If necessary, device drivers that need the virtual traps and extended mode
++   data will use them.
++
++Virtual Microcode Traps
++
++These virtual traps are conditional branches in the microcode.  These are
++"soft" provisional introduced in the ROMcode in order to enable higher
++flexibility and save h/w traps If new features are activated or an issue is
++being fixed in the RAM package utilizing they should be activated.  This data
++structure signals the microcode which of these virtual traps is active.
++
++This structure contains 6 words that the application should copy to some
++specific been defined.  This table describes the structure.
++
++	---------------------------------------------------------------
++	| Offset in |                  | Destination Offset | Size of |
++	|   array   |     Protocol     |   within PRAM      | Operand |
++	--------------------------------------------------------------|
++	|     0     | Ethernet         |      0xF8          | 4 bytes |
++	|           | interworking     |                    |         |
++	---------------------------------------------------------------
++	|     4     | ATM              |      0xF8          | 4 bytes |
++	|           | interworking     |                    |         |
++	---------------------------------------------------------------
++	|     8     | PPP              |      0xF8          | 4 bytes |
++	|           | interworking     |                    |         |
++	---------------------------------------------------------------
++	|     12    | Ethernet RX      |      0x22          | 1 byte  |
++	|           | Distributor Page |                    |         |
++	---------------------------------------------------------------
++	|     16    | ATM Globtal      |      0x28          | 1 byte  |
++	|           | Params Table     |                    |         |
++	---------------------------------------------------------------
++	|     20    | Insert Frame     |      0xF8          | 4 bytes |
++	---------------------------------------------------------------
++
++
++Extended Modes
++
++This is a double word bit array (64 bits) that defines special functionality
++which has an impact on the softwarew drivers.  Each bit has its own impact
++and has special instructions for the s/w associated with it.  This structure is
++described in this table:
++
++	-----------------------------------------------------------------------
++	| Bit #  |     Name     |   Description                               |
++	-----------------------------------------------------------------------
++	|   0    | General      | Indicates that prior to each host command   |
++	|        | push command | given by the application, the software must |
++	|        |              | assert a special host command (push command)|
++	|        |              | CECDR = 0x00800000.                         |
++	|        |              | CECR = 0x01c1000f.                          |
++	-----------------------------------------------------------------------
++	|   1    | UCC ATM      | Indicates that after issuing ATM RX INIT    |
++	|        | RX INIT      | command, the host must issue another special|
++	|        | push command | command (push command) and immediately      |
++	|        |              | following that re-issue the ATM RX INIT     |
++	|        |              | command. (This makes the sequence of        |
++	|        |              | initializing the ATM receiver a sequence of |
++	|        |              | three host commands)                        |
++	|        |              | CECDR = 0x00800000.                         |
++	|        |              | CECR = 0x01c1000f.                          |
++	-----------------------------------------------------------------------
++	|   2    | Add/remove   | Indicates that following the specific host  |
++	|        | command      | command: "Add/Remove entry in Hash Lookup   |
++	|        | validation   | Table" used in Interworking setup, the user |
++	|        |              | must issue another command.                 |
++	|        |              | CECDR = 0xce000003.                         |
++	|        |              | CECR = 0x01c10f58.                          |
++	-----------------------------------------------------------------------
++	|   3    | General push | Indicates that the s/w has to initialize    |
++	|        | command      | some pointers in the Ethernet thread pages  |
++	|        |              | which are used when Header Compression is   |
++	|        |              | activated.  The full details of these       |
++	|        |              | pointers is located in the software drivers.|
++	-----------------------------------------------------------------------
++	|   4    | General push | Indicates that after issuing Ethernet TX    |
++	|        | command      | INIT command, user must issue this command  |
++	|        |              | for each SNUM of Ethernet TX thread.        |
++	|        |              | CECDR = 0x00800003.                         |
++	|        |              | CECR = 0x7'b{0}, 8'b{Enet TX thread SNUM},  |
++	|        |              |        1'b{1}, 12'b{0}, 4'b{1}              |
++	-----------------------------------------------------------------------
++	| 5 - 31 |     N/A      | Reserved, set to zero.                      |
++	-----------------------------------------------------------------------
++
++V - Firmware Structure Layout
++==============================
++
++QE microcode from Freescale is typically provided as a header file.  This
++header file contains macros that define the microcode binary itself as well as
++some other data used in uploading that microcode.  The format of these files
++do not lend themselves to simple inclusion into other code.  Hence,
++the need for a more portable format.  This section defines that format.
++
++Instead of distributing a header file, the microcode and related data are
++embedded into a binary blob.  This blob is passed to the qe_upload_firmware()
++function, which parses the blob and performs everything necessary to upload
++the microcode.
++
++All integers are big-endian.  See the comments for function
++qe_upload_firmware() for up-to-date implementation information.
++
++This structure supports versioning, where the version of the structure is
++embedded into the structure itself.  To ensure forward and backwards
++compatibility, all versions of the structure must use the same 'qe_header'
++structure at the beginning.
++
++'header' (type: struct qe_header):
++	The 'length' field is the size, in bytes, of the entire structure,
++	including all the microcode embedded in it, as well as the CRC (if
++	present).
++
++	The 'magic' field is an array of three bytes that contains the letters
++	'Q', 'E', and 'F'.  This is an identifier that indicates that this
++	structure is a QE Firmware structure.
++
++	The 'version' field is a single byte that indicates the version of this
++	structure.  If the layout of the structure should ever need to be
++	changed to add support for additional types of microcode, then the
++	version number should also be changed.
++
++The 'id' field is a null-terminated string(suitable for printing) that
++identifies the firmware.
++
++The 'count' field indicates the number of 'microcode' structures.  There
++must be one and only one 'microcode' structure for each RISC processor.
++Therefore, this field also represents the number of RISC processors for this
++SOC.
++
++The 'soc' structure contains the SOC numbers and revisions used to match
++the microcode to the SOC itself.  Normally, the microcode loader should
++check the data in this structure with the SOC number and revisions, and
++only upload the microcode if there's a match.  However, this check is not
++made on all platforms.
++
++Although it is not recommended, you can specify '0' in the soc.model
++field to skip matching SOCs altogether.
++
++The 'model' field is a 16-bit number that matches the actual SOC. The
++'major' and 'minor' fields are the major and minor revision numbrs,
++respectively, of the SOC.
++
++For example, to match the 8323, revision 1.0:
++     soc.model = 8323
++     soc.major = 1
++     soc.minor = 0
++
++'padding' is neccessary for structure alignment.  This field ensures that the
++'extended_modes' field is aligned on a 64-bit boundary.
++
++'extended_modes' is a bitfield that defines special functionality which has an
++impact on the device drivers.  Each bit has its own impact and has special
++instructions for the driver associated with it.  This field is stored in
++the QE library and available to any driver that calles qe_get_firmware_info().
++
++'vtraps' is an array of 8 words that contain virtual trap values for each
++virtual traps.  As with 'extended_modes', this field is stored in the QE
++library and available to any driver that calles qe_get_firmware_info().
++
++'microcode' (type: struct qe_microcode):
++	For each RISC processor there is one 'microcode' structure.  The first
++	'microcode' structure is for the first RISC, and so on.
++
++	The 'id' field is a null-terminated string suitable for printing that
++	identifies this particular microcode.
++
++	'traps' is an array of 16 words that contain hardware trap values
++	for each of the 16 traps.  If trap[i] is 0, then this particular
++	trap is to be ignored (i.e. not written to TIBCR[i]).  The entire value
++	is written as-is to the TIBCR[i] register, so be sure to set the EN
++	and T_IBP bits if necessary.
++
++	'eccr' is the value to program into the ECCR register.
++
++	'iram_offset' is the offset into IRAM to start writing the
++	microcode.
++
++	'count' is the number of 32-bit words in the microcode.
++
++	'code_offset' is the offset, in bytes, from the beginning of this
++	structure where the microcode itself can be found.  The first
++	microcode binary should be located immediately after the 'microcode'
++	array.
++
++	'major', 'minor', and 'revision' are the major, minor, and revision
++	version numbers, respectively, of the microcode.  If all values are 0,
++	then these fields are ignored.
++
++	'reserved' is necessary for structure alignment.  Since 'microcode'
++	is an array, the 64-bit 'extended_modes' field needs to be aligned
++	on a 64-bit boundary, and this can only happen if the size of
++	'microcode' is a multiple of 8 bytes.  To ensure that, we add
++	'reserved'.
++
++After the last microcode is a 32-bit CRC.  It can be calculated using
++this algorithm:
++
++u32 crc32(const u8 *p, unsigned int len)
++{
++	unsigned int i;
++	u32 crc = 0;
++
++	while (len--) {
++	   crc ^= *p++;
++	   for (i = 0; i < 8; i++)
++		   crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
++	}
++	return crc;
++}
++
++VI - Sample Code for Creating Firmware Files
++============================================
++
++A Python program that creates firmware binaries from the header files normally
++distributed by Freescale can be found on http://opensource.freescale.com.
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/Kconfig powerpc.git/arch/powerpc/Kconfig
+--- linux-2.6.24/arch/powerpc/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/Kconfig	2008-01-28 21:37:04.000000000 +0100
+@@ -140,6 +140,9 @@
+ 	  Used to allow a board to specify it wants a uImage built by default
+ 	default n
+ 
++config REDBOOT
++	bool
++
+ config PPC64_SWSUSP
+ 	bool
+ 	depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL))
+@@ -160,11 +163,13 @@
+ 
+ config PPC_OF_PLATFORM_PCI
+ 	bool
++	depends on PCI
+ 	depends on PPC64 # not supported on 32 bits yet
+ 	default n
+ 
+ source "init/Kconfig"
+ 
++source "arch/powerpc/sysdev/Kconfig"
+ source "arch/powerpc/platforms/Kconfig"
+ 
+ menu "Kernel options"
+@@ -417,7 +422,7 @@
+ 
+ config ISA_DMA_API
+ 	bool
+-	default y
++	default !PPC_ISERIES || PCI
+ 
+ menu "Bus options"
+ 
+@@ -467,7 +472,7 @@
+ config PCI
+ 	bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
+ 		|| PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
+-		|| PPC_PS3
++		|| PPC_PS3 || 44x
+ 	default y if !40x && !CPM2 && !8xx && !PPC_83xx \
+ 		&& !PPC_85xx && !PPC_86xx
+ 	default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/Kconfig.debug powerpc.git/arch/powerpc/Kconfig.debug
+--- linux-2.6.24/arch/powerpc/Kconfig.debug	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/Kconfig.debug	2008-01-28 20:25:49.000000000 +0100
+@@ -151,6 +151,13 @@
+ 
+ config PPC_EARLY_DEBUG
+ 	bool "Early debugging (dangerous)"
++	help
++	  Say Y to enable some early debugging facilities that may be available
++	  for your processor/board combination. Those facilities are hacks
++	  intended to debug problems early during boot, this should not be
++	  enabled in a production kernel.
++	  Note that enabling this will also cause the kernel default log level
++	  to be pushed to max automatically very early during boot
+ 
+ choice
+ 	prompt "Early debugging console"
+@@ -218,7 +225,16 @@
+ 	depends on 44x
+ 	help
+ 	  Select this to enable early debugging for IBM 44x chips via the
+-	  inbuilt serial port.
++	  inbuilt serial port.  If you enable this, ensure you set
++          PPC_EARLY_DEBUG_44x_PHYSLOW below to suit your target board.
++
++config PPC_EARLY_DEBUG_40x
++	bool "Early serial debugging for IBM/AMCC 40x CPUs"
++	depends on 40x
++	help
++	  Select this to enable early debugging for IBM 40x chips via the
++	  inbuilt serial port. This works on chips with a 16550 compatible
++	  UART. Xilinx chips with uartlite cannot use this option.
+ 
+ config PPC_EARLY_DEBUG_CPM
+ 	bool "Early serial debugging for Freescale CPM-based serial ports"
+@@ -235,12 +251,20 @@
+ 	hex "Low 32 bits of early debug UART physical address"
+ 	depends on PPC_EARLY_DEBUG_44x
+ 	default "0x40000200"
++	help
++	  You probably want 0x40000200 for ebony boards and
++          0x40000300 for taishan
+ 
+ config PPC_EARLY_DEBUG_44x_PHYSHIGH
+ 	hex "EPRN of early debug UART physical address"
+ 	depends on PPC_EARLY_DEBUG_44x
+ 	default "0x1"
+ 
++config PPC_EARLY_DEBUG_40x_PHYSADDR
++	hex "Early debug UART physical address"
++	depends on PPC_EARLY_DEBUG_40x
++	default "0xef600300"
++
+ config PPC_EARLY_DEBUG_CPM_ADDR
+ 	hex "CPM UART early debug transmit descriptor address"
+ 	depends on PPC_EARLY_DEBUG_CPM
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/Makefile powerpc.git/arch/powerpc/Makefile
+--- linux-2.6.24/arch/powerpc/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -167,6 +167,9 @@
+ $(BOOT_TARGETS): vmlinux
+ 	$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
+ 
++bootwrapper_install:
++	$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
++
+ define archhelp
+   @echo '* zImage          - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)'
+   @echo '  install         - Install kernel using'
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/4xx.c powerpc.git/arch/powerpc/boot/4xx.c
+--- linux-2.6.24/arch/powerpc/boot/4xx.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/4xx.c	2008-01-28 20:25:49.000000000 +0100
+@@ -22,16 +22,14 @@
+ #include "dcr.h"
+ 
+ /* Read the 4xx SDRAM controller to get size of system memory. */
+-void ibm4xx_fixup_memsize(void)
++void ibm4xx_sdram_fixup_memsize(void)
+ {
+ 	int i;
+ 	unsigned long memsize, bank_config;
+ 
+ 	memsize = 0;
+ 	for (i = 0; i < ARRAY_SIZE(sdram_bxcr); i++) {
+-		mtdcr(DCRN_SDRAM0_CFGADDR, sdram_bxcr[i]);
+-		bank_config = mfdcr(DCRN_SDRAM0_CFGDATA);
+-
++		bank_config = SDRAM0_READ(sdram_bxcr[i]);
+ 		if (bank_config & SDRAM_CONFIG_BANK_ENABLE)
+ 			memsize += SDRAM_CONFIG_BANK_SIZE(bank_config);
+ 	}
+@@ -39,6 +37,69 @@
+ 	dt_fixup_memory(0, memsize);
+ }
+ 
++/* Read the 440SPe MQ controller to get size of system memory. */
++#define DCRN_MQ0_B0BAS		0x40
++#define DCRN_MQ0_B1BAS		0x41
++#define DCRN_MQ0_B2BAS		0x42
++#define DCRN_MQ0_B3BAS		0x43
++
++static u64 ibm440spe_decode_bas(u32 bas)
++{
++	u64 base = ((u64)(bas & 0xFFE00000u)) << 2;
++
++	/* open coded because I'm paranoid about invalid values */
++	switch ((bas >> 4) & 0xFFF) {
++	case 0:
++		return 0;
++	case 0xffc:
++		return base + 0x000800000ull;
++	case 0xff8:
++		return base + 0x001000000ull;
++	case 0xff0:
++		return base + 0x002000000ull;
++	case 0xfe0:
++		return base + 0x004000000ull;
++	case 0xfc0:
++		return base + 0x008000000ull;
++	case 0xf80:
++		return base + 0x010000000ull;
++	case 0xf00:
++		return base + 0x020000000ull;
++	case 0xe00:
++		return base + 0x040000000ull;
++	case 0xc00:
++		return base + 0x080000000ull;
++	case 0x800:
++		return base + 0x100000000ull;
++	}
++	printf("Memory BAS value 0x%08x unsupported !\n", bas);
++	return 0;
++}
++
++void ibm440spe_fixup_memsize(void)
++{
++	u64 banktop, memsize = 0;
++
++	/* Ultimately, we should directly construct the memory node
++	 * so we are able to handle holes in the memory address space
++	 */
++	banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B0BAS));
++	if (banktop > memsize)
++		memsize = banktop;
++	banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B1BAS));
++	if (banktop > memsize)
++		memsize = banktop;
++	banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B2BAS));
++	if (banktop > memsize)
++		memsize = banktop;
++	banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B3BAS));
++	if (banktop > memsize)
++		memsize = banktop;
++
++	dt_fixup_memory(0, memsize);
++}
++
++
+ /* 4xx DDR1/2 Denali memory controller support */
+ /* DDR0 registers */
+ #define DDR0_02			2
+@@ -77,19 +138,13 @@
+ 
+ #define DDR_GET_VAL(val, mask, shift)	(((val) >> (shift)) & (mask))
+ 
+-static inline u32 mfdcr_sdram0(u32 reg)
+-{
+-        mtdcr(DCRN_SDRAM0_CFGADDR, reg);
+-        return mfdcr(DCRN_SDRAM0_CFGDATA);
+-}
+-
+ void ibm4xx_denali_fixup_memsize(void)
+ {
+ 	u32 val, max_cs, max_col, max_row;
+ 	u32 cs, col, row, bank, dpath;
+ 	unsigned long memsize;
+ 
+-	val = mfdcr_sdram0(DDR0_02);
++	val = SDRAM0_READ(DDR0_02);
+ 	if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT))
+ 		fatal("DDR controller is not initialized\n");
+ 
+@@ -99,12 +154,12 @@
+ 	max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT);
+ 
+ 	/* get CS value */
+-	val = mfdcr_sdram0(DDR0_10);
++	val = SDRAM0_READ(DDR0_10);
+ 
+ 	val = DDR_GET_VAL(val, DDR_CS_MAP, DDR_CS_MAP_SHIFT);
+ 	cs = 0;
+ 	while (val) {
+-		if (val && 0x1)
++		if (val & 0x1)
+ 			cs++;
+ 		val = val >> 1;
+ 	}
+@@ -115,15 +170,15 @@
+ 		fatal("DDR wrong CS configuration\n");
+ 
+ 	/* get data path bytes */
+-	val = mfdcr_sdram0(DDR0_14);
++	val = SDRAM0_READ(DDR0_14);
+ 
+ 	if (DDR_GET_VAL(val, DDR_REDUC, DDR_REDUC_SHIFT))
+ 		dpath = 8; /* 64 bits */
+ 	else
+ 		dpath = 4; /* 32 bits */
+ 
+-	/* get adress pins (rows) */
+-	val = mfdcr_sdram0(DDR0_42);
++	/* get address pins (rows) */
++ 	val = SDRAM0_READ(DDR0_42);
+ 
+ 	row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT);
+ 	if (row > max_row)
+@@ -131,7 +186,7 @@
+ 	row = max_row - row;
+ 
+ 	/* get collomn size and banks */
+-	val = mfdcr_sdram0(DDR0_43);
++	val = SDRAM0_READ(DDR0_43);
+ 
+ 	col = DDR_GET_VAL(val, DDR_COL_SZ, DDR_COL_SZ_SHIFT);
+ 	if (col > max_col)
+@@ -179,13 +234,17 @@
+ #define EMAC_RESET 0x20000000
+ void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1)
+ {
+-	/* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't do this for us */
++	/* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't
++	 * do this for us
++	 */
+ 	if (emac0)
+ 		*emac0 = EMAC_RESET;
+ 	if (emac1)
+ 		*emac1 = EMAC_RESET;
+ 
+ 	mtdcr(DCRN_MAL0_CFG, MAL_RESET);
++	while (mfdcr(DCRN_MAL0_CFG) & MAL_RESET)
++		; /* loop until reset takes effect */
+ }
+ 
+ /* Read 4xx EBC bus bridge registers to get mappings of the peripheral
+@@ -217,84 +276,335 @@
+ 	setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32));
+ }
+ 
+-#define SPRN_CCR1 0x378
+-void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
++/* Calculate 440GP clocks */
++void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
+ {
+-	u32 cpu, plb, opb, ebc, tb, uart0, m, vco;
+-	u32 reg;
+-	u32 fwdva, fwdvb, fbdv, lfbdv, opbdv0, perdv0, spcid0, prbdv0, tmp;
+-
+-	mtdcr(DCRN_CPR0_ADDR, CPR0_PLLD0);
+-	reg = mfdcr(DCRN_CPR0_DATA);
+-	tmp = (reg & 0x000F0000) >> 16;
+-	fwdva = tmp ? tmp : 16;
+-	tmp = (reg & 0x00000700) >> 8;
+-	fwdvb = tmp ? tmp : 8;
+-	tmp = (reg & 0x1F000000) >> 24;
+-	fbdv = tmp ? tmp : 32;
+-	lfbdv = (reg & 0x0000007F);
+-
+-	mtdcr(DCRN_CPR0_ADDR, CPR0_OPBD0);
+-	reg = mfdcr(DCRN_CPR0_DATA);
+-	tmp = (reg & 0x03000000) >> 24;
+-	opbdv0 = tmp ? tmp : 4;
+-
+-	mtdcr(DCRN_CPR0_ADDR, CPR0_PERD0);
+-	reg = mfdcr(DCRN_CPR0_DATA);
+-	tmp = (reg & 0x07000000) >> 24;
+-	perdv0 = tmp ? tmp : 8;
+-
+-	mtdcr(DCRN_CPR0_ADDR, CPR0_PRIMBD0);
+-	reg = mfdcr(DCRN_CPR0_DATA);
+-	tmp = (reg & 0x07000000) >> 24;
+-	prbdv0 = tmp ? tmp : 8;
+-
+-	mtdcr(DCRN_CPR0_ADDR, CPR0_SCPID);
+-	reg = mfdcr(DCRN_CPR0_DATA);
+-	tmp = (reg & 0x03000000) >> 24;
+-	spcid0 = tmp ? tmp : 4;
+-
+-	/* Calculate M */
+-	mtdcr(DCRN_CPR0_ADDR, CPR0_PLLC0);
+-	reg = mfdcr(DCRN_CPR0_DATA);
+-	tmp = (reg & 0x03000000) >> 24;
+-	if (tmp == 0) { /* PLL output */
+-		tmp = (reg & 0x20000000) >> 29;
+-		if (!tmp) /* PLLOUTA */
+-			m = fbdv * lfbdv * fwdva;
++	u32 sys0 = mfdcr(DCRN_CPC0_SYS0);
++	u32 cr0 = mfdcr(DCRN_CPC0_CR0);
++	u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
++	u32 opdv = CPC0_SYS0_OPDV(sys0);
++	u32 epdv = CPC0_SYS0_EPDV(sys0);
++
++	if (sys0 & CPC0_SYS0_BYPASS) {
++		/* Bypass system PLL */
++		cpu = plb = sys_clk;
++	} else {
++		if (sys0 & CPC0_SYS0_EXTSL)
++			/* PerClk */
++			m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv;
+ 		else
+-			m = fbdv * lfbdv * fwdvb;
++			/* CPU clock */
++			m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0);
++		cpu = sys_clk * m / CPC0_SYS0_FWDVA(sys0);
++		plb = sys_clk * m / CPC0_SYS0_FWDVB(sys0);
+ 	}
+-	else if (tmp == 1) /* CPU output */
+-		m = fbdv * fwdva;
++
++	opb = plb / opdv;
++	ebc = opb / epdv;
++
++	/* FIXME: Check if this is for all 440GP, or just Ebony */
++	if ((mfpvr() & 0xf0000fff) == 0x40000440)
++		/* Rev. B 440GP, use external system clock */
++		tb = sys_clk;
+ 	else
+-		m = perdv0 * opbdv0 * fwdvb;
++		/* Rev. C 440GP, errata force us to use internal clock */
++		tb = cpu;
+ 
+-	vco = (m * sysclk) + (m >> 1);
+-	cpu = vco / fwdva;
+-	plb = vco / fwdvb / prbdv0;
+-	opb = plb / opbdv0;
+-	ebc = plb / perdv0;
++	if (cr0 & CPC0_CR0_U0EC)
++		/* External UART clock */
++		uart0 = ser_clk;
++	else
++		/* Internal UART clock */
++		uart0 = plb / CPC0_CR0_UDIV(cr0);
+ 
+-	/* FIXME */
+-	uart0 = ser_clk;
++	if (cr0 & CPC0_CR0_U1EC)
++		/* External UART clock */
++		uart1 = ser_clk;
++	else
++		/* Internal UART clock */
++		uart1 = plb / CPC0_CR0_UDIV(cr0);
++
++	printf("PPC440GP: SysClk = %dMHz (%x)\n\r",
++	       (sys_clk + 500000) / 1000000, sys_clk);
++
++	dt_fixup_cpu_clocks(cpu, tb, 0);
++
++	dt_fixup_clock("/plb", plb);
++	dt_fixup_clock("/plb/opb", opb);
++	dt_fixup_clock("/plb/opb/ebc", ebc);
++	dt_fixup_clock("/plb/opb/serial@40000200", uart0);
++	dt_fixup_clock("/plb/opb/serial@40000300", uart1);
++}
++
++#define SPRN_CCR1 0x378
++
++static inline u32 __fix_zero(u32 v, u32 def)
++{
++	return v ? v : def;
++}
++
++static unsigned int __ibm440eplike_fixup_clocks(unsigned int sys_clk,
++						unsigned int tmr_clk,
++						int per_clk_from_opb)
++{
++	/* PLL config */
++	u32 pllc  = CPR0_READ(DCRN_CPR0_PLLC);
++	u32 plld  = CPR0_READ(DCRN_CPR0_PLLD);
++
++	/* Dividers */
++	u32 fbdv   = __fix_zero((plld >> 24) & 0x1f, 32);
++	u32 fwdva  = __fix_zero((plld >> 16) & 0xf, 16);
++	u32 fwdvb  = __fix_zero((plld >> 8) & 7, 8);
++	u32 lfbdv  = __fix_zero(plld & 0x3f, 64);
++	u32 pradv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PRIMAD) >> 24) & 7, 8);
++	u32 prbdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PRIMBD) >> 24) & 7, 8);
++	u32 opbdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_OPBD) >> 24) & 3, 4);
++	u32 perdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PERD) >> 24) & 3, 4);
++
++	/* Input clocks for primary dividers */
++	u32 clk_a, clk_b;
++
++	/* Resulting clocks */
++	u32 cpu, plb, opb, ebc, vco;
++
++	/* Timebase */
++	u32 ccr1, tb = tmr_clk;
++
++	if (pllc & 0x40000000) {
++		u32 m;
++
++		/* Feedback path */
++		switch ((pllc >> 24) & 7) {
++		case 0:
++			/* PLLOUTx */
++			m = ((pllc & 0x20000000) ? fwdvb : fwdva) * lfbdv;
++			break;
++		case 1:
++			/* CPU */
++			m = fwdva * pradv0;
++			break;
++		case 5:
++			/* PERClk */
++			m = fwdvb * prbdv0 * opbdv0 * perdv0;
++			break;
++		default:
++			printf("WARNING ! Invalid PLL feedback source !\n");
++			goto bypass;
++		}
++		m *= fbdv;
++		vco = sys_clk * m;
++		clk_a = vco / fwdva;
++		clk_b = vco / fwdvb;
++	} else {
++bypass:
++		/* Bypass system PLL */
++		vco = 0;
++		clk_a = clk_b = sys_clk;
++	}
++
++	cpu = clk_a / pradv0;
++	plb = clk_b / prbdv0;
++	opb = plb / opbdv0;
++	ebc = (per_clk_from_opb ? opb : plb) / perdv0;
+ 
+ 	/* Figure out timebase.  Either CPU or default TmrClk */
+-	asm volatile (
+-			"mfspr	%0,%1\n"
+-			:
+-			"=&r"(reg) : "i"(SPRN_CCR1));
+-	if (reg & 0x0080)
+-		tb = 25000000; /* TmrClk is 25MHz */
+-	else
++	ccr1 = mfspr(SPRN_CCR1);
++
++	/* If passed a 0 tmr_clk, force CPU clock */
++	if (tb == 0) {
++		ccr1 &= ~0x80u;
++		mtspr(SPRN_CCR1, ccr1);
++	}
++	if ((ccr1 & 0x0080) == 0)
+ 		tb = cpu;
+ 
+ 	dt_fixup_cpu_clocks(cpu, tb, 0);
+ 	dt_fixup_clock("/plb", plb);
+ 	dt_fixup_clock("/plb/opb", opb);
+ 	dt_fixup_clock("/plb/opb/ebc", ebc);
++
++	return plb;
++}
++
++static void eplike_fixup_uart_clk(int index, const char *path,
++				  unsigned int ser_clk,
++				  unsigned int plb_clk)
++{
++	unsigned int sdr;
++	unsigned int clock;
++
++	switch (index) {
++	case 0:
++		sdr = SDR0_READ(DCRN_SDR0_UART0);
++		break;
++	case 1:
++		sdr = SDR0_READ(DCRN_SDR0_UART1);
++		break;
++	case 2:
++		sdr = SDR0_READ(DCRN_SDR0_UART2);
++		break;
++	case 3:
++		sdr = SDR0_READ(DCRN_SDR0_UART3);
++		break;
++	default:
++		return;
++	}
++
++	if (sdr & 0x00800000u)
++		clock = ser_clk;
++	else
++		clock = plb_clk / __fix_zero(sdr & 0xff, 256);
++
++	dt_fixup_clock(path, clock);
++}
++
++void ibm440ep_fixup_clocks(unsigned int sys_clk,
++			   unsigned int ser_clk,
++			   unsigned int tmr_clk)
++{
++	unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0);
++
++	/* serial clocks beed fixup based on int/ext */
++	eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk);
++	eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk);
++	eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk);
++	eplike_fixup_uart_clk(3, "/plb/opb/serial@ef600600", ser_clk, plb_clk);
++}
++
++void ibm440gx_fixup_clocks(unsigned int sys_clk,
++			   unsigned int ser_clk,
++			   unsigned int tmr_clk)
++{
++	unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
++
++	/* serial clocks beed fixup based on int/ext */
++	eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk);
++	eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk);
++}
++
++void ibm440spe_fixup_clocks(unsigned int sys_clk,
++			    unsigned int ser_clk,
++			    unsigned int tmr_clk)
++{
++	unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
++
++	/* serial clocks beed fixup based on int/ext */
++	eplike_fixup_uart_clk(0, "/plb/opb/serial@10000200", ser_clk, plb_clk);
++	eplike_fixup_uart_clk(1, "/plb/opb/serial@10000300", ser_clk, plb_clk);
++	eplike_fixup_uart_clk(2, "/plb/opb/serial@10000600", ser_clk, plb_clk);
++}
++
++void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
++{
++	u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
++	u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
++	u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
++	u32 psr = mfdcr(DCRN_405_CPC0_PSR);
++	u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
++	u32 fwdv, fwdvb, fbdv, cbdv, opdv, epdv, ppdv, udiv;
++
++	fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
++	fbdv = (pllmr & 0x1e000000) >> 25;
++	if (fbdv == 0)
++		fbdv = 16;
++	cbdv = ((pllmr & 0x00060000) >> 17) + 1; /* CPU:PLB */
++	opdv = ((pllmr & 0x00018000) >> 15) + 1; /* PLB:OPB */
++	ppdv = ((pllmr & 0x00001800) >> 13) + 1; /* PLB:PCI */
++	epdv = ((pllmr & 0x00001800) >> 11) + 2; /* PLB:EBC */
++	udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
++
++	/* check for 405GPr */
++	if ((mfpvr() & 0xfffffff0) == (0x50910951 & 0xfffffff0)) {
++		fwdvb = 8 - (pllmr & 0x00000007);
++		if (!(psr & 0x00001000)) /* PCI async mode enable == 0 */
++			if (psr & 0x00000020) /* New mode enable */
++				m = fwdvb * 2 * ppdv;
++			else
++				m = fwdvb * cbdv * ppdv;
++		else if (psr & 0x00000020) /* New mode enable */
++			if (psr & 0x00000800) /* PerClk synch mode */
++				m = fwdvb * 2 * epdv;
++			else
++				m = fbdv * fwdv;
++		else if (epdv == fbdv)
++			m = fbdv * cbdv * epdv;
++		else
++			m = fbdv * fwdvb * cbdv;
++
++		cpu = sys_clk * m / fwdv;
++		plb = sys_clk * m / (fwdvb * cbdv);
++	} else {
++		m = fwdv * fbdv * cbdv;
++		cpu = sys_clk * m / fwdv;
++		plb = cpu / cbdv;
++	}
++	opb = plb / opdv;
++	ebc = plb / epdv;
++
++	if (cpc0_cr0 & 0x80)
++		/* uart0 uses the external clock */
++		uart0 = ser_clk;
++	else
++		uart0 = cpu / udiv;
++
++	if (cpc0_cr0 & 0x40)
++		/* uart1 uses the external clock */
++		uart1 = ser_clk;
++	else
++		uart1 = cpu / udiv;
++
++	/* setup the timebase clock to tick at the cpu frequency */
++	cpc0_cr1 = cpc0_cr1 & ~0x00800000;
++	mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
++	tb = cpu;
++
++	dt_fixup_cpu_clocks(cpu, tb, 0);
++	dt_fixup_clock("/plb", plb);
++	dt_fixup_clock("/plb/opb", opb);
++	dt_fixup_clock("/plb/ebc", ebc);
++	dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
++	dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
++}
++
++
++void ibm405ep_fixup_clocks(unsigned int sys_clk)
++{
++	u32 pllmr0 = mfdcr(DCRN_CPC0_PLLMR0);
++	u32 pllmr1 = mfdcr(DCRN_CPC0_PLLMR1);
++	u32 cpc0_ucr = mfdcr(DCRN_CPC0_UCR);
++	u32 cpu, plb, opb, ebc, uart0, uart1;
++	u32 fwdva, fwdvb, fbdv, cbdv, opdv, epdv;
++	u32 pllmr0_ccdv, tb, m;
++
++	fwdva = 8 - ((pllmr1 & 0x00070000) >> 16);
++	fwdvb = 8 - ((pllmr1 & 0x00007000) >> 12);
++	fbdv = (pllmr1 & 0x00f00000) >> 20;
++	if (fbdv == 0)
++		fbdv = 16;
++
++	cbdv = ((pllmr0 & 0x00030000) >> 16) + 1; /* CPU:PLB */
++	epdv = ((pllmr0 & 0x00000300) >> 8) + 2;  /* PLB:EBC */
++	opdv = ((pllmr0 & 0x00003000) >> 12) + 1; /* PLB:OPB */
++
++	m = fbdv * fwdvb;
++
++	pllmr0_ccdv = ((pllmr0 & 0x00300000) >> 20) + 1;
++	if (pllmr1 & 0x80000000)
++		cpu = sys_clk * m / (fwdva * pllmr0_ccdv);
++	else
++		cpu = sys_clk / pllmr0_ccdv;
++
++	plb = cpu / cbdv;
++	opb = plb / opdv;
++	ebc = plb / epdv;
++	tb = cpu;
++	uart0 = cpu / (cpc0_ucr & 0x0000007f);
++	uart1 = cpu / ((cpc0_ucr & 0x00007f00) >> 8);
++
++	dt_fixup_cpu_clocks(cpu, tb, 0);
++	dt_fixup_clock("/plb", plb);
++	dt_fixup_clock("/plb/opb", opb);
++	dt_fixup_clock("/plb/ebc", ebc);
+ 	dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
+-	dt_fixup_clock("/plb/opb/serial@ef600400", uart0);
+-	dt_fixup_clock("/plb/opb/serial@ef600500", uart0);
+-	dt_fixup_clock("/plb/opb/serial@ef600600", uart0);
++	dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/4xx.h powerpc.git/arch/powerpc/boot/4xx.h
+--- linux-2.6.24/arch/powerpc/boot/4xx.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/4xx.h	2008-01-28 20:25:49.000000000 +0100
+@@ -11,12 +11,22 @@
+ #ifndef _POWERPC_BOOT_4XX_H_
+ #define _POWERPC_BOOT_4XX_H_
+ 
+-void ibm4xx_fixup_memsize(void);
++void ibm4xx_sdram_fixup_memsize(void);
++void ibm440spe_fixup_memsize(void);
+ void ibm4xx_denali_fixup_memsize(void);
+ void ibm44x_dbcr_reset(void);
+ void ibm40x_dbcr_reset(void);
+ void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1);
+ void ibm4xx_fixup_ebc_ranges(const char *ebc);
+-void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk);
++
++void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk);
++void ibm405ep_fixup_clocks(unsigned int sys_clk);
++void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk);
++void ibm440ep_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk,
++			   unsigned int tmr_clk);
++void ibm440gx_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk,
++			   unsigned int tmr_clk);
++void ibm440spe_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk,
++			    unsigned int tmr_clk);
+ 
+ #endif /* _POWERPC_BOOT_4XX_H_ */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/Makefile powerpc.git/arch/powerpc/boot/Makefile
+--- linux-2.6.24/arch/powerpc/boot/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -33,12 +33,15 @@
+ BOOTCFLAGS	+= -fno-stack-protector
+ endif
+ 
+-BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj)
++BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt
+ 
+ $(obj)/4xx.o: BOOTCFLAGS += -mcpu=440
+ $(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
++$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440
++$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440
+ $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
+ 
++
+ zlib       := inffast.c inflate.c inftrees.c
+ zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
+ zliblinuxheader := zlib.h zconf.h zutil.h
+@@ -46,17 +49,21 @@
+ $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
+ 	$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
+ 
+-src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
++src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
++src-wlib := string.S crt0.S stdio.c main.c \
++		$(addprefix libfdt/,$(src-libfdt)) libfdt-wrapper.c \
+ 		ns16550.c serial.c simple_alloc.c div64.S util.S \
+ 		gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
+ 		4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
+ 		cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \
+ 		fsl-soc.c mpc8xx.c pq2.c
+-src-plat := of.c cuboot-52xx.c cuboot-83xx.c cuboot-85xx.c holly.c \
++src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
+ 		cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
+ 		ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
+ 		cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \
+-		fixed-head.S ep88xc.c cuboot-hpc2.c
++		fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c cuboot-taishan.c \
++		cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
++		cuboot-warp.c
+ src-boot := $(src-wlib) $(src-plat) empty.c
+ 
+ src-boot := $(addprefix $(obj)/, $(src-boot))
+@@ -101,24 +108,61 @@
+       cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
+ 
+ $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE
++	$(Q)mkdir -p $(dir $@)
+ 	$(call if_changed_dep,bootcc)
+ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE
++	$(Q)mkdir -p $(dir $@)
+ 	$(call if_changed_dep,bootas)
+ 
+ $(obj)/wrapper.a: $(obj-wlib) FORCE
+ 	$(call if_changed,bootar)
+ 
+-hostprogs-y	:= addnote addRamDisk hack-coff mktree
++hostprogs-y	:= addnote addRamDisk hack-coff mktree dtc
+ 
+ targets		+= $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
+ extra-y		:= $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
+ 		   $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
+ 
+ wrapper		:=$(srctree)/$(src)/wrapper
+-wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
++wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \
+ 			$(wrapper) FORCE
+ 
+ #############
++# Bits for building dtc
++# DTC_GENPARSER      := 1    # Uncomment to rebuild flex/bison output
++
++dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o srcpos.o checks.o
++dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
++dtc-objs := $(addprefix dtc-src/, $(dtc-objs))
++
++# prerequisites on generated files needs to be explicit
++$(obj)/dtc-src/dtc-parser.tab.o: $(obj)/dtc-src/dtc-parser.tab.c $(obj)/dtc-src/dtc-parser.tab.h
++$(obj)/dtc-src/dtc-lexer.lex.o:  $(obj)/dtc-src/dtc-lexer.lex.c $(obj)/dtc-src/dtc-parser.tab.h
++
++HOSTCFLAGS += -I$(src)/dtc-src/ -I$(src)/libfdt/
++
++targets += dtc-src/dtc-parser.tab.c
++targets += dtc-src/dtc-lexer.lex.c
++
++ifdef DTC_GENPARSER
++BISON = bison
++FLEX = flex
++
++quiet_cmd_bison = BISON   $@
++      cmd_bison = $(BISON) -o$@ -d $<; cp $@ $@_shipped
++quiet_cmd_flex = FLEX    $@
++      cmd_flex = $(FLEX) -o$@ $<; cp $@ $@_shipped
++
++$(obj)/dtc-src/dtc-parser.tab.c: $(src)/dtc-src/dtc-parser.y FORCE
++     $(call if_changed,bison)
++
++$(obj)/dtc-src/dtc-parser.tab.h: $(obj)/dtc-src/dtc-parser.tab.c
++
++$(obj)/dtc-src/dtc-lexer.lex.c: $(src)/dtc-src/dtc-lexer.l FORCE
++     $(call if_changed,flex)
++endif
++
++#############
+ # Bits for building various flavours of zImage
+ 
+ ifneq ($(CROSS32_COMPILE),)
+@@ -150,15 +194,26 @@
+ ifneq ($(CONFIG_DEVICE_TREE),"")
+ image-$(CONFIG_PPC_8xx)			+= cuImage.8xx
+ image-$(CONFIG_PPC_EP88XC)		+= zImage.ep88xc
++image-$(CONFIG_EP405)			+= zImage.ep405
+ image-$(CONFIG_8260)			+= cuImage.pq2
++image-$(CONFIG_EP8248E)			+= zImage.ep8248e
+ image-$(CONFIG_PPC_MPC52xx)		+= cuImage.52xx
++image-$(CONFIG_STORCENTER)		+= cuImage.824x
+ image-$(CONFIG_PPC_83xx)		+= cuImage.83xx
+ image-$(CONFIG_PPC_85xx)		+= cuImage.85xx
+ image-$(CONFIG_MPC7448HPC2)		+= cuImage.hpc2
+ image-$(CONFIG_EBONY)			+= treeImage.ebony cuImage.ebony
+ image-$(CONFIG_BAMBOO)			+= treeImage.bamboo cuImage.bamboo
+ image-$(CONFIG_SEQUOIA)			+= cuImage.sequoia
++image-$(CONFIG_RAINIER)			+= cuImage.rainier
+ image-$(CONFIG_WALNUT)			+= treeImage.walnut
++image-$(CONFIG_TAISHAN)			+= cuImage.taishan
++image-$(CONFIG_KATMAI)			+= cuImage.katmai
++image-$(CONFIG_WARP)			+= cuImage.warp
++endif
++
++ifneq ($(CONFIG_REDBOOT),"")
++image-$(CONFIG_PPC_8xx)			+= zImage.redboot-8xx
+ endif
+ 
+ # For 32-bit powermacs, build the COFF and miboot images
+@@ -243,3 +298,51 @@
+ clean-kernel += $(addsuffix .gz,$(clean-kernel))
+ # If not absolute clean-files are relative to $(obj).
+ clean-files += $(addprefix $(objtree)/, $(clean-kernel))
++
++WRAPPER_OBJDIR := /usr/lib/kernel-wrapper
++WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts
++WRAPPER_BINDIR := /usr/sbin
++INSTALL := install
++
++extra-installed		:= $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y))
++hostprogs-installed	:= $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y))
++wrapper-installed	:= $(DESTDIR)$(WRAPPER_BINDIR)/wrapper
++dts-installed		:= $(patsubst $(obj)/dts/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(obj)/dts/*.dts))
++
++all-installed		:= $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed)
++
++quiet_cmd_mkdir           = MKDIR   $(patsubst $(INSTALL_HDR_PATH)/%,%,$@)
++      cmd_mkdir           = mkdir -p $@
++
++quiet_cmd_install	  = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,%,$@)
++      cmd_install	  = $(INSTALL)  -m0644 $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,$(obj)/%,$@) $@
++
++quiet_cmd_install_dts	  = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,dts/%,$@)
++      cmd_install_dts	  = $(INSTALL)  -m0644 $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,$(srctree)/$(obj)/dts/%,$@) $@
++
++quiet_cmd_install_exe	  = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@)
++      cmd_install_exe	  = $(INSTALL)  -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(obj)/%,$@) $@
++
++quiet_cmd_install_wrapper = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@)
++      cmd_install_wrapper = $(INSTALL)  -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(srctree)/$(obj)/%,$@) $@ ;\
++				sed -i $@ -e 's%^object=.*%object=$(WRAPPER_OBJDIR)%' \
++					  -e 's%^objbin=.*%objbin=$(WRAPPER_BINDIR)%' \
++
++
++$(DESTDIR)$(WRAPPER_OBJDIR) $(DESTDIR)$(WRAPPER_DTSDIR) $(DESTDIR)$(WRAPPER_BINDIR):
++	$(call cmd,mkdir)
++
++$(extra-installed)	: $(DESTDIR)$(WRAPPER_OBJDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_OBJDIR)
++	$(call cmd,install)
++
++$(hostprogs-installed)  : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_BINDIR)
++	$(call cmd,install_exe)
++
++$(dts-installed)	: $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/% | $(DESTDIR)$(WRAPPER_DTSDIR)
++	$(call cmd,install_dts)
++
++$(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrapper | $(DESTDIR)$(WRAPPER_BINDIR)
++	$(call cmd,install_wrapper)
++
++$(obj)/bootwrapper_install: $(all-installed)
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/bamboo.c powerpc.git/arch/powerpc/boot/bamboo.c
+--- linux-2.6.24/arch/powerpc/boot/bamboo.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/bamboo.c	2008-01-28 20:25:49.000000000 +0100
+@@ -30,8 +30,8 @@
+ {
+ 	unsigned long sysclk = 33333333;
+ 
+-	ibm440ep_fixup_clocks(sysclk, 11059200);
+-	ibm4xx_fixup_memsize();
++	ibm440ep_fixup_clocks(sysclk, 11059200, 25000000);
++	ibm4xx_sdram_fixup_memsize();
+ 	ibm4xx_quiesce_eth((u32 *)0xef600e00, (u32 *)0xef600f00);
+ 	dt_fixup_mac_addresses(bamboo_mac0, bamboo_mac1);
+ }
+@@ -42,6 +42,6 @@
+ 	platform_ops.exit = ibm44x_dbcr_reset;
+ 	bamboo_mac0 = mac0;
+ 	bamboo_mac1 = mac1;
+-	ft_init(_dtb_start, 0, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-52xx.c powerpc.git/arch/powerpc/boot/cuboot-52xx.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-52xx.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-52xx.c	2008-01-28 20:25:49.000000000 +0100
+@@ -53,7 +53,7 @@
+                    unsigned long r6, unsigned long r7)
+ {
+ 	CUBOOT_INIT();
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ 	platform_ops.fixups = platform_fixups;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-824x.c powerpc.git/arch/powerpc/boot/cuboot-824x.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-824x.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-824x.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,53 @@
++/*
++ * Old U-boot compatibility for 824x
++ *
++ * Copyright (c) 2007 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 version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include "ops.h"
++#include "stdio.h"
++#include "cuboot.h"
++
++#define TARGET_824x
++#include "ppcboot.h"
++
++static bd_t bd;
++
++
++static void platform_fixups(void)
++{
++	void *soc;
++
++	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
++	dt_fixup_mac_addresses(bd.bi_enetaddr);
++	dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq);
++
++	soc = find_node_by_devtype(NULL, "soc");
++	if (soc) {
++		void *serial = NULL;
++
++		setprop(soc, "bus-frequency", &bd.bi_busfreq,
++		        sizeof(bd.bi_busfreq));
++
++		while ((serial = find_node_by_devtype(serial, "serial"))) {
++			if (get_parent(serial) != soc)
++				continue;
++
++			setprop(serial, "clock-frequency", &bd.bi_busfreq,
++			        sizeof(bd.bi_busfreq));
++		}
++	}
++}
++
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++                   unsigned long r6, unsigned long r7)
++{
++	CUBOOT_INIT();
++	fdt_init(_dtb_start);
++	serial_console_init();
++	platform_ops.fixups = platform_fixups;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-83xx.c powerpc.git/arch/powerpc/boot/cuboot-83xx.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-83xx.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-83xx.c	2008-01-28 20:25:49.000000000 +0100
+@@ -24,7 +24,8 @@
+ 	void *soc;
+ 
+ 	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
+-	dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr);
++	dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
++	dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
+ 	dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq);
+ 
+ 	/* Unfortunately, the specific model number is encoded in the
+@@ -52,7 +53,7 @@
+                    unsigned long r6, unsigned long r7)
+ {
+ 	CUBOOT_INIT();
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ 	platform_ops.fixups = platform_fixups;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-85xx.c powerpc.git/arch/powerpc/boot/cuboot-85xx.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-85xx.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-85xx.c	2008-01-28 20:25:49.000000000 +0100
+@@ -24,8 +24,9 @@
+ 	void *soc;
+ 
+ 	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
+-	dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr,
+-	                       bd.bi_enet2addr);
++	dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
++	dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
++	dt_fixup_mac_address_by_alias("ethernet2", bd.bi_enet2addr);
+ 	dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 8, bd.bi_busfreq);
+ 
+ 	/* Unfortunately, the specific model number is encoded in the
+@@ -53,7 +54,7 @@
+                    unsigned long r6, unsigned long r7)
+ {
+ 	CUBOOT_INIT();
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ 	platform_ops.fixups = platform_fixups;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-8xx.c powerpc.git/arch/powerpc/boot/cuboot-8xx.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-8xx.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-8xx.c	2008-01-28 20:25:49.000000000 +0100
+@@ -41,7 +41,7 @@
+                    unsigned long r6, unsigned long r7)
+ {
+ 	CUBOOT_INIT();
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ 	platform_ops.fixups = platform_fixups;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-hpc2.c powerpc.git/arch/powerpc/boot/cuboot-hpc2.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-hpc2.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-hpc2.c	2008-01-28 20:25:49.000000000 +0100
+@@ -42,7 +42,7 @@
+ 		unsigned long r6, unsigned long r7)
+ {
+ 	CUBOOT_INIT();
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ 	platform_ops.fixups = platform_fixups;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-katmai.c powerpc.git/arch/powerpc/boot/cuboot-katmai.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-katmai.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-katmai.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,56 @@
++/*
++ * Old U-boot compatibility for Katmai
++ *
++ * Author: Hugh Blemings <hugh@au.ibm.com>
++ *
++ * Copyright 2007 Hugh Blemings, IBM Corporation.
++ *   Based on cuboot-ebony.c which is:
++ * Copyright 2007 David Gibson, IBM Corporation.
++ *   Based on cuboot-83xx.c, which is:
++ * Copyright (c) 2007 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 version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include "ops.h"
++#include "stdio.h"
++#include "reg.h"
++#include "dcr.h"
++#include "4xx.h"
++#include "44x.h"
++#include "cuboot.h"
++
++#define TARGET_44x
++#include "ppcboot.h"
++
++static bd_t bd;
++
++BSS_STACK(4096);
++
++static void katmai_fixups(void)
++{
++	unsigned long sysclk = 33333000;
++
++	/* 440SP Clock logic is all but identical to 440GX
++	 * so we just use that code for now at least
++	 */
++	ibm440spe_fixup_clocks(sysclk, 6 * 1843200, 0);
++
++	ibm440spe_fixup_memsize();
++
++	dt_fixup_mac_address(0, bd.bi_enetaddr);
++
++	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
++}
++
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++		   unsigned long r6, unsigned long r7)
++{
++	CUBOOT_INIT();
++
++	platform_ops.fixups = katmai_fixups;
++	fdt_init(_dtb_start);
++	serial_console_init();
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-pq2.c powerpc.git/arch/powerpc/boot/cuboot-pq2.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-pq2.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-pq2.c	2008-01-28 20:25:49.000000000 +0100
+@@ -255,7 +255,7 @@
+                    unsigned long r6, unsigned long r7)
+ {
+ 	CUBOOT_INIT();
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ 	platform_ops.fixups = pq2_platform_fixups;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-rainier.c powerpc.git/arch/powerpc/boot/cuboot-rainier.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-rainier.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-rainier.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,56 @@
++/*
++ * Old U-boot compatibility for Rainier
++ *
++ * Valentine Barshak <vbarshak@ru.mvista.com>
++ * Copyright 2007 MontaVista Software, Inc
++ *
++ * Based on Ebony code by David Gibson <david@gibson.dropbear.id.au>
++ * Copyright IBM Corporation, 2007
++ *
++ * Based on Bamboo code by Josh Boyer <jwboyer@linux.vnet.ibm.com>
++ * Copyright IBM Corporation, 2007
++ *
++ * 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; version 2 of the License
++ */
++
++#include <stdarg.h>
++#include <stddef.h>
++#include "types.h"
++#include "elf.h"
++#include "string.h"
++#include "stdio.h"
++#include "page.h"
++#include "ops.h"
++#include "dcr.h"
++#include "4xx.h"
++#include "44x.h"
++#include "cuboot.h"
++
++#define TARGET_4xx
++#define TARGET_44x
++#include "ppcboot.h"
++
++static bd_t bd;
++
++
++static void rainier_fixups(void)
++{
++	unsigned long sysclk = 33333333;
++
++	ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
++	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
++	ibm4xx_denali_fixup_memsize();
++	dt_fixup_mac_addresses(&bd.bi_enetaddr, &bd.bi_enet1addr);
++}
++
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++                   unsigned long r6, unsigned long r7)
++{
++	CUBOOT_INIT();
++	platform_ops.fixups = rainier_fixups;
++	platform_ops.exit = ibm44x_dbcr_reset;
++	fdt_init(_dtb_start);
++	serial_console_init();
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-sequoia.c powerpc.git/arch/powerpc/boot/cuboot-sequoia.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-sequoia.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-sequoia.c	2008-01-28 20:25:49.000000000 +0100
+@@ -39,7 +39,7 @@
+ {
+ 	unsigned long sysclk = 33333333;
+ 
+-	ibm440ep_fixup_clocks(sysclk, 11059200);
++	ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
+ 	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
+ 	ibm4xx_denali_fixup_memsize();
+ 	dt_fixup_mac_addresses(&bd.bi_enetaddr, &bd.bi_enet1addr);
+@@ -51,6 +51,6 @@
+ 	CUBOOT_INIT();
+ 	platform_ops.fixups = sequoia_fixups;
+ 	platform_ops.exit = ibm44x_dbcr_reset;
+-	ft_init(_dtb_start, 0, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-taishan.c powerpc.git/arch/powerpc/boot/cuboot-taishan.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-taishan.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-taishan.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,54 @@
++/*
++ * Old U-boot compatibility for Taishan
++ *
++ * Author: Hugh Blemings <hugh@au.ibm.com>
++ *
++ * Copyright 2007 Hugh Blemings, IBM Corporation.
++ *   Based on cuboot-ebony.c which is:
++ * Copyright 2007 David Gibson, IBM Corporation.
++ *   Based on cuboot-83xx.c, which is:
++ * Copyright (c) 2007 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 version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include "ops.h"
++#include "stdio.h"
++#include "cuboot.h"
++#include "reg.h"
++#include "dcr.h"
++#include "4xx.h"
++
++#define TARGET_44x
++#include "ppcboot.h"
++
++static bd_t bd;
++
++BSS_STACK(4096);
++
++static void taishan_fixups(void)
++{
++	/* FIXME: sysclk should be derived by reading the FPGA
++	   registers */
++	unsigned long sysclk = 33000000;
++
++	ibm440gx_fixup_clocks(sysclk, 6 * 1843200, 25000000);
++
++	ibm4xx_sdram_fixup_memsize();
++
++	dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr);
++
++	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
++}
++
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++		   unsigned long r6, unsigned long r7)
++{
++	CUBOOT_INIT();
++
++	platform_ops.fixups = taishan_fixups;
++	fdt_init(_dtb_start);
++	serial_console_init();
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/cuboot-warp.c powerpc.git/arch/powerpc/boot/cuboot-warp.c
+--- linux-2.6.24/arch/powerpc/boot/cuboot-warp.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/cuboot-warp.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (c) 2008 PIKA Technologies
++ *   Sean MacLennan <smaclennan@pikatech.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include "ops.h"
++#include "4xx.h"
++#include "cuboot.h"
++
++#define TARGET_44x
++#include "ppcboot.h"
++
++static bd_t bd;
++
++static void warp_fixups(void)
++{
++	unsigned long sysclk = 66000000;
++
++	ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
++	ibm4xx_sdram_fixup_memsize();
++	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
++	dt_fixup_mac_addresses(&bd.bi_enetaddr);
++}
++
++
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++		   unsigned long r6, unsigned long r7)
++{
++	CUBOOT_INIT();
++
++	platform_ops.fixups = warp_fixups;
++	platform_ops.exit = ibm44x_dbcr_reset;
++	fdt_init(_dtb_start);
++	serial_console_init();
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dcr.h powerpc.git/arch/powerpc/boot/dcr.h
+--- linux-2.6.24/arch/powerpc/boot/dcr.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dcr.h	2008-01-28 20:25:49.000000000 +0100
+@@ -14,12 +14,20 @@
+ #define DCRN_SDRAM0_CFGADDR				0x010
+ #define DCRN_SDRAM0_CFGDATA				0x011
+ 
++#define SDRAM0_READ(offset) ({\
++	mtdcr(DCRN_SDRAM0_CFGADDR, offset); \
++	mfdcr(DCRN_SDRAM0_CFGDATA); })
++#define SDRAM0_WRITE(offset, data) ({\
++	mtdcr(DCRN_SDRAM0_CFGADDR, offset); \
++	mtdcr(DCRN_SDRAM0_CFGDATA, data); })
++
+ #define 	SDRAM0_B0CR				0x40
+ #define 	SDRAM0_B1CR				0x44
+ #define 	SDRAM0_B2CR				0x48
+ #define 	SDRAM0_B3CR				0x4c
+ 
+-static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2CR, SDRAM0_B3CR };
++static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR,
++					    SDRAM0_B2CR, SDRAM0_B3CR };
+ 
+ #define			SDRAM_CONFIG_BANK_ENABLE        0x00000001
+ #define			SDRAM_CONFIG_SIZE_MASK          0x000e0000
+@@ -138,5 +146,54 @@
+ #define DCRN_CPC0_PLLMR 0xb0
+ #define DCRN_405_CPC0_CR0 0xb1
+ #define DCRN_405_CPC0_CR1 0xb2
++#define DCRN_405_CPC0_PSR 0xb4
++
++/* 405EP Clocking/Power Management/Chip Control regs */
++#define DCRN_CPC0_PLLMR0  0xf0
++#define DCRN_CPC0_PLLMR1  0xf4
++#define DCRN_CPC0_UCR     0xf5
++
++/* 440GX Clock control etc */
++
++
++#define DCRN_CPR0_CLKUPD				0x020
++#define DCRN_CPR0_PLLC					0x040
++#define DCRN_CPR0_PLLD					0x060
++#define DCRN_CPR0_PRIMAD				0x080
++#define DCRN_CPR0_PRIMBD				0x0a0
++#define DCRN_CPR0_OPBD					0x0c0
++#define DCRN_CPR0_PERD					0x0e0
++#define DCRN_CPR0_MALD					0x100
++
++#define DCRN_SDR0_CONFIG_ADDR 	0xe
++#define DCRN_SDR0_CONFIG_DATA	0xf
++
++/* SDR read/write helper macros */
++#define SDR0_READ(offset) ({\
++	mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \
++	mfdcr(DCRN_SDR0_CONFIG_DATA); })
++#define SDR0_WRITE(offset, data) ({\
++	mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \
++	mtdcr(DCRN_SDR0_CONFIG_DATA, data); })
++
++#define DCRN_SDR0_UART0		0x0120
++#define DCRN_SDR0_UART1		0x0121
++#define DCRN_SDR0_UART2		0x0122
++#define DCRN_SDR0_UART3		0x0123
++
++
++/* CPRs read/write helper macros - based off include/asm-ppc/ibm44x.h */
++
++#define DCRN_CPR0_CFGADDR				0xc
++#define DCRN_CPR0_CFGDATA				0xd
++
++#define CPR0_READ(offset) ({\
++	mtdcr(DCRN_CPR0_CFGADDR, offset); \
++	mfdcr(DCRN_CPR0_CFGDATA); })
++#define CPR0_WRITE(offset, data) ({\
++	mtdcr(DCRN_CPR0_CFGADDR, offset); \
++	mtdcr(DCRN_CPR0_CFGDATA, data); })
++
++
+ 
+ #endif	/* _PPC_BOOT_DCR_H_ */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/devtree.c powerpc.git/arch/powerpc/boot/devtree.c
+--- linux-2.6.24/arch/powerpc/boot/devtree.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/devtree.c	2008-01-28 20:25:49.000000000 +0100
+@@ -88,6 +88,20 @@
+ 	}
+ }
+ 
++void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr)
++{
++	void *devp = find_node_by_alias(alias);
++
++	if (devp) {
++		printf("%s: local-mac-address <-"
++		       " %02x:%02x:%02x:%02x:%02x:%02x\n\r", alias,
++		       addr[0], addr[1], addr[2],
++		       addr[3], addr[4], addr[5]);
++
++		setprop(devp, "local-mac-address", addr, 6);
++	}
++}
++
+ void dt_fixup_mac_address(u32 index, const u8 *addr)
+ {
+ 	void *devp = find_node_by_prop_value(NULL, "linux,network-index",
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/Makefile.dtc powerpc.git/arch/powerpc/boot/dtc-src/Makefile.dtc
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/Makefile.dtc	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/Makefile.dtc	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,25 @@
++# Makefile.dtc
++#
++# This is not a complete Makefile of itself.  Instead, it is designed to
++# be easily embeddable into other systems of Makefiles.
++#
++DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
++	checks.c
++DTC_EXTRA = dtc.h srcpos.h
++DTC_LEXFILES = dtc-lexer.l
++DTC_BISONFILES = dtc-parser.y
++
++DTC_LEX_SRCS = $(DTC_LEXFILES:%.l=%.lex.c)
++DTC_BISON_SRCS = $(DTC_BISONFILES:%.y=%.tab.c)
++DTC_BISON_INCLUDES = $(DTC_BISONFILES:%.y=%.tab.h)
++
++DTC_GEN_SRCS = $(DTC_LEX_SRCS) $(DTC_BISON_SRCS)
++DTC_GEN_ALL = $(DTC_GEN_SRCS) $(DTC_BISON_INCLUDES)
++DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
++
++DTC_CLEANFILES = $(DTC_GEN_ALL)
++
++# We assume the containing Makefile system can do auto-dependencies for most
++# things, but we supply the dependencies on generated header files explicitly
++
++$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES))
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/checks.c powerpc.git/arch/powerpc/boot/dtc-src/checks.c
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/checks.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/checks.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,750 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2007.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include "dtc.h"
++
++#ifdef TRACE_CHECKS
++#define TRACE(c, ...) \
++	do { \
++		fprintf(stderr, "=== %s: ", (c)->name); \
++		fprintf(stderr, __VA_ARGS__); \
++		fprintf(stderr, "\n"); \
++	} while (0)
++#else
++#define TRACE(c, fmt, ...)	do { } while (0)
++#endif
++
++enum checklevel {
++	IGNORE = 0,
++	WARN = 1,
++	ERROR = 2,
++};
++
++enum checkstatus {
++	UNCHECKED = 0,
++	PREREQ,
++	PASSED,
++	FAILED,
++};
++
++struct check;
++
++typedef void (*tree_check_fn)(struct check *c, struct node *dt);
++typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node);
++typedef void (*prop_check_fn)(struct check *c, struct node *dt,
++			      struct node *node, struct property *prop);
++
++struct check {
++	const char *name;
++	tree_check_fn tree_fn;
++	node_check_fn node_fn;
++	prop_check_fn prop_fn;
++	void *data;
++	enum checklevel level;
++	enum checkstatus status;
++	int inprogress;
++	int num_prereqs;
++	struct check **prereq;
++};
++
++#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \
++	static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
++	static struct check nm = { \
++		.name = #nm, \
++		.tree_fn = (tfn), \
++		.node_fn = (nfn), \
++		.prop_fn = (pfn), \
++		.data = (d), \
++		.level = (lvl), \
++		.status = UNCHECKED, \
++		.num_prereqs = ARRAY_SIZE(nm##_prereqs), \
++		.prereq = nm##_prereqs, \
++	};
++
++#define TREE_CHECK(nm, d, lvl, ...) \
++	CHECK(nm, check_##nm, NULL, NULL, d, lvl, __VA_ARGS__)
++#define NODE_CHECK(nm, d, lvl, ...) \
++	CHECK(nm, NULL, check_##nm, NULL, d, lvl, __VA_ARGS__)
++#define PROP_CHECK(nm, d, lvl, ...) \
++	CHECK(nm, NULL, NULL, check_##nm, d, lvl, __VA_ARGS__)
++#define BATCH_CHECK(nm, lvl, ...) \
++	CHECK(nm, NULL, NULL, NULL, NULL, lvl, __VA_ARGS__)
++
++#ifdef __GNUC__
++static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
++#endif
++static inline void check_msg(struct check *c, const char *fmt, ...)
++{
++	va_list ap;
++	va_start(ap, fmt);
++
++	if ((c->level < WARN) || (c->level <= quiet))
++		return; /* Suppress message */
++
++	fprintf(stderr, "%s (%s): ",
++		(c->level == ERROR) ? "ERROR" : "Warning", c->name);
++	vfprintf(stderr, fmt, ap);
++	fprintf(stderr, "\n");
++}
++
++#define FAIL(c, ...) \
++	do { \
++		TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
++		(c)->status = FAILED; \
++		check_msg((c), __VA_ARGS__); \
++	} while (0)
++
++static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
++{
++	struct node *child;
++	struct property *prop;
++
++	TRACE(c, "%s", node->fullpath);
++	if (c->node_fn)
++		c->node_fn(c, dt, node);
++
++	if (c->prop_fn)
++		for_each_property(node, prop) {
++			TRACE(c, "%s\t'%s'", node->fullpath, prop->name);
++			c->prop_fn(c, dt, node, prop);
++		}
++
++	for_each_child(node, child)
++		check_nodes_props(c, dt, child);
++}
++
++static int run_check(struct check *c, struct node *dt)
++{
++	int error = 0;
++	int i;
++
++	assert(!c->inprogress);
++
++	if (c->status != UNCHECKED)
++		goto out;
++
++	c->inprogress = 1;
++
++	for (i = 0; i < c->num_prereqs; i++) {
++		struct check *prq = c->prereq[i];
++		error |= run_check(prq, dt);
++		if (prq->status != PASSED) {
++			c->status = PREREQ;
++			check_msg(c, "Failed prerequisite '%s'",
++				  c->prereq[i]->name);
++		}
++	}
++
++	if (c->status != UNCHECKED)
++		goto out;
++
++	if (c->node_fn || c->prop_fn)
++		check_nodes_props(c, dt, dt);
++
++	if (c->tree_fn)
++		c->tree_fn(c, dt);
++	if (c->status == UNCHECKED)
++		c->status = PASSED;
++
++	TRACE(c, "\tCompleted, status %d", c->status);
++
++out:
++	c->inprogress = 0;
++	if ((c->status != PASSED) && (c->level == ERROR))
++		error = 1;
++	return error;
++}
++
++/*
++ * Utility check functions
++ */
++
++static void check_is_string(struct check *c, struct node *root,
++			    struct node *node)
++{
++	struct property *prop;
++	char *propname = c->data;
++
++	prop = get_property(node, propname);
++	if (!prop)
++		return; /* Not present, assumed ok */
++
++	if (!data_is_one_string(prop->val))
++		FAIL(c, "\"%s\" property in %s is not a string",
++		     propname, node->fullpath);
++}
++#define CHECK_IS_STRING(nm, propname, lvl) \
++	CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl))
++
++static void check_is_cell(struct check *c, struct node *root,
++			  struct node *node)
++{
++	struct property *prop;
++	char *propname = c->data;
++
++	prop = get_property(node, propname);
++	if (!prop)
++		return; /* Not present, assumed ok */
++
++	if (prop->val.len != sizeof(cell_t))
++		FAIL(c, "\"%s\" property in %s is not a single cell",
++		     propname, node->fullpath);
++}
++#define CHECK_IS_CELL(nm, propname, lvl) \
++	CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl))
++
++/*
++ * Structural check functions
++ */
++
++static void check_duplicate_node_names(struct check *c, struct node *dt,
++				       struct node *node)
++{
++	struct node *child, *child2;
++
++	for_each_child(node, child)
++		for (child2 = child->next_sibling;
++		     child2;
++		     child2 = child2->next_sibling)
++			if (streq(child->name, child2->name))
++				FAIL(c, "Duplicate node name %s",
++				     child->fullpath);
++}
++NODE_CHECK(duplicate_node_names, NULL, ERROR);
++
++static void check_duplicate_property_names(struct check *c, struct node *dt,
++					   struct node *node)
++{
++	struct property *prop, *prop2;
++
++	for_each_property(node, prop)
++		for (prop2 = prop->next; prop2; prop2 = prop2->next)
++			if (streq(prop->name, prop2->name))
++				FAIL(c, "Duplicate property name %s in %s",
++				     prop->name, node->fullpath);
++}
++NODE_CHECK(duplicate_property_names, NULL, ERROR);
++
++static void check_explicit_phandles(struct check *c, struct node *root,
++					  struct node *node)
++{
++	struct property *prop;
++	struct node *other;
++	cell_t phandle;
++
++	prop = get_property(node, "linux,phandle");
++	if (! prop)
++		return; /* No phandle, that's fine */
++
++	if (prop->val.len != sizeof(cell_t)) {
++		FAIL(c, "%s has bad length (%d) linux,phandle property",
++		     node->fullpath, prop->val.len);
++		return;
++	}
++
++	phandle = propval_cell(prop);
++	if ((phandle == 0) || (phandle == -1)) {
++		FAIL(c, "%s has invalid linux,phandle value 0x%x",
++		     node->fullpath, phandle);
++		return;
++	}
++
++	other = get_node_by_phandle(root, phandle);
++	if (other) {
++		FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
++		     node->fullpath, phandle, other->fullpath);
++		return;
++	}
++
++	node->phandle = phandle;
++}
++NODE_CHECK(explicit_phandles, NULL, ERROR);
++
++static void check_name_properties(struct check *c, struct node *root,
++				  struct node *node)
++{
++	struct property *prop;
++
++	prop = get_property(node, "name");
++	if (!prop)
++		return; /* No name property, that's fine */
++
++	if ((prop->val.len != node->basenamelen+1)
++	    || (memcmp(prop->val.val, node->name, node->basenamelen) != 0))
++		FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
++		     " of base node name)", node->fullpath, prop->val.val);
++}
++CHECK_IS_STRING(name_is_string, "name", ERROR);
++NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
++
++/*
++ * Reference fixup functions
++ */
++
++static void fixup_phandle_references(struct check *c, struct node *dt,
++				     struct node *node, struct property *prop)
++{
++      struct marker *m = prop->val.markers;
++      struct node *refnode;
++      cell_t phandle;
++
++      for_each_marker_of_type(m, REF_PHANDLE) {
++	      assert(m->offset + sizeof(cell_t) <= prop->val.len);
++
++	      refnode = get_node_by_ref(dt, m->ref);
++	      if (! refnode) {
++		      FAIL(c, "Reference to non-existent node or label \"%s\"\n",
++			   m->ref);
++		      continue;
++	      }
++
++	      phandle = get_node_phandle(dt, refnode);
++	      *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle);
++      }
++}
++CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
++      &duplicate_node_names, &explicit_phandles);
++
++static void fixup_path_references(struct check *c, struct node *dt,
++				  struct node *node, struct property *prop)
++{
++	struct marker *m = prop->val.markers;
++	struct node *refnode;
++	char *path;
++
++	for_each_marker_of_type(m, REF_PATH) {
++		assert(m->offset <= prop->val.len);
++
++		refnode = get_node_by_ref(dt, m->ref);
++		if (!refnode) {
++			FAIL(c, "Reference to non-existent node or label \"%s\"\n",
++			     m->ref);
++			continue;
++		}
++
++		path = refnode->fullpath;
++		prop->val = data_insert_at_marker(prop->val, m, path,
++						  strlen(path) + 1);
++	}
++}
++CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR,
++      &duplicate_node_names);
++
++/*
++ * Semantic checks
++ */
++CHECK_IS_CELL(address_cells_is_cell, "#address-cells", WARN);
++CHECK_IS_CELL(size_cells_is_cell, "#size-cells", WARN);
++CHECK_IS_CELL(interrupt_cells_is_cell, "#interrupt-cells", WARN);
++
++CHECK_IS_STRING(device_type_is_string, "device_type", WARN);
++CHECK_IS_STRING(model_is_string, "model", WARN);
++CHECK_IS_STRING(status_is_string, "status", WARN);
++
++static void fixup_addr_size_cells(struct check *c, struct node *dt,
++				  struct node *node)
++{
++	struct property *prop;
++
++	node->addr_cells = -1;
++	node->size_cells = -1;
++
++	prop = get_property(node, "#address-cells");
++	if (prop)
++		node->addr_cells = propval_cell(prop);
++
++	prop = get_property(node, "#size-cells");
++	if (prop)
++		node->size_cells = propval_cell(prop);
++}
++CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN,
++      &address_cells_is_cell, &size_cells_is_cell);
++
++#define node_addr_cells(n) \
++	(((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
++#define node_size_cells(n) \
++	(((n)->size_cells == -1) ? 1 : (n)->size_cells)
++
++static void check_reg_format(struct check *c, struct node *dt,
++			     struct node *node)
++{
++	struct property *prop;
++	int addr_cells, size_cells, entrylen;
++
++	prop = get_property(node, "reg");
++	if (!prop)
++		return; /* No "reg", that's fine */
++
++	if (!node->parent) {
++		FAIL(c, "Root node has a \"reg\" property");
++		return;
++	}
++
++	if (prop->val.len == 0)
++		FAIL(c, "\"reg\" property in %s is empty", node->fullpath);
++
++	addr_cells = node_addr_cells(node->parent);
++	size_cells = node_size_cells(node->parent);
++	entrylen = (addr_cells + size_cells) * sizeof(cell_t);
++
++	if ((prop->val.len % entrylen) != 0)
++		FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
++		     "(#address-cells == %d, #size-cells == %d)",
++		     node->fullpath, prop->val.len, addr_cells, size_cells);
++}
++NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells);
++
++static void check_ranges_format(struct check *c, struct node *dt,
++				struct node *node)
++{
++	struct property *prop;
++	int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
++
++	prop = get_property(node, "ranges");
++	if (!prop)
++		return;
++
++	if (!node->parent) {
++		FAIL(c, "Root node has a \"ranges\" property");
++		return;
++	}
++
++	p_addr_cells = node_addr_cells(node->parent);
++	p_size_cells = node_size_cells(node->parent);
++	c_addr_cells = node_addr_cells(node);
++	c_size_cells = node_size_cells(node);
++	entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t);
++
++	if (prop->val.len == 0) {
++		if (p_addr_cells != c_addr_cells)
++			FAIL(c, "%s has empty \"ranges\" property but its "
++			     "#address-cells (%d) differs from %s (%d)",
++			     node->fullpath, c_addr_cells, node->parent->fullpath,
++			     p_addr_cells);
++		if (p_size_cells != c_size_cells)
++			FAIL(c, "%s has empty \"ranges\" property but its "
++			     "#size-cells (%d) differs from %s (%d)",
++			     node->fullpath, c_size_cells, node->parent->fullpath,
++			     p_size_cells);
++	} else if ((prop->val.len % entrylen) != 0) {
++		FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) "
++		     "(parent #address-cells == %d, child #address-cells == %d, "
++		     "#size-cells == %d)", node->fullpath, prop->val.len,
++		     p_addr_cells, c_addr_cells, c_size_cells);
++	}
++}
++NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells);
++
++/*
++ * Style checks
++ */
++static void check_avoid_default_addr_size(struct check *c, struct node *dt,
++					  struct node *node)
++{
++	struct property *reg, *ranges;
++
++	if (!node->parent)
++		return; /* Ignore root node */
++
++	reg = get_property(node, "reg");
++	ranges = get_property(node, "ranges");
++
++	if (!reg && !ranges)
++		return;
++
++	if ((node->parent->addr_cells == -1))
++		FAIL(c, "Relying on default #address-cells value for %s",
++		     node->fullpath);
++
++	if ((node->parent->size_cells == -1))
++		FAIL(c, "Relying on default #size-cells value for %s",
++		     node->fullpath);
++}
++NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
++
++static void check_obsolete_chosen_interrupt_controller(struct check *c,
++						       struct node *dt)
++{
++	struct node *chosen;
++	struct property *prop;
++
++	chosen = get_node_by_path(dt, "/chosen");
++	if (!chosen)
++		return;
++
++	prop = get_property(chosen, "interrupt-controller");
++	if (prop)
++		FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
++		     "property");
++}
++TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
++
++static struct check *check_table[] = {
++	&duplicate_node_names, &duplicate_property_names,
++	&name_is_string, &name_properties,
++	&explicit_phandles,
++	&phandle_references, &path_references,
++
++	&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
++	&device_type_is_string, &model_is_string, &status_is_string,
++
++	&addr_size_cells, &reg_format, &ranges_format,
++
++	&avoid_default_addr_size,
++	&obsolete_chosen_interrupt_controller,
++};
++
++int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
++
++void process_checks(int force, struct boot_info *bi,
++		    int checkflag, int outversion, int boot_cpuid_phys)
++{
++	struct node *dt = bi->dt;
++	int i;
++	int error = 0;
++
++	for (i = 0; i < ARRAY_SIZE(check_table); i++) {
++		struct check *c = check_table[i];
++
++		if (c->level != IGNORE)
++			error = error || run_check(c, dt);
++	}
++
++	if (error) {
++		if (!force) {
++			fprintf(stderr, "ERROR: Input tree has errors, aborting "
++				"(use -f to force output)\n");
++			exit(2);
++		} else if (quiet < 3) {
++			fprintf(stderr, "Warning: Input tree has errors, "
++				"output forced\n");
++		}
++	}
++
++	if (checkflag) {
++		if (error) {
++			fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n");
++		} else {
++			if (!check_semantics(bi->dt, outversion,
++					     boot_cpuid_phys))
++				fprintf(stderr, "Warning: Input tree has semantic errors\n");
++		}
++	}
++}
++
++/*
++ * Semantic check functions
++ */
++
++#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__)
++#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__)
++
++#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
++
++#define CHECK_HAVE(node, propname) \
++	do { \
++		if (! (prop = get_property((node), (propname)))) \
++			DO_ERR("Missing \"%s\" property in %s\n", (propname), \
++				(node)->fullpath); \
++	} while (0);
++
++#define CHECK_HAVE_WARN(node, propname) \
++	do { \
++		if (! (prop  = get_property((node), (propname)))) \
++			WARNMSG("%s has no \"%s\" property\n", \
++				(node)->fullpath, (propname)); \
++	} while (0)
++
++#define CHECK_HAVE_STRING(node, propname) \
++	do { \
++		CHECK_HAVE((node), (propname)); \
++		if (prop && !data_is_one_string(prop->val)) \
++			DO_ERR("\"%s\" property in %s is not a string\n", \
++				(propname), (node)->fullpath); \
++	} while (0)
++
++#define CHECK_HAVE_STREQ(node, propname, value) \
++	do { \
++		CHECK_HAVE_STRING((node), (propname)); \
++		if (prop && !streq(prop->val.val, (value))) \
++			DO_ERR("%s has wrong %s, %s (should be %s\n", \
++				(node)->fullpath, (propname), \
++				prop->val.val, (value)); \
++	} while (0)
++
++#define CHECK_HAVE_ONECELL(node, propname) \
++	do { \
++		CHECK_HAVE((node), (propname)); \
++		if (prop && (prop->val.len != sizeof(cell_t))) \
++			DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
++	} while (0)
++
++#define CHECK_HAVE_WARN_ONECELL(node, propname) \
++	do { \
++		CHECK_HAVE_WARN((node), (propname)); \
++		if (prop && (prop->val.len != sizeof(cell_t))) \
++			DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
++	} while (0)
++
++#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
++	do { \
++		struct node *ref; \
++		CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
++		if (prop) {\
++			cell_t phandle = propval_cell(prop); \
++			if ((phandle == 0) || (phandle == -1)) { \
++				DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \
++			} else { \
++				ref = get_node_by_phandle((root), propval_cell(prop)); \
++				if (! ref) \
++					DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
++			} \
++		} \
++	} while (0)
++
++#define CHECK_HAVE_WARN_STRING(node, propname) \
++	do { \
++		CHECK_HAVE_WARN((node), (propname)); \
++		if (prop && !data_is_one_string(prop->val)) \
++			DO_ERR("\"%s\" property in %s is not a string\n", \
++				(propname), (node)->fullpath); \
++	} while (0)
++
++static int check_root(struct node *root)
++{
++	struct property *prop;
++	int ok = 1;
++
++	CHECK_HAVE_STRING(root, "model");
++	CHECK_HAVE_WARN(root, "compatible");
++
++	return ok;
++}
++
++static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
++{
++	struct node *cpus, *cpu;
++	struct property *prop;
++	struct node *bootcpu = NULL;
++	int ok = 1;
++
++	cpus = get_subnode(root, "cpus");
++	if (! cpus) {
++		ERRMSG("Missing /cpus node\n");
++		return 0;
++	}
++
++	if (cpus->addr_cells != 1)
++		DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
++		       cpus->fullpath, cpus->addr_cells);
++	if (cpus->size_cells != 0)
++		DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
++		       cpus->fullpath, cpus->size_cells);
++
++	for_each_child(cpus, cpu) {
++		CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
++
++		CHECK_HAVE_ONECELL(cpu, "reg");
++		if (prop) {
++			cell_t unitnum;
++			char *eptr;
++
++			unitnum = strtol(get_unitname(cpu), &eptr, 16);
++			if (*eptr) {
++				WARNMSG("%s has bad format unit name %s (should be CPU number\n",
++					cpu->fullpath, get_unitname(cpu));
++			} else if (unitnum != propval_cell(prop)) {
++				WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n",
++				       cpu->fullpath, get_unitname(cpu),
++				       propval_cell(prop));
++			}
++		}
++
++/* 		CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */
++/* 		CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */
++		CHECK_HAVE_ONECELL(cpu, "d-cache-size");
++		CHECK_HAVE_ONECELL(cpu, "i-cache-size");
++
++		CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
++		CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
++
++		prop = get_property(cpu, "linux,boot-cpu");
++		if (prop) {
++			if (prop->val.len)
++				WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
++					cpu->fullpath);
++			if (bootcpu)
++				DO_ERR("Multiple boot cpus (%s and %s)\n",
++				       bootcpu->fullpath, cpu->fullpath);
++			else
++				bootcpu = cpu;
++		}
++	}
++
++	if (outversion < 2) {
++		if (! bootcpu)
++			WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
++	} else {
++		if (bootcpu)
++			WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n");
++		if (boot_cpuid_phys == 0xfeedbeef)
++			WARNMSG("physical boot CPU not set.  Use -b option to set\n");
++	}
++
++	return ok;
++}
++
++static int check_memory(struct node *root)
++{
++	struct node *mem;
++	struct property *prop;
++	int nnodes = 0;
++	int ok = 1;
++
++	for_each_child(root, mem) {
++		if (! strneq(mem->name, "memory", mem->basenamelen))
++			continue;
++
++		nnodes++;
++
++		CHECK_HAVE_STREQ(mem, "device_type", "memory");
++		CHECK_HAVE(mem, "reg");
++	}
++
++	if (nnodes == 0) {
++		ERRMSG("No memory nodes\n");
++		return 0;
++	}
++
++	return ok;
++}
++
++int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
++{
++	int ok = 1;
++
++	ok = ok && check_root(dt);
++	ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
++	ok = ok && check_memory(dt);
++	if (! ok)
++		return 0;
++
++	return 1;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/data.c powerpc.git/arch/powerpc/boot/dtc-src/data.c
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/data.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/data.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,321 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include "dtc.h"
++
++void data_free(struct data d)
++{
++	struct marker *m, *nm;
++
++	m = d.markers;
++	while (m) {
++		nm = m->next;
++		free(m->ref);
++		free(m);
++		m = nm;
++	}
++
++	assert(!d.val || d.asize);
++
++	if (d.val)
++		free(d.val);
++}
++
++struct data data_grow_for(struct data d, int xlen)
++{
++	struct data nd;
++	int newsize;
++
++	/* we must start with an allocated datum */
++	assert(!d.val || d.asize);
++
++	if (xlen == 0)
++		return d;
++
++	nd = d;
++
++	newsize = xlen;
++
++	while ((d.len + xlen) > newsize)
++		newsize *= 2;
++
++	nd.asize = newsize;
++	nd.val = xrealloc(d.val, newsize);
++
++	assert(nd.asize >= (d.len + xlen));
++
++	return nd;
++}
++
++struct data data_copy_mem(const char *mem, int len)
++{
++	struct data d;
++
++	d = data_grow_for(empty_data, len);
++
++	d.len = len;
++	memcpy(d.val, mem, len);
++
++	return d;
++}
++
++static char get_oct_char(const char *s, int *i)
++{
++	char x[4];
++	char *endx;
++	long val;
++
++	x[3] = '\0';
++	x[0] = s[(*i)];
++	if (x[0]) {
++		x[1] = s[(*i)+1];
++		if (x[1])
++			x[2] = s[(*i)+2];
++	}
++
++	val = strtol(x, &endx, 8);
++	if ((endx - x) == 0)
++		fprintf(stderr, "Empty \\nnn escape\n");
++
++	(*i) += endx - x;
++	return val;
++}
++
++static char get_hex_char(const char *s, int *i)
++{
++	char x[3];
++	char *endx;
++	long val;
++
++	x[2] = '\0';
++	x[0] = s[(*i)];
++	if (x[0])
++		x[1] = s[(*i)+1];
++
++	val = strtol(x, &endx, 16);
++	if ((endx - x) == 0)
++		fprintf(stderr, "Empty \\x escape\n");
++
++	(*i) += endx - x;
++	return val;
++}
++
++struct data data_copy_escape_string(const char *s, int len)
++{
++	int i = 0;
++	struct data d;
++	char *q;
++
++	d = data_grow_for(empty_data, strlen(s)+1);
++
++	q = d.val;
++	while (i < len) {
++		char c = s[i++];
++
++		if (c != '\\') {
++			q[d.len++] = c;
++			continue;
++		}
++
++		c = s[i++];
++		assert(c);
++		switch (c) {
++		case 'a':
++			q[d.len++] = '\a';
++			break;
++		case 'b':
++			q[d.len++] = '\b';
++			break;
++		case 't':
++			q[d.len++] = '\t';
++			break;
++		case 'n':
++			q[d.len++] = '\n';
++			break;
++		case 'v':
++			q[d.len++] = '\v';
++			break;
++		case 'f':
++			q[d.len++] = '\f';
++			break;
++		case 'r':
++			q[d.len++] = '\r';
++			break;
++		case '0':
++		case '1':
++		case '2':
++		case '3':
++		case '4':
++		case '5':
++		case '6':
++		case '7':
++			i--; /* need to re-read the first digit as
++			      * part of the octal value */
++			q[d.len++] = get_oct_char(s, &i);
++			break;
++		case 'x':
++			q[d.len++] = get_hex_char(s, &i);
++			break;
++		default:
++			q[d.len++] = c;
++		}
++	}
++
++	q[d.len++] = '\0';
++	return d;
++}
++
++struct data data_copy_file(FILE *f, size_t len)
++{
++	struct data d;
++
++	d = data_grow_for(empty_data, len);
++
++	d.len = len;
++	fread(d.val, len, 1, f);
++
++	return d;
++}
++
++struct data data_append_data(struct data d, const void *p, int len)
++{
++	d = data_grow_for(d, len);
++	memcpy(d.val + d.len, p, len);
++	d.len += len;
++	return d;
++}
++
++struct data data_insert_at_marker(struct data d, struct marker *m,
++				  const void *p, int len)
++{
++	d = data_grow_for(d, len);
++	memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
++	memcpy(d.val + m->offset, p, len);
++	d.len += len;
++
++	/* Adjust all markers after the one we're inserting at */
++	m = m->next;
++	for_each_marker(m)
++		m->offset += len;
++	return d;
++}
++
++struct data data_append_markers(struct data d, struct marker *m)
++{
++	struct marker **mp = &d.markers;
++
++	/* Find the end of the markerlist */
++	while (*mp)
++		mp = &((*mp)->next);
++	*mp = m;
++	return d;
++}
++
++struct data data_merge(struct data d1, struct data d2)
++{
++	struct data d;
++	struct marker *m2 = d2.markers;
++
++	d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
++
++	/* Adjust for the length of d1 */
++	for_each_marker(m2)
++		m2->offset += d1.len;
++
++	d2.markers = NULL; /* So data_free() doesn't clobber them */
++	data_free(d2);
++
++	return d;
++}
++
++struct data data_append_cell(struct data d, cell_t word)
++{
++	cell_t beword = cpu_to_be32(word);
++
++	return data_append_data(d, &beword, sizeof(beword));
++}
++
++struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
++{
++	struct fdt_reserve_entry bere;
++
++	bere.address = cpu_to_be64(re->address);
++	bere.size = cpu_to_be64(re->size);
++
++	return data_append_data(d, &bere, sizeof(bere));
++}
++
++struct data data_append_addr(struct data d, u64 addr)
++{
++	u64 beaddr = cpu_to_be64(addr);
++
++	return data_append_data(d, &beaddr, sizeof(beaddr));
++}
++
++struct data data_append_byte(struct data d, uint8_t byte)
++{
++	return data_append_data(d, &byte, 1);
++}
++
++struct data data_append_zeroes(struct data d, int len)
++{
++	d = data_grow_for(d, len);
++
++	memset(d.val + d.len, 0, len);
++	d.len += len;
++	return d;
++}
++
++struct data data_append_align(struct data d, int align)
++{
++	int newlen = ALIGN(d.len, align);
++	return data_append_zeroes(d, newlen - d.len);
++}
++
++struct data data_add_marker(struct data d, enum markertype type, char *ref)
++{
++	struct marker *m;
++
++	m = xmalloc(sizeof(*m));
++	m->offset = d.len;
++	m->type = type;
++	m->ref = ref;
++	m->next = NULL;
++
++	return data_append_markers(d, m);
++}
++
++int data_is_one_string(struct data d)
++{
++	int i;
++	int len = d.len;
++
++	if (len == 0)
++		return 0;
++
++	for (i = 0; i < len-1; i++)
++		if (d.val[i] == '\0')
++			return 0;
++
++	if (d.val[len-1] != '\0')
++		return 0;
++
++	return 1;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-lexer.l powerpc.git/arch/powerpc/boot/dtc-src/dtc-lexer.l
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-lexer.l	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/dtc-lexer.l	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,328 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++%option noyywrap nounput yylineno
++
++%x INCLUDE
++%x BYTESTRING
++%x PROPNODENAME
++%s V1
++
++PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
++PATHCHAR	({PROPNODECHAR}|[/])
++LABEL		[a-zA-Z_][a-zA-Z0-9_]*
++
++%{
++#include "dtc.h"
++#include "srcpos.h"
++#include "dtc-parser.tab.h"
++
++
++/*#define LEXDEBUG	1*/
++
++#ifdef LEXDEBUG
++#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
++#else
++#define DPRINT(fmt, ...)	do { } while (0)
++#endif
++
++static int dts_version; /* = 0 */
++
++#define BEGIN_DEFAULT()	if (dts_version == 0) { \
++				DPRINT("<INITIAL>\n"); \
++				BEGIN(INITIAL); \
++			} else { \
++				DPRINT("<V1>\n"); \
++				BEGIN(V1); \
++			}
++%}
++
++%%
++<*>"/include/"		BEGIN(INCLUDE);
++
++<INCLUDE>\"[^"\n]*\"	{
++			yytext[strlen(yytext) - 1] = 0;
++			if (!push_input_file(yytext + 1)) {
++				/* Some unrecoverable error.*/
++				exit(1);
++			}
++			BEGIN_DEFAULT();
++		}
++
++
++<*><<EOF>>		{
++			if (!pop_input_file()) {
++				yyterminate();
++			}
++		}
++
++<*>\"([^\\"]|\\.)*\"	{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("String: %s\n", yytext);
++			yylval.data = data_copy_escape_string(yytext+1,
++					yyleng-2);
++			yylloc.first_line = yylineno;
++			return DT_STRING;
++		}
++
++<*>"/dts-v1/"	{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Keyword: /dts-v1/\n");
++			dts_version = 1;
++			BEGIN_DEFAULT();
++			return DT_V1;
++		}
++
++<*>"/memreserve/"	{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Keyword: /memreserve/\n");
++			BEGIN_DEFAULT();
++			return DT_MEMRESERVE;
++		}
++
++<*>{LABEL}:	{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Label: %s\n", yytext);
++			yylval.labelref = strdup(yytext);
++			yylval.labelref[yyleng-1] = '\0';
++			return DT_LABEL;
++		}
++
++<INITIAL>[bodh]# {
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			if (*yytext == 'b')
++				yylval.cbase = 2;
++			else if (*yytext == 'o')
++				yylval.cbase = 8;
++			else if (*yytext == 'd')
++				yylval.cbase = 10;
++			else
++				yylval.cbase = 16;
++			DPRINT("Base: %d\n", yylval.cbase);
++			return DT_BASE;
++		}
++
++<INITIAL>[0-9a-fA-F]+	{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			yylval.literal = strdup(yytext);
++			DPRINT("Literal: '%s'\n", yylval.literal);
++			return DT_LEGACYLITERAL;
++		}
++
++<V1>[0-9]+|0[xX][0-9a-fA-F]+      {
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			yylval.literal = strdup(yytext);
++			DPRINT("Literal: '%s'\n", yylval.literal);
++			return DT_LITERAL;
++		}
++
++\&{LABEL}	{	/* label reference */
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Ref: %s\n", yytext+1);
++			yylval.labelref = strdup(yytext+1);
++			return DT_REF;
++		}
++
++"&{/"{PATHCHAR}+\}	{	/* new-style path reference */
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			yytext[yyleng-1] = '\0';
++			DPRINT("Ref: %s\n", yytext+2);
++			yylval.labelref = strdup(yytext+2);
++			return DT_REF;
++		}
++
++<INITIAL>"&/"{PATHCHAR}+ {	/* old-style path reference */
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Ref: %s\n", yytext+1);
++			yylval.labelref = strdup(yytext+1);
++			return DT_REF;
++		}
++
++<BYTESTRING>[0-9a-fA-F]{2} {
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			yylval.byte = strtol(yytext, NULL, 16);
++			DPRINT("Byte: %02x\n", (int)yylval.byte);
++			return DT_BYTE;
++		}
++
++<BYTESTRING>"]"	{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("/BYTESTRING\n");
++			BEGIN_DEFAULT();
++			return ']';
++		}
++
++<PROPNODENAME>{PROPNODECHAR}+ {
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("PropNodeName: %s\n", yytext);
++			yylval.propnodename = strdup(yytext);
++			BEGIN_DEFAULT();
++			return DT_PROPNODENAME;
++		}
++
++
++<*>[[:space:]]+	/* eat whitespace */
++
++<*>"/*"([^*]|\*+[^*/])*\*+"/"	{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Comment: %s\n", yytext);
++			/* eat comments */
++		}
++
++<*>"//".*\n	/* eat line comments */
++
++<*>.		{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
++				(unsigned)yytext[0]);
++			if (yytext[0] == '[') {
++				DPRINT("<BYTESTRING>\n");
++				BEGIN(BYTESTRING);
++			}
++			if ((yytext[0] == '{')
++			    || (yytext[0] == ';')) {
++				DPRINT("<PROPNODENAME>\n");
++				BEGIN(PROPNODENAME);
++			}
++			return yytext[0];
++		}
++
++%%
++
++
++/*
++ * Stack of nested include file contexts.
++ */
++
++struct incl_file {
++	int filenum;
++	FILE *file;
++	YY_BUFFER_STATE yy_prev_buf;
++	int yy_prev_lineno;
++	struct incl_file *prev;
++};
++
++struct incl_file *incl_file_stack;
++
++
++/*
++ * Detect infinite include recursion.
++ */
++#define MAX_INCLUDE_DEPTH	(100)
++
++static int incl_depth = 0;
++
++
++int push_input_file(const char *filename)
++{
++	FILE *f;
++	struct incl_file *incl_file;
++
++	if (!filename) {
++		yyerror("No include file name given.");
++		return 0;
++	}
++
++	if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
++		yyerror("Includes nested too deeply");
++		return 0;
++	}
++
++	f = dtc_open_file(filename);
++
++	incl_file = malloc(sizeof(struct incl_file));
++	if (!incl_file) {
++		yyerror("Can not allocate include file space.");
++		return 0;
++	}
++
++	/*
++	 * Save current context.
++	 */
++	incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
++	incl_file->yy_prev_lineno = yylineno;
++	incl_file->filenum = srcpos_filenum;
++	incl_file->file = yyin;
++	incl_file->prev = incl_file_stack;
++
++	incl_file_stack = incl_file;
++
++	/*
++	 * Establish new context.
++	 */
++	srcpos_filenum = lookup_file_name(filename, 0);
++	yylineno = 1;
++	yyin = f;
++	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
++
++	return 1;
++}
++
++
++int pop_input_file(void)
++{
++	struct incl_file *incl_file;
++
++	if (incl_file_stack == 0)
++		return 0;
++
++	fclose(yyin);
++
++	/*
++	 * Pop.
++	 */
++	--incl_depth;
++	incl_file = incl_file_stack;
++	incl_file_stack = incl_file->prev;
++
++	/*
++	 * Recover old context.
++	 */
++	yy_delete_buffer(YY_CURRENT_BUFFER);
++	yy_switch_to_buffer(incl_file->yy_prev_buf);
++	yylineno = incl_file->yy_prev_lineno;
++	srcpos_filenum = incl_file->filenum;
++	yyin = incl_file->file;
++
++	/*
++	 * Free old state.
++	 */
++	free(incl_file);
++
++	if (YY_CURRENT_BUFFER == 0)
++		return 0;
++
++	return 1;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped powerpc.git/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,2174 @@
++#line 2 "dtc-lexer.lex.c"
++
++#line 4 "dtc-lexer.lex.c"
++
++#define  YY_INT_ALIGNED short int
++
++/* A lexical scanner generated by flex */
++
++#define FLEX_SCANNER
++#define YY_FLEX_MAJOR_VERSION 2
++#define YY_FLEX_MINOR_VERSION 5
++#define YY_FLEX_SUBMINOR_VERSION 33
++#if YY_FLEX_SUBMINOR_VERSION > 0
++#define FLEX_BETA
++#endif
++
++/* First, we deal with  platform-specific or compiler-specific issues. */
++
++/* begin standard C headers. */
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#include <stdlib.h>
++
++/* end standard C headers. */
++
++/* flex integer type definitions */
++
++#ifndef FLEXINT_H
++#define FLEXINT_H
++
++/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
++
++#if __STDC_VERSION__ >= 199901L
++
++/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
++ * if you want the limit (max/min) macros for int types. 
++ */
++#ifndef __STDC_LIMIT_MACROS
++#define __STDC_LIMIT_MACROS 1
++#endif
++
++#include <inttypes.h>
++typedef int8_t flex_int8_t;
++typedef uint8_t flex_uint8_t;
++typedef int16_t flex_int16_t;
++typedef uint16_t flex_uint16_t;
++typedef int32_t flex_int32_t;
++typedef uint32_t flex_uint32_t;
++#else
++typedef signed char flex_int8_t;
++typedef short int flex_int16_t;
++typedef int flex_int32_t;
++typedef unsigned char flex_uint8_t; 
++typedef unsigned short int flex_uint16_t;
++typedef unsigned int flex_uint32_t;
++#endif /* ! C99 */
++
++/* Limits of integral types. */
++#ifndef INT8_MIN
++#define INT8_MIN               (-128)
++#endif
++#ifndef INT16_MIN
++#define INT16_MIN              (-32767-1)
++#endif
++#ifndef INT32_MIN
++#define INT32_MIN              (-2147483647-1)
++#endif
++#ifndef INT8_MAX
++#define INT8_MAX               (127)
++#endif
++#ifndef INT16_MAX
++#define INT16_MAX              (32767)
++#endif
++#ifndef INT32_MAX
++#define INT32_MAX              (2147483647)
++#endif
++#ifndef UINT8_MAX
++#define UINT8_MAX              (255U)
++#endif
++#ifndef UINT16_MAX
++#define UINT16_MAX             (65535U)
++#endif
++#ifndef UINT32_MAX
++#define UINT32_MAX             (4294967295U)
++#endif
++
++#endif /* ! FLEXINT_H */
++
++#ifdef __cplusplus
++
++/* The "const" storage-class-modifier is valid. */
++#define YY_USE_CONST
++
++#else	/* ! __cplusplus */
++
++#if __STDC__
++
++#define YY_USE_CONST
++
++#endif	/* __STDC__ */
++#endif	/* ! __cplusplus */
++
++#ifdef YY_USE_CONST
++#define yyconst const
++#else
++#define yyconst
++#endif
++
++/* Returned upon end-of-file. */
++#define YY_NULL 0
++
++/* Promotes a possibly negative, possibly signed char to an unsigned
++ * integer for use as an array index.  If the signed char is negative,
++ * we want to instead treat it as an 8-bit unsigned char, hence the
++ * double cast.
++ */
++#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
++
++/* Enter a start condition.  This macro really ought to take a parameter,
++ * but we do it the disgusting crufty way forced on us by the ()-less
++ * definition of BEGIN.
++ */
++#define BEGIN (yy_start) = 1 + 2 *
++
++/* Translate the current start state into a value that can be later handed
++ * to BEGIN to return to the state.  The YYSTATE alias is for lex
++ * compatibility.
++ */
++#define YY_START (((yy_start) - 1) / 2)
++#define YYSTATE YY_START
++
++/* Action number for EOF rule of a given start state. */
++#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
++
++/* Special action meaning "start processing a new file". */
++#define YY_NEW_FILE yyrestart(yyin  )
++
++#define YY_END_OF_BUFFER_CHAR 0
++
++/* Size of default input buffer. */
++#ifndef YY_BUF_SIZE
++#define YY_BUF_SIZE 16384
++#endif
++
++/* The state buf must be large enough to hold one state per character in the main buffer.
++ */
++#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
++
++#ifndef YY_TYPEDEF_YY_BUFFER_STATE
++#define YY_TYPEDEF_YY_BUFFER_STATE
++typedef struct yy_buffer_state *YY_BUFFER_STATE;
++#endif
++
++extern int yyleng;
++
++extern FILE *yyin, *yyout;
++
++#define EOB_ACT_CONTINUE_SCAN 0
++#define EOB_ACT_END_OF_FILE 1
++#define EOB_ACT_LAST_MATCH 2
++
++    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
++     *       access to the local variable yy_act. Since yyless() is a macro, it would break
++     *       existing scanners that call yyless() from OUTSIDE yylex. 
++     *       One obvious solution it to make yy_act a global. I tried that, and saw
++     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
++     *       normally declared as a register variable-- so it is not worth it.
++     */
++    #define  YY_LESS_LINENO(n) \
++            do { \
++                int yyl;\
++                for ( yyl = n; yyl < yyleng; ++yyl )\
++                    if ( yytext[yyl] == '\n' )\
++                        --yylineno;\
++            }while(0)
++    
++/* Return all but the first "n" matched characters back to the input stream. */
++#define yyless(n) \
++	do \
++		{ \
++		/* Undo effects of setting up yytext. */ \
++        int yyless_macro_arg = (n); \
++        YY_LESS_LINENO(yyless_macro_arg);\
++		*yy_cp = (yy_hold_char); \
++		YY_RESTORE_YY_MORE_OFFSET \
++		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
++		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
++		} \
++	while ( 0 )
++
++#define unput(c) yyunput( c, (yytext_ptr)  )
++
++/* The following is because we cannot portably get our hands on size_t
++ * (without autoconf's help, which isn't available because we want
++ * flex-generated scanners to compile on their own).
++ */
++
++#ifndef YY_TYPEDEF_YY_SIZE_T
++#define YY_TYPEDEF_YY_SIZE_T
++typedef unsigned int yy_size_t;
++#endif
++
++#ifndef YY_STRUCT_YY_BUFFER_STATE
++#define YY_STRUCT_YY_BUFFER_STATE
++struct yy_buffer_state
++	{
++	FILE *yy_input_file;
++
++	char *yy_ch_buf;		/* input buffer */
++	char *yy_buf_pos;		/* current position in input buffer */
++
++	/* Size of input buffer in bytes, not including room for EOB
++	 * characters.
++	 */
++	yy_size_t yy_buf_size;
++
++	/* Number of characters read into yy_ch_buf, not including EOB
++	 * characters.
++	 */
++	int yy_n_chars;
++
++	/* Whether we "own" the buffer - i.e., we know we created it,
++	 * and can realloc() it to grow it, and should free() it to
++	 * delete it.
++	 */
++	int yy_is_our_buffer;
++
++	/* Whether this is an "interactive" input source; if so, and
++	 * if we're using stdio for input, then we want to use getc()
++	 * instead of fread(), to make sure we stop fetching input after
++	 * each newline.
++	 */
++	int yy_is_interactive;
++
++	/* Whether we're considered to be at the beginning of a line.
++	 * If so, '^' rules will be active on the next match, otherwise
++	 * not.
++	 */
++	int yy_at_bol;
++
++    int yy_bs_lineno; /**< The line count. */
++    int yy_bs_column; /**< The column count. */
++    
++	/* Whether to try to fill the input buffer when we reach the
++	 * end of it.
++	 */
++	int yy_fill_buffer;
++
++	int yy_buffer_status;
++
++#define YY_BUFFER_NEW 0
++#define YY_BUFFER_NORMAL 1
++	/* When an EOF's been seen but there's still some text to process
++	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
++	 * shouldn't try reading from the input source any more.  We might
++	 * still have a bunch of tokens to match, though, because of
++	 * possible backing-up.
++	 *
++	 * When we actually see the EOF, we change the status to "new"
++	 * (via yyrestart()), so that the user can continue scanning by
++	 * just pointing yyin at a new input file.
++	 */
++#define YY_BUFFER_EOF_PENDING 2
++
++	};
++#endif /* !YY_STRUCT_YY_BUFFER_STATE */
++
++/* Stack of input buffers. */
++static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
++static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
++static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
++
++/* We provide macros for accessing buffer states in case in the
++ * future we want to put the buffer states in a more general
++ * "scanner state".
++ *
++ * Returns the top of the stack, or NULL.
++ */
++#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
++                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
++                          : NULL)
++
++/* Same as previous macro, but useful when we know that the buffer stack is not
++ * NULL or when we need an lvalue. For internal use only.
++ */
++#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
++
++/* yy_hold_char holds the character lost when yytext is formed. */
++static char yy_hold_char;
++static int yy_n_chars;		/* number of characters read into yy_ch_buf */
++int yyleng;
++
++/* Points to current character in buffer. */
++static char *yy_c_buf_p = (char *) 0;
++static int yy_init = 0;		/* whether we need to initialize */
++static int yy_start = 0;	/* start state number */
++
++/* Flag which is used to allow yywrap()'s to do buffer switches
++ * instead of setting up a fresh yyin.  A bit of a hack ...
++ */
++static int yy_did_buffer_switch_on_eof;
++
++void yyrestart (FILE *input_file  );
++void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
++YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
++void yy_delete_buffer (YY_BUFFER_STATE b  );
++void yy_flush_buffer (YY_BUFFER_STATE b  );
++void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
++void yypop_buffer_state (void );
++
++static void yyensure_buffer_stack (void );
++static void yy_load_buffer_state (void );
++static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
++
++#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
++
++YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
++YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
++YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
++
++void *yyalloc (yy_size_t  );
++void *yyrealloc (void *,yy_size_t  );
++void yyfree (void *  );
++
++#define yy_new_buffer yy_create_buffer
++
++#define yy_set_interactive(is_interactive) \
++	{ \
++	if ( ! YY_CURRENT_BUFFER ){ \
++        yyensure_buffer_stack (); \
++		YY_CURRENT_BUFFER_LVALUE =    \
++            yy_create_buffer(yyin,YY_BUF_SIZE ); \
++	} \
++	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
++	}
++
++#define yy_set_bol(at_bol) \
++	{ \
++	if ( ! YY_CURRENT_BUFFER ){\
++        yyensure_buffer_stack (); \
++		YY_CURRENT_BUFFER_LVALUE =    \
++            yy_create_buffer(yyin,YY_BUF_SIZE ); \
++	} \
++	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
++	}
++
++#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
++
++/* Begin user sect3 */
++
++#define yywrap() 1
++#define YY_SKIP_YYWRAP
++
++typedef unsigned char YY_CHAR;
++
++FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
++
++typedef int yy_state_type;
++
++extern int yylineno;
++
++int yylineno = 1;
++
++extern char *yytext;
++#define yytext_ptr yytext
++
++static yy_state_type yy_get_previous_state (void );
++static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
++static int yy_get_next_buffer (void );
++static void yy_fatal_error (yyconst char msg[]  );
++
++/* Done after the current pattern has been matched and before the
++ * corresponding action - sets up yytext.
++ */
++#define YY_DO_BEFORE_ACTION \
++	(yytext_ptr) = yy_bp; \
++	yyleng = (size_t) (yy_cp - yy_bp); \
++	(yy_hold_char) = *yy_cp; \
++	*yy_cp = '\0'; \
++	(yy_c_buf_p) = yy_cp;
++
++#define YY_NUM_RULES 20
++#define YY_END_OF_BUFFER 21
++/* This struct is not used in this scanner,
++   but its presence is necessary. */
++struct yy_trans_info
++	{
++	flex_int32_t yy_verify;
++	flex_int32_t yy_nxt;
++	};
++static yyconst flex_int16_t yy_accept[94] =
++    {   0,
++        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
++       21,   19,   16,   16,   19,   19,   19,    8,    8,   19,
++        8,   19,   19,   19,   19,   14,   15,   15,   19,    9,
++        9,   16,    0,    3,    0,    0,   10,    0,    0,    0,
++        0,    0,    0,    8,    8,    6,    0,    7,    0,    2,
++        0,   13,   13,   15,   15,    9,    0,   12,   10,    0,
++        0,    0,    0,   18,    0,    0,    0,    2,    9,    0,
++       17,    0,    0,    0,   11,    0,    0,    0,    0,    0,
++        0,    0,    0,    0,    4,    0,    0,    1,    0,    0,
++        0,    5,    0
++
++    } ;
++
++static yyconst flex_int32_t yy_ec[256] =
++    {   0,
++        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
++        2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    2,    1,    4,    5,    1,    1,    6,    1,    1,
++        1,    7,    8,    8,    9,    8,   10,   11,   12,   13,
++       13,   13,   13,   13,   13,   13,   13,   14,    1,    1,
++        1,    1,    8,    8,   15,   15,   15,   15,   15,   15,
++       16,   16,   16,   16,   16,   16,   16,   16,   16,   16,
++       16,   16,   16,   16,   16,   16,   16,   17,   16,   16,
++        1,   18,   19,    1,   16,    1,   15,   20,   21,   22,
++
++       23,   15,   16,   24,   25,   16,   16,   26,   27,   28,
++       24,   16,   16,   29,   30,   31,   32,   33,   16,   17,
++       16,   16,   34,    1,   35,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1
++    } ;
++
++static yyconst flex_int32_t yy_meta[36] =
++    {   0,
++        1,    1,    1,    1,    2,    1,    2,    2,    2,    3,
++        4,    4,    4,    5,    6,    7,    7,    1,    1,    6,
++        6,    6,    6,    7,    7,    7,    7,    7,    7,    7,
++        7,    7,    7,    8,    1
++    } ;
++
++static yyconst flex_int16_t yy_base[107] =
++    {   0,
++        0,    0,   32,    0,   53,    0,   76,    0,  108,  111,
++      280,  288,   37,   39,   33,   36,  106,    0,  123,  146,
++      255,  251,   45,    0,  159,  288,    0,   53,  108,  172,
++      114,  127,  158,  288,  245,    0,    0,  234,  235,  236,
++      197,  195,  199,    0,    0,  288,    0,  288,  160,  288,
++      183,  288,    0,    0,  183,  182,    0,    0,    0,    0,
++      204,  189,  207,  288,  179,  187,  180,  194,    0,  171,
++      288,  196,  178,  174,  288,  169,  169,  177,  165,  153,
++      143,  155,  137,  118,  288,  122,   42,  288,   36,   36,
++       40,  288,  288,  212,  218,  223,  229,  234,  239,  245,
++
++      251,  255,  262,  270,  275,  280
++    } ;
++
++static yyconst flex_int16_t yy_def[107] =
++    {   0,
++       93,    1,    1,    3,    3,    5,   93,    7,    3,    3,
++       93,   93,   93,   93,   94,   95,   93,   96,   93,   19,
++       19,   20,   97,   98,   20,   93,   99,  100,   95,   93,
++       93,   93,   94,   93,   94,  101,  102,   93,  103,  104,
++       93,   93,   93,   96,   19,   93,   20,   93,   97,   93,
++       97,   93,   20,   99,  100,   93,  105,  101,  102,  106,
++      103,  103,  104,   93,   93,   93,   93,   94,  105,  106,
++       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
++       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
++       93,   93,    0,   93,   93,   93,   93,   93,   93,   93,
++
++       93,   93,   93,   93,   93,   93
++    } ;
++
++static yyconst flex_int16_t yy_nxt[324] =
++    {   0,
++       12,   13,   14,   15,   12,   16,   12,   12,   12,   17,
++       18,   18,   18,   12,   19,   20,   20,   12,   12,   21,
++       19,   21,   19,   22,   20,   20,   20,   20,   20,   20,
++       20,   20,   20,   12,   12,   23,   34,   12,   32,   32,
++       32,   32,   12,   12,   12,   36,   20,   33,   50,   92,
++       35,   20,   20,   20,   20,   20,   15,   54,   91,   54,
++       54,   54,   51,   24,   24,   24,   46,   25,   90,   38,
++       89,   26,   25,   25,   25,   25,   12,   13,   14,   15,
++       27,   12,   27,   27,   27,   17,   27,   27,   27,   12,
++       28,   28,   28,   12,   12,   28,   28,   28,   28,   28,
++
++       28,   28,   28,   28,   28,   28,   28,   28,   28,   12,
++       12,   15,   39,   29,   15,   40,   29,   93,   30,   31,
++       31,   30,   31,   31,   56,   56,   56,   41,   32,   32,
++       42,   88,   43,   45,   45,   45,   46,   45,   47,   47,
++       87,   38,   45,   45,   45,   45,   47,   47,   47,   47,
++       47,   47,   47,   47,   47,   47,   47,   47,   47,   86,
++       47,   34,   33,   50,   85,   47,   47,   47,   47,   53,
++       53,   53,   84,   53,   83,   35,   82,   51,   53,   53,
++       53,   53,   56,   56,   56,   93,   68,   54,   57,   54,
++       54,   54,   56,   56,   56,   62,   46,   34,   71,   81,
++
++       80,   79,   78,   77,   76,   75,   74,   73,   72,   64,
++       62,   35,   33,   33,   33,   33,   33,   33,   33,   33,
++       37,   67,   66,   37,   37,   37,   44,   65,   44,   49,
++       49,   49,   49,   49,   49,   49,   49,   52,   64,   52,
++       54,   62,   54,   60,   54,   54,   55,   93,   55,   55,
++       55,   55,   58,   58,   58,   48,   58,   58,   59,   48,
++       59,   59,   61,   61,   61,   61,   61,   61,   61,   61,
++       63,   63,   63,   63,   63,   63,   63,   63,   69,   93,
++       69,   70,   70,   70,   93,   70,   70,   11,   93,   93,
++       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
++
++       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
++       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
++       93,   93,   93
++    } ;
++
++static yyconst flex_int16_t yy_chk[324] =
++    {   0,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
++        1,    1,    1,    1,    1,    3,   15,    3,   13,   13,
++       14,   14,    3,    3,    3,   16,    3,   23,   23,   91,
++       15,    3,    3,    3,    3,    3,    5,   28,   90,   28,
++       28,   28,   23,    5,    5,    5,   28,    5,   89,   16,
++       87,    5,    5,    5,    5,    5,    7,    7,    7,    7,
++        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
++        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
++
++        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
++        7,    9,   17,    9,   10,   17,   10,   29,    9,    9,
++        9,   10,   10,   10,   31,   31,   31,   17,   32,   32,
++       17,   86,   17,   19,   19,   19,   19,   19,   19,   19,
++       84,   29,   19,   19,   19,   19,   19,   19,   19,   19,
++       19,   19,   19,   19,   19,   19,   20,   20,   20,   83,
++       20,   33,   49,   49,   82,   20,   20,   20,   20,   25,
++       25,   25,   81,   25,   80,   33,   79,   49,   25,   25,
++       25,   25,   30,   30,   30,   51,   51,   55,   30,   55,
++       55,   55,   56,   56,   56,   62,   55,   68,   62,   78,
++
++       77,   76,   74,   73,   72,   70,   67,   66,   65,   63,
++       61,   68,   94,   94,   94,   94,   94,   94,   94,   94,
++       95,   43,   42,   95,   95,   95,   96,   41,   96,   97,
++       97,   97,   97,   97,   97,   97,   97,   98,   40,   98,
++       99,   39,   99,   38,   99,   99,  100,   35,  100,  100,
++      100,  100,  101,  101,  101,   22,  101,  101,  102,   21,
++      102,  102,  103,  103,  103,  103,  103,  103,  103,  103,
++      104,  104,  104,  104,  104,  104,  104,  104,  105,   11,
++      105,  106,  106,  106,    0,  106,  106,   93,   93,   93,
++       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
++
++       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
++       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
++       93,   93,   93
++    } ;
++
++/* Table of booleans, true if rule could match eol. */
++static yyconst flex_int32_t yy_rule_can_match_eol[21] =
++    {   0,
++0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 
++    0,     };
++
++static yy_state_type yy_last_accepting_state;
++static char *yy_last_accepting_cpos;
++
++extern int yy_flex_debug;
++int yy_flex_debug = 0;
++
++/* The intent behind this definition is that it'll catch
++ * any uses of REJECT which flex missed.
++ */
++#define REJECT reject_used_but_not_detected
++#define yymore() yymore_used_but_not_detected
++#define YY_MORE_ADJ 0
++#define YY_RESTORE_YY_MORE_OFFSET
++char *yytext;
++#line 1 "dtc-lexer.l"
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++
++
++
++#line 33 "dtc-lexer.l"
++#include "dtc.h"
++#include "srcpos.h"
++#include "dtc-parser.tab.h"
++
++
++/*#define LEXDEBUG	1*/
++
++#ifdef LEXDEBUG
++#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
++#else
++#define DPRINT(fmt, ...)	do { } while (0)
++#endif
++
++static int dts_version; /* = 0 */
++
++#define BEGIN_DEFAULT()	if (dts_version == 0) { \
++				DPRINT("<INITIAL>\n"); \
++				BEGIN(INITIAL); \
++			} else { \
++				DPRINT("<V1>\n"); \
++				BEGIN(V1); \
++			}
++#line 627 "dtc-lexer.lex.c"
++
++#define INITIAL 0
++#define INCLUDE 1
++#define BYTESTRING 2
++#define PROPNODENAME 3
++#define V1 4
++
++#ifndef YY_NO_UNISTD_H
++/* Special case for "unistd.h", since it is non-ANSI. We include it way
++ * down here because we want the user's section 1 to have been scanned first.
++ * The user has a chance to override it with an option.
++ */
++#include <unistd.h>
++#endif
++
++#ifndef YY_EXTRA_TYPE
++#define YY_EXTRA_TYPE void *
++#endif
++
++static int yy_init_globals (void );
++
++/* Macros after this point can all be overridden by user definitions in
++ * section 1.
++ */
++
++#ifndef YY_SKIP_YYWRAP
++#ifdef __cplusplus
++extern "C" int yywrap (void );
++#else
++extern int yywrap (void );
++#endif
++#endif
++
++#ifndef yytext_ptr
++static void yy_flex_strncpy (char *,yyconst char *,int );
++#endif
++
++#ifdef YY_NEED_STRLEN
++static int yy_flex_strlen (yyconst char * );
++#endif
++
++#ifndef YY_NO_INPUT
++
++#ifdef __cplusplus
++static int yyinput (void );
++#else
++static int input (void );
++#endif
++
++#endif
++
++/* Amount of stuff to slurp up with each read. */
++#ifndef YY_READ_BUF_SIZE
++#define YY_READ_BUF_SIZE 8192
++#endif
++
++/* Copy whatever the last rule matched to the standard output. */
++#ifndef ECHO
++/* This used to be an fputs(), but since the string might contain NUL's,
++ * we now use fwrite().
++ */
++#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
++#endif
++
++/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
++ * is returned in "result".
++ */
++#ifndef YY_INPUT
++#define YY_INPUT(buf,result,max_size) \
++	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
++		{ \
++		int c = '*'; \
++		size_t n; \
++		for ( n = 0; n < max_size && \
++			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
++			buf[n] = (char) c; \
++		if ( c == '\n' ) \
++			buf[n++] = (char) c; \
++		if ( c == EOF && ferror( yyin ) ) \
++			YY_FATAL_ERROR( "input in flex scanner failed" ); \
++		result = n; \
++		} \
++	else \
++		{ \
++		errno=0; \
++		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
++			{ \
++			if( errno != EINTR) \
++				{ \
++				YY_FATAL_ERROR( "input in flex scanner failed" ); \
++				break; \
++				} \
++			errno=0; \
++			clearerr(yyin); \
++			} \
++		}\
++\
++
++#endif
++
++/* No semi-colon after return; correct usage is to write "yyterminate();" -
++ * we don't want an extra ';' after the "return" because that will cause
++ * some compilers to complain about unreachable statements.
++ */
++#ifndef yyterminate
++#define yyterminate() return YY_NULL
++#endif
++
++/* Number of entries by which start-condition stack grows. */
++#ifndef YY_START_STACK_INCR
++#define YY_START_STACK_INCR 25
++#endif
++
++/* Report a fatal error. */
++#ifndef YY_FATAL_ERROR
++#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
++#endif
++
++/* end tables serialization structures and prototypes */
++
++/* Default declaration of generated scanner - a define so the user can
++ * easily add parameters.
++ */
++#ifndef YY_DECL
++#define YY_DECL_IS_OURS 1
++
++extern int yylex (void);
++
++#define YY_DECL int yylex (void)
++#endif /* !YY_DECL */
++
++/* Code executed at the beginning of each rule, after yytext and yyleng
++ * have been set up.
++ */
++#ifndef YY_USER_ACTION
++#define YY_USER_ACTION
++#endif
++
++/* Code executed at the end of each rule. */
++#ifndef YY_BREAK
++#define YY_BREAK break;
++#endif
++
++#define YY_RULE_SETUP \
++	YY_USER_ACTION
++
++/** The main scanner function which does all the work.
++ */
++YY_DECL
++{
++	register yy_state_type yy_current_state;
++	register char *yy_cp, *yy_bp;
++	register int yy_act;
++    
++#line 57 "dtc-lexer.l"
++
++#line 784 "dtc-lexer.lex.c"
++
++	if ( !(yy_init) )
++		{
++		(yy_init) = 1;
++
++#ifdef YY_USER_INIT
++		YY_USER_INIT;
++#endif
++
++		if ( ! (yy_start) )
++			(yy_start) = 1;	/* first start state */
++
++		if ( ! yyin )
++			yyin = stdin;
++
++		if ( ! yyout )
++			yyout = stdout;
++
++		if ( ! YY_CURRENT_BUFFER ) {
++			yyensure_buffer_stack ();
++			YY_CURRENT_BUFFER_LVALUE =
++				yy_create_buffer(yyin,YY_BUF_SIZE );
++		}
++
++		yy_load_buffer_state( );
++		}
++
++	while ( 1 )		/* loops until end-of-file is reached */
++		{
++		yy_cp = (yy_c_buf_p);
++
++		/* Support of yytext. */
++		*yy_cp = (yy_hold_char);
++
++		/* yy_bp points to the position in yy_ch_buf of the start of
++		 * the current run.
++		 */
++		yy_bp = yy_cp;
++
++		yy_current_state = (yy_start);
++yy_match:
++		do
++			{
++			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
++			if ( yy_accept[yy_current_state] )
++				{
++				(yy_last_accepting_state) = yy_current_state;
++				(yy_last_accepting_cpos) = yy_cp;
++				}
++			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
++				{
++				yy_current_state = (int) yy_def[yy_current_state];
++				if ( yy_current_state >= 94 )
++					yy_c = yy_meta[(unsigned int) yy_c];
++				}
++			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++			++yy_cp;
++			}
++		while ( yy_base[yy_current_state] != 288 );
++
++yy_find_action:
++		yy_act = yy_accept[yy_current_state];
++		if ( yy_act == 0 )
++			{ /* have to back up */
++			yy_cp = (yy_last_accepting_cpos);
++			yy_current_state = (yy_last_accepting_state);
++			yy_act = yy_accept[yy_current_state];
++			}
++
++		YY_DO_BEFORE_ACTION;
++
++		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
++			{
++			int yyl;
++			for ( yyl = 0; yyl < yyleng; ++yyl )
++				if ( yytext[yyl] == '\n' )
++					   
++    yylineno++;
++;
++			}
++
++do_action:	/* This label is used only to access EOF actions. */
++
++		switch ( yy_act )
++	{ /* beginning of action switch */
++			case 0: /* must back up */
++			/* undo the effects of YY_DO_BEFORE_ACTION */
++			*yy_cp = (yy_hold_char);
++			yy_cp = (yy_last_accepting_cpos);
++			yy_current_state = (yy_last_accepting_state);
++			goto yy_find_action;
++
++case 1:
++YY_RULE_SETUP
++#line 58 "dtc-lexer.l"
++BEGIN(INCLUDE);
++	YY_BREAK
++case 2:
++YY_RULE_SETUP
++#line 60 "dtc-lexer.l"
++{
++			yytext[strlen(yytext) - 1] = 0;
++			if (!push_input_file(yytext + 1)) {
++				/* Some unrecoverable error.*/
++				exit(1);
++			}
++			BEGIN_DEFAULT();
++		}
++	YY_BREAK
++case YY_STATE_EOF(INITIAL):
++case YY_STATE_EOF(INCLUDE):
++case YY_STATE_EOF(BYTESTRING):
++case YY_STATE_EOF(PROPNODENAME):
++case YY_STATE_EOF(V1):
++#line 70 "dtc-lexer.l"
++{
++			if (!pop_input_file()) {
++				yyterminate();
++			}
++		}
++	YY_BREAK
++case 3:
++/* rule 3 can match eol */
++YY_RULE_SETUP
++#line 76 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("String: %s\n", yytext);
++			yylval.data = data_copy_escape_string(yytext+1,
++					yyleng-2);
++			yylloc.first_line = yylineno;
++			return DT_STRING;
++		}
++	YY_BREAK
++case 4:
++YY_RULE_SETUP
++#line 86 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Keyword: /dts-v1/\n");
++			dts_version = 1;
++			BEGIN_DEFAULT();
++			return DT_V1;
++		}
++	YY_BREAK
++case 5:
++YY_RULE_SETUP
++#line 95 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Keyword: /memreserve/\n");
++			BEGIN_DEFAULT();
++			return DT_MEMRESERVE;
++		}
++	YY_BREAK
++case 6:
++YY_RULE_SETUP
++#line 103 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Label: %s\n", yytext);
++			yylval.labelref = strdup(yytext);
++			yylval.labelref[yyleng-1] = '\0';
++			return DT_LABEL;
++		}
++	YY_BREAK
++case 7:
++YY_RULE_SETUP
++#line 112 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			if (*yytext == 'b')
++				yylval.cbase = 2;
++			else if (*yytext == 'o')
++				yylval.cbase = 8;
++			else if (*yytext == 'd')
++				yylval.cbase = 10;
++			else
++				yylval.cbase = 16;
++			DPRINT("Base: %d\n", yylval.cbase);
++			return DT_BASE;
++		}
++	YY_BREAK
++case 8:
++YY_RULE_SETUP
++#line 127 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			yylval.literal = strdup(yytext);
++			DPRINT("Literal: '%s'\n", yylval.literal);
++			return DT_LEGACYLITERAL;
++		}
++	YY_BREAK
++case 9:
++YY_RULE_SETUP
++#line 135 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			yylval.literal = strdup(yytext);
++			DPRINT("Literal: '%s'\n", yylval.literal);
++			return DT_LITERAL;
++		}
++	YY_BREAK
++case 10:
++YY_RULE_SETUP
++#line 143 "dtc-lexer.l"
++{	/* label reference */
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Ref: %s\n", yytext+1);
++			yylval.labelref = strdup(yytext+1);
++			return DT_REF;
++		}
++	YY_BREAK
++case 11:
++YY_RULE_SETUP
++#line 151 "dtc-lexer.l"
++{	/* new-style path reference */
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			yytext[yyleng-1] = '\0';
++			DPRINT("Ref: %s\n", yytext+2);
++			yylval.labelref = strdup(yytext+2);
++			return DT_REF;
++		}
++	YY_BREAK
++case 12:
++YY_RULE_SETUP
++#line 160 "dtc-lexer.l"
++{	/* old-style path reference */
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Ref: %s\n", yytext+1);
++			yylval.labelref = strdup(yytext+1);
++			return DT_REF;
++		}
++	YY_BREAK
++case 13:
++YY_RULE_SETUP
++#line 168 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			yylval.byte = strtol(yytext, NULL, 16);
++			DPRINT("Byte: %02x\n", (int)yylval.byte);
++			return DT_BYTE;
++		}
++	YY_BREAK
++case 14:
++YY_RULE_SETUP
++#line 176 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("/BYTESTRING\n");
++			BEGIN_DEFAULT();
++			return ']';
++		}
++	YY_BREAK
++case 15:
++YY_RULE_SETUP
++#line 184 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("PropNodeName: %s\n", yytext);
++			yylval.propnodename = strdup(yytext);
++			BEGIN_DEFAULT();
++			return DT_PROPNODENAME;
++		}
++	YY_BREAK
++case 16:
++/* rule 16 can match eol */
++YY_RULE_SETUP
++#line 194 "dtc-lexer.l"
++/* eat whitespace */
++	YY_BREAK
++case 17:
++/* rule 17 can match eol */
++YY_RULE_SETUP
++#line 196 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Comment: %s\n", yytext);
++			/* eat comments */
++		}
++	YY_BREAK
++case 18:
++/* rule 18 can match eol */
++YY_RULE_SETUP
++#line 203 "dtc-lexer.l"
++/* eat line comments */
++	YY_BREAK
++case 19:
++YY_RULE_SETUP
++#line 205 "dtc-lexer.l"
++{
++			yylloc.filenum = srcpos_filenum;
++			yylloc.first_line = yylineno;
++			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
++				(unsigned)yytext[0]);
++			if (yytext[0] == '[') {
++				DPRINT("<BYTESTRING>\n");
++				BEGIN(BYTESTRING);
++			}
++			if ((yytext[0] == '{')
++			    || (yytext[0] == ';')) {
++				DPRINT("<PROPNODENAME>\n");
++				BEGIN(PROPNODENAME);
++			}
++			return yytext[0];
++		}
++	YY_BREAK
++case 20:
++YY_RULE_SETUP
++#line 222 "dtc-lexer.l"
++ECHO;
++	YY_BREAK
++#line 1111 "dtc-lexer.lex.c"
++
++	case YY_END_OF_BUFFER:
++		{
++		/* Amount of text matched not including the EOB char. */
++		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
++
++		/* Undo the effects of YY_DO_BEFORE_ACTION. */
++		*yy_cp = (yy_hold_char);
++		YY_RESTORE_YY_MORE_OFFSET
++
++		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
++			{
++			/* We're scanning a new file or input source.  It's
++			 * possible that this happened because the user
++			 * just pointed yyin at a new source and called
++			 * yylex().  If so, then we have to assure
++			 * consistency between YY_CURRENT_BUFFER and our
++			 * globals.  Here is the right place to do so, because
++			 * this is the first action (other than possibly a
++			 * back-up) that will match for the new input source.
++			 */
++			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
++			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
++			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
++			}
++
++		/* Note that here we test for yy_c_buf_p "<=" to the position
++		 * of the first EOB in the buffer, since yy_c_buf_p will
++		 * already have been incremented past the NUL character
++		 * (since all states make transitions on EOB to the
++		 * end-of-buffer state).  Contrast this with the test
++		 * in input().
++		 */
++		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
++			{ /* This was really a NUL. */
++			yy_state_type yy_next_state;
++
++			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
++
++			yy_current_state = yy_get_previous_state(  );
++
++			/* Okay, we're now positioned to make the NUL
++			 * transition.  We couldn't have
++			 * yy_get_previous_state() go ahead and do it
++			 * for us because it doesn't know how to deal
++			 * with the possibility of jamming (and we don't
++			 * want to build jamming into it because then it
++			 * will run more slowly).
++			 */
++
++			yy_next_state = yy_try_NUL_trans( yy_current_state );
++
++			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
++
++			if ( yy_next_state )
++				{
++				/* Consume the NUL. */
++				yy_cp = ++(yy_c_buf_p);
++				yy_current_state = yy_next_state;
++				goto yy_match;
++				}
++
++			else
++				{
++				yy_cp = (yy_c_buf_p);
++				goto yy_find_action;
++				}
++			}
++
++		else switch ( yy_get_next_buffer(  ) )
++			{
++			case EOB_ACT_END_OF_FILE:
++				{
++				(yy_did_buffer_switch_on_eof) = 0;
++
++				if ( yywrap( ) )
++					{
++					/* Note: because we've taken care in
++					 * yy_get_next_buffer() to have set up
++					 * yytext, we can now set up
++					 * yy_c_buf_p so that if some total
++					 * hoser (like flex itself) wants to
++					 * call the scanner after we return the
++					 * YY_NULL, it'll still work - another
++					 * YY_NULL will get returned.
++					 */
++					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
++
++					yy_act = YY_STATE_EOF(YY_START);
++					goto do_action;
++					}
++
++				else
++					{
++					if ( ! (yy_did_buffer_switch_on_eof) )
++						YY_NEW_FILE;
++					}
++				break;
++				}
++
++			case EOB_ACT_CONTINUE_SCAN:
++				(yy_c_buf_p) =
++					(yytext_ptr) + yy_amount_of_matched_text;
++
++				yy_current_state = yy_get_previous_state(  );
++
++				yy_cp = (yy_c_buf_p);
++				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
++				goto yy_match;
++
++			case EOB_ACT_LAST_MATCH:
++				(yy_c_buf_p) =
++				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
++
++				yy_current_state = yy_get_previous_state(  );
++
++				yy_cp = (yy_c_buf_p);
++				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
++				goto yy_find_action;
++			}
++		break;
++		}
++
++	default:
++		YY_FATAL_ERROR(
++			"fatal flex scanner internal error--no action found" );
++	} /* end of action switch */
++		} /* end of scanning one token */
++} /* end of yylex */
++
++/* yy_get_next_buffer - try to read in a new buffer
++ *
++ * Returns a code representing an action:
++ *	EOB_ACT_LAST_MATCH -
++ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
++ *	EOB_ACT_END_OF_FILE - end of file
++ */
++static int yy_get_next_buffer (void)
++{
++    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
++	register char *source = (yytext_ptr);
++	register int number_to_move, i;
++	int ret_val;
++
++	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
++		YY_FATAL_ERROR(
++		"fatal flex scanner internal error--end of buffer missed" );
++
++	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
++		{ /* Don't try to fill the buffer, so this is an EOF. */
++		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
++			{
++			/* We matched a single character, the EOB, so
++			 * treat this as a final EOF.
++			 */
++			return EOB_ACT_END_OF_FILE;
++			}
++
++		else
++			{
++			/* We matched some text prior to the EOB, first
++			 * process it.
++			 */
++			return EOB_ACT_LAST_MATCH;
++			}
++		}
++
++	/* Try to read more data. */
++
++	/* First move last chars to start of buffer. */
++	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
++
++	for ( i = 0; i < number_to_move; ++i )
++		*(dest++) = *(source++);
++
++	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
++		/* don't do the read, it's not guaranteed to return an EOF,
++		 * just force an EOF
++		 */
++		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
++
++	else
++		{
++			int num_to_read =
++			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
++
++		while ( num_to_read <= 0 )
++			{ /* Not enough room in the buffer - grow it. */
++
++			/* just a shorter name for the current buffer */
++			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
++
++			int yy_c_buf_p_offset =
++				(int) ((yy_c_buf_p) - b->yy_ch_buf);
++
++			if ( b->yy_is_our_buffer )
++				{
++				int new_size = b->yy_buf_size * 2;
++
++				if ( new_size <= 0 )
++					b->yy_buf_size += b->yy_buf_size / 8;
++				else
++					b->yy_buf_size *= 2;
++
++				b->yy_ch_buf = (char *)
++					/* Include room in for 2 EOB chars. */
++					yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
++				}
++			else
++				/* Can't grow it, we don't own it. */
++				b->yy_ch_buf = 0;
++
++			if ( ! b->yy_ch_buf )
++				YY_FATAL_ERROR(
++				"fatal error - scanner input buffer overflow" );
++
++			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
++
++			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
++						number_to_move - 1;
++
++			}
++
++		if ( num_to_read > YY_READ_BUF_SIZE )
++			num_to_read = YY_READ_BUF_SIZE;
++
++		/* Read in more data. */
++		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
++			(yy_n_chars), (size_t) num_to_read );
++
++		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
++		}
++
++	if ( (yy_n_chars) == 0 )
++		{
++		if ( number_to_move == YY_MORE_ADJ )
++			{
++			ret_val = EOB_ACT_END_OF_FILE;
++			yyrestart(yyin  );
++			}
++
++		else
++			{
++			ret_val = EOB_ACT_LAST_MATCH;
++			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
++				YY_BUFFER_EOF_PENDING;
++			}
++		}
++
++	else
++		ret_val = EOB_ACT_CONTINUE_SCAN;
++
++	(yy_n_chars) += number_to_move;
++	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
++	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
++
++	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
++
++	return ret_val;
++}
++
++/* yy_get_previous_state - get the state just before the EOB char was reached */
++
++    static yy_state_type yy_get_previous_state (void)
++{
++	register yy_state_type yy_current_state;
++	register char *yy_cp;
++    
++	yy_current_state = (yy_start);
++
++	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
++		{
++		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
++		if ( yy_accept[yy_current_state] )
++			{
++			(yy_last_accepting_state) = yy_current_state;
++			(yy_last_accepting_cpos) = yy_cp;
++			}
++		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
++			{
++			yy_current_state = (int) yy_def[yy_current_state];
++			if ( yy_current_state >= 94 )
++				yy_c = yy_meta[(unsigned int) yy_c];
++			}
++		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++		}
++
++	return yy_current_state;
++}
++
++/* yy_try_NUL_trans - try to make a transition on the NUL character
++ *
++ * synopsis
++ *	next_state = yy_try_NUL_trans( current_state );
++ */
++    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
++{
++	register int yy_is_jam;
++    	register char *yy_cp = (yy_c_buf_p);
++
++	register YY_CHAR yy_c = 1;
++	if ( yy_accept[yy_current_state] )
++		{
++		(yy_last_accepting_state) = yy_current_state;
++		(yy_last_accepting_cpos) = yy_cp;
++		}
++	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
++		{
++		yy_current_state = (int) yy_def[yy_current_state];
++		if ( yy_current_state >= 94 )
++			yy_c = yy_meta[(unsigned int) yy_c];
++		}
++	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++	yy_is_jam = (yy_current_state == 93);
++
++	return yy_is_jam ? 0 : yy_current_state;
++}
++
++#ifndef YY_NO_INPUT
++#ifdef __cplusplus
++    static int yyinput (void)
++#else
++    static int input  (void)
++#endif
++
++{
++	int c;
++    
++	*(yy_c_buf_p) = (yy_hold_char);
++
++	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
++		{
++		/* yy_c_buf_p now points to the character we want to return.
++		 * If this occurs *before* the EOB characters, then it's a
++		 * valid NUL; if not, then we've hit the end of the buffer.
++		 */
++		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
++			/* This was really a NUL. */
++			*(yy_c_buf_p) = '\0';
++
++		else
++			{ /* need more input */
++			int offset = (yy_c_buf_p) - (yytext_ptr);
++			++(yy_c_buf_p);
++
++			switch ( yy_get_next_buffer(  ) )
++				{
++				case EOB_ACT_LAST_MATCH:
++					/* This happens because yy_g_n_b()
++					 * sees that we've accumulated a
++					 * token and flags that we need to
++					 * try matching the token before
++					 * proceeding.  But for input(),
++					 * there's no matching to consider.
++					 * So convert the EOB_ACT_LAST_MATCH
++					 * to EOB_ACT_END_OF_FILE.
++					 */
++
++					/* Reset buffer status. */
++					yyrestart(yyin );
++
++					/*FALLTHROUGH*/
++
++				case EOB_ACT_END_OF_FILE:
++					{
++					if ( yywrap( ) )
++						return EOF;
++
++					if ( ! (yy_did_buffer_switch_on_eof) )
++						YY_NEW_FILE;
++#ifdef __cplusplus
++					return yyinput();
++#else
++					return input();
++#endif
++					}
++
++				case EOB_ACT_CONTINUE_SCAN:
++					(yy_c_buf_p) = (yytext_ptr) + offset;
++					break;
++				}
++			}
++		}
++
++	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
++	*(yy_c_buf_p) = '\0';	/* preserve yytext */
++	(yy_hold_char) = *++(yy_c_buf_p);
++
++	if ( c == '\n' )
++		   
++    yylineno++;
++;
++
++	return c;
++}
++#endif	/* ifndef YY_NO_INPUT */
++
++/** Immediately switch to a different input stream.
++ * @param input_file A readable stream.
++ * 
++ * @note This function does not reset the start condition to @c INITIAL .
++ */
++    void yyrestart  (FILE * input_file )
++{
++    
++	if ( ! YY_CURRENT_BUFFER ){
++        yyensure_buffer_stack ();
++		YY_CURRENT_BUFFER_LVALUE =
++            yy_create_buffer(yyin,YY_BUF_SIZE );
++	}
++
++	yy_init_buffer(YY_CURRENT_BUFFER,input_file );
++	yy_load_buffer_state( );
++}
++
++/** Switch to a different input buffer.
++ * @param new_buffer The new input buffer.
++ * 
++ */
++    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
++{
++    
++	/* TODO. We should be able to replace this entire function body
++	 * with
++	 *		yypop_buffer_state();
++	 *		yypush_buffer_state(new_buffer);
++     */
++	yyensure_buffer_stack ();
++	if ( YY_CURRENT_BUFFER == new_buffer )
++		return;
++
++	if ( YY_CURRENT_BUFFER )
++		{
++		/* Flush out information for old buffer. */
++		*(yy_c_buf_p) = (yy_hold_char);
++		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
++		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
++		}
++
++	YY_CURRENT_BUFFER_LVALUE = new_buffer;
++	yy_load_buffer_state( );
++
++	/* We don't actually know whether we did this switch during
++	 * EOF (yywrap()) processing, but the only time this flag
++	 * is looked at is after yywrap() is called, so it's safe
++	 * to go ahead and always set it.
++	 */
++	(yy_did_buffer_switch_on_eof) = 1;
++}
++
++static void yy_load_buffer_state  (void)
++{
++    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
++	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
++	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
++	(yy_hold_char) = *(yy_c_buf_p);
++}
++
++/** Allocate and initialize an input buffer state.
++ * @param file A readable stream.
++ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
++ * 
++ * @return the allocated buffer state.
++ */
++    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
++{
++	YY_BUFFER_STATE b;
++    
++	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
++	if ( ! b )
++		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
++
++	b->yy_buf_size = size;
++
++	/* yy_ch_buf has to be 2 characters longer than the size given because
++	 * we need to put in 2 end-of-buffer characters.
++	 */
++	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
++	if ( ! b->yy_ch_buf )
++		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
++
++	b->yy_is_our_buffer = 1;
++
++	yy_init_buffer(b,file );
++
++	return b;
++}
++
++/** Destroy the buffer.
++ * @param b a buffer created with yy_create_buffer()
++ * 
++ */
++    void yy_delete_buffer (YY_BUFFER_STATE  b )
++{
++    
++	if ( ! b )
++		return;
++
++	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
++		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
++
++	if ( b->yy_is_our_buffer )
++		yyfree((void *) b->yy_ch_buf  );
++
++	yyfree((void *) b  );
++}
++
++#ifndef __cplusplus
++extern int isatty (int );
++#endif /* __cplusplus */
++    
++/* Initializes or reinitializes a buffer.
++ * This function is sometimes called more than once on the same buffer,
++ * such as during a yyrestart() or at EOF.
++ */
++    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
++
++{
++	int oerrno = errno;
++    
++	yy_flush_buffer(b );
++
++	b->yy_input_file = file;
++	b->yy_fill_buffer = 1;
++
++    /* If b is the current buffer, then yy_init_buffer was _probably_
++     * called from yyrestart() or through yy_get_next_buffer.
++     * In that case, we don't want to reset the lineno or column.
++     */
++    if (b != YY_CURRENT_BUFFER){
++        b->yy_bs_lineno = 1;
++        b->yy_bs_column = 0;
++    }
++
++        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
++    
++	errno = oerrno;
++}
++
++/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
++ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
++ * 
++ */
++    void yy_flush_buffer (YY_BUFFER_STATE  b )
++{
++    	if ( ! b )
++		return;
++
++	b->yy_n_chars = 0;
++
++	/* We always need two end-of-buffer characters.  The first causes
++	 * a transition to the end-of-buffer state.  The second causes
++	 * a jam in that state.
++	 */
++	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
++	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
++
++	b->yy_buf_pos = &b->yy_ch_buf[0];
++
++	b->yy_at_bol = 1;
++	b->yy_buffer_status = YY_BUFFER_NEW;
++
++	if ( b == YY_CURRENT_BUFFER )
++		yy_load_buffer_state( );
++}
++
++/** Pushes the new state onto the stack. The new state becomes
++ *  the current state. This function will allocate the stack
++ *  if necessary.
++ *  @param new_buffer The new state.
++ *  
++ */
++void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
++{
++    	if (new_buffer == NULL)
++		return;
++
++	yyensure_buffer_stack();
++
++	/* This block is copied from yy_switch_to_buffer. */
++	if ( YY_CURRENT_BUFFER )
++		{
++		/* Flush out information for old buffer. */
++		*(yy_c_buf_p) = (yy_hold_char);
++		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
++		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
++		}
++
++	/* Only push if top exists. Otherwise, replace top. */
++	if (YY_CURRENT_BUFFER)
++		(yy_buffer_stack_top)++;
++	YY_CURRENT_BUFFER_LVALUE = new_buffer;
++
++	/* copied from yy_switch_to_buffer. */
++	yy_load_buffer_state( );
++	(yy_did_buffer_switch_on_eof) = 1;
++}
++
++/** Removes and deletes the top of the stack, if present.
++ *  The next element becomes the new top.
++ *  
++ */
++void yypop_buffer_state (void)
++{
++    	if (!YY_CURRENT_BUFFER)
++		return;
++
++	yy_delete_buffer(YY_CURRENT_BUFFER );
++	YY_CURRENT_BUFFER_LVALUE = NULL;
++	if ((yy_buffer_stack_top) > 0)
++		--(yy_buffer_stack_top);
++
++	if (YY_CURRENT_BUFFER) {
++		yy_load_buffer_state( );
++		(yy_did_buffer_switch_on_eof) = 1;
++	}
++}
++
++/* Allocates the stack if it does not exist.
++ *  Guarantees space for at least one push.
++ */
++static void yyensure_buffer_stack (void)
++{
++	int num_to_alloc;
++    
++	if (!(yy_buffer_stack)) {
++
++		/* First allocation is just for 2 elements, since we don't know if this
++		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
++		 * immediate realloc on the next call.
++         */
++		num_to_alloc = 1;
++		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
++								(num_to_alloc * sizeof(struct yy_buffer_state*)
++								);
++		
++		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
++				
++		(yy_buffer_stack_max) = num_to_alloc;
++		(yy_buffer_stack_top) = 0;
++		return;
++	}
++
++	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
++
++		/* Increase the buffer to prepare for a possible push. */
++		int grow_size = 8 /* arbitrary grow size */;
++
++		num_to_alloc = (yy_buffer_stack_max) + grow_size;
++		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
++								((yy_buffer_stack),
++								num_to_alloc * sizeof(struct yy_buffer_state*)
++								);
++
++		/* zero only the new slots.*/
++		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
++		(yy_buffer_stack_max) = num_to_alloc;
++	}
++}
++
++/** Setup the input buffer state to scan directly from a user-specified character buffer.
++ * @param base the character buffer
++ * @param size the size in bytes of the character buffer
++ * 
++ * @return the newly allocated buffer state object. 
++ */
++YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
++{
++	YY_BUFFER_STATE b;
++    
++	if ( size < 2 ||
++	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
++	     base[size-1] != YY_END_OF_BUFFER_CHAR )
++		/* They forgot to leave room for the EOB's. */
++		return 0;
++
++	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
++	if ( ! b )
++		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
++
++	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
++	b->yy_buf_pos = b->yy_ch_buf = base;
++	b->yy_is_our_buffer = 0;
++	b->yy_input_file = 0;
++	b->yy_n_chars = b->yy_buf_size;
++	b->yy_is_interactive = 0;
++	b->yy_at_bol = 1;
++	b->yy_fill_buffer = 0;
++	b->yy_buffer_status = YY_BUFFER_NEW;
++
++	yy_switch_to_buffer(b  );
++
++	return b;
++}
++
++/** Setup the input buffer state to scan a string. The next call to yylex() will
++ * scan from a @e copy of @a str.
++ * @param yystr a NUL-terminated string to scan
++ * 
++ * @return the newly allocated buffer state object.
++ * @note If you want to scan bytes that may contain NUL values, then use
++ *       yy_scan_bytes() instead.
++ */
++YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
++{
++    
++	return yy_scan_bytes(yystr,strlen(yystr) );
++}
++
++/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
++ * scan from a @e copy of @a bytes.
++ * @param bytes the byte buffer to scan
++ * @param len the number of bytes in the buffer pointed to by @a bytes.
++ * 
++ * @return the newly allocated buffer state object.
++ */
++YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
++{
++	YY_BUFFER_STATE b;
++	char *buf;
++	yy_size_t n;
++	int i;
++    
++	/* Get memory for full buffer, including space for trailing EOB's. */
++	n = _yybytes_len + 2;
++	buf = (char *) yyalloc(n  );
++	if ( ! buf )
++		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
++
++	for ( i = 0; i < _yybytes_len; ++i )
++		buf[i] = yybytes[i];
++
++	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
++
++	b = yy_scan_buffer(buf,n );
++	if ( ! b )
++		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
++
++	/* It's okay to grow etc. this buffer, and we should throw it
++	 * away when we're done.
++	 */
++	b->yy_is_our_buffer = 1;
++
++	return b;
++}
++
++#ifndef YY_EXIT_FAILURE
++#define YY_EXIT_FAILURE 2
++#endif
++
++static void yy_fatal_error (yyconst char* msg )
++{
++    	(void) fprintf( stderr, "%s\n", msg );
++	exit( YY_EXIT_FAILURE );
++}
++
++/* Redefine yyless() so it works in section 3 code. */
++
++#undef yyless
++#define yyless(n) \
++	do \
++		{ \
++		/* Undo effects of setting up yytext. */ \
++        int yyless_macro_arg = (n); \
++        YY_LESS_LINENO(yyless_macro_arg);\
++		yytext[yyleng] = (yy_hold_char); \
++		(yy_c_buf_p) = yytext + yyless_macro_arg; \
++		(yy_hold_char) = *(yy_c_buf_p); \
++		*(yy_c_buf_p) = '\0'; \
++		yyleng = yyless_macro_arg; \
++		} \
++	while ( 0 )
++
++/* Accessor  methods (get/set functions) to struct members. */
++
++/** Get the current line number.
++ * 
++ */
++int yyget_lineno  (void)
++{
++        
++    return yylineno;
++}
++
++/** Get the input stream.
++ * 
++ */
++FILE *yyget_in  (void)
++{
++        return yyin;
++}
++
++/** Get the output stream.
++ * 
++ */
++FILE *yyget_out  (void)
++{
++        return yyout;
++}
++
++/** Get the length of the current token.
++ * 
++ */
++int yyget_leng  (void)
++{
++        return yyleng;
++}
++
++/** Get the current token.
++ * 
++ */
++
++char *yyget_text  (void)
++{
++        return yytext;
++}
++
++/** Set the current line number.
++ * @param line_number
++ * 
++ */
++void yyset_lineno (int  line_number )
++{
++    
++    yylineno = line_number;
++}
++
++/** Set the input stream. This does not discard the current
++ * input buffer.
++ * @param in_str A readable stream.
++ * 
++ * @see yy_switch_to_buffer
++ */
++void yyset_in (FILE *  in_str )
++{
++        yyin = in_str ;
++}
++
++void yyset_out (FILE *  out_str )
++{
++        yyout = out_str ;
++}
++
++int yyget_debug  (void)
++{
++        return yy_flex_debug;
++}
++
++void yyset_debug (int  bdebug )
++{
++        yy_flex_debug = bdebug ;
++}
++
++static int yy_init_globals (void)
++{
++        /* Initialization is the same as for the non-reentrant scanner.
++     * This function is called from yylex_destroy(), so don't allocate here.
++     */
++
++    /* We do not touch yylineno unless the option is enabled. */
++    yylineno =  1;
++    
++    (yy_buffer_stack) = 0;
++    (yy_buffer_stack_top) = 0;
++    (yy_buffer_stack_max) = 0;
++    (yy_c_buf_p) = (char *) 0;
++    (yy_init) = 0;
++    (yy_start) = 0;
++
++/* Defined in main.c */
++#ifdef YY_STDINIT
++    yyin = stdin;
++    yyout = stdout;
++#else
++    yyin = (FILE *) 0;
++    yyout = (FILE *) 0;
++#endif
++
++    /* For future reference: Set errno on error, since we are called by
++     * yylex_init()
++     */
++    return 0;
++}
++
++/* yylex_destroy is for both reentrant and non-reentrant scanners. */
++int yylex_destroy  (void)
++{
++    
++    /* Pop the buffer stack, destroying each element. */
++	while(YY_CURRENT_BUFFER){
++		yy_delete_buffer(YY_CURRENT_BUFFER  );
++		YY_CURRENT_BUFFER_LVALUE = NULL;
++		yypop_buffer_state();
++	}
++
++	/* Destroy the stack itself. */
++	yyfree((yy_buffer_stack) );
++	(yy_buffer_stack) = NULL;
++
++    /* Reset the globals. This is important in a non-reentrant scanner so the next time
++     * yylex() is called, initialization will occur. */
++    yy_init_globals( );
++
++    return 0;
++}
++
++/*
++ * Internal utility routines.
++ */
++
++#ifndef yytext_ptr
++static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
++{
++	register int i;
++	for ( i = 0; i < n; ++i )
++		s1[i] = s2[i];
++}
++#endif
++
++#ifdef YY_NEED_STRLEN
++static int yy_flex_strlen (yyconst char * s )
++{
++	register int n;
++	for ( n = 0; s[n]; ++n )
++		;
++
++	return n;
++}
++#endif
++
++void *yyalloc (yy_size_t  size )
++{
++	return (void *) malloc( size );
++}
++
++void *yyrealloc  (void * ptr, yy_size_t  size )
++{
++	/* The cast to (char *) in the following accommodates both
++	 * implementations that use char* generic pointers, and those
++	 * that use void* generic pointers.  It works with the latter
++	 * because both ANSI C and C++ allow castless assignment from
++	 * any pointer type to void*, and deal with argument conversions
++	 * as though doing an assignment.
++	 */
++	return (void *) realloc( (char *) ptr, size );
++}
++
++void yyfree (void * ptr )
++{
++	free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
++}
++
++#define YYTABLES_NAME "yytables"
++
++#line 222 "dtc-lexer.l"
++
++
++
++
++/*
++ * Stack of nested include file contexts.
++ */
++
++struct incl_file {
++	int filenum;
++	FILE *file;
++	YY_BUFFER_STATE yy_prev_buf;
++	int yy_prev_lineno;
++	struct incl_file *prev;
++};
++
++struct incl_file *incl_file_stack;
++
++
++/*
++ * Detect infinite include recursion.
++ */
++#define MAX_INCLUDE_DEPTH	(100)
++
++static int incl_depth = 0;
++
++
++int push_input_file(const char *filename)
++{
++	FILE *f;
++	struct incl_file *incl_file;
++
++	if (!filename) {
++		yyerror("No include file name given.");
++		return 0;
++	}
++
++	if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
++		yyerror("Includes nested too deeply");
++		return 0;
++	}
++
++	f = dtc_open_file(filename);
++
++	incl_file = malloc(sizeof(struct incl_file));
++	if (!incl_file) {
++		yyerror("Can not allocate include file space.");
++		return 0;
++	}
++
++	/*
++	 * Save current context.
++	 */
++	incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
++	incl_file->yy_prev_lineno = yylineno;
++	incl_file->filenum = srcpos_filenum;
++	incl_file->file = yyin;
++	incl_file->prev = incl_file_stack;
++
++	incl_file_stack = incl_file;
++
++	/*
++	 * Establish new context.
++	 */
++	srcpos_filenum = lookup_file_name(filename, 0);
++	yylineno = 1;
++	yyin = f;
++	yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
++
++	return 1;
++}
++
++
++int pop_input_file(void)
++{
++	struct incl_file *incl_file;
++
++	if (incl_file_stack == 0)
++		return 0;
++
++	fclose(yyin);
++
++	/*
++	 * Pop.
++	 */
++	--incl_depth;
++	incl_file = incl_file_stack;
++	incl_file_stack = incl_file->prev;
++
++	/*
++	 * Recover old context.
++	 */
++	yy_delete_buffer(YY_CURRENT_BUFFER);
++	yy_switch_to_buffer(incl_file->yy_prev_buf);
++	yylineno = incl_file->yy_prev_lineno;
++	srcpos_filenum = incl_file->filenum;
++	yyin = incl_file->file;
++
++	/*
++	 * Free old state.
++	 */
++	free(incl_file);
++
++	if (YY_CURRENT_BUFFER == 0)
++		return 0;
++
++	return 1;
++}
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped powerpc.git/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,1983 @@
++/* A Bison parser, made by GNU Bison 2.3.  */
++
++/* Skeleton implementation for Bison's Yacc-like parsers in C
++
++   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
++   Free Software Foundation, 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, or (at your option)
++   any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, USA.  */
++
++/* As a special exception, you may create a larger work that contains
++   part or all of the Bison parser skeleton and distribute that work
++   under terms of your choice, so long as that work isn't itself a
++   parser generator using the skeleton or a modified version thereof
++   as a parser skeleton.  Alternatively, if you modify or redistribute
++   the parser skeleton itself, you may (at your option) remove this
++   special exception, which will cause the skeleton and the resulting
++   Bison output files to be licensed under the GNU General Public
++   License without this special exception.
++
++   This special exception was added by the Free Software Foundation in
++   version 2.2 of Bison.  */
++
++/* C LALR(1) parser skeleton written by Richard Stallman, by
++   simplifying the original so-called "semantic" parser.  */
++
++/* All symbols defined below should begin with yy or YY, to avoid
++   infringing on user name space.  This should be done even for local
++   variables, as they might otherwise be expanded by user macros.
++   There are some unavoidable exceptions within include files to
++   define necessary library symbols; they are noted "INFRINGES ON
++   USER NAME SPACE" below.  */
++
++/* Identify Bison output.  */
++#define YYBISON 1
++
++/* Bison version.  */
++#define YYBISON_VERSION "2.3"
++
++/* Skeleton name.  */
++#define YYSKELETON_NAME "yacc.c"
++
++/* Pure parsers.  */
++#define YYPURE 0
++
++/* Using locations.  */
++#define YYLSP_NEEDED 1
++
++
++
++/* Tokens.  */
++#ifndef YYTOKENTYPE
++# define YYTOKENTYPE
++   /* Put the tokens into the symbol table, so that GDB and other debuggers
++      know about them.  */
++   enum yytokentype {
++     DT_V1 = 258,
++     DT_MEMRESERVE = 259,
++     DT_PROPNODENAME = 260,
++     DT_LITERAL = 261,
++     DT_LEGACYLITERAL = 262,
++     DT_BASE = 263,
++     DT_BYTE = 264,
++     DT_STRING = 265,
++     DT_LABEL = 266,
++     DT_REF = 267
++   };
++#endif
++/* Tokens.  */
++#define DT_V1 258
++#define DT_MEMRESERVE 259
++#define DT_PROPNODENAME 260
++#define DT_LITERAL 261
++#define DT_LEGACYLITERAL 262
++#define DT_BASE 263
++#define DT_BYTE 264
++#define DT_STRING 265
++#define DT_LABEL 266
++#define DT_REF 267
++
++
++
++
++/* Copy the first part of user declarations.  */
++#line 23 "dtc-parser.y"
++
++#include "dtc.h"
++#include "srcpos.h"
++
++int yylex(void);
++unsigned long long eval_literal(const char *s, int base, int bits);
++
++extern struct boot_info *the_boot_info;
++
++
++
++/* Enabling traces.  */
++#ifndef YYDEBUG
++# define YYDEBUG 0
++#endif
++
++/* Enabling verbose error messages.  */
++#ifdef YYERROR_VERBOSE
++# undef YYERROR_VERBOSE
++# define YYERROR_VERBOSE 1
++#else
++# define YYERROR_VERBOSE 0
++#endif
++
++/* Enabling the token table.  */
++#ifndef YYTOKEN_TABLE
++# define YYTOKEN_TABLE 0
++#endif
++
++#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
++typedef union YYSTYPE
++#line 34 "dtc-parser.y"
++{
++	char *propnodename;
++	char *literal;
++	char *labelref;
++	unsigned int cbase;
++	u8 byte;
++	struct data data;
++
++	u64 addr;
++	cell_t cell;
++	struct property *prop;
++	struct property *proplist;
++	struct node *node;
++	struct node *nodelist;
++	struct reserve_info *re;
++}
++/* Line 187 of yacc.c.  */
++#line 148 "dtc-parser.tab.c"
++	YYSTYPE;
++# define yystype YYSTYPE /* obsolescent; will be withdrawn */
++# define YYSTYPE_IS_DECLARED 1
++# define YYSTYPE_IS_TRIVIAL 1
++#endif
++
++#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
++typedef struct YYLTYPE
++{
++  int first_line;
++  int first_column;
++  int last_line;
++  int last_column;
++} YYLTYPE;
++# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
++# define YYLTYPE_IS_DECLARED 1
++# define YYLTYPE_IS_TRIVIAL 1
++#endif
++
++
++/* Copy the second part of user declarations.  */
++
++
++/* Line 216 of yacc.c.  */
++#line 173 "dtc-parser.tab.c"
++
++#ifdef short
++# undef short
++#endif
++
++#ifdef YYTYPE_UINT8
++typedef YYTYPE_UINT8 yytype_uint8;
++#else
++typedef unsigned char yytype_uint8;
++#endif
++
++#ifdef YYTYPE_INT8
++typedef YYTYPE_INT8 yytype_int8;
++#elif (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++typedef signed char yytype_int8;
++#else
++typedef short int yytype_int8;
++#endif
++
++#ifdef YYTYPE_UINT16
++typedef YYTYPE_UINT16 yytype_uint16;
++#else
++typedef unsigned short int yytype_uint16;
++#endif
++
++#ifdef YYTYPE_INT16
++typedef YYTYPE_INT16 yytype_int16;
++#else
++typedef short int yytype_int16;
++#endif
++
++#ifndef YYSIZE_T
++# ifdef __SIZE_TYPE__
++#  define YYSIZE_T __SIZE_TYPE__
++# elif defined size_t
++#  define YYSIZE_T size_t
++# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
++#  define YYSIZE_T size_t
++# else
++#  define YYSIZE_T unsigned int
++# endif
++#endif
++
++#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
++
++#ifndef YY_
++# if YYENABLE_NLS
++#  if ENABLE_NLS
++#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
++#   define YY_(msgid) dgettext ("bison-runtime", msgid)
++#  endif
++# endif
++# ifndef YY_
++#  define YY_(msgid) msgid
++# endif
++#endif
++
++/* Suppress unused-variable warnings by "using" E.  */
++#if ! defined lint || defined __GNUC__
++# define YYUSE(e) ((void) (e))
++#else
++# define YYUSE(e) /* empty */
++#endif
++
++/* Identity function, used to suppress warnings about constant conditions.  */
++#ifndef lint
++# define YYID(n) (n)
++#else
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++static int
++YYID (int i)
++#else
++static int
++YYID (i)
++    int i;
++#endif
++{
++  return i;
++}
++#endif
++
++#if ! defined yyoverflow || YYERROR_VERBOSE
++
++/* The parser invokes alloca or malloc; define the necessary symbols.  */
++
++# ifdef YYSTACK_USE_ALLOCA
++#  if YYSTACK_USE_ALLOCA
++#   ifdef __GNUC__
++#    define YYSTACK_ALLOC __builtin_alloca
++#   elif defined __BUILTIN_VA_ARG_INCR
++#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
++#   elif defined _AIX
++#    define YYSTACK_ALLOC __alloca
++#   elif defined _MSC_VER
++#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
++#    define alloca _alloca
++#   else
++#    define YYSTACK_ALLOC alloca
++#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
++#     ifndef _STDLIB_H
++#      define _STDLIB_H 1
++#     endif
++#    endif
++#   endif
++#  endif
++# endif
++
++# ifdef YYSTACK_ALLOC
++   /* Pacify GCC's `empty if-body' warning.  */
++#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
++#  ifndef YYSTACK_ALLOC_MAXIMUM
++    /* The OS might guarantee only one guard page at the bottom of the stack,
++       and a page size can be as small as 4096 bytes.  So we cannot safely
++       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
++       to allow for a few compiler-allocated temporary stack slots.  */
++#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
++#  endif
++# else
++#  define YYSTACK_ALLOC YYMALLOC
++#  define YYSTACK_FREE YYFREE
++#  ifndef YYSTACK_ALLOC_MAXIMUM
++#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
++#  endif
++#  if (defined __cplusplus && ! defined _STDLIB_H \
++       && ! ((defined YYMALLOC || defined malloc) \
++	     && (defined YYFREE || defined free)))
++#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
++#   ifndef _STDLIB_H
++#    define _STDLIB_H 1
++#   endif
++#  endif
++#  ifndef YYMALLOC
++#   define YYMALLOC malloc
++#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
++#   endif
++#  endif
++#  ifndef YYFREE
++#   define YYFREE free
++#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++void free (void *); /* INFRINGES ON USER NAME SPACE */
++#   endif
++#  endif
++# endif
++#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
++
++
++#if (! defined yyoverflow \
++     && (! defined __cplusplus \
++	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
++	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
++
++/* A type that is properly aligned for any stack member.  */
++union yyalloc
++{
++  yytype_int16 yyss;
++  YYSTYPE yyvs;
++    YYLTYPE yyls;
++};
++
++/* The size of the maximum gap between one aligned stack and the next.  */
++# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
++
++/* The size of an array large to enough to hold all stacks, each with
++   N elements.  */
++# define YYSTACK_BYTES(N) \
++     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
++      + 2 * YYSTACK_GAP_MAXIMUM)
++
++/* Copy COUNT objects from FROM to TO.  The source and destination do
++   not overlap.  */
++# ifndef YYCOPY
++#  if defined __GNUC__ && 1 < __GNUC__
++#   define YYCOPY(To, From, Count) \
++      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
++#  else
++#   define YYCOPY(To, From, Count)		\
++      do					\
++	{					\
++	  YYSIZE_T yyi;				\
++	  for (yyi = 0; yyi < (Count); yyi++)	\
++	    (To)[yyi] = (From)[yyi];		\
++	}					\
++      while (YYID (0))
++#  endif
++# endif
++
++/* Relocate STACK from its old location to the new one.  The
++   local variables YYSIZE and YYSTACKSIZE give the old and new number of
++   elements in the stack, and YYPTR gives the new location of the
++   stack.  Advance YYPTR to a properly aligned location for the next
++   stack.  */
++# define YYSTACK_RELOCATE(Stack)					\
++    do									\
++      {									\
++	YYSIZE_T yynewbytes;						\
++	YYCOPY (&yyptr->Stack, Stack, yysize);				\
++	Stack = &yyptr->Stack;						\
++	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
++	yyptr += yynewbytes / sizeof (*yyptr);				\
++      }									\
++    while (YYID (0))
++
++#endif
++
++/* YYFINAL -- State number of the termination state.  */
++#define YYFINAL  9
++/* YYLAST -- Last index in YYTABLE.  */
++#define YYLAST   60
++
++/* YYNTOKENS -- Number of terminals.  */
++#define YYNTOKENS  24
++/* YYNNTS -- Number of nonterminals.  */
++#define YYNNTS  20
++/* YYNRULES -- Number of rules.  */
++#define YYNRULES  43
++/* YYNRULES -- Number of states.  */
++#define YYNSTATES  67
++
++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
++#define YYUNDEFTOK  2
++#define YYMAXUTOK   267
++
++#define YYTRANSLATE(YYX)						\
++  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
++
++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
++static const yytype_uint8 yytranslate[] =
++{
++       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,    23,    14,     2,    15,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,    13,
++      19,    18,    20,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,    21,     2,    22,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,    16,     2,    17,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
++       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
++       5,     6,     7,     8,     9,    10,    11,    12
++};
++
++#if YYDEBUG
++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
++   YYRHS.  */
++static const yytype_uint8 yyprhs[] =
++{
++       0,     0,     3,     8,    11,    12,    15,    21,    22,    25,
++      27,    34,    36,    38,    41,    47,    48,    51,    57,    61,
++      64,    69,    74,    77,    80,    81,    84,    87,    88,    91,
++      94,    97,    98,   100,   102,   105,   106,   109,   112,   113,
++     116,   119,   123,   124
++};
++
++/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
++static const yytype_int8 yyrhs[] =
++{
++      25,     0,    -1,     3,    13,    26,    31,    -1,    28,    31,
++      -1,    -1,    27,    26,    -1,    43,     4,    30,    30,    13,
++      -1,    -1,    29,    28,    -1,    27,    -1,    43,     4,    30,
++      14,    30,    13,    -1,     6,    -1,     7,    -1,    15,    32,
++      -1,    16,    33,    41,    17,    13,    -1,    -1,    33,    34,
++      -1,    43,     5,    18,    35,    13,    -1,    43,     5,    13,
++      -1,    36,    10,    -1,    36,    19,    37,    20,    -1,    36,
++      21,    40,    22,    -1,    36,    12,    -1,    35,    11,    -1,
++      -1,    35,    23,    -1,    36,    11,    -1,    -1,    37,    39,
++      -1,    37,    12,    -1,    37,    11,    -1,    -1,     8,    -1,
++       6,    -1,    38,     7,    -1,    -1,    40,     9,    -1,    40,
++      11,    -1,    -1,    42,    41,    -1,    42,    34,    -1,    43,
++       5,    32,    -1,    -1,    11,    -1
++};
++
++/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
++static const yytype_uint16 yyrline[] =
++{
++       0,    85,    85,    89,    97,   100,   107,   115,   118,   125,
++     129,   136,   140,   147,   154,   162,   165,   172,   176,   183,
++     187,   191,   195,   199,   207,   210,   214,   222,   225,   229,
++     234,   242,   245,   249,   253,   261,   264,   268,   276,   279,
++     283,   291,   299,   302
++};
++#endif
++
++#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
++/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
++   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
++static const char *const yytname[] =
++{
++  "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
++  "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE",
++  "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "';'", "'-'", "'/'", "'{'",
++  "'}'", "'='", "'<'", "'>'", "'['", "']'", "','", "$accept", "sourcefile",
++  "memreserves", "memreserve", "v0_memreserves", "v0_memreserve", "addr",
++  "devicetree", "nodedef", "proplist", "propdef", "propdata",
++  "propdataprefix", "celllist", "cellbase", "cellval", "bytestring",
++  "subnodes", "subnode", "label", 0
++};
++#endif
++
++# ifdef YYPRINT
++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
++   token YYLEX-NUM.  */
++static const yytype_uint16 yytoknum[] =
++{
++       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
++     265,   266,   267,    59,    45,    47,   123,   125,    61,    60,
++      62,    91,    93,    44
++};
++# endif
++
++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
++static const yytype_uint8 yyr1[] =
++{
++       0,    24,    25,    25,    26,    26,    27,    28,    28,    29,
++      29,    30,    30,    31,    32,    33,    33,    34,    34,    35,
++      35,    35,    35,    35,    36,    36,    36,    37,    37,    37,
++      37,    38,    38,    39,    39,    40,    40,    40,    41,    41,
++      41,    42,    43,    43
++};
++
++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
++static const yytype_uint8 yyr2[] =
++{
++       0,     2,     4,     2,     0,     2,     5,     0,     2,     1,
++       6,     1,     1,     2,     5,     0,     2,     5,     3,     2,
++       4,     4,     2,     2,     0,     2,     2,     0,     2,     2,
++       2,     0,     1,     1,     2,     0,     2,     2,     0,     2,
++       2,     3,     0,     1
++};
++
++/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
++   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
++   means the default is an error.  */
++static const yytype_uint8 yydefact[] =
++{
++       7,     0,    43,     0,     9,     0,     7,     0,     4,     1,
++       0,     3,     8,     0,     0,     4,     0,    15,    13,    11,
++      12,     0,     2,     5,     0,    38,     0,     0,     0,    16,
++       0,    38,     0,     0,     6,     0,    40,    39,     0,    10,
++      14,    18,    24,    41,     0,     0,    23,    17,    25,    19,
++      26,    22,    27,    35,    31,     0,    33,    32,    30,    29,
++      20,     0,    28,    36,    37,    21,    34
++};
++
++/* YYDEFGOTO[NTERM-NUM].  */
++static const yytype_int8 yydefgoto[] =
++{
++      -1,     3,    14,     4,     5,     6,    27,    11,    18,    25,
++      29,    44,    45,    54,    61,    62,    55,    30,    31,     7
++};
++
++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
++   STATE-NUM.  */
++#define YYPACT_NINF -13
++static const yytype_int8 yypact[] =
++{
++      23,    11,   -13,    37,   -13,    -4,    18,    39,    18,   -13,
++      28,   -13,   -13,    34,    -4,    18,    41,   -13,   -13,   -13,
++     -13,    25,   -13,   -13,    34,    -3,    34,    33,    34,   -13,
++      30,    -3,    43,    36,   -13,    38,   -13,   -13,    20,   -13,
++     -13,   -13,   -13,   -13,     2,     9,   -13,   -13,   -13,   -13,
++     -13,   -13,   -13,   -13,    -2,    -6,   -13,   -13,   -13,   -13,
++     -13,    45,   -13,   -13,   -13,   -13,   -13
++};
++
++/* YYPGOTO[NTERM-NUM].  */
++static const yytype_int8 yypgoto[] =
++{
++     -13,   -13,    35,    27,    47,   -13,   -12,    40,    17,   -13,
++      26,   -13,   -13,   -13,   -13,   -13,   -13,    29,   -13,    -8
++};
++
++/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
++   positive, shift that token.  If negative, reduce the rule which
++   number is the opposite.  If zero, do what YYDEFACT says.
++   If YYTABLE_NINF, syntax error.  */
++#define YYTABLE_NINF -43
++static const yytype_int8 yytable[] =
++{
++      16,    21,   -42,    63,    56,    64,    57,    16,     2,    58,
++      59,    10,    28,    46,    33,    47,    65,    32,    60,    49,
++      50,    51,   -42,    32,     8,    48,     1,   -42,    52,     2,
++      53,    19,    20,    41,     2,    15,    17,     9,    42,    26,
++      19,    20,    15,    13,    17,    24,    34,    35,    38,    39,
++      23,    40,    66,    12,    22,    43,     0,    36,     0,     0,
++      37
++};
++
++static const yytype_int8 yycheck[] =
++{
++       8,    13,     5,     9,     6,    11,     8,    15,    11,    11,
++      12,    15,    24,    11,    26,    13,    22,    25,    20,    10,
++      11,    12,     4,    31,    13,    23,     3,     4,    19,    11,
++      21,     6,     7,    13,    11,     8,    16,     0,    18,    14,
++       6,     7,    15,     4,    16,     4,    13,    17,     5,    13,
++      15,    13,     7,     6,    14,    38,    -1,    31,    -1,    -1,
++      31
++};
++
++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
++   symbol of state STATE-NUM.  */
++static const yytype_uint8 yystos[] =
++{
++       0,     3,    11,    25,    27,    28,    29,    43,    13,     0,
++      15,    31,    28,     4,    26,    27,    43,    16,    32,     6,
++       7,    30,    31,    26,     4,    33,    14,    30,    30,    34,
++      41,    42,    43,    30,    13,    17,    34,    41,     5,    13,
++      13,    13,    18,    32,    35,    36,    11,    13,    23,    10,
++      11,    12,    19,    21,    37,    40,     6,     8,    11,    12,
++      20,    38,    39,     9,    11,    22,     7
++};
++
++#define yyerrok		(yyerrstatus = 0)
++#define yyclearin	(yychar = YYEMPTY)
++#define YYEMPTY		(-2)
++#define YYEOF		0
++
++#define YYACCEPT	goto yyacceptlab
++#define YYABORT		goto yyabortlab
++#define YYERROR		goto yyerrorlab
++
++
++/* Like YYERROR except do call yyerror.  This remains here temporarily
++   to ease the transition to the new meaning of YYERROR, for GCC.
++   Once GCC version 2 has supplanted version 1, this can go.  */
++
++#define YYFAIL		goto yyerrlab
++
++#define YYRECOVERING()  (!!yyerrstatus)
++
++#define YYBACKUP(Token, Value)					\
++do								\
++  if (yychar == YYEMPTY && yylen == 1)				\
++    {								\
++      yychar = (Token);						\
++      yylval = (Value);						\
++      yytoken = YYTRANSLATE (yychar);				\
++      YYPOPSTACK (1);						\
++      goto yybackup;						\
++    }								\
++  else								\
++    {								\
++      yyerror (YY_("syntax error: cannot back up")); \
++      YYERROR;							\
++    }								\
++while (YYID (0))
++
++
++#define YYTERROR	1
++#define YYERRCODE	256
++
++
++/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
++   If N is 0, then set CURRENT to the empty location which ends
++   the previous symbol: RHS[0] (always defined).  */
++
++#define YYRHSLOC(Rhs, K) ((Rhs)[K])
++#ifndef YYLLOC_DEFAULT
++# define YYLLOC_DEFAULT(Current, Rhs, N)				\
++    do									\
++      if (YYID (N))                                                    \
++	{								\
++	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
++	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
++	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
++	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
++	}								\
++      else								\
++	{								\
++	  (Current).first_line   = (Current).last_line   =		\
++	    YYRHSLOC (Rhs, 0).last_line;				\
++	  (Current).first_column = (Current).last_column =		\
++	    YYRHSLOC (Rhs, 0).last_column;				\
++	}								\
++    while (YYID (0))
++#endif
++
++
++/* YY_LOCATION_PRINT -- Print the location on the stream.
++   This macro was not mandated originally: define only if we know
++   we won't break user code: when these are the locations we know.  */
++
++#ifndef YY_LOCATION_PRINT
++# if YYLTYPE_IS_TRIVIAL
++#  define YY_LOCATION_PRINT(File, Loc)			\
++     fprintf (File, "%d.%d-%d.%d",			\
++	      (Loc).first_line, (Loc).first_column,	\
++	      (Loc).last_line,  (Loc).last_column)
++# else
++#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
++# endif
++#endif
++
++
++/* YYLEX -- calling `yylex' with the right arguments.  */
++
++#ifdef YYLEX_PARAM
++# define YYLEX yylex (YYLEX_PARAM)
++#else
++# define YYLEX yylex ()
++#endif
++
++/* Enable debugging if requested.  */
++#if YYDEBUG
++
++# ifndef YYFPRINTF
++#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
++#  define YYFPRINTF fprintf
++# endif
++
++# define YYDPRINTF(Args)			\
++do {						\
++  if (yydebug)					\
++    YYFPRINTF Args;				\
++} while (YYID (0))
++
++# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
++do {									  \
++  if (yydebug)								  \
++    {									  \
++      YYFPRINTF (stderr, "%s ", Title);					  \
++      yy_symbol_print (stderr,						  \
++		  Type, Value, Location); \
++      YYFPRINTF (stderr, "\n");						  \
++    }									  \
++} while (YYID (0))
++
++
++/*--------------------------------.
++| Print this symbol on YYOUTPUT.  |
++`--------------------------------*/
++
++/*ARGSUSED*/
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++static void
++yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
++#else
++static void
++yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
++    FILE *yyoutput;
++    int yytype;
++    YYSTYPE const * const yyvaluep;
++    YYLTYPE const * const yylocationp;
++#endif
++{
++  if (!yyvaluep)
++    return;
++  YYUSE (yylocationp);
++# ifdef YYPRINT
++  if (yytype < YYNTOKENS)
++    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
++# else
++  YYUSE (yyoutput);
++# endif
++  switch (yytype)
++    {
++      default:
++	break;
++    }
++}
++
++
++/*--------------------------------.
++| Print this symbol on YYOUTPUT.  |
++`--------------------------------*/
++
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++static void
++yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
++#else
++static void
++yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
++    FILE *yyoutput;
++    int yytype;
++    YYSTYPE const * const yyvaluep;
++    YYLTYPE const * const yylocationp;
++#endif
++{
++  if (yytype < YYNTOKENS)
++    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
++  else
++    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
++
++  YY_LOCATION_PRINT (yyoutput, *yylocationp);
++  YYFPRINTF (yyoutput, ": ");
++  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
++  YYFPRINTF (yyoutput, ")");
++}
++
++/*------------------------------------------------------------------.
++| yy_stack_print -- Print the state stack from its BOTTOM up to its |
++| TOP (included).                                                   |
++`------------------------------------------------------------------*/
++
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++static void
++yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
++#else
++static void
++yy_stack_print (bottom, top)
++    yytype_int16 *bottom;
++    yytype_int16 *top;
++#endif
++{
++  YYFPRINTF (stderr, "Stack now");
++  for (; bottom <= top; ++bottom)
++    YYFPRINTF (stderr, " %d", *bottom);
++  YYFPRINTF (stderr, "\n");
++}
++
++# define YY_STACK_PRINT(Bottom, Top)				\
++do {								\
++  if (yydebug)							\
++    yy_stack_print ((Bottom), (Top));				\
++} while (YYID (0))
++
++
++/*------------------------------------------------.
++| Report that the YYRULE is going to be reduced.  |
++`------------------------------------------------*/
++
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++static void
++yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
++#else
++static void
++yy_reduce_print (yyvsp, yylsp, yyrule)
++    YYSTYPE *yyvsp;
++    YYLTYPE *yylsp;
++    int yyrule;
++#endif
++{
++  int yynrhs = yyr2[yyrule];
++  int yyi;
++  unsigned long int yylno = yyrline[yyrule];
++  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
++	     yyrule - 1, yylno);
++  /* The symbols being reduced.  */
++  for (yyi = 0; yyi < yynrhs; yyi++)
++    {
++      fprintf (stderr, "   $%d = ", yyi + 1);
++      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
++		       &(yyvsp[(yyi + 1) - (yynrhs)])
++		       , &(yylsp[(yyi + 1) - (yynrhs)])		       );
++      fprintf (stderr, "\n");
++    }
++}
++
++# define YY_REDUCE_PRINT(Rule)		\
++do {					\
++  if (yydebug)				\
++    yy_reduce_print (yyvsp, yylsp, Rule); \
++} while (YYID (0))
++
++/* Nonzero means print parse trace.  It is left uninitialized so that
++   multiple parsers can coexist.  */
++int yydebug;
++#else /* !YYDEBUG */
++# define YYDPRINTF(Args)
++# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
++# define YY_STACK_PRINT(Bottom, Top)
++# define YY_REDUCE_PRINT(Rule)
++#endif /* !YYDEBUG */
++
++
++/* YYINITDEPTH -- initial size of the parser's stacks.  */
++#ifndef	YYINITDEPTH
++# define YYINITDEPTH 200
++#endif
++
++/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
++   if the built-in stack extension method is used).
++
++   Do not make this value too large; the results are undefined if
++   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
++   evaluated with infinite-precision integer arithmetic.  */
++
++#ifndef YYMAXDEPTH
++# define YYMAXDEPTH 10000
++#endif
++
++
++
++#if YYERROR_VERBOSE
++
++# ifndef yystrlen
++#  if defined __GLIBC__ && defined _STRING_H
++#   define yystrlen strlen
++#  else
++/* Return the length of YYSTR.  */
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++static YYSIZE_T
++yystrlen (const char *yystr)
++#else
++static YYSIZE_T
++yystrlen (yystr)
++    const char *yystr;
++#endif
++{
++  YYSIZE_T yylen;
++  for (yylen = 0; yystr[yylen]; yylen++)
++    continue;
++  return yylen;
++}
++#  endif
++# endif
++
++# ifndef yystpcpy
++#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
++#   define yystpcpy stpcpy
++#  else
++/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
++   YYDEST.  */
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++static char *
++yystpcpy (char *yydest, const char *yysrc)
++#else
++static char *
++yystpcpy (yydest, yysrc)
++    char *yydest;
++    const char *yysrc;
++#endif
++{
++  char *yyd = yydest;
++  const char *yys = yysrc;
++
++  while ((*yyd++ = *yys++) != '\0')
++    continue;
++
++  return yyd - 1;
++}
++#  endif
++# endif
++
++# ifndef yytnamerr
++/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
++   quotes and backslashes, so that it's suitable for yyerror.  The
++   heuristic is that double-quoting is unnecessary unless the string
++   contains an apostrophe, a comma, or backslash (other than
++   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
++   null, do not copy; instead, return the length of what the result
++   would have been.  */
++static YYSIZE_T
++yytnamerr (char *yyres, const char *yystr)
++{
++  if (*yystr == '"')
++    {
++      YYSIZE_T yyn = 0;
++      char const *yyp = yystr;
++
++      for (;;)
++	switch (*++yyp)
++	  {
++	  case '\'':
++	  case ',':
++	    goto do_not_strip_quotes;
++
++	  case '\\':
++	    if (*++yyp != '\\')
++	      goto do_not_strip_quotes;
++	    /* Fall through.  */
++	  default:
++	    if (yyres)
++	      yyres[yyn] = *yyp;
++	    yyn++;
++	    break;
++
++	  case '"':
++	    if (yyres)
++	      yyres[yyn] = '\0';
++	    return yyn;
++	  }
++    do_not_strip_quotes: ;
++    }
++
++  if (! yyres)
++    return yystrlen (yystr);
++
++  return yystpcpy (yyres, yystr) - yyres;
++}
++# endif
++
++/* Copy into YYRESULT an error message about the unexpected token
++   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
++   including the terminating null byte.  If YYRESULT is null, do not
++   copy anything; just return the number of bytes that would be
++   copied.  As a special case, return 0 if an ordinary "syntax error"
++   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
++   size calculation.  */
++static YYSIZE_T
++yysyntax_error (char *yyresult, int yystate, int yychar)
++{
++  int yyn = yypact[yystate];
++
++  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
++    return 0;
++  else
++    {
++      int yytype = YYTRANSLATE (yychar);
++      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
++      YYSIZE_T yysize = yysize0;
++      YYSIZE_T yysize1;
++      int yysize_overflow = 0;
++      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
++      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
++      int yyx;
++
++# if 0
++      /* This is so xgettext sees the translatable formats that are
++	 constructed on the fly.  */
++      YY_("syntax error, unexpected %s");
++      YY_("syntax error, unexpected %s, expecting %s");
++      YY_("syntax error, unexpected %s, expecting %s or %s");
++      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
++      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
++# endif
++      char *yyfmt;
++      char const *yyf;
++      static char const yyunexpected[] = "syntax error, unexpected %s";
++      static char const yyexpecting[] = ", expecting %s";
++      static char const yyor[] = " or %s";
++      char yyformat[sizeof yyunexpected
++		    + sizeof yyexpecting - 1
++		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
++		       * (sizeof yyor - 1))];
++      char const *yyprefix = yyexpecting;
++
++      /* Start YYX at -YYN if negative to avoid negative indexes in
++	 YYCHECK.  */
++      int yyxbegin = yyn < 0 ? -yyn : 0;
++
++      /* Stay within bounds of both yycheck and yytname.  */
++      int yychecklim = YYLAST - yyn + 1;
++      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
++      int yycount = 1;
++
++      yyarg[0] = yytname[yytype];
++      yyfmt = yystpcpy (yyformat, yyunexpected);
++
++      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
++	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
++	  {
++	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
++	      {
++		yycount = 1;
++		yysize = yysize0;
++		yyformat[sizeof yyunexpected - 1] = '\0';
++		break;
++	      }
++	    yyarg[yycount++] = yytname[yyx];
++	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
++	    yysize_overflow |= (yysize1 < yysize);
++	    yysize = yysize1;
++	    yyfmt = yystpcpy (yyfmt, yyprefix);
++	    yyprefix = yyor;
++	  }
++
++      yyf = YY_(yyformat);
++      yysize1 = yysize + yystrlen (yyf);
++      yysize_overflow |= (yysize1 < yysize);
++      yysize = yysize1;
++
++      if (yysize_overflow)
++	return YYSIZE_MAXIMUM;
++
++      if (yyresult)
++	{
++	  /* Avoid sprintf, as that infringes on the user's name space.
++	     Don't have undefined behavior even if the translation
++	     produced a string with the wrong number of "%s"s.  */
++	  char *yyp = yyresult;
++	  int yyi = 0;
++	  while ((*yyp = *yyf) != '\0')
++	    {
++	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
++		{
++		  yyp += yytnamerr (yyp, yyarg[yyi++]);
++		  yyf += 2;
++		}
++	      else
++		{
++		  yyp++;
++		  yyf++;
++		}
++	    }
++	}
++      return yysize;
++    }
++}
++#endif /* YYERROR_VERBOSE */
++
++
++/*-----------------------------------------------.
++| Release the memory associated to this symbol.  |
++`-----------------------------------------------*/
++
++/*ARGSUSED*/
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++static void
++yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
++#else
++static void
++yydestruct (yymsg, yytype, yyvaluep, yylocationp)
++    const char *yymsg;
++    int yytype;
++    YYSTYPE *yyvaluep;
++    YYLTYPE *yylocationp;
++#endif
++{
++  YYUSE (yyvaluep);
++  YYUSE (yylocationp);
++
++  if (!yymsg)
++    yymsg = "Deleting";
++  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
++
++  switch (yytype)
++    {
++
++      default:
++	break;
++    }
++}
++
++
++/* Prevent warnings from -Wmissing-prototypes.  */
++
++#ifdef YYPARSE_PARAM
++#if defined __STDC__ || defined __cplusplus
++int yyparse (void *YYPARSE_PARAM);
++#else
++int yyparse ();
++#endif
++#else /* ! YYPARSE_PARAM */
++#if defined __STDC__ || defined __cplusplus
++int yyparse (void);
++#else
++int yyparse ();
++#endif
++#endif /* ! YYPARSE_PARAM */
++
++
++
++/* The look-ahead symbol.  */
++int yychar;
++
++/* The semantic value of the look-ahead symbol.  */
++YYSTYPE yylval;
++
++/* Number of syntax errors so far.  */
++int yynerrs;
++/* Location data for the look-ahead symbol.  */
++YYLTYPE yylloc;
++
++
++
++/*----------.
++| yyparse.  |
++`----------*/
++
++#ifdef YYPARSE_PARAM
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++int
++yyparse (void *YYPARSE_PARAM)
++#else
++int
++yyparse (YYPARSE_PARAM)
++    void *YYPARSE_PARAM;
++#endif
++#else /* ! YYPARSE_PARAM */
++#if (defined __STDC__ || defined __C99__FUNC__ \
++     || defined __cplusplus || defined _MSC_VER)
++int
++yyparse (void)
++#else
++int
++yyparse ()
++
++#endif
++#endif
++{
++  
++  int yystate;
++  int yyn;
++  int yyresult;
++  /* Number of tokens to shift before error messages enabled.  */
++  int yyerrstatus;
++  /* Look-ahead token as an internal (translated) token number.  */
++  int yytoken = 0;
++#if YYERROR_VERBOSE
++  /* Buffer for error messages, and its allocated size.  */
++  char yymsgbuf[128];
++  char *yymsg = yymsgbuf;
++  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
++#endif
++
++  /* Three stacks and their tools:
++     `yyss': related to states,
++     `yyvs': related to semantic values,
++     `yyls': related to locations.
++
++     Refer to the stacks thru separate pointers, to allow yyoverflow
++     to reallocate them elsewhere.  */
++
++  /* The state stack.  */
++  yytype_int16 yyssa[YYINITDEPTH];
++  yytype_int16 *yyss = yyssa;
++  yytype_int16 *yyssp;
++
++  /* The semantic value stack.  */
++  YYSTYPE yyvsa[YYINITDEPTH];
++  YYSTYPE *yyvs = yyvsa;
++  YYSTYPE *yyvsp;
++
++  /* The location stack.  */
++  YYLTYPE yylsa[YYINITDEPTH];
++  YYLTYPE *yyls = yylsa;
++  YYLTYPE *yylsp;
++  /* The locations where the error started and ended.  */
++  YYLTYPE yyerror_range[2];
++
++#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
++
++  YYSIZE_T yystacksize = YYINITDEPTH;
++
++  /* The variables used to return semantic value and location from the
++     action routines.  */
++  YYSTYPE yyval;
++  YYLTYPE yyloc;
++
++  /* The number of symbols on the RHS of the reduced rule.
++     Keep to zero when no symbol should be popped.  */
++  int yylen = 0;
++
++  YYDPRINTF ((stderr, "Starting parse\n"));
++
++  yystate = 0;
++  yyerrstatus = 0;
++  yynerrs = 0;
++  yychar = YYEMPTY;		/* Cause a token to be read.  */
++
++  /* Initialize stack pointers.
++     Waste one element of value and location stack
++     so that they stay on the same level as the state stack.
++     The wasted elements are never initialized.  */
++
++  yyssp = yyss;
++  yyvsp = yyvs;
++  yylsp = yyls;
++#if YYLTYPE_IS_TRIVIAL
++  /* Initialize the default location before parsing starts.  */
++  yylloc.first_line   = yylloc.last_line   = 1;
++  yylloc.first_column = yylloc.last_column = 0;
++#endif
++
++  goto yysetstate;
++
++/*------------------------------------------------------------.
++| yynewstate -- Push a new state, which is found in yystate.  |
++`------------------------------------------------------------*/
++ yynewstate:
++  /* In all cases, when you get here, the value and location stacks
++     have just been pushed.  So pushing a state here evens the stacks.  */
++  yyssp++;
++
++ yysetstate:
++  *yyssp = yystate;
++
++  if (yyss + yystacksize - 1 <= yyssp)
++    {
++      /* Get the current used size of the three stacks, in elements.  */
++      YYSIZE_T yysize = yyssp - yyss + 1;
++
++#ifdef yyoverflow
++      {
++	/* Give user a chance to reallocate the stack.  Use copies of
++	   these so that the &'s don't force the real ones into
++	   memory.  */
++	YYSTYPE *yyvs1 = yyvs;
++	yytype_int16 *yyss1 = yyss;
++	YYLTYPE *yyls1 = yyls;
++
++	/* Each stack pointer address is followed by the size of the
++	   data in use in that stack, in bytes.  This used to be a
++	   conditional around just the two extra args, but that might
++	   be undefined if yyoverflow is a macro.  */
++	yyoverflow (YY_("memory exhausted"),
++		    &yyss1, yysize * sizeof (*yyssp),
++		    &yyvs1, yysize * sizeof (*yyvsp),
++		    &yyls1, yysize * sizeof (*yylsp),
++		    &yystacksize);
++	yyls = yyls1;
++	yyss = yyss1;
++	yyvs = yyvs1;
++      }
++#else /* no yyoverflow */
++# ifndef YYSTACK_RELOCATE
++      goto yyexhaustedlab;
++# else
++      /* Extend the stack our own way.  */
++      if (YYMAXDEPTH <= yystacksize)
++	goto yyexhaustedlab;
++      yystacksize *= 2;
++      if (YYMAXDEPTH < yystacksize)
++	yystacksize = YYMAXDEPTH;
++
++      {
++	yytype_int16 *yyss1 = yyss;
++	union yyalloc *yyptr =
++	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
++	if (! yyptr)
++	  goto yyexhaustedlab;
++	YYSTACK_RELOCATE (yyss);
++	YYSTACK_RELOCATE (yyvs);
++	YYSTACK_RELOCATE (yyls);
++#  undef YYSTACK_RELOCATE
++	if (yyss1 != yyssa)
++	  YYSTACK_FREE (yyss1);
++      }
++# endif
++#endif /* no yyoverflow */
++
++      yyssp = yyss + yysize - 1;
++      yyvsp = yyvs + yysize - 1;
++      yylsp = yyls + yysize - 1;
++
++      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
++		  (unsigned long int) yystacksize));
++
++      if (yyss + yystacksize - 1 <= yyssp)
++	YYABORT;
++    }
++
++  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
++
++  goto yybackup;
++
++/*-----------.
++| yybackup.  |
++`-----------*/
++yybackup:
++
++  /* Do appropriate processing given the current state.  Read a
++     look-ahead token if we need one and don't already have one.  */
++
++  /* First try to decide what to do without reference to look-ahead token.  */
++  yyn = yypact[yystate];
++  if (yyn == YYPACT_NINF)
++    goto yydefault;
++
++  /* Not known => get a look-ahead token if don't already have one.  */
++
++  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
++  if (yychar == YYEMPTY)
++    {
++      YYDPRINTF ((stderr, "Reading a token: "));
++      yychar = YYLEX;
++    }
++
++  if (yychar <= YYEOF)
++    {
++      yychar = yytoken = YYEOF;
++      YYDPRINTF ((stderr, "Now at end of input.\n"));
++    }
++  else
++    {
++      yytoken = YYTRANSLATE (yychar);
++      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
++    }
++
++  /* If the proper action on seeing token YYTOKEN is to reduce or to
++     detect an error, take that action.  */
++  yyn += yytoken;
++  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
++    goto yydefault;
++  yyn = yytable[yyn];
++  if (yyn <= 0)
++    {
++      if (yyn == 0 || yyn == YYTABLE_NINF)
++	goto yyerrlab;
++      yyn = -yyn;
++      goto yyreduce;
++    }
++
++  if (yyn == YYFINAL)
++    YYACCEPT;
++
++  /* Count tokens shifted since error; after three, turn off error
++     status.  */
++  if (yyerrstatus)
++    yyerrstatus--;
++
++  /* Shift the look-ahead token.  */
++  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
++
++  /* Discard the shifted token unless it is eof.  */
++  if (yychar != YYEOF)
++    yychar = YYEMPTY;
++
++  yystate = yyn;
++  *++yyvsp = yylval;
++  *++yylsp = yylloc;
++  goto yynewstate;
++
++
++/*-----------------------------------------------------------.
++| yydefault -- do the default action for the current state.  |
++`-----------------------------------------------------------*/
++yydefault:
++  yyn = yydefact[yystate];
++  if (yyn == 0)
++    goto yyerrlab;
++  goto yyreduce;
++
++
++/*-----------------------------.
++| yyreduce -- Do a reduction.  |
++`-----------------------------*/
++yyreduce:
++  /* yyn is the number of a rule to reduce with.  */
++  yylen = yyr2[yyn];
++
++  /* If YYLEN is nonzero, implement the default value of the action:
++     `$$ = $1'.
++
++     Otherwise, the following line sets YYVAL to garbage.
++     This behavior is undocumented and Bison
++     users should not rely upon it.  Assigning to YYVAL
++     unconditionally makes the parser a bit smaller, and it avoids a
++     GCC warning that YYVAL may be used uninitialized.  */
++  yyval = yyvsp[1-yylen];
++
++  /* Default location.  */
++  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
++  YY_REDUCE_PRINT (yyn);
++  switch (yyn)
++    {
++        case 2:
++#line 86 "dtc-parser.y"
++    {
++			the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node));
++		;}
++    break;
++
++  case 3:
++#line 90 "dtc-parser.y"
++    {
++			the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node));
++		;}
++    break;
++
++  case 4:
++#line 97 "dtc-parser.y"
++    {
++			(yyval.re) = NULL;
++		;}
++    break;
++
++  case 5:
++#line 101 "dtc-parser.y"
++    {
++			(yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
++		;}
++    break;
++
++  case 6:
++#line 108 "dtc-parser.y"
++    {
++			(yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref));
++		;}
++    break;
++
++  case 7:
++#line 115 "dtc-parser.y"
++    {
++			(yyval.re) = NULL;
++		;}
++    break;
++
++  case 8:
++#line 119 "dtc-parser.y"
++    {
++			(yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
++		;}
++    break;
++
++  case 9:
++#line 126 "dtc-parser.y"
++    {
++			(yyval.re) = (yyvsp[(1) - (1)].re);
++		;}
++    break;
++
++  case 10:
++#line 130 "dtc-parser.y"
++    {
++			(yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref));
++		;}
++    break;
++
++  case 11:
++#line 137 "dtc-parser.y"
++    {
++			(yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
++		;}
++    break;
++
++  case 12:
++#line 141 "dtc-parser.y"
++    {
++			(yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64);
++		;}
++    break;
++
++  case 13:
++#line 148 "dtc-parser.y"
++    {
++			(yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL);
++		;}
++    break;
++
++  case 14:
++#line 155 "dtc-parser.y"
++    {
++			(yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
++		;}
++    break;
++
++  case 15:
++#line 162 "dtc-parser.y"
++    {
++			(yyval.proplist) = NULL;
++		;}
++    break;
++
++  case 16:
++#line 166 "dtc-parser.y"
++    {
++			(yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
++		;}
++    break;
++
++  case 17:
++#line 173 "dtc-parser.y"
++    {
++			(yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref));
++		;}
++    break;
++
++  case 18:
++#line 177 "dtc-parser.y"
++    {
++			(yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref));
++		;}
++    break;
++
++  case 19:
++#line 184 "dtc-parser.y"
++    {
++			(yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
++		;}
++    break;
++
++  case 20:
++#line 188 "dtc-parser.y"
++    {
++			(yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
++		;}
++    break;
++
++  case 21:
++#line 192 "dtc-parser.y"
++    {
++			(yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
++		;}
++    break;
++
++  case 22:
++#line 196 "dtc-parser.y"
++    {
++			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
++		;}
++    break;
++
++  case 23:
++#line 200 "dtc-parser.y"
++    {
++			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
++		;}
++    break;
++
++  case 24:
++#line 207 "dtc-parser.y"
++    {
++			(yyval.data) = empty_data;
++		;}
++    break;
++
++  case 25:
++#line 211 "dtc-parser.y"
++    {
++			(yyval.data) = (yyvsp[(1) - (2)].data);
++		;}
++    break;
++
++  case 26:
++#line 215 "dtc-parser.y"
++    {
++			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
++		;}
++    break;
++
++  case 27:
++#line 222 "dtc-parser.y"
++    {
++			(yyval.data) = empty_data;
++		;}
++    break;
++
++  case 28:
++#line 226 "dtc-parser.y"
++    {
++			(yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
++		;}
++    break;
++
++  case 29:
++#line 230 "dtc-parser.y"
++    {
++			(yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
++							      (yyvsp[(2) - (2)].labelref)), -1);
++		;}
++    break;
++
++  case 30:
++#line 235 "dtc-parser.y"
++    {
++			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
++		;}
++    break;
++
++  case 31:
++#line 242 "dtc-parser.y"
++    {
++			(yyval.cbase) = 16;
++		;}
++    break;
++
++  case 33:
++#line 250 "dtc-parser.y"
++    {
++			(yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
++		;}
++    break;
++
++  case 34:
++#line 254 "dtc-parser.y"
++    {
++			(yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32);
++		;}
++    break;
++
++  case 35:
++#line 261 "dtc-parser.y"
++    {
++			(yyval.data) = empty_data;
++		;}
++    break;
++
++  case 36:
++#line 265 "dtc-parser.y"
++    {
++			(yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
++		;}
++    break;
++
++  case 37:
++#line 269 "dtc-parser.y"
++    {
++			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
++		;}
++    break;
++
++  case 38:
++#line 276 "dtc-parser.y"
++    {
++			(yyval.nodelist) = NULL;
++		;}
++    break;
++
++  case 39:
++#line 280 "dtc-parser.y"
++    {
++			(yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
++		;}
++    break;
++
++  case 40:
++#line 284 "dtc-parser.y"
++    {
++			yyerror("syntax error: properties must precede subnodes\n");
++			YYERROR;
++		;}
++    break;
++
++  case 41:
++#line 292 "dtc-parser.y"
++    {
++			(yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref));
++		;}
++    break;
++
++  case 42:
++#line 299 "dtc-parser.y"
++    {
++			(yyval.labelref) = NULL;
++		;}
++    break;
++
++  case 43:
++#line 303 "dtc-parser.y"
++    {
++			(yyval.labelref) = (yyvsp[(1) - (1)].labelref);
++		;}
++    break;
++
++
++/* Line 1267 of yacc.c.  */
++#line 1734 "dtc-parser.tab.c"
++      default: break;
++    }
++  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
++
++  YYPOPSTACK (yylen);
++  yylen = 0;
++  YY_STACK_PRINT (yyss, yyssp);
++
++  *++yyvsp = yyval;
++  *++yylsp = yyloc;
++
++  /* Now `shift' the result of the reduction.  Determine what state
++     that goes to, based on the state we popped back to and the rule
++     number reduced by.  */
++
++  yyn = yyr1[yyn];
++
++  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
++  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
++    yystate = yytable[yystate];
++  else
++    yystate = yydefgoto[yyn - YYNTOKENS];
++
++  goto yynewstate;
++
++
++/*------------------------------------.
++| yyerrlab -- here on detecting error |
++`------------------------------------*/
++yyerrlab:
++  /* If not already recovering from an error, report this error.  */
++  if (!yyerrstatus)
++    {
++      ++yynerrs;
++#if ! YYERROR_VERBOSE
++      yyerror (YY_("syntax error"));
++#else
++      {
++	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
++	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
++	  {
++	    YYSIZE_T yyalloc = 2 * yysize;
++	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
++	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
++	    if (yymsg != yymsgbuf)
++	      YYSTACK_FREE (yymsg);
++	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
++	    if (yymsg)
++	      yymsg_alloc = yyalloc;
++	    else
++	      {
++		yymsg = yymsgbuf;
++		yymsg_alloc = sizeof yymsgbuf;
++	      }
++	  }
++
++	if (0 < yysize && yysize <= yymsg_alloc)
++	  {
++	    (void) yysyntax_error (yymsg, yystate, yychar);
++	    yyerror (yymsg);
++	  }
++	else
++	  {
++	    yyerror (YY_("syntax error"));
++	    if (yysize != 0)
++	      goto yyexhaustedlab;
++	  }
++      }
++#endif
++    }
++
++  yyerror_range[0] = yylloc;
++
++  if (yyerrstatus == 3)
++    {
++      /* If just tried and failed to reuse look-ahead token after an
++	 error, discard it.  */
++
++      if (yychar <= YYEOF)
++	{
++	  /* Return failure if at end of input.  */
++	  if (yychar == YYEOF)
++	    YYABORT;
++	}
++      else
++	{
++	  yydestruct ("Error: discarding",
++		      yytoken, &yylval, &yylloc);
++	  yychar = YYEMPTY;
++	}
++    }
++
++  /* Else will try to reuse look-ahead token after shifting the error
++     token.  */
++  goto yyerrlab1;
++
++
++/*---------------------------------------------------.
++| yyerrorlab -- error raised explicitly by YYERROR.  |
++`---------------------------------------------------*/
++yyerrorlab:
++
++  /* Pacify compilers like GCC when the user code never invokes
++     YYERROR and the label yyerrorlab therefore never appears in user
++     code.  */
++  if (/*CONSTCOND*/ 0)
++     goto yyerrorlab;
++
++  yyerror_range[0] = yylsp[1-yylen];
++  /* Do not reclaim the symbols of the rule which action triggered
++     this YYERROR.  */
++  YYPOPSTACK (yylen);
++  yylen = 0;
++  YY_STACK_PRINT (yyss, yyssp);
++  yystate = *yyssp;
++  goto yyerrlab1;
++
++
++/*-------------------------------------------------------------.
++| yyerrlab1 -- common code for both syntax error and YYERROR.  |
++`-------------------------------------------------------------*/
++yyerrlab1:
++  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
++
++  for (;;)
++    {
++      yyn = yypact[yystate];
++      if (yyn != YYPACT_NINF)
++	{
++	  yyn += YYTERROR;
++	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
++	    {
++	      yyn = yytable[yyn];
++	      if (0 < yyn)
++		break;
++	    }
++	}
++
++      /* Pop the current state because it cannot handle the error token.  */
++      if (yyssp == yyss)
++	YYABORT;
++
++      yyerror_range[0] = *yylsp;
++      yydestruct ("Error: popping",
++		  yystos[yystate], yyvsp, yylsp);
++      YYPOPSTACK (1);
++      yystate = *yyssp;
++      YY_STACK_PRINT (yyss, yyssp);
++    }
++
++  if (yyn == YYFINAL)
++    YYACCEPT;
++
++  *++yyvsp = yylval;
++
++  yyerror_range[1] = yylloc;
++  /* Using YYLLOC is tempting, but would change the location of
++     the look-ahead.  YYLOC is available though.  */
++  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
++  *++yylsp = yyloc;
++
++  /* Shift the error token.  */
++  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
++
++  yystate = yyn;
++  goto yynewstate;
++
++
++/*-------------------------------------.
++| yyacceptlab -- YYACCEPT comes here.  |
++`-------------------------------------*/
++yyacceptlab:
++  yyresult = 0;
++  goto yyreturn;
++
++/*-----------------------------------.
++| yyabortlab -- YYABORT comes here.  |
++`-----------------------------------*/
++yyabortlab:
++  yyresult = 1;
++  goto yyreturn;
++
++#ifndef yyoverflow
++/*-------------------------------------------------.
++| yyexhaustedlab -- memory exhaustion comes here.  |
++`-------------------------------------------------*/
++yyexhaustedlab:
++  yyerror (YY_("memory exhausted"));
++  yyresult = 2;
++  /* Fall through.  */
++#endif
++
++yyreturn:
++  if (yychar != YYEOF && yychar != YYEMPTY)
++     yydestruct ("Cleanup: discarding lookahead",
++		 yytoken, &yylval, &yylloc);
++  /* Do not reclaim the symbols of the rule which action triggered
++     this YYABORT or YYACCEPT.  */
++  YYPOPSTACK (yylen);
++  YY_STACK_PRINT (yyss, yyssp);
++  while (yyssp != yyss)
++    {
++      yydestruct ("Cleanup: popping",
++		  yystos[*yyssp], yyvsp, yylsp);
++      YYPOPSTACK (1);
++    }
++#ifndef yyoverflow
++  if (yyss != yyssa)
++    YYSTACK_FREE (yyss);
++#endif
++#if YYERROR_VERBOSE
++  if (yymsg != yymsgbuf)
++    YYSTACK_FREE (yymsg);
++#endif
++  /* Make sure YYID is used.  */
++  return YYID (yyresult);
++}
++
++
++#line 308 "dtc-parser.y"
++
++
++void yyerror (char const *s)
++{
++	const char *fname = srcpos_filename_for_num(yylloc.filenum);
++
++	if (strcmp(fname, "-") == 0)
++		fname = "stdin";
++
++	fprintf(stderr, "%s:%d %s\n",
++		fname, yylloc.first_line, s);
++}
++
++unsigned long long eval_literal(const char *s, int base, int bits)
++{
++	unsigned long long val;
++	char *e;
++
++	errno = 0;
++	val = strtoull(s, &e, base);
++	if (*e)
++		yyerror("bad characters in literal");
++	else if ((errno == ERANGE)
++		 || ((bits < 64) && (val >= (1ULL << bits))))
++		yyerror("literal out of range");
++	else if (errno != 0)
++		yyerror("bad literal");
++	return val;
++}
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped powerpc.git/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,111 @@
++/* A Bison parser, made by GNU Bison 2.3.  */
++
++/* Skeleton interface for Bison's Yacc-like parsers in C
++
++   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
++   Free Software Foundation, 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, or (at your option)
++   any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, USA.  */
++
++/* As a special exception, you may create a larger work that contains
++   part or all of the Bison parser skeleton and distribute that work
++   under terms of your choice, so long as that work isn't itself a
++   parser generator using the skeleton or a modified version thereof
++   as a parser skeleton.  Alternatively, if you modify or redistribute
++   the parser skeleton itself, you may (at your option) remove this
++   special exception, which will cause the skeleton and the resulting
++   Bison output files to be licensed under the GNU General Public
++   License without this special exception.
++
++   This special exception was added by the Free Software Foundation in
++   version 2.2 of Bison.  */
++
++/* Tokens.  */
++#ifndef YYTOKENTYPE
++# define YYTOKENTYPE
++   /* Put the tokens into the symbol table, so that GDB and other debuggers
++      know about them.  */
++   enum yytokentype {
++     DT_V1 = 258,
++     DT_MEMRESERVE = 259,
++     DT_PROPNODENAME = 260,
++     DT_LITERAL = 261,
++     DT_LEGACYLITERAL = 262,
++     DT_BASE = 263,
++     DT_BYTE = 264,
++     DT_STRING = 265,
++     DT_LABEL = 266,
++     DT_REF = 267
++   };
++#endif
++/* Tokens.  */
++#define DT_V1 258
++#define DT_MEMRESERVE 259
++#define DT_PROPNODENAME 260
++#define DT_LITERAL 261
++#define DT_LEGACYLITERAL 262
++#define DT_BASE 263
++#define DT_BYTE 264
++#define DT_STRING 265
++#define DT_LABEL 266
++#define DT_REF 267
++
++
++
++
++#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
++typedef union YYSTYPE
++#line 34 "dtc-parser.y"
++{
++	char *propnodename;
++	char *literal;
++	char *labelref;
++	unsigned int cbase;
++	u8 byte;
++	struct data data;
++
++	u64 addr;
++	cell_t cell;
++	struct property *prop;
++	struct property *proplist;
++	struct node *node;
++	struct node *nodelist;
++	struct reserve_info *re;
++}
++/* Line 1489 of yacc.c.  */
++#line 90 "dtc-parser.tab.h"
++	YYSTYPE;
++# define yystype YYSTYPE /* obsolescent; will be withdrawn */
++# define YYSTYPE_IS_DECLARED 1
++# define YYSTYPE_IS_TRIVIAL 1
++#endif
++
++extern YYSTYPE yylval;
++
++#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
++typedef struct YYLTYPE
++{
++  int first_line;
++  int first_column;
++  int last_line;
++  int last_column;
++} YYLTYPE;
++# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
++# define YYLTYPE_IS_DECLARED 1
++# define YYLTYPE_IS_TRIVIAL 1
++#endif
++
++extern YYLTYPE yylloc;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-parser.y powerpc.git/arch/powerpc/boot/dtc-src/dtc-parser.y
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/dtc-parser.y	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/dtc-parser.y	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,336 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++%locations
++
++%{
++#include "dtc.h"
++#include "srcpos.h"
++
++int yylex(void);
++unsigned long long eval_literal(const char *s, int base, int bits);
++
++extern struct boot_info *the_boot_info;
++
++%}
++
++%union {
++	char *propnodename;
++	char *literal;
++	char *labelref;
++	unsigned int cbase;
++	u8 byte;
++	struct data data;
++
++	u64 addr;
++	cell_t cell;
++	struct property *prop;
++	struct property *proplist;
++	struct node *node;
++	struct node *nodelist;
++	struct reserve_info *re;
++}
++
++%token DT_V1
++%token DT_MEMRESERVE
++%token <propnodename> DT_PROPNODENAME
++%token <literal> DT_LITERAL
++%token <literal> DT_LEGACYLITERAL
++%token <cbase> DT_BASE
++%token <byte> DT_BYTE
++%token <data> DT_STRING
++%token <labelref> DT_LABEL
++%token <labelref> DT_REF
++
++%type <data> propdata
++%type <data> propdataprefix
++%type <re> memreserve
++%type <re> memreserves
++%type <re> v0_memreserve
++%type <re> v0_memreserves
++%type <addr> addr
++%type <data> celllist
++%type <cbase> cellbase
++%type <cell> cellval
++%type <data> bytestring
++%type <prop> propdef
++%type <proplist> proplist
++
++%type <node> devicetree
++%type <node> nodedef
++%type <node> subnode
++%type <nodelist> subnodes
++%type <labelref> label
++
++%%
++
++sourcefile:
++	  DT_V1 ';' memreserves devicetree
++		{
++			the_boot_info = build_boot_info($3, $4);
++		}
++	| v0_memreserves devicetree
++		{
++			the_boot_info = build_boot_info($1, $2);
++		}
++	;
++
++memreserves:
++	  /* empty */
++		{
++			$$ = NULL;
++		}
++	| memreserve memreserves
++		{
++			$$ = chain_reserve_entry($1, $2);
++		}
++	;
++
++memreserve:
++	  label DT_MEMRESERVE addr addr ';'
++		{
++			$$ = build_reserve_entry($3, $4, $1);
++		}
++	;
++
++v0_memreserves:
++	  /* empty */
++		{
++			$$ = NULL;
++		}
++	| v0_memreserve v0_memreserves
++		{
++			$$ = chain_reserve_entry($1, $2);
++		};
++	;
++
++v0_memreserve:
++	  memreserve
++		{
++			$$ = $1;
++		}
++	| label DT_MEMRESERVE addr '-' addr ';'
++		{
++			$$ = build_reserve_entry($3, $5 - $3 + 1, $1);
++		}
++	;
++
++addr:
++	  DT_LITERAL
++		{
++			$$ = eval_literal($1, 0, 64);
++		}
++	| DT_LEGACYLITERAL
++		{
++			$$ = eval_literal($1, 16, 64);
++		}
++	  ;
++
++devicetree:
++	  '/' nodedef
++		{
++			$$ = name_node($2, "", NULL);
++		}
++	;
++
++nodedef:
++	  '{' proplist subnodes '}' ';'
++		{
++			$$ = build_node($2, $3);
++		}
++	;
++
++proplist:
++	  /* empty */
++		{
++			$$ = NULL;
++		}
++	| proplist propdef
++		{
++			$$ = chain_property($2, $1);
++		}
++	;
++
++propdef:
++	  label DT_PROPNODENAME '=' propdata ';'
++		{
++			$$ = build_property($2, $4, $1);
++		}
++	| label DT_PROPNODENAME ';'
++		{
++			$$ = build_property($2, empty_data, $1);
++		}
++	;
++
++propdata:
++	  propdataprefix DT_STRING
++		{
++			$$ = data_merge($1, $2);
++		}
++	| propdataprefix '<' celllist '>'
++		{
++			$$ = data_merge($1, $3);
++		}
++	| propdataprefix '[' bytestring ']'
++		{
++			$$ = data_merge($1, $3);
++		}
++	| propdataprefix DT_REF
++		{
++			$$ = data_add_marker($1, REF_PATH, $2);
++		}
++	| propdata DT_LABEL
++		{
++			$$ = data_add_marker($1, LABEL, $2);
++		}
++	;
++
++propdataprefix:
++	  /* empty */
++		{
++			$$ = empty_data;
++		}
++	| propdata ','
++		{
++			$$ = $1;
++		}
++	| propdataprefix DT_LABEL
++		{
++			$$ = data_add_marker($1, LABEL, $2);
++		}
++	;
++
++celllist:
++	  /* empty */
++		{
++			$$ = empty_data;
++		}
++	| celllist cellval
++		{
++			$$ = data_append_cell($1, $2);
++		}
++	| celllist DT_REF
++		{
++			$$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
++							      $2), -1);
++		}
++	| celllist DT_LABEL
++		{
++			$$ = data_add_marker($1, LABEL, $2);
++		}
++	;
++
++cellbase:
++	  /* empty */
++		{
++			$$ = 16;
++		}
++	| DT_BASE
++	;
++
++cellval:
++	  DT_LITERAL
++		{
++			$$ = eval_literal($1, 0, 32);
++		}
++	| cellbase DT_LEGACYLITERAL
++		{
++			$$ = eval_literal($2, $1, 32);
++		}
++	;
++
++bytestring:
++	  /* empty */
++		{
++			$$ = empty_data;
++		}
++	| bytestring DT_BYTE
++		{
++			$$ = data_append_byte($1, $2);
++		}
++	| bytestring DT_LABEL
++		{
++			$$ = data_add_marker($1, LABEL, $2);
++		}
++	;
++
++subnodes:
++	  /* empty */
++		{
++			$$ = NULL;
++		}
++	|  subnode subnodes
++		{
++			$$ = chain_node($1, $2);
++		}
++	| subnode propdef
++		{
++			yyerror("syntax error: properties must precede subnodes\n");
++			YYERROR;
++		}
++	;
++
++subnode:
++	  label DT_PROPNODENAME nodedef
++		{
++			$$ = name_node($3, $2, $1);
++		}
++	;
++
++label:
++	  /* empty */
++		{
++			$$ = NULL;
++		}
++	| DT_LABEL
++		{
++			$$ = $1;
++		}
++	;
++
++%%
++
++void yyerror (char const *s)
++{
++	const char *fname = srcpos_filename_for_num(yylloc.filenum);
++
++	if (strcmp(fname, "-") == 0)
++		fname = "stdin";
++
++	fprintf(stderr, "%s:%d %s\n",
++		fname, yylloc.first_line, s);
++}
++
++unsigned long long eval_literal(const char *s, int base, int bits)
++{
++	unsigned long long val;
++	char *e;
++
++	errno = 0;
++	val = strtoull(s, &e, base);
++	if (*e)
++		yyerror("bad characters in literal");
++	else if ((errno == ERANGE)
++		 || ((bits < 64) && (val >= (1ULL << bits))))
++		yyerror("literal out of range");
++	else if (errno != 0)
++		yyerror("bad literal");
++	return val;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/dtc.c powerpc.git/arch/powerpc/boot/dtc-src/dtc.c
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/dtc.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/dtc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,231 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include "dtc.h"
++#include "srcpos.h"
++
++#include "version_gen.h"
++
++/*
++ * Command line options
++ */
++int quiet;		/* Level of quietness */
++int reservenum;		/* Number of memory reservation slots */
++int minsize;		/* Minimum blob size */
++int padsize;		/* Additional padding to blob */
++
++char *join_path(const char *path, const char *name)
++{
++	int lenp = strlen(path);
++	int lenn = strlen(name);
++	int len;
++	int needslash = 1;
++	char *str;
++
++	len = lenp + lenn + 2;
++	if ((lenp > 0) && (path[lenp-1] == '/')) {
++		needslash = 0;
++		len--;
++	}
++
++	str = xmalloc(len);
++	memcpy(str, path, lenp);
++	if (needslash) {
++		str[lenp] = '/';
++		lenp++;
++	}
++	memcpy(str+lenp, name, lenn+1);
++	return str;
++}
++
++void fill_fullpaths(struct node *tree, const char *prefix)
++{
++	struct node *child;
++	const char *unit;
++
++	tree->fullpath = join_path(prefix, tree->name);
++
++	unit = strchr(tree->name, '@');
++	if (unit)
++		tree->basenamelen = unit - tree->name;
++	else
++		tree->basenamelen = strlen(tree->name);
++
++	for_each_child(tree, child)
++		fill_fullpaths(child, tree->fullpath);
++}
++
++static void  __attribute__ ((noreturn)) usage(void)
++{
++	fprintf(stderr, "Usage:\n");
++	fprintf(stderr, "\tdtc [options] <input file>\n");
++	fprintf(stderr, "\nOptions:\n");
++	fprintf(stderr, "\t-h\n");
++	fprintf(stderr, "\t\tThis help text\n");
++	fprintf(stderr, "\t-q\n");
++	fprintf(stderr, "\t\tQuiet: -q suppress warnings, -qq errors, -qqq all\n");
++	fprintf(stderr, "\t-I <input format>\n");
++	fprintf(stderr, "\t\tInput formats are:\n");
++	fprintf(stderr, "\t\t\tdts - device tree source text\n");
++	fprintf(stderr, "\t\t\tdtb - device tree blob\n");
++	fprintf(stderr, "\t\t\tfs - /proc/device-tree style directory\n");
++	fprintf(stderr, "\t-o <output file>\n");
++	fprintf(stderr, "\t-O <output format>\n");
++	fprintf(stderr, "\t\tOutput formats are:\n");
++	fprintf(stderr, "\t\t\tdts - device tree source text\n");
++	fprintf(stderr, "\t\t\tdtb - device tree blob\n");
++	fprintf(stderr, "\t\t\tasm - assembler source\n");
++	fprintf(stderr, "\t-V <output version>\n");
++	fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION);
++	fprintf(stderr, "\t-R <number>\n");
++	fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n");
++	fprintf(stderr, "\t-S <bytes>\n");
++	fprintf(stderr, "\t\tMake the blob at least <bytes> long (extra space)\n");
++	fprintf(stderr, "\t-p <bytes>\n");
++	fprintf(stderr, "\t\tAdd padding to the blob of <bytes> long (extra space)\n");
++	fprintf(stderr, "\t-b <number>\n");
++	fprintf(stderr, "\t\tSet the physical boot cpu\n");
++	fprintf(stderr, "\t-f\n");
++	fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
++	fprintf(stderr, "\t-v\n");
++	fprintf(stderr, "\t\tPrint DTC version and exit\n");
++	exit(2);
++}
++
++int main(int argc, char *argv[])
++{
++	struct boot_info *bi;
++	const char *inform = "dts";
++	const char *outform = "dts";
++	const char *outname = "-";
++	int force = 0, check = 0;
++	const char *arg;
++	int opt;
++	FILE *inf = NULL;
++	FILE *outf = NULL;
++	int outversion = DEFAULT_FDT_VERSION;
++	int boot_cpuid_phys = 0xfeedbeef;
++
++	quiet      = 0;
++	reservenum = 0;
++	minsize    = 0;
++	padsize    = 0;
++
++	while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) {
++		switch (opt) {
++		case 'I':
++			inform = optarg;
++			break;
++		case 'O':
++			outform = optarg;
++			break;
++		case 'o':
++			outname = optarg;
++			break;
++		case 'V':
++			outversion = strtol(optarg, NULL, 0);
++			break;
++		case 'R':
++			reservenum = strtol(optarg, NULL, 0);
++			break;
++		case 'S':
++			minsize = strtol(optarg, NULL, 0);
++			break;
++		case 'p':
++			padsize = strtol(optarg, NULL, 0);
++			break;
++		case 'f':
++			force = 1;
++			break;
++		case 'c':
++			check = 1;
++			break;
++		case 'q':
++			quiet++;
++			break;
++		case 'b':
++			boot_cpuid_phys = strtol(optarg, NULL, 0);
++			break;
++		case 'v':
++		    printf("Version: %s\n", DTC_VERSION);
++		    exit(0);
++		case 'h':
++		default:
++			usage();
++		}
++	}
++
++	if (argc > (optind+1))
++		usage();
++	else if (argc < (optind+1))
++		arg = "-";
++	else
++		arg = argv[optind];
++
++	/* minsize and padsize are mutually exclusive */
++	if ((minsize) && (padsize)) {
++		die("Can't set both -p and -S\n");
++	}
++
++	fprintf(stderr, "DTC: %s->%s  on file \"%s\"\n",
++		inform, outform, arg);
++
++	if (streq(inform, "dts")) {
++		bi = dt_from_source(arg);
++	} else if (streq(inform, "fs")) {
++		bi = dt_from_fs(arg);
++	} else if(streq(inform, "dtb")) {
++		inf = dtc_open_file(arg);
++		bi = dt_from_blob(inf);
++	} else {
++		die("Unknown input format \"%s\"\n", inform);
++	}
++
++	if (inf && (inf != stdin))
++		fclose(inf);
++
++	if (! bi || ! bi->dt)
++		die("Couldn't read input tree\n");
++
++	process_checks(force, bi, check, outversion, boot_cpuid_phys);
++
++	if (streq(outname, "-")) {
++		outf = stdout;
++	} else {
++		outf = fopen(outname, "w");
++		if (! outf)
++			die("Couldn't open output file %s: %s\n",
++			    outname, strerror(errno));
++	}
++
++	if (streq(outform, "dts")) {
++		dt_to_source(outf, bi);
++	} else if (streq(outform, "dtb")) {
++		dt_to_blob(outf, bi, outversion, boot_cpuid_phys);
++	} else if (streq(outform, "asm")) {
++		dt_to_asm(outf, bi, outversion, boot_cpuid_phys);
++	} else if (streq(outform, "null")) {
++		/* do nothing */
++	} else {
++		die("Unknown output format \"%s\"\n", outform);
++	}
++
++	exit(0);
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/dtc.h powerpc.git/arch/powerpc/boot/dtc-src/dtc.h
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/dtc.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/dtc.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,269 @@
++#ifndef _DTC_H
++#define _DTC_H
++
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <stdarg.h>
++#include <assert.h>
++#include <ctype.h>
++#include <errno.h>
++#include <unistd.h>
++#include <netinet/in.h>
++#include <endian.h>
++#include <byteswap.h>
++
++#include <fdt.h>
++
++#define DEFAULT_FDT_VERSION	17
++/*
++ * Command line options
++ */
++extern int quiet;		/* Level of quietness */
++extern int reservenum;		/* Number of memory reservation slots */
++extern int minsize;		/* Minimum blob size */
++extern int padsize;		/* Additional padding to blob */
++
++static inline void __attribute__((noreturn)) die(char * str, ...)
++{
++	va_list ap;
++
++	va_start(ap, str);
++	fprintf(stderr, "FATAL ERROR: ");
++	vfprintf(stderr, str, ap);
++	exit(1);
++}
++
++static inline void *xmalloc(size_t len)
++{
++	void *new = malloc(len);
++
++	if (! new)
++		die("malloc() failed\n");
++
++	return new;
++}
++
++static inline void *xrealloc(void *p, size_t len)
++{
++	void *new = realloc(p, len);
++
++	if (! new)
++		die("realloc() failed (len=%d)\n", len);
++
++	return new;
++}
++
++typedef uint8_t u8;
++typedef uint16_t u16;
++typedef uint32_t u32;
++typedef uint64_t u64;
++typedef u32 cell_t;
++
++#define cpu_to_be16(x)	htons(x)
++#define be16_to_cpu(x)	ntohs(x)
++
++#define cpu_to_be32(x)	htonl(x)
++#define be32_to_cpu(x)	ntohl(x)
++
++#if __BYTE_ORDER == __BIG_ENDIAN
++#define cpu_to_be64(x)	(x)
++#define be64_to_cpu(x)	(x)
++#else
++#define cpu_to_be64(x)	bswap_64(x)
++#define be64_to_cpu(x)	bswap_64(x)
++#endif
++
++#define streq(a, b)	(strcmp((a), (b)) == 0)
++#define strneq(a, b, n)	(strncmp((a), (b), (n)) == 0)
++
++#define ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
++
++/* Data blobs */
++enum markertype {
++	REF_PHANDLE,
++	REF_PATH,
++	LABEL,
++};
++
++struct  marker {
++	enum markertype type;
++	int offset;
++	char *ref;
++	struct marker *next;
++};
++
++struct data {
++	int len;
++	char *val;
++	int asize;
++	struct marker *markers;
++};
++
++
++#define empty_data ((struct data){ /* all .members = 0 or NULL */ })
++
++#define for_each_marker(m) \
++	for (; (m); (m) = (m)->next)
++#define for_each_marker_of_type(m, t) \
++	for_each_marker(m) \
++		if ((m)->type == (t))
++
++void data_free(struct data d);
++
++struct data data_grow_for(struct data d, int xlen);
++
++struct data data_copy_mem(const char *mem, int len);
++struct data data_copy_escape_string(const char *s, int len);
++struct data data_copy_file(FILE *f, size_t len);
++
++struct data data_append_data(struct data d, const void *p, int len);
++struct data data_insert_at_marker(struct data d, struct marker *m,
++				  const void *p, int len);
++struct data data_merge(struct data d1, struct data d2);
++struct data data_append_cell(struct data d, cell_t word);
++struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
++struct data data_append_addr(struct data d, u64 addr);
++struct data data_append_byte(struct data d, uint8_t byte);
++struct data data_append_zeroes(struct data d, int len);
++struct data data_append_align(struct data d, int align);
++
++struct data data_add_marker(struct data d, enum markertype type, char *ref);
++
++int data_is_one_string(struct data d);
++
++/* DT constraints */
++
++#define MAX_PROPNAME_LEN	31
++#define MAX_NODENAME_LEN	31
++
++/* Live trees */
++struct property {
++	char *name;
++	struct data val;
++
++	struct property *next;
++
++	char *label;
++};
++
++struct node {
++	char *name;
++	struct property *proplist;
++	struct node *children;
++
++	struct node *parent;
++	struct node *next_sibling;
++
++	char *fullpath;
++	int basenamelen;
++
++	cell_t phandle;
++	int addr_cells, size_cells;
++
++	char *label;
++};
++
++#define for_each_property(n, p) \
++	for ((p) = (n)->proplist; (p); (p) = (p)->next)
++
++#define for_each_child(n, c)	\
++	for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
++
++struct property *build_property(char *name, struct data val, char *label);
++struct property *chain_property(struct property *first, struct property *list);
++struct property *reverse_properties(struct property *first);
++
++struct node *build_node(struct property *proplist, struct node *children);
++struct node *name_node(struct node *node, char *name, char *label);
++struct node *chain_node(struct node *first, struct node *list);
++
++void add_property(struct node *node, struct property *prop);
++void add_child(struct node *parent, struct node *child);
++
++const char *get_unitname(struct node *node);
++struct property *get_property(struct node *node, const char *propname);
++cell_t propval_cell(struct property *prop);
++struct node *get_subnode(struct node *node, const char *nodename);
++struct node *get_node_by_path(struct node *tree, const char *path);
++struct node *get_node_by_label(struct node *tree, const char *label);
++struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
++struct node *get_node_by_ref(struct node *tree, const char *ref);
++cell_t get_node_phandle(struct node *root, struct node *node);
++
++/* Boot info (tree plus memreserve information */
++
++struct reserve_info {
++	struct fdt_reserve_entry re;
++
++	struct reserve_info *next;
++
++	char *label;
++};
++
++struct reserve_info *build_reserve_entry(u64 start, u64 len, char *label);
++struct reserve_info *chain_reserve_entry(struct reserve_info *first,
++					 struct reserve_info *list);
++struct reserve_info *add_reserve_entry(struct reserve_info *list,
++				       struct reserve_info *new);
++
++
++struct boot_info {
++	struct reserve_info *reservelist;
++	struct node *dt;		/* the device tree */
++};
++
++struct boot_info *build_boot_info(struct reserve_info *reservelist,
++				  struct node *tree);
++
++/* Checks */
++
++void process_checks(int force, struct boot_info *bi,
++		    int checkflag, int outversion, int boot_cpuid_phys);
++
++/* Flattened trees */
++
++void dt_to_blob(FILE *f, struct boot_info *bi, int version,
++		int boot_cpuid_phys);
++void dt_to_asm(FILE *f, struct boot_info *bi, int version,
++	       int boot_cpuid_phys);
++
++struct boot_info *dt_from_blob(FILE *f);
++
++/* Tree source */
++
++void dt_to_source(FILE *f, struct boot_info *bi);
++struct boot_info *dt_from_source(const char *f);
++
++/* FS trees */
++
++struct boot_info *dt_from_fs(const char *dirname);
++
++/* misc */
++
++char *join_path(const char *path, const char *name);
++void fill_fullpaths(struct node *tree, const char *prefix);
++
++#endif /* _DTC_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/flattree.c powerpc.git/arch/powerpc/boot/dtc-src/flattree.c
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/flattree.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/flattree.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,968 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include "dtc.h"
++
++#define FTF_FULLPATH	0x1
++#define FTF_VARALIGN	0x2
++#define FTF_NAMEPROPS	0x4
++#define FTF_BOOTCPUID	0x8
++#define FTF_STRTABSIZE	0x10
++#define FTF_STRUCTSIZE	0x20
++#define FTF_NOPS	0x40
++
++static struct version_info {
++	int version;
++	int last_comp_version;
++	int hdr_size;
++	int flags;
++} version_table[] = {
++	{1, 1, FDT_V1_SIZE,
++	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS},
++	{2, 1, FDT_V2_SIZE,
++	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID},
++	{3, 1, FDT_V3_SIZE,
++	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE},
++	{16, 16, FDT_V3_SIZE,
++	 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS},
++	{17, 16, FDT_V17_SIZE,
++	 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS},
++};
++
++struct emitter {
++	void (*cell)(void *, cell_t);
++	void (*string)(void *, char *, int);
++	void (*align)(void *, int);
++	void (*data)(void *, struct data);
++	void (*beginnode)(void *, const char *);
++	void (*endnode)(void *, const char *);
++	void (*property)(void *, const char *);
++};
++
++static void bin_emit_cell(void *e, cell_t val)
++{
++	struct data *dtbuf = e;
++
++	*dtbuf = data_append_cell(*dtbuf, val);
++}
++
++static void bin_emit_string(void *e, char *str, int len)
++{
++	struct data *dtbuf = e;
++
++	if (len == 0)
++		len = strlen(str);
++
++	*dtbuf = data_append_data(*dtbuf, str, len);
++	*dtbuf = data_append_byte(*dtbuf, '\0');
++}
++
++static void bin_emit_align(void *e, int a)
++{
++	struct data *dtbuf = e;
++
++	*dtbuf = data_append_align(*dtbuf, a);
++}
++
++static void bin_emit_data(void *e, struct data d)
++{
++	struct data *dtbuf = e;
++
++	*dtbuf = data_append_data(*dtbuf, d.val, d.len);
++}
++
++static void bin_emit_beginnode(void *e, const char *label)
++{
++	bin_emit_cell(e, FDT_BEGIN_NODE);
++}
++
++static void bin_emit_endnode(void *e, const char *label)
++{
++	bin_emit_cell(e, FDT_END_NODE);
++}
++
++static void bin_emit_property(void *e, const char *label)
++{
++	bin_emit_cell(e, FDT_PROP);
++}
++
++static struct emitter bin_emitter = {
++	.cell = bin_emit_cell,
++	.string = bin_emit_string,
++	.align = bin_emit_align,
++	.data = bin_emit_data,
++	.beginnode = bin_emit_beginnode,
++	.endnode = bin_emit_endnode,
++	.property = bin_emit_property,
++};
++
++static void emit_label(FILE *f, const char *prefix, const char *label)
++{
++	fprintf(f, "\t.globl\t%s_%s\n", prefix, label);
++	fprintf(f, "%s_%s:\n", prefix, label);
++	fprintf(f, "_%s_%s:\n", prefix, label);
++}
++
++static void emit_offset_label(FILE *f, const char *label, int offset)
++{
++	fprintf(f, "\t.globl\t%s\n", label);
++	fprintf(f, "%s\t= . + %d\n", label, offset);
++}
++
++static void asm_emit_cell(void *e, cell_t val)
++{
++	FILE *f = e;
++
++	fprintf(f, "\t.long\t0x%x\n", val);
++}
++
++static void asm_emit_string(void *e, char *str, int len)
++{
++	FILE *f = e;
++	char c = 0;
++
++	if (len != 0) {
++		/* XXX: ewww */
++		c = str[len];
++		str[len] = '\0';
++	}
++
++	fprintf(f, "\t.string\t\"%s\"\n", str);
++
++	if (len != 0) {
++		str[len] = c;
++	}
++}
++
++static void asm_emit_align(void *e, int a)
++{
++	FILE *f = e;
++
++	fprintf(f, "\t.balign\t%d\n", a);
++}
++
++static void asm_emit_data(void *e, struct data d)
++{
++	FILE *f = e;
++	int off = 0;
++	struct marker *m;
++
++	m = d.markers;
++	while (m) {
++		if (m->type == LABEL)
++			emit_offset_label(f, m->ref, m->offset);
++		m = m->next;
++	}
++
++	while ((d.len - off) >= sizeof(u32)) {
++		fprintf(f, "\t.long\t0x%x\n",
++			be32_to_cpu(*((u32 *)(d.val+off))));
++		off += sizeof(u32);
++	}
++
++	if ((d.len - off) >= sizeof(u16)) {
++		fprintf(f, "\t.short\t0x%hx\n",
++			be16_to_cpu(*((u16 *)(d.val+off))));
++		off += sizeof(u16);
++	}
++
++	if ((d.len - off) >= 1) {
++		fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]);
++		off += 1;
++	}
++
++	assert(off == d.len);
++}
++
++static void asm_emit_beginnode(void *e, const char *label)
++{
++	FILE *f = e;
++
++	if (label) {
++		fprintf(f, "\t.globl\t%s\n", label);
++		fprintf(f, "%s:\n", label);
++	}
++	fprintf(f, "\t.long\tFDT_BEGIN_NODE\n");
++}
++
++static void asm_emit_endnode(void *e, const char *label)
++{
++	FILE *f = e;
++
++	fprintf(f, "\t.long\tFDT_END_NODE\n");
++	if (label) {
++		fprintf(f, "\t.globl\t%s_end\n", label);
++		fprintf(f, "%s_end:\n", label);
++	}
++}
++
++static void asm_emit_property(void *e, const char *label)
++{
++	FILE *f = e;
++
++	if (label) {
++		fprintf(f, "\t.globl\t%s\n", label);
++		fprintf(f, "%s:\n", label);
++	}
++	fprintf(f, "\t.long\tFDT_PROP\n");
++}
++
++static struct emitter asm_emitter = {
++	.cell = asm_emit_cell,
++	.string = asm_emit_string,
++	.align = asm_emit_align,
++	.data = asm_emit_data,
++	.beginnode = asm_emit_beginnode,
++	.endnode = asm_emit_endnode,
++	.property = asm_emit_property,
++};
++
++static int stringtable_insert(struct data *d, const char *str)
++{
++	int i;
++
++	/* FIXME: do this more efficiently? */
++
++	for (i = 0; i < d->len; i++) {
++		if (streq(str, d->val + i))
++			return i;
++	}
++
++	*d = data_append_data(*d, str, strlen(str)+1);
++	return i;
++}
++
++static void flatten_tree(struct node *tree, struct emitter *emit,
++			 void *etarget, struct data *strbuf,
++			 struct version_info *vi)
++{
++	struct property *prop;
++	struct node *child;
++	int seen_name_prop = 0;
++
++	emit->beginnode(etarget, tree->label);
++
++	if (vi->flags & FTF_FULLPATH)
++		emit->string(etarget, tree->fullpath, 0);
++	else
++		emit->string(etarget, tree->name, 0);
++
++	emit->align(etarget, sizeof(cell_t));
++
++	for_each_property(tree, prop) {
++		int nameoff;
++
++		if (streq(prop->name, "name"))
++			seen_name_prop = 1;
++
++		nameoff = stringtable_insert(strbuf, prop->name);
++
++		emit->property(etarget, prop->label);
++		emit->cell(etarget, prop->val.len);
++		emit->cell(etarget, nameoff);
++
++		if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8))
++			emit->align(etarget, 8);
++
++		emit->data(etarget, prop->val);
++		emit->align(etarget, sizeof(cell_t));
++	}
++
++	if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) {
++		emit->property(etarget, NULL);
++		emit->cell(etarget, tree->basenamelen+1);
++		emit->cell(etarget, stringtable_insert(strbuf, "name"));
++
++		if ((vi->flags & FTF_VARALIGN) && ((tree->basenamelen+1) >= 8))
++			emit->align(etarget, 8);
++
++		emit->string(etarget, tree->name, tree->basenamelen);
++		emit->align(etarget, sizeof(cell_t));
++	}
++
++	for_each_child(tree, child) {
++		flatten_tree(child, emit, etarget, strbuf, vi);
++	}
++
++	emit->endnode(etarget, tree->label);
++}
++
++static struct data flatten_reserve_list(struct reserve_info *reservelist,
++				 struct version_info *vi)
++{
++	struct reserve_info *re;
++	struct data d = empty_data;
++	static struct fdt_reserve_entry null_re = {0,0};
++	int    j;
++
++	for (re = reservelist; re; re = re->next) {
++		d = data_append_re(d, &re->re);
++	}
++	/*
++	 * Add additional reserved slots if the user asked for them.
++	 */
++	for (j = 0; j < reservenum; j++) {
++		d = data_append_re(d, &null_re);
++	}
++
++	return d;
++}
++
++static void make_fdt_header(struct fdt_header *fdt,
++			    struct version_info *vi,
++			    int reservesize, int dtsize, int strsize,
++			    int boot_cpuid_phys)
++{
++	int reserve_off;
++
++	reservesize += sizeof(struct fdt_reserve_entry);
++
++	memset(fdt, 0xff, sizeof(*fdt));
++
++	fdt->magic = cpu_to_be32(FDT_MAGIC);
++	fdt->version = cpu_to_be32(vi->version);
++	fdt->last_comp_version = cpu_to_be32(vi->last_comp_version);
++
++	/* Reserve map should be doubleword aligned */
++	reserve_off = ALIGN(vi->hdr_size, 8);
++
++	fdt->off_mem_rsvmap = cpu_to_be32(reserve_off);
++	fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize);
++	fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize
++					  + dtsize);
++	fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize);
++
++	if (vi->flags & FTF_BOOTCPUID)
++		fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys);
++	if (vi->flags & FTF_STRTABSIZE)
++		fdt->size_dt_strings = cpu_to_be32(strsize);
++	if (vi->flags & FTF_STRUCTSIZE)
++		fdt->size_dt_struct = cpu_to_be32(dtsize);
++}
++
++void dt_to_blob(FILE *f, struct boot_info *bi, int version,
++		int boot_cpuid_phys)
++{
++	struct version_info *vi = NULL;
++	int i;
++	struct data blob       = empty_data;
++	struct data reservebuf = empty_data;
++	struct data dtbuf      = empty_data;
++	struct data strbuf     = empty_data;
++	struct fdt_header fdt;
++	int padlen = 0;
++
++	for (i = 0; i < ARRAY_SIZE(version_table); i++) {
++		if (version_table[i].version == version)
++			vi = &version_table[i];
++	}
++	if (!vi)
++		die("Unknown device tree blob version %d\n", version);
++
++	flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi);
++	bin_emit_cell(&dtbuf, FDT_END);
++
++	reservebuf = flatten_reserve_list(bi->reservelist, vi);
++
++	/* Make header */
++	make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
++			boot_cpuid_phys);
++
++	/*
++	 * If the user asked for more space than is used, adjust the totalsize.
++	 */
++	if (minsize > 0) {
++		padlen = minsize - be32_to_cpu(fdt.totalsize);
++		if ((padlen < 0) && (quiet < 1))
++			fprintf(stderr,
++				"Warning: blob size %d >= minimum size %d\n",
++				be32_to_cpu(fdt.totalsize), minsize);
++	}
++
++	if (padsize > 0)
++		padlen = padsize;
++
++	if (padlen > 0) {
++		int tsize = be32_to_cpu(fdt.totalsize);
++		tsize += padlen;
++		fdt.totalsize = cpu_to_be32(tsize);
++	}
++
++	/*
++	 * Assemble the blob: start with the header, add with alignment
++	 * the reserve buffer, add the reserve map terminating zeroes,
++	 * the device tree itself, and finally the strings.
++	 */
++	blob = data_append_data(blob, &fdt, sizeof(fdt));
++	blob = data_append_align(blob, 8);
++	blob = data_merge(blob, reservebuf);
++	blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
++	blob = data_merge(blob, dtbuf);
++	blob = data_merge(blob, strbuf);
++
++	/*
++	 * If the user asked for more space than is used, pad out the blob.
++	 */
++	if (padlen > 0)
++		blob = data_append_zeroes(blob, padlen);
++
++	fwrite(blob.val, blob.len, 1, f);
++
++	if (ferror(f))
++		die("Error writing device tree blob: %s\n", strerror(errno));
++
++	/*
++	 * data_merge() frees the right-hand element so only the blob
++	 * remains to be freed.
++	 */
++	data_free(blob);
++}
++
++static void dump_stringtable_asm(FILE *f, struct data strbuf)
++{
++	const char *p;
++	int len;
++
++	p = strbuf.val;
++
++	while (p < (strbuf.val + strbuf.len)) {
++		len = strlen(p);
++		fprintf(f, "\t.string \"%s\"\n", p);
++		p += len+1;
++	}
++}
++
++void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys)
++{
++	struct version_info *vi = NULL;
++	int i;
++	struct data strbuf = empty_data;
++	struct reserve_info *re;
++	const char *symprefix = "dt";
++
++	for (i = 0; i < ARRAY_SIZE(version_table); i++) {
++		if (version_table[i].version == version)
++			vi = &version_table[i];
++	}
++	if (!vi)
++		die("Unknown device tree blob version %d\n", version);
++
++	fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
++	fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
++	fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
++	fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
++	fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
++	fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
++	fprintf(f, "\n");
++
++	emit_label(f, symprefix, "blob_start");
++	emit_label(f, symprefix, "header");
++	fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n");
++	fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n",
++		symprefix, symprefix);
++	fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n",
++		symprefix, symprefix);
++	fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n",
++		symprefix, symprefix);
++	fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n",
++		symprefix, symprefix);
++	fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version);
++	fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n",
++		vi->last_comp_version);
++
++	if (vi->flags & FTF_BOOTCPUID)
++		fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
++			boot_cpuid_phys);
++
++	if (vi->flags & FTF_STRTABSIZE)
++		fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
++			symprefix, symprefix);
++
++	if (vi->flags & FTF_STRUCTSIZE)
++		fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n",
++			symprefix, symprefix);
++
++	/*
++	 * Reserve map entries.
++	 * Align the reserve map to a doubleword boundary.
++	 * Each entry is an (address, size) pair of u64 values.
++	 * Always supply a zero-sized temination entry.
++	 */
++	asm_emit_align(f, 8);
++	emit_label(f, symprefix, "reserve_map");
++
++	fprintf(f, "/* Memory reserve map from source file */\n");
++
++	/*
++	 * Use .long on high and low halfs of u64s to avoid .quad
++	 * as it appears .quad isn't available in some assemblers.
++	 */
++	for (re = bi->reservelist; re; re = re->next) {
++		if (re->label) {
++			fprintf(f, "\t.globl\t%s\n", re->label);
++			fprintf(f, "%s:\n", re->label);
++		}
++		fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
++			(unsigned int)(re->re.address >> 32),
++			(unsigned int)(re->re.address & 0xffffffff));
++		fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
++			(unsigned int)(re->re.size >> 32),
++			(unsigned int)(re->re.size & 0xffffffff));
++	}
++	for (i = 0; i < reservenum; i++) {
++		fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
++	}
++
++	fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
++
++	emit_label(f, symprefix, "struct_start");
++	flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
++	fprintf(f, "\t.long\tFDT_END\n");
++	emit_label(f, symprefix, "struct_end");
++
++	emit_label(f, symprefix, "strings_start");
++	dump_stringtable_asm(f, strbuf);
++	emit_label(f, symprefix, "strings_end");
++
++	emit_label(f, symprefix, "blob_end");
++
++	/*
++	 * If the user asked for more space than is used, pad it out.
++	 */
++	if (minsize > 0) {
++		fprintf(f, "\t.space\t%d - (_%s_blob_end - _%s_blob_start), 0\n",
++			minsize, symprefix, symprefix);
++	}
++	if (padsize > 0) {
++		fprintf(f, "\t.space\t%d, 0\n", padsize);
++	}
++	emit_label(f, symprefix, "blob_abs_end");
++
++	data_free(strbuf);
++}
++
++struct inbuf {
++	char *base, *limit, *ptr;
++};
++
++static void inbuf_init(struct inbuf *inb, void *base, void *limit)
++{
++	inb->base = base;
++	inb->limit = limit;
++	inb->ptr = inb->base;
++}
++
++static void flat_read_chunk(struct inbuf *inb, void *p, int len)
++{
++	if ((inb->ptr + len) > inb->limit)
++		die("Premature end of data parsing flat device tree\n");
++
++	memcpy(p, inb->ptr, len);
++
++	inb->ptr += len;
++}
++
++static u32 flat_read_word(struct inbuf *inb)
++{
++	u32 val;
++
++	assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
++
++	flat_read_chunk(inb, &val, sizeof(val));
++
++	return be32_to_cpu(val);
++}
++
++static void flat_realign(struct inbuf *inb, int align)
++{
++	int off = inb->ptr - inb->base;
++
++	inb->ptr = inb->base + ALIGN(off, align);
++	if (inb->ptr > inb->limit)
++		die("Premature end of data parsing flat device tree\n");
++}
++
++static char *flat_read_string(struct inbuf *inb)
++{
++	int len = 0;
++	const char *p = inb->ptr;
++	char *str;
++
++	do {
++		if (p >= inb->limit)
++			die("Premature end of data parsing flat device tree\n");
++		len++;
++	} while ((*p++) != '\0');
++
++	str = strdup(inb->ptr);
++
++	inb->ptr += len;
++
++	flat_realign(inb, sizeof(u32));
++
++	return str;
++}
++
++static struct data flat_read_data(struct inbuf *inb, int len)
++{
++	struct data d = empty_data;
++
++	if (len == 0)
++		return empty_data;
++
++	d = data_grow_for(d, len);
++	d.len = len;
++
++	flat_read_chunk(inb, d.val, len);
++
++	flat_realign(inb, sizeof(u32));
++
++	return d;
++}
++
++static char *flat_read_stringtable(struct inbuf *inb, int offset)
++{
++	const char *p;
++
++	p = inb->base + offset;
++	while (1) {
++		if (p >= inb->limit || p < inb->base)
++			die("String offset %d overruns string table\n",
++			    offset);
++
++		if (*p == '\0')
++			break;
++
++		p++;
++	}
++
++	return strdup(inb->base + offset);
++}
++
++static struct property *flat_read_property(struct inbuf *dtbuf,
++					   struct inbuf *strbuf, int flags)
++{
++	u32 proplen, stroff;
++	char *name;
++	struct data val;
++
++	proplen = flat_read_word(dtbuf);
++	stroff = flat_read_word(dtbuf);
++
++	name = flat_read_stringtable(strbuf, stroff);
++
++	if ((flags & FTF_VARALIGN) && (proplen >= 8))
++		flat_realign(dtbuf, 8);
++
++	val = flat_read_data(dtbuf, proplen);
++
++	return build_property(name, val, NULL);
++}
++
++
++static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
++{
++	struct reserve_info *reservelist = NULL;
++	struct reserve_info *new;
++	const char *p;
++	struct fdt_reserve_entry re;
++
++	/*
++	 * Each entry is a pair of u64 (addr, size) values for 4 cell_t's.
++	 * List terminates at an entry with size equal to zero.
++	 *
++	 * First pass, count entries.
++	 */
++	p = inb->ptr;
++	while (1) {
++		flat_read_chunk(inb, &re, sizeof(re));
++		re.address  = be64_to_cpu(re.address);
++		re.size = be64_to_cpu(re.size);
++		if (re.size == 0)
++			break;
++
++		new = build_reserve_entry(re.address, re.size, NULL);
++		reservelist = add_reserve_entry(reservelist, new);
++	}
++
++	return reservelist;
++}
++
++
++static char *nodename_from_path(const char *ppath, const char *cpath)
++{
++	const char *lslash;
++	int plen;
++
++	lslash = strrchr(cpath, '/');
++	if (! lslash)
++		return NULL;
++
++	plen = lslash - cpath;
++
++	if (streq(cpath, "/") && streq(ppath, ""))
++		return "";
++
++	if ((plen == 0) && streq(ppath, "/"))
++		return strdup(lslash+1);
++
++	if (! strneq(ppath, cpath, plen))
++		return NULL;
++
++	return strdup(lslash+1);
++}
++
++static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-";
++static const char UNITCHAR[] = "0123456789abcdef,";
++
++static int check_node_name(const char *name)
++{
++	const char *atpos;
++	int basenamelen;
++
++	atpos = strrchr(name, '@');
++
++	if (atpos)
++		basenamelen = atpos - name;
++	else
++		basenamelen = strlen(name);
++
++	if (strspn(name, PROPCHAR) < basenamelen)
++		return -1;
++
++	if (atpos
++	    && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name)))
++		return -1;
++
++	return basenamelen;
++}
++
++static struct node *unflatten_tree(struct inbuf *dtbuf,
++				   struct inbuf *strbuf,
++				   const char *parent_path, int flags)
++{
++	struct node *node;
++	u32 val;
++
++	node = build_node(NULL, NULL);
++
++	if (flags & FTF_FULLPATH) {
++		node->fullpath = flat_read_string(dtbuf);
++		node->name = nodename_from_path(parent_path, node->fullpath);
++
++		if (! node->name)
++			die("Path \"%s\" is not valid as a child of \"%s\"\n",
++			    node->fullpath, parent_path);
++	} else {
++		node->name = flat_read_string(dtbuf);
++		node->fullpath = join_path(parent_path, node->name);
++	}
++
++	node->basenamelen = check_node_name(node->name);
++	if (node->basenamelen < 0) {
++		fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name);
++	}
++
++	do {
++		struct property *prop;
++		struct node *child;
++
++		val = flat_read_word(dtbuf);
++		switch (val) {
++		case FDT_PROP:
++			if (node->children)
++				fprintf(stderr, "Warning: Flat tree input has "
++					"subnodes preceding a property.\n");
++			prop = flat_read_property(dtbuf, strbuf, flags);
++			add_property(node, prop);
++			break;
++
++		case FDT_BEGIN_NODE:
++			child = unflatten_tree(dtbuf,strbuf, node->fullpath,
++					       flags);
++			add_child(node, child);
++			break;
++
++		case FDT_END_NODE:
++			break;
++
++		case FDT_END:
++			die("Premature FDT_END in device tree blob\n");
++			break;
++
++		case FDT_NOP:
++			if (!(flags & FTF_NOPS))
++				fprintf(stderr, "Warning: NOP tag found in flat tree"
++					" version <16\n");
++
++			/* Ignore */
++			break;
++
++		default:
++			die("Invalid opcode word %08x in device tree blob\n",
++			    val);
++		}
++	} while (val != FDT_END_NODE);
++
++	return node;
++}
++
++
++struct boot_info *dt_from_blob(FILE *f)
++{
++	u32 magic, totalsize, version, size_str, size_dt;
++	u32 off_dt, off_str, off_mem_rsvmap;
++	int rc;
++	char *blob;
++	struct fdt_header *fdt;
++	char *p;
++	struct inbuf dtbuf, strbuf;
++	struct inbuf memresvbuf;
++	int sizeleft;
++	struct reserve_info *reservelist;
++	struct node *tree;
++	u32 val;
++	int flags = 0;
++
++	rc = fread(&magic, sizeof(magic), 1, f);
++	if (ferror(f))
++		die("Error reading DT blob magic number: %s\n",
++		    strerror(errno));
++	if (rc < 1) {
++		if (feof(f))
++			die("EOF reading DT blob magic number\n");
++		else
++			die("Mysterious short read reading magic number\n");
++	}
++
++	magic = be32_to_cpu(magic);
++	if (magic != FDT_MAGIC)
++		die("Blob has incorrect magic number\n");
++
++	rc = fread(&totalsize, sizeof(totalsize), 1, f);
++	if (ferror(f))
++		die("Error reading DT blob size: %s\n", strerror(errno));
++	if (rc < 1) {
++		if (feof(f))
++			die("EOF reading DT blob size\n");
++		else
++			die("Mysterious short read reading blob size\n");
++	}
++
++	totalsize = be32_to_cpu(totalsize);
++	if (totalsize < FDT_V1_SIZE)
++		die("DT blob size (%d) is too small\n", totalsize);
++
++	blob = xmalloc(totalsize);
++
++	fdt = (struct fdt_header *)blob;
++	fdt->magic = cpu_to_be32(magic);
++	fdt->totalsize = cpu_to_be32(totalsize);
++
++	sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
++	p = blob + sizeof(magic)  + sizeof(totalsize);
++
++	while (sizeleft) {
++		if (feof(f))
++			die("EOF before reading %d bytes of DT blob\n",
++			    totalsize);
++
++		rc = fread(p, 1, sizeleft, f);
++		if (ferror(f))
++			die("Error reading DT blob: %s\n",
++			    strerror(errno));
++
++		sizeleft -= rc;
++		p += rc;
++	}
++
++	off_dt = be32_to_cpu(fdt->off_dt_struct);
++	off_str = be32_to_cpu(fdt->off_dt_strings);
++	off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap);
++	version = be32_to_cpu(fdt->version);
++
++	fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
++	fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
++	fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt);
++	fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str);
++	fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
++	fprintf(stderr, "\tversion:\t\t0x%x\n", version );
++	fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
++		be32_to_cpu(fdt->last_comp_version));
++
++	if (off_mem_rsvmap >= totalsize)
++		die("Mem Reserve structure offset exceeds total size\n");
++
++	if (off_dt >= totalsize)
++		die("DT structure offset exceeds total size\n");
++
++	if (off_str > totalsize)
++		die("String table offset exceeds total size\n");
++
++	if (version >= 2)
++		fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n",
++			be32_to_cpu(fdt->boot_cpuid_phys));
++
++	size_str = -1;
++	if (version >= 3) {
++		size_str = be32_to_cpu(fdt->size_dt_strings);
++		fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str);
++		if (off_str+size_str > totalsize)
++			die("String table extends past total size\n");
++	}
++
++	if (version >= 17) {
++		size_dt = be32_to_cpu(fdt->size_dt_struct);
++		fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt);
++		if (off_dt+size_dt > totalsize)
++			die("Structure block extends past total size\n");
++	}
++
++	if (version < 16) {
++		flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN;
++	} else {
++		flags |= FTF_NOPS;
++	}
++
++	inbuf_init(&memresvbuf,
++		   blob + off_mem_rsvmap, blob + totalsize);
++	inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
++	if (size_str >= 0)
++		inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
++	else
++		inbuf_init(&strbuf, blob + off_str, blob + totalsize);
++
++	reservelist = flat_read_mem_reserve(&memresvbuf);
++
++	val = flat_read_word(&dtbuf);
++
++	if (val != FDT_BEGIN_NODE)
++		die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val);
++
++	tree = unflatten_tree(&dtbuf, &strbuf, "", flags);
++
++	val = flat_read_word(&dtbuf);
++	if (val != FDT_END)
++		die("Device tree blob doesn't end with FDT_END\n");
++
++	free(blob);
++
++	return build_boot_info(reservelist, tree);
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/fstree.c powerpc.git/arch/powerpc/boot/dtc-src/fstree.c
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/fstree.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/fstree.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,94 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include "dtc.h"
++
++#include <dirent.h>
++#include <sys/stat.h>
++
++static struct node *read_fstree(const char *dirname)
++{
++	DIR *d;
++	struct dirent *de;
++	struct stat st;
++	struct node *tree;
++
++	d = opendir(dirname);
++	if (! d)
++		die("opendir(): %s\n", strerror(errno));
++
++	tree = build_node(NULL, NULL);
++
++	while ((de = readdir(d)) != NULL) {
++		char *tmpnam;
++
++		if (streq(de->d_name, ".")
++		    || streq(de->d_name, ".."))
++			continue;
++
++		tmpnam = join_path(dirname, de->d_name);
++
++		if (lstat(tmpnam, &st) < 0)
++			die("stat(%s): %s\n", tmpnam, strerror(errno));
++
++		if (S_ISREG(st.st_mode)) {
++			struct property *prop;
++			FILE *pfile;
++
++			pfile = fopen(tmpnam, "r");
++			if (! pfile) {
++				fprintf(stderr,
++					"WARNING: Cannot open %s: %s\n",
++					tmpnam, strerror(errno));
++			} else {
++				prop = build_property(strdup(de->d_name),
++						      data_copy_file(pfile,
++								     st.st_size),
++						      NULL);
++				add_property(tree, prop);
++				fclose(pfile);
++			}
++		} else if (S_ISDIR(st.st_mode)) {
++			struct node *newchild;
++
++			newchild = read_fstree(tmpnam);
++			newchild = name_node(newchild, strdup(de->d_name),
++					     NULL);
++			add_child(tree, newchild);
++		}
++
++		free(tmpnam);
++	}
++
++	return tree;
++}
++
++struct boot_info *dt_from_fs(const char *dirname)
++{
++	struct node *tree;
++
++	tree = read_fstree(dirname);
++	tree = name_node(tree, "", NULL);
++
++	fill_fullpaths(tree, "");
++
++	return build_boot_info(NULL, tree);
++}
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/livetree.c powerpc.git/arch/powerpc/boot/dtc-src/livetree.c
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/livetree.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/livetree.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,305 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include "dtc.h"
++
++/*
++ * Tree building functions
++ */
++
++struct property *build_property(char *name, struct data val, char *label)
++{
++	struct property *new = xmalloc(sizeof(*new));
++
++	new->name = name;
++	new->val = val;
++
++	new->next = NULL;
++
++	new->label = label;
++
++	return new;
++}
++
++struct property *chain_property(struct property *first, struct property *list)
++{
++	assert(first->next == NULL);
++
++	first->next = list;
++	return first;
++}
++
++struct property *reverse_properties(struct property *first)
++{
++	struct property *p = first;
++	struct property *head = NULL;
++	struct property *next;
++
++	while (p) {
++		next = p->next;
++		p->next = head;
++		head = p;
++		p = next;
++	}
++	return head;
++}
++
++struct node *build_node(struct property *proplist, struct node *children)
++{
++	struct node *new = xmalloc(sizeof(*new));
++	struct node *child;
++
++	memset(new, 0, sizeof(*new));
++
++	new->proplist = reverse_properties(proplist);
++	new->children = children;
++
++	for_each_child(new, child) {
++		child->parent = new;
++	}
++
++	return new;
++}
++
++struct node *name_node(struct node *node, char *name, char * label)
++{
++	assert(node->name == NULL);
++
++	node->name = name;
++
++	node->label = label;
++
++	return node;
++}
++
++struct node *chain_node(struct node *first, struct node *list)
++{
++	assert(first->next_sibling == NULL);
++
++	first->next_sibling = list;
++	return first;
++}
++
++void add_property(struct node *node, struct property *prop)
++{
++	struct property **p;
++
++	prop->next = NULL;
++
++	p = &node->proplist;
++	while (*p)
++		p = &((*p)->next);
++
++	*p = prop;
++}
++
++void add_child(struct node *parent, struct node *child)
++{
++	struct node **p;
++
++	child->next_sibling = NULL;
++
++	p = &parent->children;
++	while (*p)
++		p = &((*p)->next_sibling);
++
++	*p = child;
++}
++
++struct reserve_info *build_reserve_entry(u64 address, u64 size, char *label)
++{
++	struct reserve_info *new = xmalloc(sizeof(*new));
++
++	new->re.address = address;
++	new->re.size = size;
++
++	new->next = NULL;
++
++	new->label = label;
++
++	return new;
++}
++
++struct reserve_info *chain_reserve_entry(struct reserve_info *first,
++					struct reserve_info *list)
++{
++	assert(first->next == NULL);
++
++	first->next = list;
++	return first;
++}
++
++struct reserve_info *add_reserve_entry(struct reserve_info *list,
++				      struct reserve_info *new)
++{
++	struct reserve_info *last;
++
++	new->next = NULL;
++
++	if (! list)
++		return new;
++
++	for (last = list; last->next; last = last->next)
++		;
++
++	last->next = new;
++
++	return list;
++}
++
++struct boot_info *build_boot_info(struct reserve_info *reservelist,
++				  struct node *tree)
++{
++	struct boot_info *bi;
++
++	bi = xmalloc(sizeof(*bi));
++	bi->reservelist = reservelist;
++	bi->dt = tree;
++
++	return bi;
++}
++
++/*
++ * Tree accessor functions
++ */
++
++const char *get_unitname(struct node *node)
++{
++	if (node->name[node->basenamelen] == '\0')
++		return "";
++	else
++		return node->name + node->basenamelen + 1;
++}
++
++struct property *get_property(struct node *node, const char *propname)
++{
++	struct property *prop;
++
++	for_each_property(node, prop)
++		if (streq(prop->name, propname))
++			return prop;
++
++	return NULL;
++}
++
++cell_t propval_cell(struct property *prop)
++{
++	assert(prop->val.len == sizeof(cell_t));
++	return be32_to_cpu(*((cell_t *)prop->val.val));
++}
++
++struct node *get_subnode(struct node *node, const char *nodename)
++{
++	struct node *child;
++
++	for_each_child(node, child)
++		if (streq(child->name, nodename))
++			return child;
++
++	return NULL;
++}
++
++struct node *get_node_by_path(struct node *tree, const char *path)
++{
++	const char *p;
++	struct node *child;
++
++	if (!path || ! (*path))
++		return tree;
++
++	while (path[0] == '/')
++		path++;
++
++	p = strchr(path, '/');
++
++	for_each_child(tree, child) {
++		if (p && strneq(path, child->name, p-path))
++			return get_node_by_path(child, p+1);
++		else if (!p && streq(path, child->name))
++			return child;
++	}
++
++	return NULL;
++}
++
++struct node *get_node_by_label(struct node *tree, const char *label)
++{
++	struct node *child, *node;
++
++	assert(label && (strlen(label) > 0));
++
++	if (tree->label && streq(tree->label, label))
++		return tree;
++
++	for_each_child(tree, child) {
++		node = get_node_by_label(child, label);
++		if (node)
++			return node;
++	}
++
++	return NULL;
++}
++
++struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
++{
++	struct node *child, *node;
++
++	assert((phandle != 0) && (phandle != -1));
++
++	if (tree->phandle == phandle)
++		return tree;
++
++	for_each_child(tree, child) {
++		node = get_node_by_phandle(child, phandle);
++		if (node)
++			return node;
++	}
++
++	return NULL;
++}
++
++struct node *get_node_by_ref(struct node *tree, const char *ref)
++{
++	if (ref[0] == '/')
++		return get_node_by_path(tree, ref);
++	else
++		return get_node_by_label(tree, ref);
++}
++
++cell_t get_node_phandle(struct node *root, struct node *node)
++{
++	static cell_t phandle = 1; /* FIXME: ick, static local */
++
++	if ((node->phandle != 0) && (node->phandle != -1))
++		return node->phandle;
++
++	assert(! get_property(node, "linux,phandle"));
++
++	while (get_node_by_phandle(root, phandle))
++		phandle++;
++
++	node->phandle = phandle;
++	add_property(node,
++		     build_property("linux,phandle",
++				    data_append_cell(empty_data, phandle),
++				    NULL));
++
++	return node->phandle;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/srcpos.c powerpc.git/arch/powerpc/boot/dtc-src/srcpos.c
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/srcpos.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/srcpos.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,105 @@
++/*
++ * Copyright 2007 Jon Loeliger, 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.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include "dtc.h"
++#include "srcpos.h"
++
++
++/*
++ * Record the complete unique set of opened file names.
++ * Primarily used to cache source position file names.
++ */
++#define MAX_N_FILE_NAMES	(100)
++
++const char *file_names[MAX_N_FILE_NAMES];
++static int n_file_names = 0;
++
++/*
++ * Like yylineno, this is the current open file pos.
++ */
++
++int srcpos_filenum = -1;
++
++
++
++FILE *dtc_open_file(const char *fname)
++{
++	FILE *f;
++
++	if (lookup_file_name(fname, 1) < 0)
++		die("Too many files opened\n");
++
++	if (streq(fname, "-"))
++		f = stdin;
++	else
++		f = fopen(fname, "r");
++
++	if (! f)
++		die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
++
++	return f;
++}
++
++
++
++/*
++ * Locate and optionally add filename fname in the file_names[] array.
++ *
++ * If the filename is currently not in the array and the boolean
++ * add_it is non-zero, an attempt to add the filename will be made.
++ *
++ * Returns;
++ *    Index [0..MAX_N_FILE_NAMES) where the filename is kept
++ *    -1 if the name can not be recorded
++ */
++
++int lookup_file_name(const char *fname, int add_it)
++{
++	int i;
++
++	for (i = 0; i < n_file_names; i++) {
++		if (strcmp(file_names[i], fname) == 0)
++			return i;
++	}
++
++	if (add_it) {
++		if (n_file_names < MAX_N_FILE_NAMES) {
++			file_names[n_file_names] = strdup(fname);
++			return n_file_names++;
++		}
++	}
++
++	return -1;
++}
++
++
++const char *srcpos_filename_for_num(int filenum)
++{
++	if (0 <= filenum && filenum < n_file_names) {
++		return file_names[filenum];
++	}
++
++	return 0;
++}
++
++
++const char *srcpos_get_filename(void)
++{
++	return srcpos_filename_for_num(srcpos_filenum);
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/srcpos.h powerpc.git/arch/powerpc/boot/dtc-src/srcpos.h
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/srcpos.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/srcpos.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,75 @@
++/*
++ * Copyright 2007 Jon Loeliger, 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.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++/*
++ * Augment the standard YYLTYPE with a filenum index into an
++ * array of all opened filenames.
++ */
++
++#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
++typedef struct YYLTYPE {
++    int first_line;
++    int first_column;
++    int last_line;
++    int last_column;
++    int filenum;
++} YYLTYPE;
++
++#define YYLTYPE_IS_DECLARED	1
++#define YYLTYPE_IS_TRIVIAL	1
++#endif
++
++/* Cater to old parser templates. */
++#ifndef YYID
++#define YYID(n)	(n)
++#endif
++
++#define YYLLOC_DEFAULT(Current, Rhs, N)					\
++    do									\
++      if (YYID (N))							\
++	{								\
++	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
++	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
++	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
++	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
++	  (Current).filenum      = YYRHSLOC (Rhs, N).filenum;		\
++	}								\
++      else								\
++	{								\
++	  (Current).first_line   = (Current).last_line   =		\
++	    YYRHSLOC (Rhs, 0).last_line;				\
++	  (Current).first_column = (Current).last_column =		\
++	    YYRHSLOC (Rhs, 0).last_column;				\
++	  (Current).filenum      = YYRHSLOC (Rhs, 0).filenum;		\
++	}								\
++    while (YYID (0))
++
++
++
++extern void yyerror(char const *);
++
++extern int srcpos_filenum;
++
++extern int push_input_file(const char *filename);
++extern int pop_input_file(void);
++
++extern FILE *dtc_open_file(const char *fname);
++extern int lookup_file_name(const char *fname, int add_it);
++extern const char *srcpos_filename_for_num(int filenum);
++const char *srcpos_get_filename(void);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/treesource.c powerpc.git/arch/powerpc/boot/dtc-src/treesource.c
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/treesource.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/treesource.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,275 @@
++/*
++ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
++ *                                                                   USA
++ */
++
++#include "dtc.h"
++#include "srcpos.h"
++
++extern FILE *yyin;
++extern int yyparse(void);
++extern void yyerror(char const *);
++
++struct boot_info *the_boot_info;
++
++struct boot_info *dt_from_source(const char *fname)
++{
++	the_boot_info = NULL;
++
++	push_input_file(fname);
++
++	if (yyparse() != 0)
++		return NULL;
++
++	fill_fullpaths(the_boot_info->dt, "");
++
++	return the_boot_info;
++}
++
++static void write_prefix(FILE *f, int level)
++{
++	int i;
++
++	for (i = 0; i < level; i++)
++		fputc('\t', f);
++}
++
++int isstring(char c)
++{
++	return (isprint(c)
++		|| (c == '\0')
++		|| strchr("\a\b\t\n\v\f\r", c));
++}
++
++static void write_propval_string(FILE *f, struct data val)
++{
++	const char *str = val.val;
++	int i;
++	int newchunk = 1;
++	struct marker *m = val.markers;
++
++	assert(str[val.len-1] == '\0');
++
++	for (i = 0; i < (val.len-1); i++) {
++		char c = str[i];
++
++		if (newchunk) {
++			while (m && (m->offset <= i)) {
++				if (m->type == LABEL) {
++					assert(m->offset == i);
++					fprintf(f, "%s: ", m->ref);
++				}
++				m = m->next;
++			}
++			fprintf(f, "\"");
++			newchunk = 0;
++		}
++
++		switch (c) {
++		case '\a':
++			fprintf(f, "\\a");
++			break;
++		case '\b':
++			fprintf(f, "\\b");
++			break;
++		case '\t':
++			fprintf(f, "\\t");
++			break;
++		case '\n':
++			fprintf(f, "\\n");
++			break;
++		case '\v':
++			fprintf(f, "\\v");
++			break;
++		case '\f':
++			fprintf(f, "\\f");
++			break;
++		case '\r':
++			fprintf(f, "\\r");
++			break;
++		case '\\':
++			fprintf(f, "\\\\");
++			break;
++		case '\"':
++			fprintf(f, "\\\"");
++			break;
++		case '\0':
++			fprintf(f, "\", ");
++			newchunk = 1;
++			break;
++		default:
++			if (isprint(c))
++				fprintf(f, "%c", c);
++			else
++				fprintf(f, "\\x%02hhx", c);
++		}
++	}
++	fprintf(f, "\"");
++
++	/* Wrap up any labels at the end of the value */
++	for_each_marker_of_type(m, LABEL) {
++		assert (m->offset == val.len);
++		fprintf(f, " %s:", m->ref);
++	}
++}
++
++static void write_propval_cells(FILE *f, struct data val)
++{
++	void *propend = val.val + val.len;
++	cell_t *cp = (cell_t *)val.val;
++	struct marker *m = val.markers;
++
++	fprintf(f, "<");
++	for (;;) {
++		while (m && (m->offset <= ((char *)cp - val.val))) {
++			if (m->type == LABEL) {
++				assert(m->offset == ((char *)cp - val.val));
++				fprintf(f, "%s: ", m->ref);
++			}
++			m = m->next;
++		}
++
++		fprintf(f, "0x%x", be32_to_cpu(*cp++));
++		if ((void *)cp >= propend)
++			break;
++		fprintf(f, " ");
++	}
++
++	/* Wrap up any labels at the end of the value */
++	for_each_marker_of_type(m, LABEL) {
++		assert (m->offset == val.len);
++		fprintf(f, " %s:", m->ref);
++	}
++	fprintf(f, ">");
++}
++
++static void write_propval_bytes(FILE *f, struct data val)
++{
++	void *propend = val.val + val.len;
++	const char *bp = val.val;
++	struct marker *m = val.markers;
++
++	fprintf(f, "[");
++	for (;;) {
++		while (m && (m->offset == (bp-val.val))) {
++			if (m->type == LABEL)
++				fprintf(f, "%s: ", m->ref);
++			m = m->next;
++		}
++
++		fprintf(f, "%02hhx", *bp++);
++		if ((void *)bp >= propend)
++			break;
++		fprintf(f, " ");
++	}
++
++	/* Wrap up any labels at the end of the value */
++	for_each_marker_of_type(m, LABEL) {
++		assert (m->offset == val.len);
++		fprintf(f, " %s:", m->ref);
++	}
++	fprintf(f, "]");
++}
++
++static void write_propval(FILE *f, struct property *prop)
++{
++	int len = prop->val.len;
++	const char *p = prop->val.val;
++	struct marker *m = prop->val.markers;
++	int nnotstring = 0, nnul = 0;
++	int nnotstringlbl = 0, nnotcelllbl = 0;
++	int i;
++
++	if (len == 0) {
++		fprintf(f, ";\n");
++		return;
++	}
++
++	for (i = 0; i < len; i++) {
++		if (! isstring(p[i]))
++			nnotstring++;
++		if (p[i] == '\0')
++			nnul++;
++	}
++
++	for_each_marker_of_type(m, LABEL) {
++		if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
++			nnotstringlbl++;
++		if ((m->offset % sizeof(cell_t)) != 0)
++			nnotcelllbl++;
++	}
++
++	fprintf(f, " = ");
++	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
++	    && (nnotstringlbl == 0)) {
++		write_propval_string(f, prop->val);
++	} else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
++		write_propval_cells(f, prop->val);
++	} else {
++		write_propval_bytes(f, prop->val);
++	}
++
++	fprintf(f, ";\n");
++}
++
++static void write_tree_source_node(FILE *f, struct node *tree, int level)
++{
++	struct property *prop;
++	struct node *child;
++
++	write_prefix(f, level);
++	if (tree->label)
++		fprintf(f, "%s: ", tree->label);
++	if (tree->name && (*tree->name))
++		fprintf(f, "%s {\n", tree->name);
++	else
++		fprintf(f, "/ {\n");
++
++	for_each_property(tree, prop) {
++		write_prefix(f, level+1);
++		if (prop->label)
++			fprintf(f, "%s: ", prop->label);
++		fprintf(f, "%s", prop->name);
++		write_propval(f, prop);
++	}
++	for_each_child(tree, child) {
++		fprintf(f, "\n");
++		write_tree_source_node(f, child, level+1);
++	}
++	write_prefix(f, level);
++	fprintf(f, "};\n");
++}
++
++
++void dt_to_source(FILE *f, struct boot_info *bi)
++{
++	struct reserve_info *re;
++
++	fprintf(f, "/dts-v1/;\n\n");
++
++	for (re = bi->reservelist; re; re = re->next) {
++		if (re->label)
++			fprintf(f, "%s: ", re->label);
++		fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
++			(unsigned long long)re->re.address,
++			(unsigned long long)re->re.size);
++	}
++
++	write_tree_source_node(f, bi->dt, 0);
++}
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dtc-src/version_gen.h powerpc.git/arch/powerpc/boot/dtc-src/version_gen.h
+--- linux-2.6.24/arch/powerpc/boot/dtc-src/version_gen.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dtc-src/version_gen.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1 @@
++#define DTC_VERSION "DTC 1.0.0-gd6f9b62f"
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/adder875-redboot.dts powerpc.git/arch/powerpc/boot/dts/adder875-redboot.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/adder875-redboot.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/adder875-redboot.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,184 @@
++/*
++ * Device Tree Source for MPC885 ADS running RedBoot
++ *
++ * Copyright 2006 MontaVista Software, Inc.
++ * Copyright 2007 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.
++ */
++
++/dts-v1/;
++/ {
++	model = "Analogue & Micro Adder MPC875";
++	compatible = "analogue-and-micro,adder875";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	aliases {
++		console = &console;
++		ethernet0 = &eth0;
++		ethernet1 = &eth1;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,875@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <16>;
++			i-cache-line-size = <16>;
++			d-cache-size = <8192>;
++			i-cache-size = <8192>;
++			timebase-frequency = <0>;
++			bus-frequency = <0>;
++			clock-frequency = <0>;
++			interrupts = <15 2>;	// decrementer interrupt
++			interrupt-parent = <&PIC>;
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0x01000000>;
++	};
++
++	localbus@fa200100 {
++		compatible = "fsl,mpc885-localbus", "fsl,pq1-localbus",
++		             "simple-bus";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		reg = <0xfa200100 0x40>;
++
++		ranges = <
++			0 0 0xfe000000 0x00800000
++			2 0 0xfa100000 0x00008000
++		>;
++
++		flash@0,0 {
++			compatible = "cfi-flash";
++			reg = <0 0 0x800000>;
++			bank-width = <2>;
++			device-width = <2>;
++		};
++	};
++
++	soc@fa200000 {
++		compatible = "fsl,mpc875-immr", "fsl,pq1-soc", "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		ranges = <0 0xfa200000 0x00004000>;
++
++		// Temporary until code stops depending on it.
++		device_type = "soc";
++
++		// Temporary until get_immrbase() is fixed.
++		reg = <0xfa200000 0x4000>;
++
++		mdio@e00 {
++			compatible = "fsl,mpc875-fec-mdio", "fsl,pq1-fec-mdio";
++			reg = <0xe00 0x188>;
++			#address-cells = <1>;
++			#size-cells = <0>;
++
++			PHY0: ethernet-phy@0 {
++				reg = <0>;
++				device_type = "ethernet-phy";
++			};
++
++			PHY1: ethernet-phy@1 {
++				reg = <1>;
++				device_type = "ethernet-phy";
++			};
++		};
++
++		eth0: ethernet@e00 {
++			device_type = "network";
++			compatible = "fsl,mpc875-fec-enet",
++			             "fsl,pq1-fec-enet";
++			reg = <0xe00 0x188>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <3 1>;
++			interrupt-parent = <&PIC>;
++			phy-handle = <&PHY0>;
++			linux,network-index = <0>;
++		};
++
++		eth1: ethernet@1e00 {
++			device_type = "network";
++			compatible = "fsl,mpc875-fec-enet",
++			             "fsl,pq1-fec-enet";
++			reg = <0x1e00 0x188>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <7 1>;
++			interrupt-parent = <&PIC>;
++			phy-handle = <&PHY1>;
++			linux,network-index = <1>;
++		};
++
++		PIC: interrupt-controller@0 {
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			reg = <0 0x24>;
++			compatible = "fsl,mpc875-pic", "fsl,pq1-pic";
++		};
++
++		cpm@9c0 {
++			#address-cells = <1>;
++			#size-cells = <1>;
++			compatible = "fsl,mpc875-cpm", "fsl,cpm1", "simple-bus";
++			interrupts = <0>;	// cpm error interrupt
++			interrupt-parent = <&CPM_PIC>;
++			reg = <0x9c0 0x40>;
++			ranges;
++
++			muram {
++				#address-cells = <1>;
++				#size-cells = <1>;
++				ranges = <0 0x2000 0x2000>;
++
++				data@0 {
++					compatible = "fsl,cpm-muram-data";
++					reg = <0 0x1c00>;
++				};
++			};
++
++			brg@9f0 {
++				compatible = "fsl,mpc875-brg",
++				             "fsl,cpm1-brg",
++				             "fsl,cpm-brg";
++				reg = <0x9f0 0x10>;
++			};
++
++			CPM_PIC: interrupt-controller@930 {
++				interrupt-controller;
++				#interrupt-cells = <1>;
++				interrupts = <5 2 0 2>;
++				interrupt-parent = <&PIC>;
++				reg = <0x930 0x20>;
++				compatible = "fsl,mpc875-cpm-pic",
++				             "fsl,cpm1-pic";
++			};
++
++			console: serial@a80 {
++				device_type = "serial";
++				compatible = "fsl,mpc875-smc-uart",
++				             "fsl,cpm1-smc-uart";
++				reg = <0xa80 0x10 0x3e80 0x40>;
++				interrupts = <4>;
++				interrupt-parent = <&CPM_PIC>;
++				fsl,cpm-brg = <1>;
++				fsl,cpm-command = <0x0090>;
++				current-speed = <115200>;
++			};
++		};
++	};
++
++	chosen {
++		linux,stdout-path = &console;
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/adder875-uboot.dts powerpc.git/arch/powerpc/boot/dts/adder875-uboot.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/adder875-uboot.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/adder875-uboot.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,183 @@
++/*
++ * Device Tree Source for MPC885 ADS running U-Boot
++ *
++ * Copyright 2006 MontaVista Software, Inc.
++ * Copyright 2007 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.
++ */
++
++/dts-v1/;
++/ {
++	model = "Analogue & Micro Adder MPC875";
++	compatible = "analogue-and-micro,adder875";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	aliases {
++		console = &console;
++		ethernet0 = &eth0;
++		ethernet1 = &eth1;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,875@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <16>;
++			i-cache-line-size = <16>;
++			d-cache-size = <8192>;
++			i-cache-size = <8192>;
++			timebase-frequency = <0>;
++			bus-frequency = <0>;
++			clock-frequency = <0>;
++			interrupts = <15 2>;	// decrementer interrupt
++			interrupt-parent = <&PIC>;
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0x01000000>;
++	};
++
++	localbus@ff000100 {
++		compatible = "fsl,mpc885-localbus", "fsl,pq1-localbus",
++		             "simple-bus";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		reg = <0xff000100 0x40>;
++
++		ranges = <
++			0 0 0xfe000000 0x01000000
++		>;
++
++		flash@0,0 {
++			compatible = "cfi-flash";
++			reg = <0 0 0x800000>;
++			bank-width = <2>;
++			device-width = <2>;
++		};
++	};
++
++	soc@ff000000 {
++		compatible = "fsl,mpc875-immr", "fsl,pq1-soc", "simple-bus";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		ranges = <0 0xff000000 0x00004000>;
++
++		// Temporary until code stops depending on it.
++		device_type = "soc";
++
++		// Temporary until get_immrbase() is fixed.
++		reg = <0xff000000 0x4000>;
++
++		mdio@e00 {
++			compatible = "fsl,mpc875-fec-mdio", "fsl,pq1-fec-mdio";
++			reg = <0xe00 0x188>;
++			#address-cells = <1>;
++			#size-cells = <0>;
++
++			PHY0: ethernet-phy@0 {
++				reg = <0>;
++				device_type = "ethernet-phy";
++			};
++
++			PHY1: ethernet-phy@1 {
++				reg = <1>;
++				device_type = "ethernet-phy";
++			};
++		};
++
++		eth0: ethernet@e00 {
++			device_type = "network";
++			compatible = "fsl,mpc875-fec-enet",
++			             "fsl,pq1-fec-enet";
++			reg = <0xe00 0x188>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <3 1>;
++			interrupt-parent = <&PIC>;
++			phy-handle = <&PHY0>;
++			linux,network-index = <0>;
++		};
++
++		eth1: ethernet@1e00 {
++			device_type = "network";
++			compatible = "fsl,mpc875-fec-enet",
++			             "fsl,pq1-fec-enet";
++			reg = <0x1e00 0x188>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <7 1>;
++			interrupt-parent = <&PIC>;
++			phy-handle = <&PHY1>;
++			linux,network-index = <1>;
++		};
++
++		PIC: interrupt-controller@0 {
++			interrupt-controller;
++			#interrupt-cells = <2>;
++			reg = <0 0x24>;
++			compatible = "fsl,mpc875-pic", "fsl,pq1-pic";
++		};
++
++		cpm@9c0 {
++			#address-cells = <1>;
++			#size-cells = <1>;
++			compatible = "fsl,mpc875-cpm", "fsl,cpm1", "simple-bus";
++			interrupts = <0>;	// cpm error interrupt
++			interrupt-parent = <&CPM_PIC>;
++			reg = <0x9c0 0x40>;
++			ranges;
++
++			muram {
++				#address-cells = <1>;
++				#size-cells = <1>;
++				ranges = <0 0x2000 0x2000>;
++
++				data@0 {
++					compatible = "fsl,cpm-muram-data";
++					reg = <0 0x1c00>;
++				};
++			};
++
++			brg@9f0 {
++				compatible = "fsl,mpc875-brg",
++				             "fsl,cpm1-brg",
++				             "fsl,cpm-brg";
++				reg = <0x9f0 0x10>;
++			};
++
++			CPM_PIC: interrupt-controller@930 {
++				interrupt-controller;
++				#interrupt-cells = <1>;
++				interrupts = <5 2 0 2>;
++				interrupt-parent = <&PIC>;
++				reg = <0x930 0x20>;
++				compatible = "fsl,mpc875-cpm-pic",
++				             "fsl,cpm1-pic";
++			};
++
++			console: serial@a80 {
++				device_type = "serial";
++				compatible = "fsl,mpc875-smc-uart",
++				             "fsl,cpm1-smc-uart";
++				reg = <0xa80 0x10 0x3e80 0x40>;
++				interrupts = <4>;
++				interrupt-parent = <&CPM_PIC>;
++				fsl,cpm-brg = <1>;
++				fsl,cpm-command = <0x0090>;
++				current-speed = <115200>;
++			};
++		};
++	};
++
++	chosen {
++		linux,stdout-path = &console;
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/bamboo.dts powerpc.git/arch/powerpc/boot/dts/bamboo.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/bamboo.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/bamboo.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -16,14 +16,24 @@
+ 	#size-cells = <1>;
+ 	model = "amcc,bamboo";
+ 	compatible = "amcc,bamboo";
+-	dcr-parent = <&/cpus/PowerPC,440EP@0>;
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		ethernet1 = &EMAC1;
++		serial0 = &UART0;
++		serial1 = &UART1;
++		serial2 = &UART2;
++		serial3 = &UART3;
++	};
+ 
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+ 
+-		PowerPC,440EP@0 {
++		cpu@0 {
+ 			device_type = "cpu";
++			model = "PowerPC,440EP";
+ 			reg = <0>;
+ 			clock-frequency = <0>; /* Filled in by zImage */
+ 			timebase-frequency = <0>; /* Filled in by zImage */
+@@ -126,7 +136,6 @@
+ 				#address-cells = <2>;
+ 				#size-cells = <1>;
+ 				clock-frequency = <0>; /* Filled in by zImage */
+-				ranges;
+ 				interrupts = <5 1>;
+ 				interrupt-parent = <&UIC1>;
+ 			};
+@@ -238,11 +247,56 @@
+ 				zmii-device = <&ZMII0>;
+ 				zmii-channel = <1>;
+ 			};
++
++			usb@ef601000 {
++				compatible = "ohci-be";
++				reg = <ef601000 80>;
++				interrupts = <8 1 9 1>;
++				interrupt-parent = < &UIC1 >;
++			};
++		};
++
++		PCI0: pci@ec000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb440ep-pci", "ibm,plb-pci";
++			primary;
++			reg = <0 eec00000 8	/* Config space access */
++			       0 eed00000 4	/* IACK */
++			       0 eed00000 4	/* Special cycle */
++			       0 ef400000 40>;	/* Internal registers */
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed. Chip supports a second
++			 * IO range but we don't use it for now
++			 */
++			ranges = <02000000 0 a0000000 0 a0000000 0 20000000
++				  01000000 0 00000000 0 e8000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			/* Bamboo has all 4 IRQ pins tied together per slot */
++			interrupt-map-mask = <f800 0 0 0>;
++			interrupt-map = <
++				/* IDSEL 1 */
++				0800 0 0 0 &UIC0 1c 8
++
++				/* IDSEL 2 */
++				1000 0 0 0 &UIC0 1b 8
++
++				/* IDSEL 3 */
++				1800 0 0 0 &UIC0 1a 8
++
++				/* IDSEL 4 */
++				2000 0 0 0 &UIC0 19 8
++			>;
+ 		};
+ 	};
+ 
+ 	chosen {
+ 		linux,stdout-path = "/plb/opb/serial@ef600300";
+-		bootargs = "console=ttyS0,115200";
+ 	};
+ };
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/cm5200.dts powerpc.git/arch/powerpc/boot/dts/cm5200.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/cm5200.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/cm5200.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,236 @@
++/*
++ * CM5200 board Device Tree Source
++ *
++ * Copyright (C) 2007 Semihalf
++ * Marian Balakowicz <m8@semihalf.com>
++ *
++ * 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.
++ */
++
++/*
++ * WARNING: Do not depend on this tree layout remaining static just yet.
++ * The MPC5200 device tree conventions are still in flux
++ * Keep an eye on the linuxppc-dev mailing list for more details
++ */
++
++/ {
++	model = "schindler,cm5200";
++	compatible = "schindler,cm5200";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,5200@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <20>;
++			i-cache-line-size = <20>;
++			d-cache-size = <4000>;		// L1, 16K
++			i-cache-size = <4000>;		// L1, 16K
++			timebase-frequency = <0>;	// from bootloader
++			bus-frequency = <0>;		// from bootloader
++			clock-frequency = <0>;		// from bootloader
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <00000000 04000000>;	// 64MB
++	};
++
++	soc5200@f0000000 {
++		model = "fsl,mpc5200b";
++		compatible = "fsl,mpc5200b";
++		revision = "";			// from bootloader
++		device_type = "soc";
++		ranges = <0 f0000000 0000c000>;
++		reg = <f0000000 00000100>;
++		bus-frequency = <0>;		// from bootloader
++		system-frequency = <0>;		// from bootloader
++
++		cdm@200 {
++			compatible = "mpc5200b-cdm","mpc5200-cdm";
++			reg = <200 38>;
++		};
++
++		mpc5200_pic: pic@500 {
++			// 5200 interrupts are encoded into two levels;
++			interrupt-controller;
++			#interrupt-cells = <3>;
++			compatible = "mpc5200b-pic","mpc5200-pic";
++			reg = <500 80>;
++		};
++
++		gpt@600 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <600 10>;
++			interrupts = <1 9 0>;
++			interrupt-parent = <&mpc5200_pic>;
++			fsl,has-wdt;
++		};
++
++		gpt@610 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <610 10>;
++			interrupts = <1 a 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@620 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <620 10>;
++			interrupts = <1 b 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@630 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <630 10>;
++			interrupts = <1 c 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@640 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <640 10>;
++			interrupts = <1 d 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@650 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <650 10>;
++			interrupts = <1 e 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@660 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <660 10>;
++			interrupts = <1 f 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@670 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <670 10>;
++			interrupts = <1 10 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		rtc@800 {	// Real time clock
++			compatible = "mpc5200b-rtc","mpc5200-rtc";
++			reg = <800 100>;
++			interrupts = <1 5 0 1 6 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpio@b00 {
++			compatible = "mpc5200b-gpio","mpc5200-gpio";
++			reg = <b00 40>;
++			interrupts = <1 7 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpio-wkup@c00 {
++			compatible = "mpc5200b-gpio-wkup","mpc5200-gpio-wkup";
++			reg = <c00 40>;
++			interrupts = <1 8 0 0 3 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		spi@f00 {
++			compatible = "mpc5200b-spi","mpc5200-spi";
++			reg = <f00 20>;
++			interrupts = <2 d 0 2 e 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		usb@1000 {
++			device_type = "usb-ohci-be";
++			compatible = "mpc5200b-ohci","mpc5200-ohci","ohci-be";
++			reg = <1000 ff>;
++			interrupts = <2 6 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		dma-controller@1200 {
++			compatible = "mpc5200b-bestcomm","mpc5200-bestcomm";
++			reg = <1200 80>;
++			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
++			              3 4 0  3 5 0  3 6 0  3 7 0
++			              3 8 0  3 9 0  3 a 0  3 b 0
++			              3 c 0  3 d 0  3 e 0  3 f 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		xlb@1f00 {
++			compatible = "mpc5200b-xlb","mpc5200-xlb";
++			reg = <1f00 100>;
++		};
++
++		serial@2000 {		// PSC1
++			device_type = "serial";
++			compatible = "mpc5200b-psc-uart","mpc5200-psc-uart";
++			port-number = <0>;  // Logical port assignment
++			reg = <2000 100>;
++			interrupts = <2 1 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		serial@2200 {		// PSC2
++			device_type = "serial";
++			compatible = "mpc5200-psc-uart";
++			port-number = <1>;  // Logical port assignment
++			reg = <2200 100>;
++			interrupts = <2 2 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		serial@2400 {		// PSC3
++			device_type = "serial";
++			compatible = "mpc5200-psc-uart";
++			port-number = <2>;  // Logical port assignment
++			reg = <2400 100>;
++			interrupts = <2 3 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		serial@2c00 {		// PSC6
++			device_type = "serial";
++			compatible = "mpc5200b-psc-uart","mpc5200-psc-uart";
++			port-number = <5>;  // Logical port assignment
++			reg = <2c00 100>;
++			interrupts = <2 4 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		ethernet@3000 {
++			device_type = "network";
++			compatible = "mpc5200b-fec","mpc5200-fec";
++			reg = <3000 800>;
++			local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by U-Boot */
++			interrupts = <2 5 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		i2c@3d40 {
++			compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c";
++			reg = <3d40 40>;
++			interrupts = <2 10 0>;
++			interrupt-parent = <&mpc5200_pic>;
++			fsl5200-clocking;
++		};
++
++		sram@8000 {
++			compatible = "mpc5200b-sram","mpc5200-sram";
++			reg = <8000 4000>;
++		};
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/ebony.dts powerpc.git/arch/powerpc/boot/dts/ebony.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/ebony.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/ebony.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -16,14 +16,22 @@
+ 	#size-cells = <1>;
+ 	model = "ibm,ebony";
+ 	compatible = "ibm,ebony";
+-	dcr-parent = <&/cpus/PowerPC,440GP@0>;
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		ethernet1 = &EMAC1;
++		serial0 = &UART0;
++		serial1 = &UART1;
++	};
+ 
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+ 
+-		PowerPC,440GP@0 {
++		cpu@0 {
+ 			device_type = "cpu";
++			model = "PowerPC,440GP";
+ 			reg = <0>;
+ 			clock-frequency = <0>; // Filled in by zImage
+ 			timebase-frequency = <0>; // Filled in by zImage
+@@ -150,9 +158,10 @@
+ 					};
+ 				};
+ 
+-				ds1743@1,0 {
++				nvram@1,0 {
+ 					/* NVRAM & RTC */
+-					compatible = "ds1743";
++					compatible = "ds1743-nvram";
++					#bytes = <2000>;
+ 					reg = <1 0 2000>;
+ 				};
+ 
+@@ -284,12 +293,43 @@
+ 
+ 		};
+ 
+-		PCIX0: pci@1234 {
++		PCIX0: pci@20ec00000 {
+ 			device_type = "pci";
+-			/* FIXME */
+-			reg = <2 0ec00000 8
+-			       2 0ec80000 f0
+-			       2 0ec80100 fc>;
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix";
++			primary;
++			reg = <2 0ec00000 8	/* Config space access */
++			       0 0 0		/* no IACK cycles */
++			       2 0ed00000 4     /* Special cycles */
++			       2 0ec80000 f0	/* Internal registers */
++			       2 0ec80100 fc>;	/* Internal messaging registers */
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 00000003 80000000 0 80000000
++				  01000000 0 00000000 00000002 08000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			/* Ebony has all 4 IRQ pins tied together per slot */
++			interrupt-map-mask = <f800 0 0 0>;
++			interrupt-map = <
++				/* IDSEL 1 */
++				0800 0 0 0 &UIC0 17 8
++
++				/* IDSEL 2 */
++				1000 0 0 0 &UIC0 18 8
++
++				/* IDSEL 3 */
++				1800 0 0 0 &UIC0 19 8
++
++				/* IDSEL 4 */
++				2000 0 0 0 &UIC0 1a 8
++			>;
+ 		};
+ 	};
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/ep405.dts powerpc.git/arch/powerpc/boot/dts/ep405.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/ep405.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/ep405.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,228 @@
++/*
++ * Device Tree Source for EP405
++ *
++ * Copyright 2007 IBM Corp.
++ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2.  This program is licensed "as is" without
++ * any warranty of any kind, whether express or implied.
++ */
++
++/ {
++	#address-cells = <1>;
++	#size-cells = <1>;
++	model = "ep405";
++	compatible = "ep405";
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC;
++		serial0 = &UART0;
++		serial1 = &UART1;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		cpu@0 {
++			device_type = "cpu";
++			model = "PowerPC,405GP";
++			reg = <0>;
++			clock-frequency = <bebc200>; /* Filled in by zImage */
++			timebase-frequency = <0>; /* Filled in by zImage */
++			i-cache-line-size = <20>;
++			d-cache-line-size = <20>;
++			i-cache-size = <4000>;
++			d-cache-size = <4000>;
++			dcr-controller;
++			dcr-access-method = "native";
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0>; /* Filled in by zImage */
++	};
++
++	UIC0: interrupt-controller {
++		compatible = "ibm,uic";
++		interrupt-controller;
++		cell-index = <0>;
++		dcr-reg = <0c0 9>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++	};
++
++	plb {
++		compatible = "ibm,plb3";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		ranges;
++		clock-frequency = <0>; /* Filled in by zImage */
++
++		SDRAM0: memory-controller {
++			compatible = "ibm,sdram-405gp";
++			dcr-reg = <010 2>;
++		};
++
++		MAL: mcmal {
++			compatible = "ibm,mcmal-405gp", "ibm,mcmal";
++			dcr-reg = <180 62>;
++			num-tx-chans = <1>;
++			num-rx-chans = <1>;
++			interrupt-parent = <&UIC0>;
++			interrupts = <
++				b 4 /* TXEOB */
++				c 4 /* RXEOB */
++				a 4 /* SERR */
++				d 4 /* TXDE */
++				e 4 /* RXDE */>;
++		};
++
++		POB0: opb {
++			compatible = "ibm,opb-405gp", "ibm,opb";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			ranges = <ef600000 ef600000 a00000>;
++			dcr-reg = <0a0 5>;
++			clock-frequency = <0>; /* Filled in by zImage */
++
++			UART0: serial@ef600300 {
++				device_type = "serial";
++				compatible = "ns16550";
++				reg = <ef600300 8>;
++				virtual-reg = <ef600300>;
++				clock-frequency = <0>; /* Filled in by zImage */
++				current-speed = <2580>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <0 4>;
++			};
++
++			UART1: serial@ef600400 {
++				device_type = "serial";
++				compatible = "ns16550";
++				reg = <ef600400 8>;
++				virtual-reg = <ef600400>;
++				clock-frequency = <0>; /* Filled in by zImage */
++				current-speed = <2580>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <1 4>;
++			};
++
++			IIC: i2c@ef600500 {
++				compatible = "ibm,iic-405gp", "ibm,iic";
++				reg = <ef600500 11>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <2 4>;
++			};
++
++			GPIO: gpio@ef600700 {
++				compatible = "ibm,gpio-405gp";
++				reg = <ef600700 20>;
++			};
++
++			EMAC: ethernet@ef600800 {
++				linux,network-index = <0>;
++				device_type = "network";
++				compatible = "ibm,emac-405gp", "ibm,emac";
++				interrupt-parent = <&UIC0>;
++				interrupts = <
++					f 4 /* Ethernet */
++					9 4 /* Ethernet Wake Up */>;
++				local-mac-address = [000000000000]; /* Filled in by zImage */
++				reg = <ef600800 70>;
++				mal-device = <&MAL>;
++				mal-tx-channel = <0>;
++				mal-rx-channel = <0>;
++				cell-index = <0>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rmii";
++				phy-map = <00000000>;
++			};
++
++		};
++
++		EBC0: ebc {
++			compatible = "ibm,ebc-405gp", "ibm,ebc";
++			dcr-reg = <012 2>;
++			#address-cells = <2>;
++			#size-cells = <1>;
++
++
++			/* The ranges property is supplied by the bootwrapper
++			 * and is based on the firmware's configuration of the
++			 * EBC bridge
++			 */
++			clock-frequency = <0>; /* Filled in by zImage */
++
++			/* NVRAM and RTC */
++			nvrtc@4,200000 {
++				compatible = "ds1742";
++				reg = <4 200000 0>; /* size fixed up by zImage */
++			};
++
++			/* "BCSR" CPLD contains a PCI irq controller */
++			bcsr@4,0 {
++				compatible = "ep405-bcsr";
++				reg = <4 0 10>;
++				interrupt-controller;
++				/* Routing table */
++				irq-routing = [	00	/* SYSERR */
++						01	/* STTM */
++						01	/* RTC */
++						01	/* FENET */
++						02	/* NB PCIIRQ mux ? */
++						03	/* SB Winbond 8259 ? */
++						04	/* Serial Ring */
++						05	/* USB (ep405pc) */
++						06	/* XIRQ 0 */
++						06	/* XIRQ 1 */
++						06	/* XIRQ 2 */
++						06	/* XIRQ 3 */
++						06	/* XIRQ 4 */
++						06	/* XIRQ 5 */
++						06	/* XIRQ 6 */
++						07];	/* Reserved */
++			};
++		};
++
++		PCI0: pci@ec000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb405gp-pci", "ibm,plb-pci";
++			primary;
++			reg = <eec00000 8	/* Config space access */
++			       eed80000 4	/* IACK */
++			       eed80000 4	/* Special cycle */
++			       ef480000 40>;	/* Internal registers */
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed. Chip supports a second
++			 * IO range but we don't use it for now
++			 */
++			ranges = <02000000 0 80000000 80000000 0 20000000
++				  01000000 0 00000000 e8000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 80000000>;
++
++			/* That's all I know about IRQs on that thing ... */
++			interrupt-map-mask = <f800 0 0 0>;
++			interrupt-map = <
++				/* USB */
++				7000 0 0 0 &UIC0 1e 8 /* IRQ5 */
++			>;
++		};
++	};
++
++	chosen {
++		linux,stdout-path = "/plb/opb/serial@ef600300";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/ep8248e.dts powerpc.git/arch/powerpc/boot/dts/ep8248e.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/ep8248e.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/ep8248e.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,207 @@
++/*
++ * Device Tree for the Embedded Planet EP8248E board running PlanetCore.
++ *
++ * Copyright 2007 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.
++ */
++
++/dts-v1/;
++/ {
++	model = "EP8248E";
++	compatible = "fsl,ep8248e";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	aliases {
++		planetcore-SMC1 = &smc1;
++		planetcore-SCC1 = &scc1;
++		ethernet0 = &eth0;
++		ethernet1 = &eth1;
++		serial0 = &smc1;
++		serial1 = &scc1;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,8248@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <32>;
++			i-cache-line-size = <32>;
++			d-cache-size = <16384>;
++			i-cache-size = <16384>;
++			timebase-frequency = <0>;
++			clock-frequency = <0>;
++		};
++	};
++
++	localbus@f0010100 {
++		compatible = "fsl,mpc8248-localbus",
++		             "fsl,pq2-localbus",
++		             "simple-bus";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		reg = <0xf0010100 0x40>;
++
++		ranges = <0 0 0xfc000000 0x04000000
++		          1 0 0xfa000000 0x00008000>;
++
++		flash@0,3800000 {
++			compatible = "cfi-flash";
++			reg = <0 0x3800000 0x800000>;
++			bank-width = <4>;
++			device-width = <2>;
++		};
++
++		bcsr@1,0 {
++			#address-cells = <2>;
++			#size-cells = <1>;
++			reg = <1 0 0x10>;
++			compatible = "fsl,ep8248e-bcsr";
++			ranges;
++
++			mdio {
++				device_type = "mdio";
++				compatible = "fsl,ep8248e-mdio-bitbang";
++				#address-cells = <1>;
++				#size-cells = <0>;
++				reg = <1 8 1>;
++
++				PHY0: ethernet-phy@0 {
++					interrupt-parent = <&PIC>;
++					reg = <0>;
++					device_type = "ethernet-phy";
++				};
++
++				PHY1: ethernet-phy@1 {
++					interrupt-parent = <&PIC>;
++					reg = <1>;
++					device_type = "ethernet-phy";
++				};
++			};
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0>;
++	};
++
++	soc@f0000000 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		compatible = "fsl,mpc8248-immr", "fsl,pq2-soc", "simple-bus";
++		ranges = <0x00000000 0xf0000000 0x00053000>;
++
++		// Temporary until code stops depending on it.
++		device_type = "soc";
++
++		// Temporary -- will go away once kernel uses ranges for get_immrbase().
++		reg = <0xf0000000 0x00053000>;
++
++		cpm@119c0 {
++			#address-cells = <1>;
++			#size-cells = <1>;
++			#interrupt-cells = <2>;
++			compatible = "fsl,mpc8248-cpm", "fsl,cpm2",
++			             "simple-bus";
++			reg = <0x119c0 0x30>;
++			ranges;
++
++			muram {
++				#address-cells = <1>;
++				#size-cells = <1>;
++				ranges = <0 0 0x10000>;
++
++				data@0 {
++					compatible = "fsl,cpm-muram-data";
++					reg = <0 0x1100 0x1140
++					       0xec0 0x9800 0x800>;
++				};
++			};
++
++			brg@119f0 {
++				compatible = "fsl,mpc8248-brg",
++				             "fsl,cpm2-brg",
++				             "fsl,cpm-brg";
++				reg = <0x119f0 0x10 0x115f0 0x10>;
++			};
++
++			/* Monitor port/SMC1 */
++			smc1: serial@11a80 {
++				device_type = "serial";
++				compatible = "fsl,mpc8248-smc-uart",
++				             "fsl,cpm2-smc-uart";
++				reg = <0x11a80 0x20 0x1100 0x40>;
++				interrupts = <4 8>;
++				interrupt-parent = <&PIC>;
++				fsl,cpm-brg = <7>;
++				fsl,cpm-command = <0x1d000000>;
++				linux,planetcore-label = "SMC1";
++			};
++
++			/* "Serial" port/SCC1 */
++			scc1: serial@11a00 {
++				device_type = "serial";
++				compatible = "fsl,mpc8248-scc-uart",
++				             "fsl,cpm2-scc-uart";
++				reg = <0x11a00 0x20 0x8000 0x100>;
++				interrupts = <40 8>;
++				interrupt-parent = <&PIC>;
++				fsl,cpm-brg = <1>;
++				fsl,cpm-command = <0x00800000>;
++				linux,planetcore-label = "SCC1";
++			};
++
++			eth0: ethernet@11300 {
++				device_type = "network";
++				compatible = "fsl,mpc8248-fcc-enet",
++				             "fsl,cpm2-fcc-enet";
++				reg = <0x11300 0x20 0x8400 0x100 0x11390 1>;
++				local-mac-address = [ 00 00 00 00 00 00 ];
++				interrupts = <32 8>;
++				interrupt-parent = <&PIC>;
++				phy-handle = <&PHY0>;
++				linux,network-index = <0>;
++				fsl,cpm-command = <0x12000300>;
++			};
++
++			eth1: ethernet@11320 {
++				device_type = "network";
++				compatible = "fsl,mpc8248-fcc-enet",
++				             "fsl,cpm2-fcc-enet";
++				reg = <0x11320 0x20 0x8500 0x100 0x113b0 1>;
++				local-mac-address = [ 00 00 00 00 00 00 ];
++				interrupts = <33 8>;
++				interrupt-parent = <&PIC>;
++				phy-handle = <&PHY1>;
++				linux,network-index = <1>;
++				fsl,cpm-command = <0x16200300>;
++			};
++
++			usb@11b60 {
++				#address-cells = <1>;
++				#size-cells = <0>;
++				compatible = "fsl,mpc8248-usb",
++				             "fsl,cpm2-usb";
++				reg = <0x11b60 0x18 0x8b00 0x100>;
++				interrupt-parent = <&PIC>;
++				interrupts = <11 8>;
++				fsl,cpm-command = <0x2e600000>;
++			};
++		};
++
++		PIC: interrupt-controller@10c00 {
++			#interrupt-cells = <2>;
++			interrupt-controller;
++			reg = <0x10c00 0x80>;
++			compatible = "fsl,mpc8248-pic", "fsl,pq2-pic";
++		};
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/haleakala.dts powerpc.git/arch/powerpc/boot/dts/haleakala.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/haleakala.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/haleakala.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,274 @@
++/*
++ * Device Tree Source for AMCC Haleakala (405EXr)
++ *
++ * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2.  This program is licensed "as is" without
++ * any warranty of any kind, whether express or implied.
++ */
++
++/ {
++	#address-cells = <1>;
++	#size-cells = <1>;
++	model = "amcc,haleakala";
++	compatible = "amcc,kilauea";
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		serial0 = &UART0;
++		serial1 = &UART1;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		cpu@0 {
++			device_type = "cpu";
++			model = "PowerPC,405EXr";
++			reg = <0>;
++			clock-frequency = <0>; /* Filled in by U-Boot */
++			timebase-frequency = <0>; /* Filled in by U-Boot */
++			i-cache-line-size = <20>;
++			d-cache-line-size = <20>;
++			i-cache-size = <4000>; /* 16 kB */
++			d-cache-size = <4000>; /* 16 kB */
++			dcr-controller;
++			dcr-access-method = "native";
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0>; /* Filled in by U-Boot */
++	};
++
++	UIC0: interrupt-controller {
++		compatible = "ibm,uic-405exr", "ibm,uic";
++		interrupt-controller;
++		cell-index = <0>;
++		dcr-reg = <0c0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++	};
++
++	UIC1: interrupt-controller1 {
++		compatible = "ibm,uic-405exr","ibm,uic";
++		interrupt-controller;
++		cell-index = <1>;
++		dcr-reg = <0d0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <1e 4 1f 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	UIC2: interrupt-controller2 {
++		compatible = "ibm,uic-405exr","ibm,uic";
++		interrupt-controller;
++		cell-index = <2>;
++		dcr-reg = <0e0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <1c 4 1d 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	plb {
++		compatible = "ibm,plb-405exr", "ibm,plb4";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		ranges;
++		clock-frequency = <0>; /* Filled in by U-Boot */
++
++		SDRAM0: memory-controller {
++			compatible = "ibm,sdram-405exr";
++			dcr-reg = <010 2>;
++		};
++
++		MAL0: mcmal {
++			compatible = "ibm,mcmal-405exr", "ibm,mcmal2";
++			dcr-reg = <180 62>;
++			num-tx-chans = <2>;
++			num-rx-chans = <2>;
++			interrupt-parent = <&MAL0>;
++			interrupts = <0 1 2 3 4>;
++			#interrupt-cells = <1>;
++			#address-cells = <0>;
++			#size-cells = <0>;
++			interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
++					/*RXEOB*/ 1 &UIC0 b 4
++					/*SERR*/  2 &UIC1 0 4
++					/*TXDE*/  3 &UIC1 1 4
++					/*RXDE*/  4 &UIC1 2 4>;
++			interrupt-map-mask = <ffffffff>;
++		};
++
++		POB0: opb {
++			compatible = "ibm,opb-405exr", "ibm,opb";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			ranges = <80000000 80000000 10000000
++				  ef600000 ef600000 a00000
++				  f0000000 f0000000 10000000>;
++			dcr-reg = <0a0 5>;
++			clock-frequency = <0>; /* Filled in by U-Boot */
++
++			EBC0: ebc {
++				compatible = "ibm,ebc-405exr", "ibm,ebc";
++				dcr-reg = <012 2>;
++				#address-cells = <2>;
++				#size-cells = <1>;
++				clock-frequency = <0>; /* Filled in by U-Boot */
++				/* ranges property is supplied by U-Boot */
++				interrupts = <5 1>;
++				interrupt-parent = <&UIC1>;
++
++				nor_flash@0,0 {
++					compatible = "amd,s29gl512n", "cfi-flash";
++					bank-width = <2>;
++					reg = <0 000000 4000000>;
++					#address-cells = <1>;
++					#size-cells = <1>;
++					partition@0 {
++						label = "kernel";
++						reg = <0 200000>;
++					};
++					partition@200000 {
++						label = "root";
++						reg = <200000 200000>;
++					};
++					partition@400000 {
++						label = "user";
++						reg = <400000 3b60000>;
++					};
++					partition@3f60000 {
++						label = "env";
++						reg = <3f60000 40000>;
++					};
++					partition@3fa0000 {
++						label = "u-boot";
++						reg = <3fa0000 60000>;
++					};
++				};
++			};
++
++			UART0: serial@ef600200 {
++				device_type = "serial";
++				compatible = "ns16550";
++				reg = <ef600200 8>;
++				virtual-reg = <ef600200>;
++				clock-frequency = <0>; /* Filled in by U-Boot */
++				current-speed = <0>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <1a 4>;
++			};
++
++			UART1: serial@ef600300 {
++				device_type = "serial";
++				compatible = "ns16550";
++				reg = <ef600300 8>;
++				virtual-reg = <ef600300>;
++				clock-frequency = <0>; /* Filled in by U-Boot */
++				current-speed = <0>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <1 4>;
++			};
++
++			IIC0: i2c@ef600400 {
++				compatible = "ibm,iic-405exr", "ibm,iic";
++				reg = <ef600400 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <2 4>;
++			};
++
++			IIC1: i2c@ef600500 {
++				compatible = "ibm,iic-405exr", "ibm,iic";
++				reg = <ef600500 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <7 4>;
++			};
++
++
++			RGMII0: emac-rgmii@ef600b00 {
++				compatible = "ibm,rgmii-405exr", "ibm,rgmii";
++				reg = <ef600b00 104>;
++				has-mdio;
++			};
++
++			EMAC0: ethernet@ef600900 {
++				linux,network-index = <0>;
++				device_type = "network";
++				compatible = "ibm,emac-405exr", "ibm,emac4";
++				interrupt-parent = <&EMAC0>;
++				interrupts = <0 1>;
++				#interrupt-cells = <1>;
++				#address-cells = <0>;
++				#size-cells = <0>;
++				interrupt-map = </*Status*/ 0 &UIC0 18 4
++						/*Wake*/  1 &UIC1 1d 4>;
++				reg = <ef600900 70>;
++				local-mac-address = [000000000000]; /* Filled in by U-Boot */
++				mal-device = <&MAL0>;
++				mal-tx-channel = <0>;
++				mal-rx-channel = <0>;
++				cell-index = <0>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rgmii";
++				phy-map = <00000000>;
++				rgmii-device = <&RGMII0>;
++				rgmii-channel = <0>;
++				has-inverted-stacr-oc;
++				has-new-stacr-staopc;
++			};
++		};
++
++		PCIE0: pciex@0a0000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex";
++			primary;
++			port = <0>; /* port number */
++			reg = <a0000000 20000000	/* Config space access */
++			       ef000000 00001000>;	/* Registers */
++			dcr-reg = <040 020>;
++			sdr-base = <400>;
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 90000000 0 08000000
++				  01000000 0 00000000 e0000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 80000000>;
++
++			/* This drives busses 0x00 to 0x3f */
++			bus-range = <00 3f>;
++
++			/* Legacy interrupts (note the weird polarity, the bridge seems
++			 * to invert PCIe legacy interrupts).
++			 * We are de-swizzling here because the numbers are actually for
++			 * port of the root complex virtual P2P bridge. But I want
++			 * to avoid putting a node for it in the tree, so the numbers
++			 * below are basically de-swizzled numbers.
++			 * The real slot is on idsel 0, so the swizzling is 1:1
++			 */
++			interrupt-map-mask = <0000 0 0 7>;
++			interrupt-map = <
++				0000 0 0 1 &UIC2 0 4 /* swizzled int A */
++				0000 0 0 2 &UIC2 1 4 /* swizzled int B */
++				0000 0 0 3 &UIC2 2 4 /* swizzled int C */
++				0000 0 0 4 &UIC2 3 4 /* swizzled int D */>;
++		};
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/katmai.dts powerpc.git/arch/powerpc/boot/dts/katmai.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/katmai.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/katmai.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,400 @@
++/*
++ * Device Tree Source for AMCC Katmai eval board
++ *
++ * Copyright (c) 2006, 2007 IBM Corp.
++ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
++ *
++ * Copyright (c) 2006, 2007 IBM Corp.
++ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2.  This program is licensed "as is" without
++ * any warranty of any kind, whether express or implied.
++ */
++
++/ {
++	#address-cells = <2>;
++	#size-cells = <1>;
++	model = "amcc,katmai";
++	compatible = "amcc,katmai";
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		serial0 = &UART0;
++		serial1 = &UART1;
++		serial2 = &UART2;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		cpu@0 {
++			device_type = "cpu";
++			model = "PowerPC,440SPe";
++			reg = <0>;
++			clock-frequency = <0>; /* Filled in by zImage */
++			timebase-frequency = <0>; /* Filled in by zImage */
++			i-cache-line-size = <20>;
++			d-cache-line-size = <20>;
++			i-cache-size = <20000>;
++			d-cache-size = <20000>;
++			dcr-controller;
++			dcr-access-method = "native";
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0 0>; /* Filled in by zImage */
++	};
++
++	UIC0: interrupt-controller0 {
++		compatible = "ibm,uic-440spe","ibm,uic";
++		interrupt-controller;
++		cell-index = <0>;
++		dcr-reg = <0c0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++	};
++
++	UIC1: interrupt-controller1 {
++		compatible = "ibm,uic-440spe","ibm,uic";
++		interrupt-controller;
++		cell-index = <1>;
++		dcr-reg = <0d0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <1e 4 1f 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	UIC2: interrupt-controller2 {
++		compatible = "ibm,uic-440spe","ibm,uic";
++		interrupt-controller;
++		cell-index = <2>;
++		dcr-reg = <0e0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <a 4 b 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	UIC3: interrupt-controller3 {
++		compatible = "ibm,uic-440spe","ibm,uic";
++		interrupt-controller;
++		cell-index = <3>;
++		dcr-reg = <0f0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <10 4 11 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	SDR0: sdr {
++		compatible = "ibm,sdr-440spe";
++		dcr-reg = <00e 002>;
++	};
++
++	CPR0: cpr {
++		compatible = "ibm,cpr-440spe";
++		dcr-reg = <00c 002>;
++	};
++
++	plb {
++		compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		ranges;
++		clock-frequency = <0>; /* Filled in by zImage */
++
++		SDRAM0: sdram {
++			compatible = "ibm,sdram-440spe", "ibm,sdram-405gp";
++			dcr-reg = <010 2>;
++		};
++
++		MAL0: mcmal {
++			compatible = "ibm,mcmal-440spe", "ibm,mcmal2";
++			dcr-reg = <180 62>;
++			num-tx-chans = <2>;
++			num-rx-chans = <1>;
++			interrupt-parent = <&MAL0>;
++			interrupts = <0 1 2 3 4>;
++			#interrupt-cells = <1>;
++			#address-cells = <0>;
++			#size-cells = <0>;
++			interrupt-map = </*TXEOB*/ 0 &UIC1 6 4
++					 /*RXEOB*/ 1 &UIC1 7 4
++					 /*SERR*/  2 &UIC1 1 4
++					 /*TXDE*/  3 &UIC1 2 4
++					 /*RXDE*/  4 &UIC1 3 4>;
++		};
++
++		POB0: opb {
++		  	compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
++			#address-cells = <1>;
++			#size-cells = <1>;
++		  	ranges = <00000000 4 e0000000 20000000>;
++		  	clock-frequency = <0>; /* Filled in by zImage */
++
++			EBC0: ebc {
++				compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc";
++				dcr-reg = <012 2>;
++				#address-cells = <2>;
++				#size-cells = <1>;
++				clock-frequency = <0>; /* Filled in by zImage */
++				interrupts = <5 1>;
++				interrupt-parent = <&UIC1>;
++			};
++
++			UART0: serial@10000200 {
++		   		device_type = "serial";
++		   		compatible = "ns16550";
++		   		reg = <10000200 8>;
++				virtual-reg = <a0000200>;
++		   		clock-frequency = <0>; /* Filled in by zImage */
++		   		current-speed = <1c200>;
++		   		interrupt-parent = <&UIC0>;
++		   		interrupts = <0 4>;
++	   		};
++
++			UART1: serial@10000300 {
++		   		device_type = "serial";
++		   		compatible = "ns16550";
++		   		reg = <10000300 8>;
++				virtual-reg = <a0000300>;
++		   		clock-frequency = <0>;
++		   		current-speed = <0>;
++		   		interrupt-parent = <&UIC0>;
++		   		interrupts = <1 4>;
++	   		};
++
++
++			UART2: serial@10000600 {
++		   		device_type = "serial";
++		   		compatible = "ns16550";
++		   		reg = <10000600 8>;
++				virtual-reg = <a0000600>;
++		   		clock-frequency = <0>;
++		   		current-speed = <0>;
++		   		interrupt-parent = <&UIC1>;
++		   		interrupts = <5 4>;
++	   		};
++
++			IIC0: i2c@10000400 {
++				device_type = "i2c";
++				compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
++				reg = <10000400 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <2 4>;
++			};
++
++			IIC1: i2c@10000500 {
++				device_type = "i2c";
++				compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
++				reg = <10000500 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <3 4>;
++			};
++
++			EMAC0: ethernet@10000800 {
++				linux,network-index = <0>;
++				device_type = "network";
++				compatible = "ibm,emac-440spe", "ibm,emac4";
++				interrupt-parent = <&UIC1>;
++				interrupts = <1c 4 1d 4>;
++				reg = <10000800 70>;
++				local-mac-address = [000000000000];
++				mal-device = <&MAL0>;
++				mal-tx-channel = <0>;
++				mal-rx-channel = <0>;
++				cell-index = <0>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "gmii";
++				phy-map = <00000000>;
++				has-inverted-stacr-oc;
++				has-new-stacr-staopc;
++			};
++		};
++
++		PCIX0: pci@c0ec00000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pcix-440spe", "ibm,plb-pcix";
++			primary;
++			large-inbound-windows;
++			enable-msi-hole;
++			reg = <c 0ec00000   8	/* Config space access */
++			       0 0 0		/* no IACK cycles */
++			       c 0ed00000   4   /* Special cycles */
++			       c 0ec80000 100	/* Internal registers */
++			       c 0ec80100  fc>;	/* Internal messaging registers */
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 0000000d 80000000 0 80000000
++				  01000000 0 00000000 0000000c 08000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			/* This drives busses 0 to 0xf */
++			bus-range = <0 f>;
++
++			/*
++			 * On Katmai, the following PCI-X interrupts signals
++			 * have to be enabled via jumpers (only INTA is
++			 * enabled per default):
++			 *
++			 * INTB: J3: 1-2
++			 * INTC: J2: 1-2
++			 * INTD: J1: 1-2
++			 */
++			interrupt-map-mask = <f800 0 0 7>;
++			interrupt-map = <
++				/* IDSEL 1 */
++				0800 0 0 1 &UIC1 14 8
++				0800 0 0 2 &UIC1 13 8
++				0800 0 0 3 &UIC1 12 8
++				0800 0 0 4 &UIC1 11 8
++			>;
++		};
++
++		PCIE0: pciex@d00000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex";
++			primary;
++			port = <0>; /* port number */
++			reg = <d 00000000 20000000	/* Config space access */
++			       c 10000000 00001000>;	/* Registers */
++			dcr-reg = <100 020>;
++			sdr-base = <300>;
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 0000000e 00000000 0 80000000
++				  01000000 0 00000000 0000000f 80000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			/* This drives busses 10 to 0x1f */
++			bus-range = <10 1f>;
++
++			/* Legacy interrupts (note the weird polarity, the bridge seems
++			 * to invert PCIe legacy interrupts).
++			 * We are de-swizzling here because the numbers are actually for
++			 * port of the root complex virtual P2P bridge. But I want
++			 * to avoid putting a node for it in the tree, so the numbers
++			 * below are basically de-swizzled numbers.
++			 * The real slot is on idsel 0, so the swizzling is 1:1
++			 */
++			interrupt-map-mask = <0000 0 0 7>;
++			interrupt-map = <
++				0000 0 0 1 &UIC3 0 4 /* swizzled int A */
++				0000 0 0 2 &UIC3 1 4 /* swizzled int B */
++				0000 0 0 3 &UIC3 2 4 /* swizzled int C */
++				0000 0 0 4 &UIC3 3 4 /* swizzled int D */>;
++		};
++
++		PCIE1: pciex@d20000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex";
++			primary;
++			port = <1>; /* port number */
++			reg = <d 20000000 20000000	/* Config space access */
++			       c 10001000 00001000>;	/* Registers */
++			dcr-reg = <120 020>;
++			sdr-base = <340>;
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 0000000e 80000000 0 80000000
++				  01000000 0 00000000 0000000f 80010000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			/* This drives busses 10 to 0x1f */
++			bus-range = <20 2f>;
++
++			/* Legacy interrupts (note the weird polarity, the bridge seems
++			 * to invert PCIe legacy interrupts).
++			 * We are de-swizzling here because the numbers are actually for
++			 * port of the root complex virtual P2P bridge. But I want
++			 * to avoid putting a node for it in the tree, so the numbers
++			 * below are basically de-swizzled numbers.
++			 * The real slot is on idsel 0, so the swizzling is 1:1
++			 */
++			interrupt-map-mask = <0000 0 0 7>;
++			interrupt-map = <
++				0000 0 0 1 &UIC3 4 4 /* swizzled int A */
++				0000 0 0 2 &UIC3 5 4 /* swizzled int B */
++				0000 0 0 3 &UIC3 6 4 /* swizzled int C */
++				0000 0 0 4 &UIC3 7 4 /* swizzled int D */>;
++		};
++
++		PCIE2: pciex@d40000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex";
++			primary;
++			port = <2>; /* port number */
++			reg = <d 40000000 20000000	/* Config space access */
++			       c 10002000 00001000>;	/* Registers */
++			dcr-reg = <140 020>;
++			sdr-base = <370>;
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 0000000f 00000000 0 80000000
++				  01000000 0 00000000 0000000f 80020000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			/* This drives busses 10 to 0x1f */
++			bus-range = <30 3f>;
++
++			/* Legacy interrupts (note the weird polarity, the bridge seems
++			 * to invert PCIe legacy interrupts).
++			 * We are de-swizzling here because the numbers are actually for
++			 * port of the root complex virtual P2P bridge. But I want
++			 * to avoid putting a node for it in the tree, so the numbers
++			 * below are basically de-swizzled numbers.
++			 * The real slot is on idsel 0, so the swizzling is 1:1
++			 */
++			interrupt-map-mask = <0000 0 0 7>;
++			interrupt-map = <
++				0000 0 0 1 &UIC3 8 4 /* swizzled int A */
++				0000 0 0 2 &UIC3 9 4 /* swizzled int B */
++				0000 0 0 3 &UIC3 a 4 /* swizzled int C */
++				0000 0 0 4 &UIC3 b 4 /* swizzled int D */>;
++		};
++	};
++
++	chosen {
++		linux,stdout-path = "/plb/opb/serial@10000200";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/kilauea.dts powerpc.git/arch/powerpc/boot/dts/kilauea.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/kilauea.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/kilauea.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -13,14 +13,22 @@
+ 	#size-cells = <1>;
+ 	model = "amcc,kilauea";
+ 	compatible = "amcc,kilauea";
+-	dcr-parent = <&/cpus/PowerPC,405EX@0>;
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		ethernet1 = &EMAC1;
++		serial0 = &UART0;
++		serial1 = &UART1;
++	};
+ 
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+ 
+-		PowerPC,405EX@0 {
++		cpu@0 {
+ 			device_type = "cpu";
++			model = "PowerPC,405EX";
+ 			reg = <0>;
+ 			clock-frequency = <0>; /* Filled in by U-Boot */
+ 			timebase-frequency = <0>; /* Filled in by U-Boot */
+@@ -194,6 +202,7 @@
+ 				device_type = "rgmii-interface";
+ 				compatible = "ibm,rgmii-405ex", "ibm,rgmii";
+ 				reg = <ef600b00 104>;
++				has-mdio;
+ 			};
+ 
+ 			EMAC0: ethernet@ef600900 {
+@@ -220,6 +229,8 @@
+ 				phy-map = <00000000>;
+ 				rgmii-device = <&RGMII0>;
+ 				rgmii-channel = <0>;
++				has-inverted-stacr-oc;
++				has-new-stacr-staopc;
+ 			};
+ 
+ 			EMAC1: ethernet@ef600a00 {
+@@ -246,7 +257,91 @@
+ 				phy-map = <00000000>;
+ 				rgmii-device = <&RGMII0>;
+ 				rgmii-channel = <1>;
++				has-inverted-stacr-oc;
++				has-new-stacr-staopc;
+ 			};
+ 		};
++
++		PCIE0: pciex@0a0000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
++			primary;
++			port = <0>; /* port number */
++			reg = <a0000000 20000000	/* Config space access */
++			       ef000000 00001000>;	/* Registers */
++			dcr-reg = <040 020>;
++			sdr-base = <400>;
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 90000000 0 08000000
++				  01000000 0 00000000 e0000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 80000000>;
++
++			/* This drives busses 0x00 to 0x3f */
++			bus-range = <00 3f>;
++
++			/* Legacy interrupts (note the weird polarity, the bridge seems
++			 * to invert PCIe legacy interrupts).
++			 * We are de-swizzling here because the numbers are actually for
++			 * port of the root complex virtual P2P bridge. But I want
++			 * to avoid putting a node for it in the tree, so the numbers
++			 * below are basically de-swizzled numbers.
++			 * The real slot is on idsel 0, so the swizzling is 1:1
++			 */
++			interrupt-map-mask = <0000 0 0 7>;
++			interrupt-map = <
++				0000 0 0 1 &UIC2 0 4 /* swizzled int A */
++				0000 0 0 2 &UIC2 1 4 /* swizzled int B */
++				0000 0 0 3 &UIC2 2 4 /* swizzled int C */
++				0000 0 0 4 &UIC2 3 4 /* swizzled int D */>;
++		};
++
++		PCIE1: pciex@0c0000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
++			primary;
++			port = <1>; /* port number */
++			reg = <c0000000 20000000	/* Config space access */
++			       ef001000 00001000>;	/* Registers */
++			dcr-reg = <060 020>;
++			sdr-base = <440>;
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 98000000 0 08000000
++				  01000000 0 00000000 e0010000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 80000000>;
++
++			/* This drives busses 0x40 to 0x7f */
++			bus-range = <40 7f>;
++
++			/* Legacy interrupts (note the weird polarity, the bridge seems
++			 * to invert PCIe legacy interrupts).
++			 * We are de-swizzling here because the numbers are actually for
++			 * port of the root complex virtual P2P bridge. But I want
++			 * to avoid putting a node for it in the tree, so the numbers
++			 * below are basically de-swizzled numbers.
++			 * The real slot is on idsel 0, so the swizzling is 1:1
++			 */
++			interrupt-map-mask = <0000 0 0 7>;
++			interrupt-map = <
++				0000 0 0 1 &UIC2 b 4 /* swizzled int A */
++				0000 0 0 2 &UIC2 c 4 /* swizzled int B */
++				0000 0 0 3 &UIC2 d 4 /* swizzled int C */
++				0000 0 0 4 &UIC2 e 4 /* swizzled int D */>;
++		};
+ 	};
+ };
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/kuroboxHD.dts powerpc.git/arch/powerpc/boot/dts/kuroboxHD.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/kuroboxHD.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/kuroboxHD.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -23,6 +23,12 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -60,7 +66,7 @@
+ 		i2c@80003000 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <80003000 1000>;
+ 			interrupts = <5 2>;
+@@ -73,7 +79,8 @@
+ 			};
+ 		};
+ 
+-		serial@80004500 {
++		serial0: serial@80004500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <80004500 8>;
+@@ -83,7 +90,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@80004600 {
++		serial1: serial@80004600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <80004600 8>;
+@@ -102,7 +110,7 @@
+ 			reg = <80040000 40000>;
+ 		};
+ 
+-		pci@fec00000 {
++		pci0: pci@fec00000 {
+ 			#address-cells = <3>;
+ 			#size-cells = <2>;
+ 			#interrupt-cells = <1>;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/kuroboxHG.dts powerpc.git/arch/powerpc/boot/dts/kuroboxHG.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/kuroboxHG.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/kuroboxHG.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -23,6 +23,12 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -60,7 +66,7 @@
+ 		i2c@80003000 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <80003000 1000>;
+ 			interrupts = <5 2>;
+@@ -73,7 +79,8 @@
+ 			};
+ 		};
+ 
+-		serial@80004500 {
++		serial0: serial@80004500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <80004500 8>;
+@@ -83,7 +90,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@80004600 {
++		serial1: serial@80004600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <80004600 8>;
+@@ -102,7 +110,7 @@
+ 			reg = <80040000 40000>;
+ 		};
+ 
+-		pci@fec00000 {
++		pci0: pci@fec00000 {
+ 			#address-cells = <3>;
+ 			#size-cells = <2>;
+ 			#interrupt-cells = <1>;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/lite5200.dts powerpc.git/arch/powerpc/boot/dts/lite5200.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/lite5200.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/lite5200.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -19,7 +19,7 @@
+ / {
+ 	model = "fsl,lite5200";
+ 	// revision = "1.0";
+-	compatible = "fsl,lite5200","generic-mpc5200";
++	compatible = "fsl,lite5200";
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
+@@ -284,7 +284,8 @@
+ 		};
+ 
+ 		i2c@3d00 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
+ 			compatible = "mpc5200-i2c","fsl-i2c";
+ 			cell-index = <0>;
+ 			reg = <3d00 40>;
+@@ -294,7 +295,8 @@
+ 		};
+ 
+ 		i2c@3d40 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
+ 			compatible = "mpc5200-i2c","fsl-i2c";
+ 			cell-index = <1>;
+ 			reg = <3d40 40>;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/lite5200b.dts powerpc.git/arch/powerpc/boot/dts/lite5200b.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/lite5200b.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/lite5200b.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -19,7 +19,7 @@
+ / {
+ 	model = "fsl,lite5200b";
+ 	// revision = "1.0";
+-	compatible = "fsl,lite5200b","generic-mpc5200";
++	compatible = "fsl,lite5200b";
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
+@@ -300,7 +300,8 @@
+ 		};
+ 
+ 		i2c@3d00 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
+ 			compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c";
+ 			cell-index = <0>;
+ 			reg = <3d00 40>;
+@@ -310,7 +311,8 @@
+ 		};
+ 
+ 		i2c@3d40 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
+ 			compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c";
+ 			cell-index = <1>;
+ 			reg = <3d40 40>;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/makalu.dts powerpc.git/arch/powerpc/boot/dts/makalu.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/makalu.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/makalu.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,347 @@
++/*
++ * Device Tree Source for AMCC Makalu (405EX)
++ *
++ * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2.  This program is licensed "as is" without
++ * any warranty of any kind, whether express or implied.
++ */
++
++/ {
++	#address-cells = <1>;
++	#size-cells = <1>;
++	model = "amcc,makalu";
++	compatible = "amcc,makalu";
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		ethernet1 = &EMAC1;
++		serial0 = &UART0;
++		serial1 = &UART1;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		cpu@0 {
++			device_type = "cpu";
++			model = "PowerPC,405EX";
++			reg = <0>;
++			clock-frequency = <0>; /* Filled in by U-Boot */
++			timebase-frequency = <0>; /* Filled in by U-Boot */
++			i-cache-line-size = <20>;
++			d-cache-line-size = <20>;
++			i-cache-size = <4000>; /* 16 kB */
++			d-cache-size = <4000>; /* 16 kB */
++			dcr-controller;
++			dcr-access-method = "native";
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0>; /* Filled in by U-Boot */
++	};
++
++	UIC0: interrupt-controller {
++		compatible = "ibm,uic-405ex", "ibm,uic";
++		interrupt-controller;
++		cell-index = <0>;
++		dcr-reg = <0c0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++	};
++
++	UIC1: interrupt-controller1 {
++		compatible = "ibm,uic-405ex","ibm,uic";
++		interrupt-controller;
++		cell-index = <1>;
++		dcr-reg = <0d0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <1e 4 1f 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	UIC2: interrupt-controller2 {
++		compatible = "ibm,uic-405ex","ibm,uic";
++		interrupt-controller;
++		cell-index = <2>;
++		dcr-reg = <0e0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <1c 4 1d 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	plb {
++		compatible = "ibm,plb-405ex", "ibm,plb4";
++		#address-cells = <1>;
++		#size-cells = <1>;
++		ranges;
++		clock-frequency = <0>; /* Filled in by U-Boot */
++
++		SDRAM0: memory-controller {
++			compatible = "ibm,sdram-405ex";
++			dcr-reg = <010 2>;
++		};
++
++		MAL0: mcmal {
++			compatible = "ibm,mcmal-405ex", "ibm,mcmal2";
++			dcr-reg = <180 62>;
++			num-tx-chans = <2>;
++			num-rx-chans = <2>;
++			interrupt-parent = <&MAL0>;
++			interrupts = <0 1 2 3 4>;
++			#interrupt-cells = <1>;
++			#address-cells = <0>;
++			#size-cells = <0>;
++			interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
++					/*RXEOB*/ 1 &UIC0 b 4
++					/*SERR*/  2 &UIC1 0 4
++					/*TXDE*/  3 &UIC1 1 4
++					/*RXDE*/  4 &UIC1 2 4>;
++			interrupt-map-mask = <ffffffff>;
++		};
++
++		POB0: opb {
++			compatible = "ibm,opb-405ex", "ibm,opb";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			ranges = <80000000 80000000 10000000
++				  ef600000 ef600000 a00000
++				  f0000000 f0000000 10000000>;
++			dcr-reg = <0a0 5>;
++			clock-frequency = <0>; /* Filled in by U-Boot */
++
++			EBC0: ebc {
++				compatible = "ibm,ebc-405ex", "ibm,ebc";
++				dcr-reg = <012 2>;
++				#address-cells = <2>;
++				#size-cells = <1>;
++				clock-frequency = <0>; /* Filled in by U-Boot */
++				/* ranges property is supplied by U-Boot */
++				interrupts = <5 1>;
++				interrupt-parent = <&UIC1>;
++
++				nor_flash@0,0 {
++					compatible = "amd,s29gl512n", "cfi-flash";
++					bank-width = <2>;
++					reg = <0 000000 4000000>;
++					#address-cells = <1>;
++					#size-cells = <1>;
++					partition@0 {
++						label = "kernel";
++						reg = <0 200000>;
++					};
++					partition@200000 {
++						label = "root";
++						reg = <200000 200000>;
++					};
++					partition@400000 {
++						label = "user";
++						reg = <400000 3b60000>;
++					};
++					partition@3f60000 {
++						label = "env";
++						reg = <3f60000 40000>;
++					};
++					partition@3fa0000 {
++						label = "u-boot";
++						reg = <3fa0000 60000>;
++					};
++				};
++			};
++
++			UART0: serial@ef600200 {
++				device_type = "serial";
++				compatible = "ns16550";
++				reg = <ef600200 8>;
++				virtual-reg = <ef600200>;
++				clock-frequency = <0>; /* Filled in by U-Boot */
++				current-speed = <0>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <1a 4>;
++			};
++
++			UART1: serial@ef600300 {
++				device_type = "serial";
++				compatible = "ns16550";
++				reg = <ef600300 8>;
++				virtual-reg = <ef600300>;
++				clock-frequency = <0>; /* Filled in by U-Boot */
++				current-speed = <0>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <1 4>;
++			};
++
++			IIC0: i2c@ef600400 {
++				device_type = "i2c";
++				compatible = "ibm,iic-405ex", "ibm,iic";
++				reg = <ef600400 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <2 4>;
++			};
++
++			IIC1: i2c@ef600500 {
++				device_type = "i2c";
++				compatible = "ibm,iic-405ex", "ibm,iic";
++				reg = <ef600500 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <7 4>;
++			};
++
++
++			RGMII0: emac-rgmii@ef600b00 {
++				device_type = "rgmii-interface";
++				compatible = "ibm,rgmii-405ex", "ibm,rgmii";
++				reg = <ef600b00 104>;
++				has-mdio;
++			};
++
++			EMAC0: ethernet@ef600900 {
++				linux,network-index = <0>;
++				device_type = "network";
++				compatible = "ibm,emac-405ex", "ibm,emac4";
++				interrupt-parent = <&EMAC0>;
++				interrupts = <0 1>;
++				#interrupt-cells = <1>;
++				#address-cells = <0>;
++				#size-cells = <0>;
++				interrupt-map = </*Status*/ 0 &UIC0 18 4
++						/*Wake*/  1 &UIC1 1d 4>;
++				reg = <ef600900 70>;
++				local-mac-address = [000000000000]; /* Filled in by U-Boot */
++				mal-device = <&MAL0>;
++				mal-tx-channel = <0>;
++				mal-rx-channel = <0>;
++				cell-index = <0>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rgmii";
++				phy-map = <0000003f>;	/* Start at 6 */
++				rgmii-device = <&RGMII0>;
++				rgmii-channel = <0>;
++				has-inverted-stacr-oc;
++				has-new-stacr-staopc;
++			};
++
++			EMAC1: ethernet@ef600a00 {
++				linux,network-index = <1>;
++				device_type = "network";
++				compatible = "ibm,emac-405ex", "ibm,emac4";
++				interrupt-parent = <&EMAC1>;
++				interrupts = <0 1>;
++				#interrupt-cells = <1>;
++				#address-cells = <0>;
++				#size-cells = <0>;
++				interrupt-map = </*Status*/ 0 &UIC0 19 4
++						/*Wake*/  1 &UIC1 1f 4>;
++				reg = <ef600a00 70>;
++				local-mac-address = [000000000000]; /* Filled in by U-Boot */
++				mal-device = <&MAL0>;
++				mal-tx-channel = <1>;
++				mal-rx-channel = <1>;
++				cell-index = <1>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rgmii";
++				phy-map = <00000000>;
++				rgmii-device = <&RGMII0>;
++				rgmii-channel = <1>;
++				has-inverted-stacr-oc;
++				has-new-stacr-staopc;
++			};
++		};
++
++		PCIE0: pciex@0a0000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
++			primary;
++			port = <0>; /* port number */
++			reg = <a0000000 20000000	/* Config space access */
++			       ef000000 00001000>;	/* Registers */
++			dcr-reg = <040 020>;
++			sdr-base = <400>;
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 90000000 0 08000000
++				  01000000 0 00000000 e0000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 80000000>;
++
++			/* This drives busses 0x00 to 0x3f */
++			bus-range = <00 3f>;
++
++			/* Legacy interrupts (note the weird polarity, the bridge seems
++			 * to invert PCIe legacy interrupts).
++			 * We are de-swizzling here because the numbers are actually for
++			 * port of the root complex virtual P2P bridge. But I want
++			 * to avoid putting a node for it in the tree, so the numbers
++			 * below are basically de-swizzled numbers.
++			 * The real slot is on idsel 0, so the swizzling is 1:1
++			 */
++			interrupt-map-mask = <0000 0 0 7>;
++			interrupt-map = <
++				0000 0 0 1 &UIC2 0 4 /* swizzled int A */
++				0000 0 0 2 &UIC2 1 4 /* swizzled int B */
++				0000 0 0 3 &UIC2 2 4 /* swizzled int C */
++				0000 0 0 4 &UIC2 3 4 /* swizzled int D */>;
++		};
++
++		PCIE1: pciex@0c0000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
++			primary;
++			port = <1>; /* port number */
++			reg = <c0000000 20000000	/* Config space access */
++			       ef001000 00001000>;	/* Registers */
++			dcr-reg = <060 020>;
++			sdr-base = <440>;
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 98000000 0 08000000
++				  01000000 0 00000000 e0010000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 80000000>;
++
++			/* This drives busses 0x40 to 0x7f */
++			bus-range = <40 7f>;
++
++			/* Legacy interrupts (note the weird polarity, the bridge seems
++			 * to invert PCIe legacy interrupts).
++			 * We are de-swizzling here because the numbers are actually for
++			 * port of the root complex virtual P2P bridge. But I want
++			 * to avoid putting a node for it in the tree, so the numbers
++			 * below are basically de-swizzled numbers.
++			 * The real slot is on idsel 0, so the swizzling is 1:1
++			 */
++			interrupt-map-mask = <0000 0 0 7>;
++			interrupt-map = <
++				0000 0 0 1 &UIC2 b 4 /* swizzled int A */
++				0000 0 0 2 &UIC2 c 4 /* swizzled int B */
++				0000 0 0 3 &UIC2 d 4 /* swizzled int C */
++				0000 0 0 4 &UIC2 e 4 /* swizzled int D */>;
++		};
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/motionpro.dts powerpc.git/arch/powerpc/boot/dts/motionpro.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/motionpro.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/motionpro.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,309 @@
++/*
++ * Motion-PRO board Device Tree Source
++ *
++ * Copyright (C) 2007 Semihalf
++ * Marian Balakowicz <m8@semihalf.com>
++ *
++ * 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.
++ */
++
++/*
++ * WARNING: Do not depend on this tree layout remaining static just yet.
++ * The MPC5200 device tree conventions are still in flux
++ * Keep an eye on the linuxppc-dev mailing list for more details
++ */
++
++/ {
++	model = "promess,motionpro";
++	compatible = "promess,motionpro";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,5200@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <20>;
++			i-cache-line-size = <20>;
++			d-cache-size = <4000>;		// L1, 16K
++			i-cache-size = <4000>;		// L1, 16K
++			timebase-frequency = <0>;	// from bootloader
++			bus-frequency = <0>;		// from bootloader
++			clock-frequency = <0>;		// from bootloader
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <00000000 04000000>;	// 64MB
++	};
++
++	soc5200@f0000000 {
++		model = "fsl,mpc5200b";
++		compatible = "fsl,mpc5200b";
++		revision = "";			// from bootloader
++		device_type = "soc";
++		ranges = <0 f0000000 0000c000>;
++		reg = <f0000000 00000100>;
++		bus-frequency = <0>;		// from bootloader
++		system-frequency = <0>;		// from bootloader
++
++		cdm@200 {
++			compatible = "mpc5200b-cdm","mpc5200-cdm";
++			reg = <200 38>;
++		};
++
++		mpc5200_pic: pic@500 {
++			// 5200 interrupts are encoded into two levels;
++			interrupt-controller;
++			#interrupt-cells = <3>;
++			compatible = "mpc5200b-pic","mpc5200-pic";
++			reg = <500 80>;
++		};
++
++		gpt@600 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <600 10>;
++			interrupts = <1 9 0>;
++			interrupt-parent = <&mpc5200_pic>;
++			fsl,has-wdt;
++		};
++
++		gpt@610 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <610 10>;
++			interrupts = <1 a 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@620 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <620 10>;
++			interrupts = <1 b 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@630 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <630 10>;
++			interrupts = <1 c 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@640 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <640 10>;
++			interrupts = <1 d 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpt@650 {	// General Purpose Timer
++			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
++			reg = <650 10>;
++			interrupts = <1 e 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		motionpro-led@660 {	// Motion-PRO status LED
++			compatible = "promess,motionpro-led";
++			label = "motionpro-statusled";
++			reg = <660 10>;
++			interrupts = <1 f 0>;
++			interrupt-parent = <&mpc5200_pic>;
++			blink-delay = <64>; // 100 msec
++		};
++
++		motionpro-led@670 {	// Motion-PRO ready LED
++			compatible = "promess,motionpro-led";
++			label = "motionpro-readyled";
++			reg = <670 10>;
++			interrupts = <1 10 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		rtc@800 {	// Real time clock
++			compatible = "mpc5200b-rtc","mpc5200-rtc";
++			reg = <800 100>;
++			interrupts = <1 5 0 1 6 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		mscan@980 {
++			compatible = "mpc5200b-mscan","mpc5200-mscan";
++			interrupts = <2 12 0>;
++			interrupt-parent = <&mpc5200_pic>;
++			reg = <980 80>;
++		};
++
++		gpio@b00 {
++			compatible = "mpc5200b-gpio","mpc5200-gpio";
++			reg = <b00 40>;
++			interrupts = <1 7 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		gpio-wkup@c00 {
++			compatible = "mpc5200b-gpio-wkup","mpc5200-gpio-wkup";
++			reg = <c00 40>;
++			interrupts = <1 8 0 0 3 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++
++		spi@f00 {
++			compatible = "mpc5200b-spi","mpc5200-spi";
++			reg = <f00 20>;
++			interrupts = <2 d 0 2 e 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		usb@1000 {
++			compatible = "mpc5200b-ohci","mpc5200-ohci","ohci-be";
++			reg = <1000 ff>;
++			interrupts = <2 6 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		dma-controller@1200 {
++			compatible = "mpc5200b-bestcomm","mpc5200-bestcomm";
++			reg = <1200 80>;
++			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
++			              3 4 0  3 5 0  3 6 0  3 7 0
++			              3 8 0  3 9 0  3 a 0  3 b 0
++			              3 c 0  3 d 0  3 e 0  3 f 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		xlb@1f00 {
++			compatible = "mpc5200b-xlb","mpc5200-xlb";
++			reg = <1f00 100>;
++		};
++
++		serial@2000 {		// PSC1
++			device_type = "serial";
++			compatible = "mpc5200b-psc-uart","mpc5200-psc-uart";
++			port-number = <0>;  // Logical port assignment
++			reg = <2000 100>;
++			interrupts = <2 1 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		// PSC2 in spi master mode 
++		spi@2200 {		// PSC2
++			compatible = "mpc5200b-psc-spi","mpc5200-psc-spi";
++			cell-index = <1>;
++			reg = <2200 100>;
++			interrupts = <2 2 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		// PSC5 in uart mode
++		serial@2800 {		// PSC5
++			device_type = "serial";
++			compatible = "mpc5200b-psc-uart","mpc5200-psc-uart";
++			port-number = <4>;  // Logical port assignment
++			reg = <2800 100>;
++			interrupts = <2 c 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		ethernet@3000 {
++			device_type = "network";
++			compatible = "mpc5200b-fec","mpc5200-fec";
++			reg = <3000 800>;
++			local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by U-Boot */
++			interrupts = <2 5 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		ata@3a00 {
++			compatible = "mpc5200b-ata","mpc5200-ata";
++			reg = <3a00 100>;
++			interrupts = <2 7 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		i2c@3d40 {
++			compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c";
++			reg = <3d40 40>;
++			interrupts = <2 10 0>;
++			interrupt-parent = <&mpc5200_pic>;
++			fsl5200-clocking;
++		};
++
++		sram@8000 {
++			compatible = "mpc5200b-sram","mpc5200-sram";
++			reg = <8000 4000>;
++		};
++	};
++
++	lpb {
++		model = "fsl,lpb";
++		compatible = "fsl,lpb";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		ranges = <1 0 50000000 00010000
++			  2 0 50010000 00010000
++			  3 0 50020000 00010000>;
++
++		// 8-bit DualPort SRAM on LocalPlus Bus CS1
++		kollmorgen@1,0 {
++			compatible = "promess,motionpro-kollmorgen";
++			reg = <1 0 10000>;
++			interrupts = <1 1 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		// 8-bit board CPLD on LocalPlus Bus CS2
++		cpld@2,0 {
++			compatible = "promess,motionpro-cpld";
++			reg = <2 0 10000>;
++		};
++
++		// 8-bit custom Anybus Module on LocalPlus Bus CS3
++		anybus@3,0 {
++			compatible = "promess,motionpro-anybus";
++			reg = <3 0 10000>;
++		};
++		pro_module_general@3,0 {
++			compatible = "promess,pro_module_general";
++			reg = <3 0 3>;
++		};
++		pro_module_dio@3,800 {
++			compatible = "promess,pro_module_dio";
++			reg = <3 800 2>;
++		};
++	};
++
++	pci@f0000d00 {
++		#interrupt-cells = <1>;
++		#size-cells = <2>;
++		#address-cells = <3>;
++		device_type = "pci";
++		compatible = "mpc5200b-pci","mpc5200-pci";
++		reg = <f0000d00 100>;
++		interrupt-map-mask = <f800 0 0 7>;
++		interrupt-map = <c000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot
++				 c000 0 0 2 &mpc5200_pic 1 1 3
++				 c000 0 0 3 &mpc5200_pic 1 2 3
++				 c000 0 0 4 &mpc5200_pic 1 3 3
++
++				 c800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot
++				 c800 0 0 2 &mpc5200_pic 1 2 3
++				 c800 0 0 3 &mpc5200_pic 1 3 3
++				 c800 0 0 4 &mpc5200_pic 0 0 3>;
++		clock-frequency = <0>; // From boot loader
++		interrupts = <2 8 0 2 9 0 2 a 0>;
++		interrupt-parent = <&mpc5200_pic>;
++		bus-range = <0 0>;
++		ranges = <42000000 0 80000000 80000000 0 20000000
++			  02000000 0 a0000000 a0000000 0 10000000
++			  01000000 0 00000000 b0000000 0 01000000>;
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8313erdb.dts powerpc.git/arch/powerpc/boot/dts/mpc8313erdb.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8313erdb.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8313erdb.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -15,6 +15,14 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -37,10 +45,58 @@
+ 		reg = <00000000 08000000>;	// 128MB at 0
+ 	};
+ 
++	localbus@e0005000 {
++		#address-cells = <2>;
++		#size-cells = <1>;
++		compatible = "fsl,mpc8313-elbc", "fsl,elbc", "simple-bus";
++		reg = <e0005000 1000>;
++		interrupts = <d#77 8>;
++		interrupt-parent = <&ipic>;
++
++		// CS0 and CS1 are swapped when
++		// booting from nand, but the
++		// addresses are the same.
++		ranges = <0 0 fe000000 00800000
++		          1 0 e2800000 00008000
++		          2 0 f0000000 00020000
++		          3 0 fa000000 00008000>;
++
++		flash@0,0 {
++			#address-cells = <1>;
++			#size-cells = <1>;
++			compatible = "cfi-flash";
++			reg = <0 0 800000>;
++			bank-width = <2>;
++			device-width = <1>;
++		};
++
++		nand@1,0 {
++			#address-cells = <1>;
++			#size-cells = <1>;
++			compatible = "fsl,mpc8313-fcm-nand",
++			             "fsl,elbc-fcm-nand";
++			reg = <1 0 2000>;
++
++			u-boot@0 {
++				reg = <0 100000>;
++				read-only;
++			};
++
++			kernel@100000 {
++				reg = <100000 300000>;
++			};
++
++			fs@400000 {
++				reg = <400000 1c00000>;
++			};
++		};
++	};
++
+ 	soc8313@e0000000 {
+ 		#address-cells = <1>;
+ 		#size-cells = <1>;
+ 		device_type = "soc";
++		compatible = "simple-bus";
+ 		ranges = <0 e0000000 00100000>;
+ 		reg = <e0000000 00000200>;
+ 		bus-frequency = <0>;
+@@ -52,7 +108,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <e 8>;
+@@ -61,7 +119,9 @@
+ 		};
+ 
+ 		i2c@3100 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <f 8>;
+@@ -80,7 +140,6 @@
+ 
+ 		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
+ 		usb@23000 {
+-			device_type = "usb";
+ 			compatible = "fsl-usb2-dr";
+ 			reg = <23000 1000>;
+ 			#address-cells = <1>;
+@@ -91,11 +150,10 @@
+ 		};
+ 
+ 		mdio@24520 {
+-			device_type = "mdio";
+-			compatible = "gianfar";
+-			reg = <24520 20>;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			compatible = "fsl,gianfar-mdio";
++			reg = <24520 20>;
+ 			phy1: ethernet-phy@1 {
+ 				interrupt-parent = < &ipic >;
+ 				interrupts = <13 8>;
+@@ -110,7 +168,8 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -121,7 +180,8 @@
+ 			phy-handle = < &phy1 >;
+ 		};
+ 
+-		ethernet@25000 {
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -132,7 +192,8 @@
+ 			phy-handle = < &phy4 >;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -141,7 +202,8 @@
+ 			interrupt-parent = < &ipic >;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -179,7 +241,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008500 {
++	pci0: pci@e0008500 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc832x_mds.dts powerpc.git/arch/powerpc/boot/dts/mpc832x_mds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc832x_mds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc832x_mds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -7,6 +7,18 @@
+  * 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.
++
++ * To enable external serial I/O on a Freescale MPC 8323 SYS/MDS board, do
++ * this:
++ *
++ * 1) On chip U61, lift (disconnect) pins 21 (TXD) and 22 (RXD) from the board.
++ * 2) Solder a wire from U61-21 to P19A-23.  P19 is a grid of pins on the board
++ *    next to the serial ports.
++ * 3) Solder a wire from U61-22 to P19K-22.
++ *
++ * Note that there's a typo in the schematic.  The board labels the last column
++ * of pins "P19K", but in the schematic, that column is called "P19J".  So if
++ * you're going by the schematic, the pin is called "P19J-K22".
+  */
+ 
+ / {
+@@ -15,6 +27,14 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -59,7 +79,7 @@
+ 		i2c@3000 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <e 8>;
+@@ -72,7 +92,8 @@
+ 			};
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -81,7 +102,8 @@
+ 			interrupt-parent = < &ipic >;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -159,6 +181,23 @@
+ 					1 1e  1  0  1  0 	/* TX_EN */
+ 					1 1f  2  0  1  0>;/* CRS */
+ 			};
++			pio5: ucc_pin@05 {
++				pio-map = <
++				/*
++				 *    		      open       has
++				 *   port  pin  dir  drain  sel  irq
++				 */
++					2    0    1      0    2    0  /* TxD5 */
++					2    8    2      0    2    0  /* RxD5 */
++
++					2   1d    2      0    0    0  /* CTS5 */
++					2   1f    1      0    2    0  /* RTS5 */
++
++					2   18    2      0    0    0  /* CD */
++
++				>;
++			};
++
+ 		};
+ 	};
+ 
+@@ -166,6 +205,7 @@
+ 		#address-cells = <1>;
+ 		#size-cells = <1>;
+ 		device_type = "qe";
++		compatible = "fsl,qe";
+ 		model = "QE";
+ 		ranges = <0 e0100000 00100000>;
+ 		reg = <e0100000 480>;
+@@ -200,7 +240,6 @@
+ 		};
+ 
+ 		usb@6c0 {
+-			device_type = "usb";
+ 			compatible = "qe_udc";
+ 			reg = <6c0 40 8B00 100>;
+ 			interrupts = <b>;
+@@ -208,48 +247,58 @@
+ 			mode = "slave";
+ 		};
+ 
+-		ucc@2200 {
++		enet0: ucc@2200 {
+ 			device_type = "network";
+ 			compatible = "ucc_geth";
+ 			model = "UCC";
++			cell-index = <3>;
+ 			device-id = <3>;
+ 			reg = <2200 200>;
+ 			interrupts = <22>;
+ 			interrupt-parent = < &qeic >;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+-			rx-clock = <19>;
+-			tx-clock = <1a>;
++			rx-clock-name = "clk9";
++			tx-clock-name = "clk10";
+ 			phy-handle = < &phy3 >;
+ 			pio-handle = < &pio3 >;
+ 		};
+ 
+-		ucc@3200 {
++		enet1: ucc@3200 {
+ 			device_type = "network";
+ 			compatible = "ucc_geth";
+ 			model = "UCC";
++			cell-index = <4>;
+ 			device-id = <4>;
+ 			reg = <3200 200>;
+ 			interrupts = <23>;
+ 			interrupt-parent = < &qeic >;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+-			rx-clock = <17>;
+-			tx-clock = <18>;
++			rx-clock-name = "clk7";
++			tx-clock-name = "clk8";
+ 			phy-handle = < &phy4 >;
+ 			pio-handle = < &pio4 >;
+ 		};
+ 
++		ucc@2400 {
++			device_type = "serial";
++			compatible = "ucc_uart";
++			model = "UCC";
++			device-id = <5>;	/* The UCC number, 1-7*/
++			port-number = <0>;	/* Which ttyQEx device */
++			soft-uart;		/* We need Soft-UART */
++			reg = <2400 200>;
++			interrupts = <28>;	/* From Table 18-12 */
++			interrupt-parent = < &qeic >;
++			/*
++			 * For Soft-UART, we need to set TX to 1X, which
++			 * means specifying separate clock sources.
++			 */
++			rx-clock-name = "brg5";
++			tx-clock-name = "brg6";
++			pio-handle = < &pio5 >;
++		};
++
++
+ 		mdio@2320 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+@@ -283,7 +332,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008500 {
++	pci0: pci@e0008500 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 				/* IDSEL 0x11 AD17 */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc832x_rdb.dts powerpc.git/arch/powerpc/boot/dts/mpc832x_rdb.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc832x_rdb.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc832x_rdb.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -15,6 +15,14 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -52,7 +60,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <e 8>;
+@@ -60,7 +70,8 @@
+ 			dfsrr;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -69,7 +80,8 @@
+ 			interrupt-parent = <&pic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -187,44 +199,34 @@
+ 			mode = "cpu";
+ 		};
+ 
+-		ucc@3000 {
++		enet0: ucc@3000 {
+ 			device_type = "network";
+ 			compatible = "ucc_geth";
+ 			model = "UCC";
++			cell-index = <2>;
+ 			device-id = <2>;
+ 			reg = <3000 200>;
+ 			interrupts = <21>;
+ 			interrupt-parent = <&qeic>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+-			rx-clock = <20>;
+-			tx-clock = <13>;
++			rx-clock-name = "clk16";
++			tx-clock-name = "clk3";
+ 			phy-handle = <&phy00>;
+ 			pio-handle = <&ucc2pio>;
+ 		};
+ 
+-		ucc@2200 {
++		enet1: ucc@2200 {
+ 			device_type = "network";
+ 			compatible = "ucc_geth";
+ 			model = "UCC";
++			cell-index = <3>;
+ 			device-id = <3>;
+ 			reg = <2200 200>;
+ 			interrupts = <22>;
+ 			interrupt-parent = <&qeic>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+-			rx-clock = <19>;
+-			tx-clock = <1a>;
++			rx-clock-name = "clk9";
++			tx-clock-name = "clk10";
+ 			phy-handle = <&phy04>;
+ 			pio-handle = <&ucc3pio>;
+ 		};
+@@ -262,7 +264,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008500 {
++	pci0: pci@e0008500 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 				/* IDSEL 0x10 AD16 (USB) */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8349emitx.dts powerpc.git/arch/powerpc/boot/dts/mpc8349emitx.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8349emitx.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8349emitx.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -14,6 +14,15 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -51,7 +60,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <e 8>;
+@@ -60,7 +71,9 @@
+ 		};
+ 
+ 		i2c@3100 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <f 8>;
+@@ -78,7 +91,6 @@
+ 		};
+ 
+ 		usb@22000 {
+-			device_type = "usb";
+ 			compatible = "fsl-usb2-mph";
+ 			reg = <22000 1000>;
+ 			#address-cells = <1>;
+@@ -90,7 +102,6 @@
+ 		};
+ 
+ 		usb@23000 {
+-			device_type = "usb";
+ 			compatible = "fsl-usb2-dr";
+ 			reg = <23000 1000>;
+ 			#address-cells = <1>;
+@@ -102,11 +113,10 @@
+ 		};
+ 
+ 		mdio@24520 {
+-			device_type = "mdio";
+-			compatible = "gianfar";
+-			reg = <24520 20>;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			compatible = "fsl,gianfar-mdio";
++			reg = <24520 20>;
+ 
+ 			/* Vitesse 8201 */
+ 			phy1c: ethernet-phy@1c {
+@@ -115,27 +125,14 @@
+ 				reg = <1c>;
+ 				device_type = "ethernet-phy";
+ 			};
+-
+-			/* Vitesse 7385 */
+-			phy1f: ethernet-phy@1f {
+-				interrupt-parent = < &ipic >;
+-				interrupts = <12 8>;
+-				reg = <1f>;
+-				device_type = "ethernet-phy";
+-			};
+ 		};
+ 
+-		ethernet@24000 {
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <24000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <20 8 21 8 22 8>;
+ 			interrupt-parent = < &ipic >;
+@@ -143,27 +140,22 @@
+ 			linux,network-index = <0>;
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <25000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <23 8 24 8 25 8>;
+ 			interrupt-parent = < &ipic >;
+-			phy-handle = < &phy1f >;
++			/* Vitesse 7385 isn't on the MDIO bus */
++			fixed-link = <1 1 d#1000 0 0>;
+ 			linux,network-index = <1>;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -172,7 +164,8 @@
+ 			interrupt-parent = < &ipic >;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -203,7 +196,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008500 {
++	pci0: pci@e0008500 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 				/* IDSEL 0x10 - SATA */
+@@ -224,7 +218,8 @@
+ 		device_type = "pci";
+ 	};
+ 
+-	pci@e0008600 {
++	pci1: pci@e0008600 {
++		cell-index = <2>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 				/* IDSEL 0x0E - MiniPCI Slot */
+@@ -249,6 +244,21 @@
+ 		device_type = "pci";
+ 	};
+ 
+-
+-
++	localbus@e0005000 {
++		#address-cells = <2>;
++		#size-cells = <1>;
++		compatible = "fsl,mpc8349e-localbus",
++			     "fsl,pq2pro-localbus";
++		reg = <e0005000 d8>;
++		ranges = <3 0 f0000000 210>;
++
++		pata@3,0 {
++			compatible = "fsl,mpc8349emitx-pata", "ata-generic";
++			reg = <3 0 10 3 20c 4>;
++			reg-shift = <1>;
++			pio-mode = <6>;
++			interrupts = <17 8>;
++			interrupt-parent = <&ipic>;
++		};
++	};
+ };
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8349emitxgp.dts powerpc.git/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8349emitxgp.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8349emitxgp.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -14,6 +14,13 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -51,7 +58,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <e 8>;
+@@ -60,7 +69,9 @@
+ 		};
+ 
+ 		i2c@3100 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <f 8>;
+@@ -78,7 +89,6 @@
+ 		};
+ 
+ 		usb@23000 {
+-			device_type = "usb";
+ 			compatible = "fsl-usb2-dr";
+ 			reg = <23000 1000>;
+ 			#address-cells = <1>;
+@@ -90,11 +100,10 @@
+ 		};
+ 
+ 		mdio@24520 {
+-			device_type = "mdio";
+-			compatible = "gianfar";
+-			reg = <24520 20>;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			compatible = "fsl,gianfar-mdio";
++			reg = <24520 20>;
+ 
+ 			/* Vitesse 8201 */
+ 			phy1c: ethernet-phy@1c {
+@@ -105,7 +114,8 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+@@ -117,7 +127,8 @@
+ 			linux,network-index = <0>;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -126,7 +137,8 @@
+ 			interrupt-parent = < &ipic >;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -157,7 +169,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008600 {
++	pci0: pci@e0008600 {
++		cell-index = <2>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 				/* IDSEL 0x0F - PCI Slot */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc834x_mds.dts powerpc.git/arch/powerpc/boot/dts/mpc834x_mds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc834x_mds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc834x_mds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -15,6 +15,15 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -59,7 +68,7 @@
+ 		i2c@3000 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <e 8>;
+@@ -75,7 +84,7 @@
+ 		i2c@3100 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <1>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <f 8>;
+@@ -95,7 +104,6 @@
+ 		/* phy type (ULPI or SERIAL) are only types supportted for MPH */
+ 		/* port = 0 or 1 */
+ 		usb@22000 {
+-			device_type = "usb";
+ 			compatible = "fsl-usb2-mph";
+ 			reg = <22000 1000>;
+ 			#address-cells = <1>;
+@@ -107,7 +115,6 @@
+ 		};
+ 		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
+ 		usb@23000 {
+-			device_type = "usb";
+ 			compatible = "fsl-usb2-dr";
+ 			reg = <23000 1000>;
+ 			#address-cells = <1>;
+@@ -119,11 +126,11 @@
+ 		};
+ 
+ 		mdio@24520 {
+-			device_type = "mdio";
+-			compatible = "gianfar";
+-			reg = <24520 20>;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			compatible = "fsl,gianfar-mdio";
++			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = < &ipic >;
+ 				interrupts = <11 8>;
+@@ -138,17 +145,12 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <24000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <20 8 21 8 22 8>;
+ 			interrupt-parent = < &ipic >;
+@@ -156,19 +158,12 @@
+ 			linux,network-index = <0>;
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <25000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <23 8 24 8 25 8>;
+ 			interrupt-parent = < &ipic >;
+@@ -176,7 +171,8 @@
+ 			linux,network-index = <1>;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -185,7 +181,8 @@
+ 			interrupt-parent = < &ipic >;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -225,7 +222,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008500 {
++	pci0: pci@e0008500 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+@@ -285,7 +283,8 @@
+ 		device_type = "pci";
+ 	};
+ 
+-	pci@e0008600 {
++	pci1: pci@e0008600 {
++		cell-index = <2>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc836x_mds.dts powerpc.git/arch/powerpc/boot/dts/mpc836x_mds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc836x_mds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc836x_mds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -20,6 +20,14 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -64,7 +72,7 @@
+ 		i2c@3000 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <e 8>;
+@@ -80,7 +88,7 @@
+ 		i2c@3100 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <1>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <f 8>;
+@@ -88,7 +96,8 @@
+ 			dfsrr;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -97,7 +106,8 @@
+ 			interrupt-parent = < &ipic >;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -231,7 +241,6 @@
+ 		};
+ 
+ 		usb@6c0 {
+-			device_type = "usb";
+ 			compatible = "qe_udc";
+ 			reg = <6c0 40 8B00 100>;
+ 			interrupts = <b>;
+@@ -239,45 +248,35 @@
+ 			mode = "slave";
+ 		};
+ 
+-		ucc@2000 {
++		enet0: ucc@2000 {
+ 			device_type = "network";
+ 			compatible = "ucc_geth";
+ 			model = "UCC";
++			cell-index = <1>;
+ 			device-id = <1>;
+ 			reg = <2000 200>;
+ 			interrupts = <20>;
+ 			interrupt-parent = < &qeic >;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+-			rx-clock = <0>;
+-			tx-clock = <19>;
++			rx-clock-name = "none";
++			tx-clock-name = "clk9";
+ 			phy-handle = < &phy0 >;
+ 			phy-connection-type = "rgmii-id";
+ 			pio-handle = < &pio1 >;
+ 		};
+ 
+-		ucc@3000 {
++		enet1: ucc@3000 {
+ 			device_type = "network";
+ 			compatible = "ucc_geth";
+ 			model = "UCC";
++			cell-index = <2>;
+ 			device-id = <2>;
+ 			reg = <3000 200>;
+ 			interrupts = <21>;
+ 			interrupt-parent = < &qeic >;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+-			rx-clock = <0>;
+-			tx-clock = <14>;
++			rx-clock-name = "none";
++			tx-clock-name = "clk4";
+ 			phy-handle = < &phy1 >;
+ 			phy-connection-type = "rgmii-id";
+ 			pio-handle = < &pio2 >;
+@@ -316,7 +315,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008500 {
++	pci0: pci@e0008500 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8377_mds.dts powerpc.git/arch/powerpc/boot/dts/mpc8377_mds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8377_mds.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8377_mds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,279 @@
++/*
++ * MPC8377E MDS Device Tree Source
++ *
++ * Copyright 2007 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.
++ */
++
++/dts-v1/;
++
++/ {
++	model = "fsl,mpc8377emds";
++	compatible = "fsl,mpc8377emds","fsl,mpc837xmds";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,8377@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <0x20>;
++			i-cache-line-size = <0x20>;
++			d-cache-size = <0x8000>;		// L1, 32K
++			i-cache-size = <0x8000>;		// L1, 32K
++			timebase-frequency = <0>;
++			bus-frequency = <0>;
++			clock-frequency = <0>;
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0x00000000 0x20000000>;	// 512MB at 0
++	};
++
++	soc@e0000000 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		device_type = "soc";
++		ranges = <0x0 0xe0000000 0x00100000>;
++		reg = <0xe0000000 0x00000200>;
++		bus-frequency = <0>;
++
++		wdt@200 {
++			compatible = "mpc83xx_wdt";
++			reg = <0x200 0x100>;
++		};
++
++		i2c@3000 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
++			compatible = "fsl-i2c";
++			reg = <0x3000 0x100>;
++			interrupts = <0xe 0x8>;
++			interrupt-parent = < &ipic >;
++			dfsrr;
++		};
++
++		i2c@3100 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
++			compatible = "fsl-i2c";
++			reg = <0x3100 0x100>;
++			interrupts = <0xf 0x8>;
++			interrupt-parent = < &ipic >;
++			dfsrr;
++		};
++
++		spi@7000 {
++			compatible = "fsl_spi";
++			reg = <0x7000 0x1000>;
++			interrupts = <0x10 0x8>;
++			interrupt-parent = < &ipic >;
++			mode = "cpu";
++		};
++
++		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
++		usb@23000 {
++			compatible = "fsl-usb2-dr";
++			reg = <0x23000 0x1000>;
++			#address-cells = <1>;
++			#size-cells = <0>;
++			interrupt-parent = < &ipic >;
++			interrupts = <0x26 0x8>;
++			phy_type = "utmi_wide";
++		};
++
++		mdio@24520 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			compatible = "fsl,gianfar-mdio";
++			reg = <0x24520 0x20>;
++			phy2: ethernet-phy@2 {
++				interrupt-parent = < &ipic >;
++				interrupts = <0x11 0x8>;
++				reg = <2>;
++				device_type = "ethernet-phy";
++			};
++			phy3: ethernet-phy@3 {
++				interrupt-parent = < &ipic >;
++				interrupts = <0x12 0x8>;
++				reg = <3>;
++				device_type = "ethernet-phy";
++			};
++		};
++
++		enet0: ethernet@24000 {
++			cell-index = <0>;
++			device_type = "network";
++			model = "eTSEC";
++			compatible = "gianfar";
++			reg = <0x24000 0x1000>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <0x20 0x8 0x21 0x8 0x22 0x8>;
++			phy-connection-type = "mii";
++			interrupt-parent = < &ipic >;
++			phy-handle = < &phy2 >;
++		};
++
++		enet1: ethernet@25000 {
++			cell-index = <1>;
++			device_type = "network";
++			model = "eTSEC";
++			compatible = "gianfar";
++			reg = <0x25000 0x1000>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <0x23 0x8 0x24 0x8 0x25 0x8>;
++			phy-connection-type = "mii";
++			interrupt-parent = < &ipic >;
++			phy-handle = < &phy3 >;
++		};
++
++		serial0: serial@4500 {
++			cell-index = <0>;
++			device_type = "serial";
++			compatible = "ns16550";
++			reg = <0x4500 0x100>;
++			clock-frequency = <0>;
++			interrupts = <0x9 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		serial1: serial@4600 {
++			cell-index = <1>;
++			device_type = "serial";
++			compatible = "ns16550";
++			reg = <0x4600 0x100>;
++			clock-frequency = <0>;
++			interrupts = <0xa 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		crypto@30000 {
++			model = "SEC3";
++			compatible = "talitos";
++			reg = <0x30000 0x10000>;
++			interrupts = <0xb 0x8>;
++			interrupt-parent = < &ipic >;
++			/* Rev. 3.0 geometry */
++			num-channels = <4>;
++			channel-fifo-len = <0x18>;
++			exec-units-mask = <0x000001fe>;
++			descriptor-types-mask = <0x03ab0ebf>;
++		};
++
++		sdhc@2e000 {
++			model = "eSDHC";
++			compatible = "fsl,esdhc";
++			reg = <0x2e000 0x1000>;
++			interrupts = <0x2a 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		sata@18000 {
++			compatible = "fsl,mpc8379-sata";
++			reg = <0x18000 0x1000>;
++			interrupts = <0x2c 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		sata@19000 {
++			compatible = "fsl,mpc8379-sata";
++			reg = <0x19000 0x1000>;
++			interrupts = <0x2d 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		/* IPIC
++		 * interrupts cell = <intr #, sense>
++		 * sense values match linux IORESOURCE_IRQ_* defines:
++		 * sense == 8: Level, low assertion
++		 * sense == 2: Edge, high-to-low change
++		 */
++		ipic: pic@700 {
++			compatible = "fsl,ipic";
++			interrupt-controller;
++			#address-cells = <0>;
++			#interrupt-cells = <2>;
++			reg = <0x700 0x100>;
++		};
++	};
++
++	pci0: pci@e0008500 {
++		cell-index = <0>;
++		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
++		interrupt-map = <
++
++				/* IDSEL 0x11 */
++				 0x8800 0x0 0x0 0x1 &ipic 0x14 0x8
++				 0x8800 0x0 0x0 0x2 &ipic 0x15 0x8
++				 0x8800 0x0 0x0 0x3 &ipic 0x16 0x8
++				 0x8800 0x0 0x0 0x4 &ipic 0x17 0x8
++
++				/* IDSEL 0x12 */
++				 0x9000 0x0 0x0 0x1 &ipic 0x16 0x8
++				 0x9000 0x0 0x0 0x2 &ipic 0x17 0x8
++				 0x9000 0x0 0x0 0x3 &ipic 0x14 0x8
++				 0x9000 0x0 0x0 0x4 &ipic 0x15 0x8
++
++				/* IDSEL 0x13 */
++				 0x9800 0x0 0x0 0x1 &ipic 0x17 0x8
++				 0x9800 0x0 0x0 0x2 &ipic 0x14 0x8
++				 0x9800 0x0 0x0 0x3 &ipic 0x15 0x8
++				 0x9800 0x0 0x0 0x4 &ipic 0x16 0x8
++
++				/* IDSEL 0x15 */
++				 0xa800 0x0 0x0 0x1 &ipic 0x14 0x8
++				 0xa800 0x0 0x0 0x2 &ipic 0x15 0x8
++				 0xa800 0x0 0x0 0x3 &ipic 0x16 0x8
++				 0xa800 0x0 0x0 0x4 &ipic 0x17 0x8
++
++				/* IDSEL 0x16 */
++				 0xb000 0x0 0x0 0x1 &ipic 0x17 0x8
++				 0xb000 0x0 0x0 0x2 &ipic 0x14 0x8
++				 0xb000 0x0 0x0 0x3 &ipic 0x15 0x8
++				 0xb000 0x0 0x0 0x4 &ipic 0x16 0x8
++
++				/* IDSEL 0x17 */
++				 0xb800 0x0 0x0 0x1 &ipic 0x16 0x8
++				 0xb800 0x0 0x0 0x2 &ipic 0x17 0x8
++				 0xb800 0x0 0x0 0x3 &ipic 0x14 0x8
++				 0xb800 0x0 0x0 0x4 &ipic 0x15 0x8
++
++				/* IDSEL 0x18 */
++				 0xc000 0x0 0x0 0x1 &ipic 0x15 0x8
++				 0xc000 0x0 0x0 0x2 &ipic 0x16 0x8
++				 0xc000 0x0 0x0 0x3 &ipic 0x17 0x8
++				 0xc000 0x0 0x0 0x4 &ipic 0x14 0x8>;
++		interrupt-parent = < &ipic >;
++		interrupts = <0x42 0x8>;
++		bus-range = <0 0>;
++		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
++		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
++		          0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
++		clock-frequency = <0>;
++		#interrupt-cells = <1>;
++		#size-cells = <2>;
++		#address-cells = <3>;
++		reg = <0xe0008500 0x100>;
++		compatible = "fsl,mpc8349-pci";
++		device_type = "pci";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8378_mds.dts powerpc.git/arch/powerpc/boot/dts/mpc8378_mds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8378_mds.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8378_mds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,265 @@
++/*
++ * MPC8378E MDS Device Tree Source
++ *
++ * Copyright 2007 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.
++ */
++
++/dts-v1/;
++
++/ {
++	model = "fsl,mpc8378emds";
++	compatible = "fsl,mpc8378emds","fsl,mpc837xmds";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,8378@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <0x20>;
++			i-cache-line-size = <0x20>;
++			d-cache-size = <0x8000>;		// L1, 32K
++			i-cache-size = <0x8000>;		// L1, 32K
++			timebase-frequency = <0>;
++			bus-frequency = <0>;
++			clock-frequency = <0>;
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0x00000000 0x20000000>;	// 512MB at 0
++	};
++
++	soc@e0000000 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		device_type = "soc";
++		ranges = <0x0 0xe0000000 0x00100000>;
++		reg = <0xe0000000 0x00000200>;
++		bus-frequency = <0>;
++
++		wdt@200 {
++			compatible = "mpc83xx_wdt";
++			reg = <0x200 0x100>;
++		};
++
++		i2c@3000 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
++			compatible = "fsl-i2c";
++			reg = <0x3000 0x100>;
++			interrupts = <0xe 0x8>;
++			interrupt-parent = < &ipic >;
++			dfsrr;
++		};
++
++		i2c@3100 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
++			compatible = "fsl-i2c";
++			reg = <0x3100 0x100>;
++			interrupts = <0xf 0x8>;
++			interrupt-parent = < &ipic >;
++			dfsrr;
++		};
++
++		spi@7000 {
++			compatible = "fsl_spi";
++			reg = <0x7000 0x1000>;
++			interrupts = <0x10 0x8>;
++			interrupt-parent = < &ipic >;
++			mode = "cpu";
++		};
++
++		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
++		usb@23000 {
++			compatible = "fsl-usb2-dr";
++			reg = <0x23000 0x1000>;
++			#address-cells = <1>;
++			#size-cells = <0>;
++			interrupt-parent = < &ipic >;
++			interrupts = <0x26 0x8>;
++			phy_type = "utmi_wide";
++		};
++
++		mdio@24520 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			compatible = "fsl,gianfar-mdio";
++			reg = <0x24520 0x20>;
++			phy2: ethernet-phy@2 {
++				interrupt-parent = < &ipic >;
++				interrupts = <0x11 0x8>;
++				reg = <2>;
++				device_type = "ethernet-phy";
++			};
++			phy3: ethernet-phy@3 {
++				interrupt-parent = < &ipic >;
++				interrupts = <0x12 0x8>;
++				reg = <3>;
++				device_type = "ethernet-phy";
++			};
++		};
++
++		enet0: ethernet@24000 {
++			cell-index = <0>;
++			device_type = "network";
++			model = "eTSEC";
++			compatible = "gianfar";
++			reg = <0x24000 0x1000>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <0x20 0x8 0x21 0x8 0x22 0x8>;
++			phy-connection-type = "mii";
++			interrupt-parent = < &ipic >;
++			phy-handle = < &phy2 >;
++		};
++
++		enet1: ethernet@25000 {
++			cell-index = <1>;
++			device_type = "network";
++			model = "eTSEC";
++			compatible = "gianfar";
++			reg = <0x25000 0x1000>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <0x23 0x8 0x24 0x8 0x25 0x8>;
++			phy-connection-type = "mii";
++			interrupt-parent = < &ipic >;
++			phy-handle = < &phy3 >;
++		};
++
++		serial0: serial@4500 {
++			cell-index = <0>;
++			device_type = "serial";
++			compatible = "ns16550";
++			reg = <0x4500 0x100>;
++			clock-frequency = <0>;
++			interrupts = <0x9 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		serial1: serial@4600 {
++			cell-index = <1>;
++			device_type = "serial";
++			compatible = "ns16550";
++			reg = <0x4600 0x100>;
++			clock-frequency = <0>;
++			interrupts = <0xa 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		crypto@30000 {
++			model = "SEC3";
++			compatible = "talitos";
++			reg = <0x30000 0x10000>;
++			interrupts = <0xb 0x8>;
++			interrupt-parent = < &ipic >;
++			/* Rev. 3.0 geometry */
++			num-channels = <4>;
++			channel-fifo-len = <0x18>;
++			exec-units-mask = <0x000001fe>;
++			descriptor-types-mask = <0x03ab0ebf>;
++		};
++
++		sdhc@2e000 {
++			model = "eSDHC";
++			compatible = "fsl,esdhc";
++			reg = <0x2e000 0x1000>;
++			interrupts = <0x2a 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		/* IPIC
++		 * interrupts cell = <intr #, sense>
++		 * sense values match linux IORESOURCE_IRQ_* defines:
++		 * sense == 8: Level, low assertion
++		 * sense == 2: Edge, high-to-low change
++		 */
++		ipic: pic@700 {
++			compatible = "fsl,ipic";
++			interrupt-controller;
++			#address-cells = <0>;
++			#interrupt-cells = <2>;
++			reg = <0x700 0x100>;
++		};
++	};
++
++	pci0: pci@e0008500 {
++		cell-index = <0>;
++		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
++		interrupt-map = <
++
++				/* IDSEL 0x11 */
++				 0x8800 0x0 0x0 0x1 &ipic 0x14 0x8
++				 0x8800 0x0 0x0 0x2 &ipic 0x15 0x8
++				 0x8800 0x0 0x0 0x3 &ipic 0x16 0x8
++				 0x8800 0x0 0x0 0x4 &ipic 0x17 0x8
++
++				/* IDSEL 0x12 */
++				 0x9000 0x0 0x0 0x1 &ipic 0x16 0x8
++				 0x9000 0x0 0x0 0x2 &ipic 0x17 0x8
++				 0x9000 0x0 0x0 0x3 &ipic 0x14 0x8
++				 0x9000 0x0 0x0 0x4 &ipic 0x15 0x8
++
++				/* IDSEL 0x13 */
++				 0x9800 0x0 0x0 0x1 &ipic 0x17 0x8
++				 0x9800 0x0 0x0 0x2 &ipic 0x14 0x8
++				 0x9800 0x0 0x0 0x3 &ipic 0x15 0x8
++				 0x9800 0x0 0x0 0x4 &ipic 0x16 0x8
++
++				/* IDSEL 0x15 */
++				 0xa800 0x0 0x0 0x1 &ipic 0x14 0x8
++				 0xa800 0x0 0x0 0x2 &ipic 0x15 0x8
++				 0xa800 0x0 0x0 0x3 &ipic 0x16 0x8
++				 0xa800 0x0 0x0 0x4 &ipic 0x17 0x8
++
++				/* IDSEL 0x16 */
++				 0xb000 0x0 0x0 0x1 &ipic 0x17 0x8
++				 0xb000 0x0 0x0 0x2 &ipic 0x14 0x8
++				 0xb000 0x0 0x0 0x3 &ipic 0x15 0x8
++				 0xb000 0x0 0x0 0x4 &ipic 0x16 0x8
++
++				/* IDSEL 0x17 */
++				 0xb800 0x0 0x0 0x1 &ipic 0x16 0x8
++				 0xb800 0x0 0x0 0x2 &ipic 0x17 0x8
++				 0xb800 0x0 0x0 0x3 &ipic 0x14 0x8
++				 0xb800 0x0 0x0 0x4 &ipic 0x15 0x8
++
++				/* IDSEL 0x18 */
++				 0xc000 0x0 0x0 0x1 &ipic 0x15 0x8
++				 0xc000 0x0 0x0 0x2 &ipic 0x16 0x8
++				 0xc000 0x0 0x0 0x3 &ipic 0x17 0x8
++				 0xc000 0x0 0x0 0x4 &ipic 0x14 0x8>;
++		interrupt-parent = < &ipic >;
++		interrupts = <0x42 0x8>;
++		bus-range = <0 0>;
++		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
++		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
++		          0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
++		clock-frequency = <0>;
++		#interrupt-cells = <1>;
++		#size-cells = <2>;
++		#address-cells = <3>;
++		reg = <0xe0008500 0x100>;
++		compatible = "fsl,mpc8349-pci";
++		device_type = "pci";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8379_mds.dts powerpc.git/arch/powerpc/boot/dts/mpc8379_mds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8379_mds.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8379_mds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,293 @@
++/*
++ * MPC8379E MDS Device Tree Source
++ *
++ * Copyright 2007 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.
++ */
++
++/dts-v1/;
++
++/ {
++	model = "fsl,mpc8379emds";
++	compatible = "fsl,mpc8379emds","fsl,mpc837xmds";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,8379@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <0x20>;
++			i-cache-line-size = <0x20>;
++			d-cache-size = <0x8000>;		// L1, 32K
++			i-cache-size = <0x8000>;		// L1, 32K
++			timebase-frequency = <0>;
++			bus-frequency = <0>;
++			clock-frequency = <0>;
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0x00000000 0x20000000>;	// 512MB at 0
++	};
++
++	soc@e0000000 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		device_type = "soc";
++		ranges = <0x0 0xe0000000 0x00100000>;
++		reg = <0xe0000000 0x00000200>;
++		bus-frequency = <0>;
++
++		wdt@200 {
++			compatible = "mpc83xx_wdt";
++			reg = <0x200 0x100>;
++		};
++
++		i2c@3000 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
++			compatible = "fsl-i2c";
++			reg = <0x3000 0x100>;
++			interrupts = <0xe 0x8>;
++			interrupt-parent = < &ipic >;
++			dfsrr;
++		};
++
++		i2c@3100 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
++			compatible = "fsl-i2c";
++			reg = <0x3100 0x100>;
++			interrupts = <0xf 0x8>;
++			interrupt-parent = < &ipic >;
++			dfsrr;
++		};
++
++		spi@7000 {
++			compatible = "fsl_spi";
++			reg = <0x7000 0x1000>;
++			interrupts = <0x10 0x8>;
++			interrupt-parent = < &ipic >;
++			mode = "cpu";
++		};
++
++		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
++		usb@23000 {
++			compatible = "fsl-usb2-dr";
++			reg = <0x23000 0x1000>;
++			#address-cells = <1>;
++			#size-cells = <0>;
++			interrupt-parent = < &ipic >;
++			interrupts = <0x26 0x8>;
++			phy_type = "utmi_wide";
++		};
++
++		mdio@24520 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			compatible = "fsl,gianfar-mdio";
++			reg = <0x24520 0x20>;
++			phy2: ethernet-phy@2 {
++				interrupt-parent = < &ipic >;
++				interrupts = <0x11 0x8>;
++				reg = <2>;
++				device_type = "ethernet-phy";
++			};
++			phy3: ethernet-phy@3 {
++				interrupt-parent = < &ipic >;
++				interrupts = <0x12 0x8>;
++				reg = <3>;
++				device_type = "ethernet-phy";
++			};
++		};
++
++		enet0: ethernet@24000 {
++			cell-index = <0>;
++			device_type = "network";
++			model = "eTSEC";
++			compatible = "gianfar";
++			reg = <0x24000 0x1000>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <0x20 0x8 0x21 0x8 0x22 0x8>;
++			phy-connection-type = "mii";
++			interrupt-parent = < &ipic >;
++			phy-handle = < &phy2 >;
++		};
++
++		enet1: ethernet@25000 {
++			cell-index = <1>;
++			device_type = "network";
++			model = "eTSEC";
++			compatible = "gianfar";
++			reg = <0x25000 0x1000>;
++			local-mac-address = [ 00 00 00 00 00 00 ];
++			interrupts = <0x23 0x8 0x24 0x8 0x25 0x8>;
++			phy-connection-type = "mii";
++			interrupt-parent = < &ipic >;
++			phy-handle = < &phy3 >;
++		};
++
++		serial0: serial@4500 {
++			cell-index = <0>;
++			device_type = "serial";
++			compatible = "ns16550";
++			reg = <0x4500 0x100>;
++			clock-frequency = <0>;
++			interrupts = <0x9 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		serial1: serial@4600 {
++			cell-index = <1>;
++			device_type = "serial";
++			compatible = "ns16550";
++			reg = <0x4600 0x100>;
++			clock-frequency = <0>;
++			interrupts = <0xa 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		crypto@30000 {
++			model = "SEC3";
++			compatible = "talitos";
++			reg = <0x30000 0x10000>;
++			interrupts = <0xb 0x8>;
++			interrupt-parent = < &ipic >;
++			/* Rev. 3.0 geometry */
++			num-channels = <4>;
++			channel-fifo-len = <0x18>;
++			exec-units-mask = <0x000001fe>;
++			descriptor-types-mask = <0x03ab0ebf>;
++		};
++
++		sdhc@2e000 {
++			model = "eSDHC";
++			compatible = "fsl,esdhc";
++			reg = <0x2e000 0x1000>;
++			interrupts = <0x2a 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		sata@18000 {
++			compatible = "fsl,mpc8379-sata";
++			reg = <0x18000 0x1000>;
++			interrupts = <0x2c 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		sata@19000 {
++			compatible = "fsl,mpc8379-sata";
++			reg = <0x19000 0x1000>;
++			interrupts = <0x2d 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		sata@1a000 {
++			compatible = "fsl,mpc8379-sata";
++			reg = <0x1a000 0x1000>;
++			interrupts = <0x2e 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		sata@1b000 {
++			compatible = "fsl,mpc8379-sata";
++			reg = <0x1b000 0x1000>;
++			interrupts = <0x2f 0x8>;
++			interrupt-parent = < &ipic >;
++		};
++
++		/* IPIC
++		 * interrupts cell = <intr #, sense>
++		 * sense values match linux IORESOURCE_IRQ_* defines:
++		 * sense == 8: Level, low assertion
++		 * sense == 2: Edge, high-to-low change
++		 */
++		ipic: pic@700 {
++			compatible = "fsl,ipic";
++			interrupt-controller;
++			#address-cells = <0>;
++			#interrupt-cells = <2>;
++			reg = <0x700 0x100>;
++		};
++	};
++
++	pci0: pci@e0008500 {
++		cell-index = <0>;
++		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
++		interrupt-map = <
++
++				/* IDSEL 0x11 */
++				 0x8800 0x0 0x0 0x1 &ipic 0x14 0x8
++				 0x8800 0x0 0x0 0x2 &ipic 0x15 0x8
++				 0x8800 0x0 0x0 0x3 &ipic 0x16 0x8
++				 0x8800 0x0 0x0 0x4 &ipic 0x17 0x8
++
++				/* IDSEL 0x12 */
++				 0x9000 0x0 0x0 0x1 &ipic 0x16 0x8
++				 0x9000 0x0 0x0 0x2 &ipic 0x17 0x8
++				 0x9000 0x0 0x0 0x3 &ipic 0x14 0x8
++				 0x9000 0x0 0x0 0x4 &ipic 0x15 0x8
++
++				/* IDSEL 0x13 */
++				 0x9800 0x0 0x0 0x1 &ipic 0x17 0x8
++				 0x9800 0x0 0x0 0x2 &ipic 0x14 0x8
++				 0x9800 0x0 0x0 0x3 &ipic 0x15 0x8
++				 0x9800 0x0 0x0 0x4 &ipic 0x16 0x8
++
++				/* IDSEL 0x15 */
++				 0xa800 0x0 0x0 0x1 &ipic 0x14 0x8
++				 0xa800 0x0 0x0 0x2 &ipic 0x15 0x8
++				 0xa800 0x0 0x0 0x3 &ipic 0x16 0x8
++				 0xa800 0x0 0x0 0x4 &ipic 0x17 0x8
++
++				/* IDSEL 0x16 */
++				 0xb000 0x0 0x0 0x1 &ipic 0x17 0x8
++				 0xb000 0x0 0x0 0x2 &ipic 0x14 0x8
++				 0xb000 0x0 0x0 0x3 &ipic 0x15 0x8
++				 0xb000 0x0 0x0 0x4 &ipic 0x16 0x8
++
++				/* IDSEL 0x17 */
++				 0xb800 0x0 0x0 0x1 &ipic 0x16 0x8
++				 0xb800 0x0 0x0 0x2 &ipic 0x17 0x8
++				 0xb800 0x0 0x0 0x3 &ipic 0x14 0x8
++				 0xb800 0x0 0x0 0x4 &ipic 0x15 0x8
++
++				/* IDSEL 0x18 */
++				 0xc000 0x0 0x0 0x1 &ipic 0x15 0x8
++				 0xc000 0x0 0x0 0x2 &ipic 0x16 0x8
++				 0xc000 0x0 0x0 0x3 &ipic 0x17 0x8
++				 0xc000 0x0 0x0 0x4 &ipic 0x14 0x8>;
++		interrupt-parent = < &ipic >;
++		interrupts = <0x42 0x8>;
++		bus-range = <0 0>;
++		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
++		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
++		          0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
++		clock-frequency = <0>;
++		#interrupt-cells = <1>;
++		#size-cells = <2>;
++		#address-cells = <3>;
++		reg = <0xe0008500 0x100>;
++		compatible = "fsl,mpc8349-pci";
++		device_type = "pci";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8540ads.dts powerpc.git/arch/powerpc/boot/dts/mpc8540ads.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8540ads.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8540ads.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -16,6 +16,15 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		ethernet2 = &enet2;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -63,7 +72,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+@@ -74,9 +85,9 @@
+ 		mdio@24520 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "mdio";
+-			compatible = "gianfar";
++			compatible = "fsl,gianfar-mdio";
+ 			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <5 1>;
+@@ -97,64 +108,44 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <24000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <1d 2 1e 2 22 2>;
+ 			interrupt-parent = <&mpic>;
+ 			phy-handle = <&phy0>;
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <25000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <23 2 24 2 28 2>;
+ 			interrupt-parent = <&mpic>;
+ 			phy-handle = <&phy1>;
+ 		};
+ 
+-		ethernet@26000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet2: ethernet@26000 {
++			cell-index = <2>;
+ 			device_type = "network";
+ 			model = "FEC";
+ 			compatible = "gianfar";
+ 			reg = <26000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <29 2>;
+ 			interrupt-parent = <&mpic>;
+ 			phy-handle = <&phy3>;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>; 	// reg base, size
+@@ -163,7 +154,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;	// reg base, size
+@@ -183,7 +175,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008000 {
++	pci0: pci@e0008000 {
++		cell-index = <0>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8541cds.dts powerpc.git/arch/powerpc/boot/dts/mpc8541cds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8541cds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8541cds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -16,6 +16,15 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -63,7 +72,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+@@ -74,9 +85,9 @@
+ 		mdio@24520 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "mdio";
+-			compatible = "gianfar";
++			compatible = "fsl,gianfar-mdio";
+ 			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <5 1>;
+@@ -91,9 +102,8 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+@@ -104,9 +114,8 @@
+ 			phy-handle = <&phy0>;
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+@@ -117,7 +126,8 @@
+ 			phy-handle = <&phy1>;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>; 	// reg base, size
+@@ -126,7 +136,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;	// reg base, size
+@@ -183,7 +194,8 @@
+ 		};
+ 	};
+ 
+-	pci1: pci@e0008000 {
++	pci0: pci@e0008000 {
++		cell-index = <0>;
+ 		interrupt-map-mask = <1f800 0 0 7>;
+ 		interrupt-map = <
+ 
+@@ -250,11 +262,12 @@
+ 			#interrupt-cells = <2>;
+ 			compatible = "chrp,iic";
+ 			interrupts = <1>;
+-			interrupt-parent = <&pci1>;
++			interrupt-parent = <&pci0>;
+ 		};
+ 	};
+ 
+-	pci@e0009000 {
++	pci1: pci@e0009000 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8544ds.dts powerpc.git/arch/powerpc/boot/dts/mpc8544ds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8544ds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8544ds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -15,6 +15,17 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++		pci2 = &pci2;
++		pci3 = &pci3;
++	};
++
+ 	cpus {
+ 		#cpus = <1>;
+ 		#address-cells = <1>;
+@@ -64,7 +75,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+@@ -72,12 +85,23 @@
+ 			dfsrr;
+ 		};
+ 
++		i2c@3100 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
++			compatible = "fsl-i2c";
++			reg = <3100 100>;
++			interrupts = <2b 2>;
++			interrupt-parent = <&mpic>;
++			dfsrr;
++		};
++
+ 		mdio@24520 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "mdio";
+-			compatible = "gianfar";
++			compatible = "fsl,gianfar-mdio";
+ 			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <a 1>;
+@@ -92,9 +116,8 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+@@ -106,9 +129,8 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		ethernet@26000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@26000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+@@ -120,7 +142,8 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -129,7 +152,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -156,7 +180,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008000 {
++	pci0: pci@e0008000 {
++		cell-index = <0>;
+ 		compatible = "fsl,mpc8540-pci";
+ 		device_type = "pci";
+ 		interrupt-map-mask = <f800 0 0 7>;
+@@ -187,7 +212,8 @@
+ 		reg = <e0008000 1000>;
+ 	};
+ 
+-	pcie@e0009000 {
++	pci1: pcie@e0009000 {
++		cell-index = <1>;
+ 		compatible = "fsl,mpc8548-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+@@ -223,7 +249,8 @@
+ 		};
+ 	};
+ 
+-	pcie@e000a000 {
++	pci2: pcie@e000a000 {
++		cell-index = <2>;
+ 		compatible = "fsl,mpc8548-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+@@ -259,7 +286,8 @@
+ 		};
+ 	};
+ 
+-	pcie@e000b000 {
++	pci3: pcie@e000b000 {
++		cell-index = <3>;
+ 		compatible = "fsl,mpc8548-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+@@ -276,9 +304,9 @@
+ 		interrupt-map = <
+ 			// IDSEL 0x1c  USB
+ 			e000 0 0 1 &i8259 c 2
+-			e100 0 0 1 &i8259 9 2
+-			e200 0 0 1 &i8259 a 2
+-			e300 0 0 1 &i8259 b 2
++			e100 0 0 2 &i8259 9 2
++			e200 0 0 3 &i8259 a 2
++			e300 0 0 4 &i8259 b 2
+ 
+ 			// IDSEL 0x1d  Audio
+ 			e800 0 0 1 &i8259 6 2
+@@ -369,6 +397,5 @@
+ 				};
+ 			};
+ 		};
+-
+ 	};
+ };
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8548cds.dts powerpc.git/arch/powerpc/boot/dts/mpc8548cds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8548cds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8548cds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -16,6 +16,20 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++/*
++		ethernet2 = &enet2;
++		ethernet3 = &enet3;
++*/
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++		pci2 = &pci2;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -63,7 +77,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+@@ -71,12 +87,23 @@
+ 			dfsrr;
+ 		};
+ 
++		i2c@3100 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
++			compatible = "fsl-i2c";
++			reg = <3100 100>;
++			interrupts = <2b 2>;
++			interrupt-parent = <&mpic>;
++			dfsrr;
++		};
++
+ 		mdio@24520 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "mdio";
+-			compatible = "gianfar";
++			compatible = "fsl,gianfar-mdio";
+ 			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <5 1>;
+@@ -103,9 +130,8 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -116,9 +142,8 @@
+ 			phy-handle = <&phy0>;
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -130,9 +155,8 @@
+ 		};
+ 
+ /* eTSEC 3/4 are currently broken
+-		ethernet@26000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet2: ethernet@26000 {
++			cell-index = <2>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -143,9 +167,8 @@
+ 			phy-handle = <&phy2>;
+ 		};
+ 
+-		ethernet@27000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet3: ethernet@27000 {
++			cell-index = <3>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -157,7 +180,8 @@
+ 		};
+  */
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;	// reg base, size
+@@ -166,7 +190,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;	// reg base, size
+@@ -193,7 +218,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008000 {
++	pci0: pci@e0008000 {
++		cell-index = <0>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 			/* IDSEL 0x4 (PCIX Slot 2) */
+@@ -342,7 +368,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0009000 {
++	pci1: pci@e0009000 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+@@ -366,7 +393,8 @@
+ 		device_type = "pci";
+ 	};
+ 
+-	pcie@e000a000 {
++	pci2: pcie@e000a000 {
++		cell-index = <2>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8555cds.dts powerpc.git/arch/powerpc/boot/dts/mpc8555cds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8555cds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8555cds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -16,6 +16,15 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -63,7 +72,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+@@ -74,9 +85,9 @@
+ 		mdio@24520 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "mdio";
+-			compatible = "gianfar";
++			compatible = "fsl,gianfar-mdio";
+ 			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <5 1>;
+@@ -91,9 +102,8 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+@@ -104,9 +114,8 @@
+ 			phy-handle = <&phy0>;
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+@@ -117,7 +126,8 @@
+ 			phy-handle = <&phy1>;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>; 	// reg base, size
+@@ -126,7 +136,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;	// reg base, size
+@@ -183,7 +194,8 @@
+ 		};
+ 	};
+ 
+-	pci1: pci@e0008000 {
++	pci0: pci@e0008000 {
++		cell-index = <0>;
+ 		interrupt-map-mask = <1f800 0 0 7>;
+ 		interrupt-map = <
+ 
+@@ -250,11 +262,12 @@
+ 			#interrupt-cells = <2>;
+ 			compatible = "chrp,iic";
+ 			interrupts = <1>;
+-			interrupt-parent = <&pci1>;
++			interrupt-parent = <&pci0>;
+ 		};
+ 	};
+ 
+-	pci@e0009000 {
++	pci1: pci@e0009000 {
++		cell-index = <1>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8560ads.dts powerpc.git/arch/powerpc/boot/dts/mpc8560ads.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8560ads.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8560ads.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -16,6 +16,16 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		ethernet2 = &enet2;
++		ethernet3 = &enet3;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -63,11 +73,11 @@
+ 		};
+ 
+ 		mdio@24520 {
+-			device_type = "mdio";
+-			compatible = "gianfar";
+-			reg = <24520 20>;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			compatible = "fsl,gianfar-mdio";
++			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <5 1>;
+@@ -94,36 +104,24 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <24000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <1d 2 1e 2 22 2>;
+ 			interrupt-parent = <&mpic>;
+ 			phy-handle = <&phy0>;
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <25000 1000>;
+-			/*
+-			 * address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <23 2 24 2 28 2>;
+ 			interrupt-parent = <&mpic>;
+@@ -174,7 +172,7 @@
+ 				compatible = "fsl,mpc8560-cpm-pic", "fsl,cpm2-pic";
+ 			};
+ 
+-			serial@91a00 {
++			serial0: serial@91a00 {
+ 				device_type = "serial";
+ 				compatible = "fsl,mpc8560-scc-uart",
+ 				             "fsl,cpm2-scc-uart";
+@@ -186,7 +184,7 @@
+ 				interrupt-parent = <&cpmpic>;
+ 			};
+ 
+-			serial@91a20 {
++			serial1: serial@91a20 {
+ 				device_type = "serial";
+ 				compatible = "fsl,mpc8560-scc-uart",
+ 				             "fsl,cpm2-scc-uart";
+@@ -198,17 +196,11 @@
+ 				interrupt-parent = <&cpmpic>;
+ 			};
+ 
+-			ethernet@91320 {
++			enet2: ethernet@91320 {
+ 				device_type = "network";
+ 				compatible = "fsl,mpc8560-fcc-enet",
+ 				             "fsl,cpm2-fcc-enet";
+ 				reg = <91320 20 88500 100 913b0 1>;
+-				/*
+-				 * mac-address is deprecated and will be removed
+-				 * in 2.6.25.  Only recent versions of
+-				 * U-Boot support local-mac-address, however.
+-				 */
+-				mac-address = [ 00 00 00 00 00 00 ];
+ 				local-mac-address = [ 00 00 00 00 00 00 ];
+ 				fsl,cpm-command = <16200300>;
+ 				interrupts = <21 8>;
+@@ -216,17 +208,11 @@
+ 				phy-handle = <&phy2>;
+ 			};
+ 
+-			ethernet@91340 {
++			enet3: ethernet@91340 {
+ 				device_type = "network";
+ 				compatible = "fsl,mpc8560-fcc-enet",
+ 				             "fsl,cpm2-fcc-enet";
+ 				reg = <91340 20 88600 100 913d0 1>;
+-				/*
+-				 * mac-address is deprecated and will be removed
+-				 * in 2.6.25.  Only recent versions of
+-				 * U-Boot support local-mac-address, however.
+-				 */
+-				mac-address = [ 00 00 00 00 00 00 ];
+ 				local-mac-address = [ 00 00 00 00 00 00 ];
+ 				fsl,cpm-command = <1a400300>;
+ 				interrupts = <22 8>;
+@@ -236,7 +222,8 @@
+ 		};
+ 	};
+ 
+-	pci@e0008000 {
++	pci0: pci@e0008000 {
++		cell-index = <0>;
+ 		#interrupt-cells = <1>;
+ 		#size-cells = <2>;
+ 		#address-cells = <3>;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8568mds.dts powerpc.git/arch/powerpc/boot/dts/mpc8568mds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8568mds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8568mds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -20,6 +20,17 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		ethernet2 = &enet2;
++		ethernet3 = &enet3;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -74,7 +85,7 @@
+ 		i2c@3000 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+@@ -90,7 +101,7 @@
+ 		i2c@3100 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "i2c";
++			cell-index = <1>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <2b 2>;
+@@ -101,9 +112,9 @@
+ 		mdio@24520 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "mdio";
+-			compatible = "gianfar";
++			compatible = "fsl,gianfar-mdio";
+ 			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@7 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <1 1>;
+@@ -130,45 +141,32 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+ 			reg = <24000 1000>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+  			interrupts = <1d 2 1e 2 22 2>;
+ 			interrupt-parent = <&mpic>;
+ 			phy-handle = <&phy2>;
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+ 			reg = <25000 1000>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+  			interrupts = <23 2 24 2 28 2>;
+ 			interrupt-parent = <&mpic>;
+ 			phy-handle = <&phy3>;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -183,7 +181,8 @@
+ 			fsl,has-rstcr;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -318,45 +317,35 @@
+ 			mode = "cpu";
+ 		};
+ 
+-		ucc@2000 {
++		enet2: ucc@2000 {
+ 			device_type = "network";
+ 			compatible = "ucc_geth";
+ 			model = "UCC";
++			cell-index = <1>;
+ 			device-id = <1>;
+ 			reg = <2000 200>;
+ 			interrupts = <20>;
+ 			interrupt-parent = <&qeic>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+-			rx-clock = <0>;
+-			tx-clock = <20>;
++			rx-clock-name = "none";
++			tx-clock-name = "clk16";
+ 			pio-handle = <&pio1>;
+ 			phy-handle = <&phy0>;
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		ucc@3000 {
++		enet3: ucc@3000 {
+ 			device_type = "network";
+ 			compatible = "ucc_geth";
+ 			model = "UCC";
++			cell-index = <2>;
+ 			device-id = <2>;
+ 			reg = <3000 200>;
+ 			interrupts = <21>;
+ 			interrupt-parent = <&qeic>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+-			rx-clock = <0>;
+-			tx-clock = <20>;
++			rx-clock-name = "none";
++			tx-clock-name = "clk16";
+ 			pio-handle = <&pio2>;
+ 			phy-handle = <&phy1>;
+ 			phy-connection-type = "rgmii-id";
+@@ -366,7 +355,6 @@
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+ 			reg = <2120 18>;
+-			device_type = "mdio";
+ 			compatible = "ucc_geth_phy";
+ 
+ 			/* These are the same PHYs as on
+@@ -410,7 +398,8 @@
+ 
+ 	};
+ 
+-	pci@e0008000 {
++	pci0: pci@e0008000 {
++		cell-index = <0>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 			/* IDSEL 0x12 AD18 */
+@@ -440,7 +429,8 @@
+ 	};
+ 
+ 	/* PCI Express */
+-	pcie@e000a000 {
++	pci1: pcie@e000a000 {
++		cell-index = <2>;
+ 		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8572ds.dts powerpc.git/arch/powerpc/boot/dts/mpc8572ds.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8572ds.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8572ds.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -15,6 +15,18 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		ethernet2 = &enet2;
++		ethernet3 = &enet3;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++		pci2 = &pci2;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -69,7 +81,9 @@
+ 		};
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+@@ -78,7 +92,9 @@
+ 		};
+ 
+ 		i2c@3100 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <2b 2>;
+@@ -89,9 +105,9 @@
+ 		mdio@24520 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "mdio";
+-			compatible = "gianfar";
++			compatible = "fsl,gianfar-mdio";
+ 			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <a 1>;
+@@ -114,9 +130,8 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -128,9 +143,8 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -142,9 +156,8 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		ethernet@26000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet2: ethernet@26000 {
++			cell-index = <2>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -156,9 +169,8 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		ethernet@27000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet3: ethernet@27000 {
++			cell-index = <3>;
+ 			device_type = "network";
+ 			model = "eTSEC";
+ 			compatible = "gianfar";
+@@ -170,7 +182,8 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -179,7 +192,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -206,7 +220,8 @@
+ 		};
+ 	};
+ 
+-	pcie@ffe08000 {
++	pci0: pcie@ffe08000 {
++		cell-index = <0>;
+ 		compatible = "fsl,mpc8548-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+@@ -319,9 +334,9 @@
+ 
+ 			// IDSEL 0x1c  USB
+ 			e000 0 0 1 &i8259 c 2
+-			e100 0 0 1 &i8259 9 2
+-			e200 0 0 1 &i8259 a 2
+-			e300 0 0 1 &i8259 b 2
++			e100 0 0 2 &i8259 9 2
++			e200 0 0 3 &i8259 a 2
++			e300 0 0 4 &i8259 b 2
+ 
+ 			// IDSEL 0x1d  Audio
+ 			e800 0 0 1 &i8259 6 2
+@@ -415,7 +430,8 @@
+ 
+ 	};
+ 
+-	pcie@ffe09000 {
++	pci1: pcie@ffe09000 {
++		cell-index = <1>;
+ 		compatible = "fsl,mpc8548-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+@@ -451,7 +467,8 @@
+ 		};
+ 	};
+ 
+-	pcie@ffe0a000 {
++	pci2: pcie@ffe0a000 {
++		cell-index = <2>;
+ 		compatible = "fsl,mpc8548-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+@@ -464,6 +481,7 @@
+ 		clock-frequency = <1fca055>;
+ 		interrupt-parent = <&mpic>;
+ 		interrupts = <1b 2>;
++		interrupt-map-mask = <f800 0 0 7>;
+ 		interrupt-map = <
+ 			/* IDSEL 0x0 */
+ 			0000 0 0 1 &mpic 0 1
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8610_hpcd.dts powerpc.git/arch/powerpc/boot/dts/mpc8610_hpcd.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8610_hpcd.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8610_hpcd.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ /*
+  * MPC8610 HPCD Device Tree Source
+  *
+- * Copyright 2007 Freescale Semiconductor Inc.
++ * Copyright 2007-2008 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 Version 2 as published
+@@ -15,6 +15,13 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -42,33 +49,42 @@
+ 		#size-cells = <1>;
+ 		#interrupt-cells = <2>;
+ 		device_type = "soc";
++		compatible = "fsl,mpc8610-immr", "simple-bus";
+ 		ranges = <0 e0000000 00100000>;
+ 		reg = <e0000000 1000>;
+ 		bus-frequency = <0>;
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
+-			compatible = "fsl-i2c";
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			cell-index = <0>;
++			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+ 			interrupt-parent = <&mpic>;
+ 			dfsrr;
++
++                        cs4270:codec@4f {
++				compatible = "cirrus,cs4270";
++                                reg = <4f>;
++				/* MCLK source is a stand-alone oscillator */
++				clock-frequency = <bb8000>;
++                        };
+ 		};
+ 
+ 		i2c@3100 {
+-			device_type = "i2c";
+-			compatible = "fsl-i2c";
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			cell-index = <1>;
++			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <2b 2>;
+ 			interrupt-parent = <&mpic>;
+ 			dfsrr;
+ 		};
+ 
+-		serial@4500 {
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -77,7 +93,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -86,7 +103,6 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-
+ 		mpic: interrupt-controller@40000 {
+ 			clock-frequency = <0>;
+ 			interrupt-controller;
+@@ -103,9 +119,113 @@
+ 			reg = <e0000 1000>;
+ 			fsl,has-rstcr;
+ 		};
++
++		i2s@16000 {
++			compatible = "fsl,mpc8610-ssi";
++			cell-index = <0>;
++			reg = <16000 100>;
++			interrupt-parent = <&mpic>;
++			interrupts = <3e 2>;
++			fsl,mode = "i2s-slave";
++			codec-handle = <&cs4270>;
++		};
++
++		ssi@16100 {
++			compatible = "fsl,mpc8610-ssi";
++			cell-index = <1>;
++			reg = <16100 100>;
++			interrupt-parent = <&mpic>;
++			interrupts = <3f 2>;
++		};
++
++                dma@21300 {
++                        #address-cells = <1>;
++                        #size-cells = <1>;
++                        compatible = "fsl,mpc8610-dma", "fsl,eloplus-dma";
++                        cell-index = <0>;
++                        reg = <21300 4>; /* DMA general status register */
++                        ranges = <0 21100 200>;
++
++                        dma-channel@0 {
++				compatible = "fsl,mpc8610-dma-channel",
++					"fsl,eloplus-dma-channel";
++				cell-index = <0>;
++				reg = <0 80>;
++				interrupt-parent = <&mpic>;
++				interrupts = <14 2>;
++                        };
++                        dma-channel@1 {
++				compatible = "fsl,mpc8610-dma-channel",
++					"fsl,eloplus-dma-channel";
++				cell-index = <1>;
++				reg = <80 80>;
++				interrupt-parent = <&mpic>;
++				interrupts = <15 2>;
++                        };
++                        dma-channel@2 {
++				compatible = "fsl,mpc8610-dma-channel",
++					"fsl,eloplus-dma-channel";
++				cell-index = <2>;
++				reg = <100 80>;
++				interrupt-parent = <&mpic>;
++				interrupts = <16 2>;
++                        };
++                        dma-channel@3 {
++				compatible = "fsl,mpc8610-dma-channel",
++					"fsl,eloplus-dma-channel";
++				cell-index = <3>;
++				reg = <180 80>;
++				interrupt-parent = <&mpic>;
++				interrupts = <17 2>;
++                        };
++                };
++
++                dma@c300 {
++                        #address-cells = <1>;
++                        #size-cells = <1>;
++                        compatible = "fsl,mpc8610-dma", "fsl,mpc8540-dma";
++                        cell-index = <1>;
++                        reg = <c300 4>; /* DMA general status register */
++                        ranges = <0 c100 200>;
++
++                        dma-channel@0 {
++				compatible = "fsl,mpc8610-dma-channel",
++					"fsl,mpc8540-dma-channel";
++				cell-index = <0>;
++				reg = <0 80>;
++				interrupt-parent = <&mpic>;
++				interrupts = <3c 2>;
++                        };
++                        dma-channel@1 {
++				compatible = "fsl,mpc8610-dma-channel",
++					"fsl,mpc8540-dma-channel";
++				cell-index = <1>;
++				reg = <80 80>;
++				interrupt-parent = <&mpic>;
++				interrupts = <3d 2>;
++                        };
++                        dma-channel@2 {
++				compatible = "fsl,mpc8610-dma-channel",
++					"fsl,mpc8540-dma-channel";
++				cell-index = <2>;
++				reg = <100 80>;
++				interrupt-parent = <&mpic>;
++				interrupts = <3e 2>;
++                        };
++                        dma-channel@3 {
++				compatible = "fsl,mpc8610-dma-channel",
++					"fsl,mpc8540-dma-channel";
++				cell-index = <3>;
++				reg = <180 80>;
++				interrupt-parent = <&mpic>;
++				interrupts = <3f 2>;
++                        };
++                };
++
+ 	};
+ 
+-	pci@e0008000 {
++	pci0: pci@e0008000 {
++		cell-index = <0>;
+ 		compatible = "fsl,mpc8610-pci";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+@@ -134,7 +254,8 @@
+ 			>;
+ 	};
+ 
+-	pcie@e000a000 {
++	pci1: pcie@e000a000 {
++		cell-index = <1>;
+ 		compatible = "fsl,mpc8641-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc8641_hpcn.dts powerpc.git/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc8641_hpcn.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc8641_hpcn.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -16,6 +16,17 @@
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
++	aliases {
++		ethernet0 = &enet0;
++		ethernet1 = &enet1;
++		ethernet2 = &enet2;
++		ethernet3 = &enet3;
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++		pci1 = &pci1;
++	};
++
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+@@ -49,16 +60,60 @@
+ 		reg = <00000000 40000000>;	// 1G at 0x0
+ 	};
+ 
++	localbus@f8005000 {
++		#address-cells = <2>;
++		#size-cells = <1>;
++		compatible = "fsl,mpc8641-localbus", "simple-bus";
++		reg = <f8005000 1000>;
++		interrupts = <13 2>;
++		interrupt-parent = <&mpic>;
++
++		ranges = <0 0 ff800000 00800000
++			  1 0 fe000000 01000000
++			  2 0 f8200000 00100000
++			  3 0 f8100000 00100000>;
++
++		flash@0,0 {
++			compatible = "cfi-flash";
++			reg = <0 0 00800000>;
++			bank-width = <2>;
++			device-width = <2>;
++			#address-cells = <1>;
++			#size-cells = <1>;
++			partition@0 {
++				label = "kernel";
++				reg = <00000000 00300000>;
++			};
++			partition@300000 {
++				label = "firmware b";
++				reg = <00300000 00100000>;
++				read-only;
++			};
++			partition@400000 {
++				label = "fs";
++				reg = <00400000 00300000>;
++			};
++			partition@700000 {
++				label = "firmware a";
++				reg = <00700000 00100000>;
++				read-only;
++			};
++		};
++	};
++
+ 	soc8641@f8000000 {
+ 		#address-cells = <1>;
+ 		#size-cells = <1>;
+ 		device_type = "soc";
++		compatible = "simple-bus";
+ 		ranges = <00000000 f8000000 00100000>;
+ 		reg = <f8000000 00001000>;	// CCSRBAR
+ 		bus-frequency = <0>;
+ 
+ 		i2c@3000 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <0>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3000 100>;
+ 			interrupts = <2b 2>;
+@@ -67,7 +122,9 @@
+ 		};
+ 
+ 		i2c@3100 {
+-			device_type = "i2c";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			cell-index = <1>;
+ 			compatible = "fsl-i2c";
+ 			reg = <3100 100>;
+ 			interrupts = <2b 2>;
+@@ -78,9 +135,9 @@
+ 		mdio@24520 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			device_type = "mdio";
+-			compatible = "gianfar";
++			compatible = "fsl,gianfar-mdio";
+ 			reg = <24520 20>;
++
+ 			phy0: ethernet-phy@0 {
+ 				interrupt-parent = <&mpic>;
+ 				interrupts = <a 1>;
+@@ -107,19 +164,12 @@
+ 			};
+ 		};
+ 
+-		ethernet@24000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet0: ethernet@24000 {
++			cell-index = <0>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <24000 1000>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <1d 2 1e 2 22 2>;
+ 			interrupt-parent = <&mpic>;
+@@ -127,19 +177,12 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		ethernet@25000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet1: ethernet@25000 {
++			cell-index = <1>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <25000 1000>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <23 2 24 2 28 2>;
+ 			interrupt-parent = <&mpic>;
+@@ -147,19 +190,12 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 		
+-		ethernet@26000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet2: ethernet@26000 {
++			cell-index = <2>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <26000 1000>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <1F 2 20 2 21 2>;
+ 			interrupt-parent = <&mpic>;
+@@ -167,26 +203,21 @@
+ 			phy-connection-type = "rgmii-id";
+ 		};
+ 
+-		ethernet@27000 {
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++		enet3: ethernet@27000 {
++			cell-index = <3>;
+ 			device_type = "network";
+ 			model = "TSEC";
+ 			compatible = "gianfar";
+ 			reg = <27000 1000>;
+-			/*
+-			 * mac-address is deprecated and will be removed
+-			 * in 2.6.25.  Only recent versions of
+-			 * U-Boot support local-mac-address, however.
+-			 */
+-			mac-address = [ 00 00 00 00 00 00 ];
+ 			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <25 2 26 2 27 2>;
+ 			interrupt-parent = <&mpic>;
+ 			phy-handle = <&phy3>;
+ 			phy-connection-type = "rgmii-id";
+ 		};
+-		serial@4500 {
++
++		serial0: serial@4500 {
++			cell-index = <0>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4500 100>;
+@@ -195,7 +226,8 @@
+ 			interrupt-parent = <&mpic>;
+ 		};
+ 
+-		serial@4600 {
++		serial1: serial@4600 {
++			cell-index = <1>;
+ 			device_type = "serial";
+ 			compatible = "ns16550";
+ 			reg = <4600 100>;
+@@ -222,7 +254,8 @@
+ 		};
+ 	};
+ 
+-	pcie@f8008000 {
++	pci0: pcie@f8008000 {
++		cell-index = <0>;
+ 		compatible = "fsl,mpc8641-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+@@ -335,9 +368,9 @@
+ 
+ 			// IDSEL 0x1c  USB
+ 			e000 0 0 1 &i8259 c 2
+-			e100 0 0 1 &i8259 9 2
+-			e200 0 0 1 &i8259 a 2
+-			e300 0 0 1 &i8259 b 2
++			e100 0 0 2 &i8259 9 2
++			e200 0 0 3 &i8259 a 2
++			e300 0 0 4 &i8259 b 2
+ 
+ 			// IDSEL 0x1d  Audio
+ 			e800 0 0 1 &i8259 6 2
+@@ -430,7 +463,8 @@
+ 
+ 	};
+ 
+-	pcie@f8009000 {
++	pci1: pcie@f8009000 {
++		cell-index = <1>;
+ 		compatible = "fsl,mpc8641-pcie";
+ 		device_type = "pci";
+ 		#interrupt-cells = <1>;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/mpc866ads.dts powerpc.git/arch/powerpc/boot/dts/mpc866ads.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/mpc866ads.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/mpc866ads.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -12,7 +12,7 @@
+ 
+ / {
+ 	model = "MPC866ADS";
+-	compatible = "mpc8xx";
++	compatible = "fsl,mpc866ads";
+ 	#address-cells = <1>;
+ 	#size-cells = <1>;
+ 
+@@ -23,15 +23,15 @@
+ 		PowerPC,866@0 {
+ 			device_type = "cpu";
+ 			reg = <0>;
+-			d-cache-line-size = <20>;	// 32 bytes
+-			i-cache-line-size = <20>;	// 32 bytes
++			d-cache-line-size = <10>;	// 16 bytes
++			i-cache-line-size = <10>;	// 16 bytes
+ 			d-cache-size = <2000>;		// L1, 8K
+ 			i-cache-size = <4000>;		// L1, 16K
+ 			timebase-frequency = <0>;
+ 			bus-frequency = <0>;
+ 			clock-frequency = <0>;
+ 			interrupts = <f 2>;	// decrementer interrupt
+-			interrupt-parent = <&Mpc8xx_pic>;
++			interrupt-parent = <&PIC>;
+ 		};
+ 	};
+ 
+@@ -40,107 +40,139 @@
+ 		reg = <00000000 800000>;
+ 	};
+ 
+-	soc866@ff000000 {
++	localbus@ff000100 {
++		compatible = "fsl,mpc866-localbus", "fsl,pq1-localbus";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		reg = <ff000100 40>;
++
++		ranges = <
++			1 0 ff080000 00008000
++			5 0 ff0a0000 00008000
++		>;
++
++		board-control@1,0 {
++			reg = <1 0 20 5 300 4>;
++			compatible = "fsl,mpc866ads-bcsr";
++		};
++	};
++
++	soc@ff000000 {
+ 		#address-cells = <1>;
+ 		#size-cells = <1>;
+ 		device_type = "soc";
+ 		ranges = <0 ff000000 00100000>;
+ 		reg = <ff000000 00000200>;
+ 		bus-frequency = <0>;
+-		mdio@e80 {
+-			device_type = "mdio";
+-			compatible = "fs_enet";
+-			reg = <e80 8>;
++
++		mdio@e00 {
++			compatible = "fsl,mpc866-fec-mdio", "fsl,pq1-fec-mdio";
++			reg = <e00 188>;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+-			phy: ethernet-phy@f {
++			PHY: ethernet-phy@f {
+ 				reg = <f>;
+ 				device_type = "ethernet-phy";
+ 			};
+ 		};
+ 
+-		fec@e00 {
++		ethernet@e00 {
+ 			device_type = "network";
+-			compatible = "fs_enet";
+-			model = "FEC";
+-			device-id = <1>;
++			compatible = "fsl,mpc866-fec-enet",
++			             "fsl,pq1-fec-enet";
+ 			reg = <e00 188>;
+-			mac-address = [ 00 00 0C 00 01 FD ];
++			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <3 1>;
+-			interrupt-parent = <&Mpc8xx_pic>;
+-			phy-handle = <&Phy>;
++			interrupt-parent = <&PIC>;
++			phy-handle = <&PHY>;
++			linux,network-index = <0>;
+ 		};
+ 
+-		mpc8xx_pic: pic@ff000000 {
++		PIC: pic@0 {
+ 			interrupt-controller;
+-			#address-cells = <0>;
+ 			#interrupt-cells = <2>;
+ 			reg = <0 24>;
+-			device_type = "mpc8xx-pic";
+-			compatible = "CPM";
++			compatible = "fsl,mpc866-pic", "fsl,pq1-pic";
+ 		};
+ 
+-		cpm@ff000000 {
++		cpm@9c0 {
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+-			device_type = "cpm";
+-			model = "CPM";
+-			ranges = <0 0 4000>;
+-			reg = <860 f0>;
+-			command-proc = <9c0>;
++			compatible = "fsl,mpc866-cpm", "fsl,cpm1";
++			ranges;
++			reg = <9c0 40>;
+ 			brg-frequency = <0>;
+ 			interrupts = <0 2>;	// cpm error interrupt
+-			interrupt-parent = <&Cpm_pic>;
++			interrupt-parent = <&CPM_PIC>;
+ 
+-			cpm_pic: pic@930 {
++			muram@2000 {
++				#address-cells = <1>;
++				#size-cells = <1>;
++				ranges = <0 2000 2000>;
++
++				data@0 {
++					compatible = "fsl,cpm-muram-data";
++					reg = <0 1c00>;
++				};
++			};
++
++			brg@9f0 {
++				compatible = "fsl,mpc866-brg",
++					     "fsl,cpm1-brg",
++					     "fsl,cpm-brg";
++				reg = <9f0 10>;
++				clock-frequency = <0>;
++			};
++
++			CPM_PIC: pic@930 {
+ 				interrupt-controller;
+ 				#address-cells = <0>;
+-				#interrupt-cells = <2>;
++				#interrupt-cells = <1>;
+ 				interrupts = <5 2 0 2>;
+-				interrupt-parent = <&Mpc8xx_pic>;
++				interrupt-parent = <&PIC>;
+ 				reg = <930 20>;
+-				device_type = "cpm-pic";
+-				compatible = "CPM";
++				compatible = "fsl,mpc866-cpm-pic",
++				             "fsl,cpm1-pic";
+ 			};
+ 
+-			smc@a80 {
++
++			serial@a80 {
+ 				device_type = "serial";
+-				compatible = "cpm_uart";
+-				model = "SMC";
+-				device-id = <1>;
++				compatible = "fsl,mpc866-smc-uart",
++				             "fsl,cpm1-smc-uart";
+ 				reg = <a80 10 3e80 40>;
+-				clock-setup = <00ffffff 0>;
+-				rx-clock = <1>;
+-				tx-clock = <1>;
+-				current-speed = <0>;
+-				interrupts = <4 3>;
+-				interrupt-parent = <&Cpm_pic>;
++				interrupts = <4>;
++				interrupt-parent = <&CPM_PIC>;
++				fsl,cpm-brg = <1>;
++				fsl,cpm-command = <0090>;
+ 			};
+ 
+-			smc@a90 {
++			serial@a90 {
+ 				device_type = "serial";
+-				compatible = "cpm_uart";
+-				model = "SMC";
+-				device-id = <2>;
+-				reg = <a90 20 3f80 40>;
+-				clock-setup = <ff00ffff 90000>;
+-				rx-clock = <2>;
+-				tx-clock = <2>;
+-				current-speed = <0>;
+-				interrupts = <3 3>;
+-				interrupt-parent = <&Cpm_pic>;
++				compatible = "fsl,mpc866-smc-uart",
++				             "fsl,cpm1-smc-uart";
++				reg = <a90 10 3f80 40>;
++				interrupts = <3>;
++				interrupt-parent = <&CPM_PIC>;
++				fsl,cpm-brg = <2>;
++				fsl,cpm-command = <00d0>;
+ 			};
+ 
+-			scc@a00 {
++			ethernet@a00 {
+ 				device_type = "network";
+-				compatible = "fs_enet";
+-				model = "SCC";
+-				device-id = <1>;
+-				reg = <a00 18 3c00 80>;
+-				mac-address = [ 00 00 0C 00 03 FD ];
+-				interrupts = <1e 3>;
+-				interrupt-parent = <&Cpm_pic>;
++				compatible = "fsl,mpc866-scc-enet",
++				             "fsl,cpm1-scc-enet";
++				reg = <a00 18 3c00 100>;
++				local-mac-address = [ 00 00 00 00 00 00 ];
++				interrupts = <1e>;
++				interrupt-parent = <&CPM_PIC>;
++				fsl,cpm-command = <0000>;
++				linux,network-index = <1>;
+ 			};
+ 		};
+ 	};
++
++	chosen {
++		linux,stdout-path = "/soc/cpm/serial@a80";
++	};
+ };
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/rainier.dts powerpc.git/arch/powerpc/boot/dts/rainier.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/rainier.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/rainier.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,353 @@
++/*
++ * Device Tree Source for AMCC Rainier
++ *
++ * Based on Sequoia code
++ * Copyright (c) 2007 MontaVista Software, Inc.
++ *
++ * FIXME: Draft only!
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2.  This program is licensed "as is" without
++ * any warranty of any kind, whether express or implied.
++ *
++ */
++
++/ {
++	#address-cells = <2>;
++	#size-cells = <1>;
++	model = "amcc,rainier";
++	compatible = "amcc,rainier";
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		ethernet1 = &EMAC1;
++		serial0 = &UART0;
++		serial1 = &UART1;
++		serial2 = &UART2;
++		serial3 = &UART3;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		cpu@0 {
++			device_type = "cpu";
++			model = "PowerPC,440GRx";
++			reg = <0>;
++			clock-frequency = <0>; /* Filled in by zImage */
++			timebase-frequency = <0>; /* Filled in by zImage */
++			i-cache-line-size = <20>;
++			d-cache-line-size = <20>;
++			i-cache-size = <8000>;
++			d-cache-size = <8000>;
++			dcr-controller;
++			dcr-access-method = "native";
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0 0>; /* Filled in by zImage */
++	};
++
++	UIC0: interrupt-controller0 {
++		compatible = "ibm,uic-440grx","ibm,uic";
++		interrupt-controller;
++		cell-index = <0>;
++		dcr-reg = <0c0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++	};
++
++	UIC1: interrupt-controller1 {
++		compatible = "ibm,uic-440grx","ibm,uic";
++		interrupt-controller;
++		cell-index = <1>;
++		dcr-reg = <0d0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <1e 4 1f 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	UIC2: interrupt-controller2 {
++		compatible = "ibm,uic-440grx","ibm,uic";
++		interrupt-controller;
++		cell-index = <2>;
++		dcr-reg = <0e0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <1c 4 1d 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	SDR0: sdr {
++		compatible = "ibm,sdr-440grx", "ibm,sdr-440ep";
++		dcr-reg = <00e 002>;
++	};
++
++	CPR0: cpr {
++		compatible = "ibm,cpr-440grx", "ibm,cpr-440ep";
++		dcr-reg = <00c 002>;
++	};
++
++	plb {
++		compatible = "ibm,plb-440grx", "ibm,plb4";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		ranges;
++		clock-frequency = <0>; /* Filled in by zImage */
++
++		SDRAM0: sdram {
++			compatible = "ibm,sdram-440grx", "ibm,sdram-44x-ddr2denali";
++			dcr-reg = <010 2>;
++		};
++
++		DMA0: dma {
++			compatible = "ibm,dma-440grx", "ibm,dma-4xx";
++			dcr-reg = <100 027>;
++		};
++
++		MAL0: mcmal {
++			compatible = "ibm,mcmal-440grx", "ibm,mcmal2";
++			dcr-reg = <180 62>;
++			num-tx-chans = <2>;
++			num-rx-chans = <2>;
++			interrupt-parent = <&MAL0>;
++			interrupts = <0 1 2 3 4>;
++			#interrupt-cells = <1>;
++			#address-cells = <0>;
++			#size-cells = <0>;
++			interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
++					/*RXEOB*/ 1 &UIC0 b 4
++					/*SERR*/  2 &UIC1 0 4
++					/*TXDE*/  3 &UIC1 1 4
++					/*RXDE*/  4 &UIC1 2 4>;
++			interrupt-map-mask = <ffffffff>;
++		};
++
++		POB0: opb {
++		  	compatible = "ibm,opb-440grx", "ibm,opb";
++			#address-cells = <1>;
++			#size-cells = <1>;
++		  	ranges = <00000000 1 00000000 80000000
++			          80000000 1 80000000 80000000>;
++		  	interrupt-parent = <&UIC1>;
++		  	interrupts = <7 4>;
++		  	clock-frequency = <0>; /* Filled in by zImage */
++
++			EBC0: ebc {
++				compatible = "ibm,ebc-440grx", "ibm,ebc";
++				dcr-reg = <012 2>;
++				#address-cells = <2>;
++				#size-cells = <1>;
++				clock-frequency = <0>; /* Filled in by zImage */
++				interrupts = <5 1>;
++				interrupt-parent = <&UIC1>;
++
++				nor_flash@0,0 {
++					compatible = "amd,s29gl256n", "cfi-flash";
++					bank-width = <2>;
++					reg = <0 000000 4000000>;
++					#address-cells = <1>;
++					#size-cells = <1>;
++					partition@0 {
++						label = "Kernel";
++						reg = <0 180000>;
++					};
++					partition@180000 {
++						label = "ramdisk";
++						reg = <180000 200000>;
++					};
++					partition@380000 {
++						label = "file system";
++						reg = <380000 3aa0000>;
++					};
++					partition@3e20000 {
++						label = "kozio";
++						reg = <3e20000 140000>;
++					};
++					partition@3f60000 {
++						label = "env";
++						reg = <3f60000 40000>;
++					};
++					partition@3fa0000 {
++						label = "u-boot";
++						reg = <3fa0000 60000>;
++					};
++				};
++
++			};
++
++			UART0: serial@ef600300 {
++		   		device_type = "serial";
++		   		compatible = "ns16550";
++		   		reg = <ef600300 8>;
++		   		virtual-reg = <ef600300>;
++		   		clock-frequency = <0>; /* Filled in by zImage */
++		   		current-speed = <1c200>;
++		   		interrupt-parent = <&UIC0>;
++		   		interrupts = <0 4>;
++	   		};
++
++			UART1: serial@ef600400 {
++		   		device_type = "serial";
++		   		compatible = "ns16550";
++		   		reg = <ef600400 8>;
++		   		virtual-reg = <ef600400>;
++		   		clock-frequency = <0>;
++		   		current-speed = <0>;
++		   		interrupt-parent = <&UIC0>;
++		   		interrupts = <1 4>;
++	   		};
++
++			UART2: serial@ef600500 {
++		   		device_type = "serial";
++		   		compatible = "ns16550";
++		   		reg = <ef600500 8>;
++		   		virtual-reg = <ef600500>;
++		   		clock-frequency = <0>;
++		   		current-speed = <0>;
++		   		interrupt-parent = <&UIC1>;
++		   		interrupts = <3 4>;
++	   		};
++
++			UART3: serial@ef600600 {
++		   		device_type = "serial";
++		   		compatible = "ns16550";
++		   		reg = <ef600600 8>;
++		   		virtual-reg = <ef600600>;
++		   		clock-frequency = <0>;
++		   		current-speed = <0>;
++		   		interrupt-parent = <&UIC1>;
++		   		interrupts = <4 4>;
++	   		};
++
++			IIC0: i2c@ef600700 {
++				device_type = "i2c";
++				compatible = "ibm,iic-440grx", "ibm,iic";
++				reg = <ef600700 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <2 4>;
++			};
++
++			IIC1: i2c@ef600800 {
++				device_type = "i2c";
++				compatible = "ibm,iic-440grx", "ibm,iic";
++				reg = <ef600800 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <7 4>;
++			};
++
++			ZMII0: emac-zmii@ef600d00 {
++				device_type = "zmii-interface";
++				compatible = "ibm,zmii-440grx", "ibm,zmii";
++				reg = <ef600d00 c>;
++			};
++
++			RGMII0: emac-rgmii@ef601000 {
++				device_type = "rgmii-interface";
++				compatible = "ibm,rgmii-440grx", "ibm,rgmii";
++				reg = <ef601000 8>;
++				has-mdio;
++			};
++
++			EMAC0: ethernet@ef600e00 {
++				linux,network-index = <0>;
++				device_type = "network";
++				compatible = "ibm,emac-440grx", "ibm,emac-440epx", "ibm,emac4";
++				interrupt-parent = <&EMAC0>;
++				interrupts = <0 1>;
++				#interrupt-cells = <1>;
++				#address-cells = <0>;
++				#size-cells = <0>;
++				interrupt-map = </*Status*/ 0 &UIC0 18 4
++						/*Wake*/  1 &UIC1 1d 4>;
++				reg = <ef600e00 70>;
++				local-mac-address = [000000000000];
++				mal-device = <&MAL0>;
++				mal-tx-channel = <0>;
++				mal-rx-channel = <0>;
++				cell-index = <0>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rgmii";
++				phy-map = <00000000>;
++				zmii-device = <&ZMII0>;
++				zmii-channel = <0>;
++				rgmii-device = <&RGMII0>;
++				rgmii-channel = <0>;
++				has-inverted-stacr-oc;
++				has-new-stacr-staopc;
++			};
++
++			EMAC1: ethernet@ef600f00 {
++				linux,network-index = <1>;
++				device_type = "network";
++				compatible = "ibm,emac-440grx", "ibm,emac-440epx", "ibm,emac4";
++				interrupt-parent = <&EMAC1>;
++				interrupts = <0 1>;
++				#interrupt-cells = <1>;
++				#address-cells = <0>;
++				#size-cells = <0>;
++				interrupt-map = </*Status*/ 0 &UIC0 19 4
++						/*Wake*/  1 &UIC1 1f 4>;
++				reg = <ef600f00 70>;
++				local-mac-address = [000000000000];
++				mal-device = <&MAL0>;
++				mal-tx-channel = <1>;
++				mal-rx-channel = <1>;
++				cell-index = <1>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rgmii";
++				phy-map = <00000000>;
++				zmii-device = <&ZMII0>;
++				zmii-channel = <1>;
++				rgmii-device = <&RGMII0>;
++				rgmii-channel = <1>;
++				has-inverted-stacr-oc;
++				has-new-stacr-staopc;
++			};
++		};
++
++		PCI0: pci@1ec000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb440grx-pci", "ibm,plb-pci";
++			primary;
++			reg = <1 eec00000 8	/* Config space access */
++			       1 eed00000 4	/* IACK */
++			       1 eed00000 4	/* Special cycle */
++			       1 ef400000 40>;	/* Internal registers */
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed. Chip supports a second
++			 * IO range but we don't use it for now
++			 */
++			ranges = <02000000 0 80000000 1 80000000 0 10000000
++				01000000 0 00000000 1 e8000000 0 00100000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			/* All PCI interrupts are routed to IRQ 67 */
++			interrupt-map-mask = <0000 0 0 0>;
++			interrupt-map = < 0000 0 0 0 &UIC2 3 8 >;
++		};
++	};
++
++	chosen {
++		linux,stdout-path = "/plb/opb/serial@ef600300";
++		bootargs = "console=ttyS0,115200";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/sequoia.dts powerpc.git/arch/powerpc/boot/dts/sequoia.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/sequoia.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/sequoia.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -17,14 +17,24 @@
+ 	#size-cells = <1>;
+ 	model = "amcc,sequoia";
+ 	compatible = "amcc,sequoia";
+-	dcr-parent = <&/cpus/PowerPC,440EPx@0>;
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		ethernet1 = &EMAC1;
++		serial0 = &UART0;
++		serial1 = &UART1;
++		serial2 = &UART2;
++		serial3 = &UART3;
++	};
+ 
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+ 
+-		PowerPC,440EPx@0 {
++		cpu@0 {
+ 			device_type = "cpu";
++			model = "PowerPC,440EPx";
+ 			reg = <0>;
+ 			clock-frequency = <0>; /* Filled in by zImage */
+ 			timebase-frequency = <0>; /* Filled in by zImage */
+@@ -94,7 +104,6 @@
+ 		clock-frequency = <0>; /* Filled in by zImage */
+ 
+ 		SDRAM0: sdram {
+-			device_type = "memory-controller";
+ 			compatible = "ibm,sdram-440epx", "ibm,sdram-44x-ddr2denali";
+ 			dcr-reg = <010 2>;
+ 		};
+@@ -122,6 +131,13 @@
+ 			interrupt-map-mask = <ffffffff>;
+ 		};
+ 
++		USB1: usb@e0000400 {
++			compatible = "ohci-be";
++			reg = <0 e0000400 60>;
++			interrupt-parent = <&UIC0>;
++			interrupts = <15 8>;
++		};
++
+ 		POB0: opb {
+ 		  	compatible = "ibm,opb-440epx", "ibm,opb";
+ 			#address-cells = <1>;
+@@ -308,6 +324,33 @@
+ 				has-new-stacr-staopc;
+ 			};
+ 		};
++
++		PCI0: pci@1ec000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb440epx-pci", "ibm,plb-pci";
++			primary;
++			reg = <1 eec00000 8	/* Config space access */
++			       1 eed00000 4	/* IACK */
++			       1 eed00000 4	/* Special cycle */
++			       1 ef400000 40>;	/* Internal registers */
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed. Chip supports a second
++			 * IO range but we don't use it for now
++			 */
++			ranges = <02000000 0 80000000 1 80000000 0 10000000
++				01000000 0 00000000 1 e8000000 0 00100000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			/* All PCI interrupts are routed to IRQ 67 */
++			interrupt-map-mask = <0000 0 0 0>;
++			interrupt-map = < 0000 0 0 0 &UIC2 3 8 >;
++		};
+ 	};
+ 
+ 	chosen {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/storcenter.dts powerpc.git/arch/powerpc/boot/dts/storcenter.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/storcenter.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/storcenter.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,138 @@
++/*
++ * Device Tree Source for IOMEGA StorCenter
++ *
++ * Copyright 2007 Oyvind Repvik
++ * Copyright 2007 Jon Loeliger
++ *
++ * Based on the Kurobox DTS by G. Liakhovetski <g.liakhovetski@gmx.de>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2.  This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++/ {
++	model = "StorCenter";
++	compatible = "storcenter";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	aliases {
++		serial0 = &serial0;
++		serial1 = &serial1;
++		pci0 = &pci0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,8241@0 {
++			device_type = "cpu";
++			reg = <0>;
++			clock-frequency = <d# 200000000>;	/* Hz */
++			timebase-frequency = <d# 25000000>;	/* Hz */
++			bus-frequency = <0>;	/* from bootwrapper */
++			i-cache-line-size = <d# 32>;	/* bytes */
++			d-cache-line-size = <d# 32>;	/* bytes */
++			i-cache-size = <4000>;
++			d-cache-size = <4000>;
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <00000000 04000000>;	/* 64MB @ 0x0 */
++	};
++
++	soc@fc000000 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		device_type = "soc";
++		compatible = "fsl,mpc8241", "mpc10x";
++		store-gathering = <0>; /* 0 == off, !0 == on */
++		ranges = <0 fc000000 100000>;
++		reg = <fc000000 100000>;	/* EUMB */
++		bus-frequency = <0>;		/* fixed by loader */
++
++		i2c@3000 {
++			#address-cells = <1>;
++			#size-cells = <0>;
++			compatible = "fsl-i2c";
++			reg = <3000 100>;
++			interrupts = <5 2>;
++			interrupt-parent = <&mpic>;
++
++			rtc@68 {
++				compatible = "dallas,ds1337";
++				reg = <68>;
++			};
++		};
++
++		serial0: serial@4500 {
++			cell-index = <0>;
++			device_type = "serial";
++			compatible = "ns16550";
++			reg = <4500 20>;
++			clock-frequency = <d# 97553800>; /* Hz */
++			current-speed = <d# 115200>;
++			interrupts = <9 2>;
++			interrupt-parent = <&mpic>;
++		};
++
++		serial1: serial@4600 {
++			cell-index = <1>;
++			device_type = "serial";
++			compatible = "ns16550";
++			reg = <4600 20>;
++			clock-frequency = <d# 97553800>; /* Hz */
++			current-speed = <d# 9600>;
++			interrupts = <a 2>;
++			interrupt-parent = <&mpic>;
++		};
++
++		mpic: interrupt-controller@40000 {
++			#interrupt-cells = <2>;
++			device_type = "open-pic";
++			compatible = "chrp,open-pic";
++			interrupt-controller;
++			reg = <40000 40000>;
++		};
++
++	};
++
++	pci0: pci@fe800000 {
++		#address-cells = <3>;
++		#size-cells = <2>;
++		#interrupt-cells = <1>;
++		device_type = "pci";
++		compatible = "mpc10x-pci";
++		reg = <fe800000 1000>;
++		ranges = <01000000 0        0 fe000000 0 00c00000
++			  02000000 0 80000000 80000000 0 70000000>;
++		bus-range = <0 ff>;
++		clock-frequency = <d# 97553800>; /* Hz */
++		interrupt-parent = <&mpic>;
++		interrupt-map-mask = <f800 0 0 7>;
++		interrupt-map = <
++			/* IDSEL 13 - IDE */
++			6800 0 0 1 &mpic 0 1
++			6800 0 0 2 &mpic 0 1
++			6800 0 0 3 &mpic 0 1
++			/* IDSEL 14 - USB */
++			7000 0 0 1 &mpic 0 1
++			7000 0 0 2 &mpic 0 1
++			7000 0 0 3 &mpic 0 1
++			7000 0 0 4 &mpic 0 1
++			/* IDSEL 15 - ETH */
++			7800 0 0 1 &mpic 0 1
++			7800 0 0 2 &mpic 0 1
++			7800 0 0 3 &mpic 0 1
++			7800 0 0 4 &mpic 0 1
++		>;
++	};
++
++	chosen {
++		linux,stdout-path = "/soc/serial@4500";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/taishan.dts powerpc.git/arch/powerpc/boot/dts/taishan.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/taishan.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/taishan.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,383 @@
++/*
++ * Device Tree Source for IBM/AMCC Taishan
++ *
++ * Copyright 2007 IBM Corp.
++ * Hugh Blemings <hugh@au.ibm.com> based off code by
++ * Josh Boyer <jwboyer@linux.vnet.ibm.com>, David Gibson <dwg@au1.ibm.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2.  This program is licensed "as is" without
++ * any warranty of any kind, whether express or implied.
++ */
++
++/ {
++	#address-cells = <2>;
++	#size-cells = <1>;
++	model = "amcc,taishan";
++	compatible = "amcc,taishan";
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC2;
++		ethernet1 = &EMAC3;
++		serial0 = &UART0;
++		serial1 = &UART1;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		cpu@0 {
++			device_type = "cpu";
++			model = "PowerPC,440GX";
++			reg = <0>;
++			clock-frequency = <2FAF0800>; // 800MHz
++			timebase-frequency = <0>; // Filled in by zImage
++			i-cache-line-size = <32>;
++			d-cache-line-size = <32>;
++			i-cache-size = <8000>; /* 32 kB */
++			d-cache-size = <8000>; /* 32 kB */
++			dcr-controller;
++			dcr-access-method = "native";
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0 0>; // Filled in by zImage
++	};
++
++
++	UICB0: interrupt-controller-base {
++		compatible = "ibm,uic-440gx", "ibm,uic";
++		interrupt-controller;
++		cell-index = <3>;
++		dcr-reg = <200 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++	};
++
++
++	UIC0: interrupt-controller0 {
++		compatible = "ibm,uic-440gx", "ibm,uic";
++		interrupt-controller;
++		cell-index = <0>;
++		dcr-reg = <0c0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <01 4 00 4>; /* cascade - first non-critical */
++		interrupt-parent = <&UICB0>;
++
++	};
++
++	UIC1: interrupt-controller1 {
++		compatible = "ibm,uic-440gx", "ibm,uic";
++		interrupt-controller;
++		cell-index = <1>;
++		dcr-reg = <0d0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <03 4 02 4>; /* cascade */
++		interrupt-parent = <&UICB0>;
++	};
++
++	UIC2: interrupt-controller2 {
++		compatible = "ibm,uic-440gx", "ibm,uic";
++		interrupt-controller;
++		cell-index = <2>; /* was 1 */
++		dcr-reg = <210 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <05 4 04 4>; /* cascade */
++		interrupt-parent = <&UICB0>;
++	};
++
++
++	CPC0: cpc {
++		compatible = "ibm,cpc-440gp";
++		dcr-reg = <0b0 003 0e0 010>;
++		// FIXME: anything else?
++	};
++
++	plb {
++		compatible = "ibm,plb-440gx", "ibm,plb4";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		ranges;
++		clock-frequency = <9896800>; // 160MHz
++
++		SDRAM0: memory-controller {
++			compatible = "ibm,sdram-440gp";
++			dcr-reg = <010 2>;
++			// FIXME: anything else?
++		};
++
++		SRAM0: sram {
++			compatible = "ibm,sram-440gp";
++			dcr-reg = <020 8 00a 1>;
++		};
++
++		DMA0: dma {
++			// FIXME: ???
++			compatible = "ibm,dma-440gp";
++			dcr-reg = <100 027>;
++		};
++
++		MAL0: mcmal {
++			compatible = "ibm,mcmal-440gx", "ibm,mcmal2";
++			dcr-reg = <180 62>;
++			num-tx-chans = <4>;
++			num-rx-chans = <4>;
++			interrupt-parent = <&MAL0>;
++			interrupts = <0 1 2 3 4>;
++			#interrupt-cells = <1>;
++			#address-cells = <0>;
++			#size-cells = <0>;
++			interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
++					 /*RXEOB*/ 1 &UIC0 b 4
++					 /*SERR*/  2 &UIC1 0 4
++					 /*TXDE*/  3 &UIC1 1 4
++					 /*RXDE*/  4 &UIC1 2 4>;
++			interrupt-map-mask = <ffffffff>;
++		};
++
++		POB0: opb {
++			compatible = "ibm,opb-440gx", "ibm,opb";
++			#address-cells = <1>;
++			#size-cells = <1>;
++			/* Wish there was a nicer way of specifying a full 32-bit
++			   range */
++			ranges = <00000000 1 00000000 80000000
++				  80000000 1 80000000 80000000>;
++			dcr-reg = <090 00b>;
++			interrupt-parent = <&UIC1>;
++			interrupts = <7 4>;
++			clock-frequency = <4C4B400>; // 80MHz
++
++
++			EBC0: ebc {
++				compatible = "ibm,ebc-440gx", "ibm,ebc";
++				dcr-reg = <012 2>;
++				#address-cells = <2>;
++				#size-cells = <1>;
++				clock-frequency = <4C4B400>; // 80MHz
++
++				/* ranges property is supplied by zImage
++				 * based on firmware's configuration of the
++				 * EBC bridge */
++
++				interrupts = <5 4>;
++				interrupt-parent = <&UIC1>;
++
++				/* TODO: Add other EBC devices */
++			};
++
++
++
++			UART0: serial@40000200 {
++				device_type = "serial";
++				compatible = "ns16550";
++				reg = <40000200 8>;
++				virtual-reg = <e0000200>;
++ 				clock-frequency = <A8C000>;
++				current-speed = <1C200>; /* 115200 */
++				interrupt-parent = <&UIC0>;
++				interrupts = <0 4>;
++			};
++
++			UART1: serial@40000300 {
++				device_type = "serial";
++				compatible = "ns16550";
++				reg = <40000300 8>;
++				virtual-reg = <e0000300>;
++				clock-frequency = <A8C000>;
++				current-speed = <1C200>; /* 115200 */
++				interrupt-parent = <&UIC0>;
++				interrupts = <1 4>;
++			};
++
++			IIC0: i2c@40000400 {
++				/* FIXME */
++				device_type = "i2c";
++				compatible = "ibm,iic-440gp", "ibm,iic";
++				reg = <40000400 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <2 4>;
++			};
++			IIC1: i2c@40000500 {
++				/* FIXME */
++				device_type = "i2c";
++				compatible = "ibm,iic-440gp", "ibm,iic";
++				reg = <40000500 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <3 4>;
++			};
++
++			GPIO0: gpio@40000700 {
++				/* FIXME */
++				compatible = "ibm,gpio-440gp";
++				reg = <40000700 20>;
++			};
++
++			ZMII0: emac-zmii@40000780 {
++				device_type = "zgmii-interface";
++				compatible = "ibm,zmii-440gx", "ibm,zmii";
++				reg = <40000780 c>;
++			};
++
++			RGMII0: emac-rgmii@40000790 {
++				device_type = "rgmii-interface";
++				compatible = "ibm,rgmii";
++				reg = <40000790 8>;
++			};
++
++
++			EMAC0: ethernet@40000800 {
++				unused = <1>;
++				linux,network-index = <2>;
++				device_type = "network";
++				compatible = "ibm,emac-440gx", "ibm,emac4";
++				interrupt-parent = <&UIC1>;
++				interrupts = <1c 4 1d 4>;
++				reg = <40000800 70>;
++				local-mac-address = [000000000000]; // Filled in by zImage
++				mal-device = <&MAL0>;
++				mal-tx-channel = <0>;
++				mal-rx-channel = <0>;
++				cell-index = <0>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rmii";
++				phy-map = <00000001>;
++				zmii-device = <&ZMII0>;
++				zmii-channel = <0>;
++			};
++		 	EMAC1: ethernet@40000900 {
++				unused = <1>;
++				linux,network-index = <3>;
++				device_type = "network";
++				compatible = "ibm,emac-440gx", "ibm,emac4";
++				interrupt-parent = <&UIC1>;
++				interrupts = <1e 4 1f 4>;
++				reg = <40000900 70>;
++				local-mac-address = [000000000000]; // Filled in by zImage
++				mal-device = <&MAL0>;
++				mal-tx-channel = <1>;
++				mal-rx-channel = <1>;
++				cell-index = <1>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rmii";
++				phy-map = <00000001>;
++ 				zmii-device = <&ZMII0>;
++				zmii-channel = <1>;
++			};
++
++		 	EMAC2: ethernet@40000c00 {
++				linux,network-index = <0>;
++				device_type = "network";
++				compatible = "ibm,emac-440gx", "ibm,emac4";
++				interrupt-parent = <&UIC2>;
++				interrupts = <0 4 1 4>;
++				reg = <40000c00 70>;
++				local-mac-address = [000000000000]; // Filled in by zImage
++				mal-device = <&MAL0>;
++				mal-tx-channel = <2>;
++				mal-rx-channel = <2>;
++				cell-index = <2>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rgmii";
++				phy-map = <00000001>;
++				rgmii-device = <&RGMII0>;
++				rgmii-channel = <0>;
++ 				zmii-device = <&ZMII0>;
++				zmii-channel = <2>;
++			};
++
++		 	EMAC3: ethernet@40000e00 {
++				linux,network-index = <1>;
++				device_type = "network";
++				compatible = "ibm,emac-440gx", "ibm,emac4";
++				interrupt-parent = <&UIC2>;
++				interrupts = <2 4 3 4>;
++				reg = <40000e00 70>;
++				local-mac-address = [000000000000]; // Filled in by zImage
++				mal-device = <&MAL0>;
++				mal-tx-channel = <3>;
++				mal-rx-channel = <3>;
++				cell-index = <3>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rgmii";
++				phy-map = <00000003>;
++				rgmii-device = <&RGMII0>;
++				rgmii-channel = <1>;
++ 				zmii-device = <&ZMII0>;
++				zmii-channel = <3>;
++			};
++
++
++			GPT0: gpt@40000a00 {
++				/* FIXME */
++				reg = <40000a00 d4>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <12 4 13 4 14 4 15 4 16 4>;
++			};
++
++		};
++
++		PCIX0: pci@20ec00000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix";
++			primary;
++			large-inbound-windows;
++			enable-msi-hole;
++			reg = <2 0ec00000   8	/* Config space access */
++			       0 0 0		/* no IACK cycles */
++			       2 0ed00000   4   /* Special cycles */
++			       2 0ec80000 100	/* Internal registers */
++			       2 0ec80100  fc>;	/* Internal messaging registers */
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed
++			 */
++			ranges = <02000000 0 80000000 00000003 80000000 0 80000000
++				  01000000 0 00000000 00000002 08000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 0 80000000>;
++
++			interrupt-map-mask = <f800 0 0 7>;
++			interrupt-map = <
++				/* IDSEL 1 */
++				0800 0 0 1 &UIC0 17 8
++				0800 0 0 2 &UIC0 18 8
++				0800 0 0 3 &UIC0 19 8
++				0800 0 0 4 &UIC0 1a 8
++
++				/* IDSEL 2 */
++				1000 0 0 1 &UIC0 18 8
++				1000 0 0 2 &UIC0 19 8
++				1000 0 0 3 &UIC0 1a 8
++				1000 0 0 4 &UIC0 17 8
++			>;
++		};
++	};
++
++	chosen {
++		linux,stdout-path = "/plb/opb/serial@40000300";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/tqm5200.dts powerpc.git/arch/powerpc/boot/dts/tqm5200.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/tqm5200.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/tqm5200.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,184 @@
++/*
++ * TQM5200 board Device Tree Source
++ *
++ * Copyright (C) 2007 Semihalf
++ * Marian Balakowicz <m8@semihalf.com>
++ *
++ * 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.
++ */
++
++/*
++ * WARNING: Do not depend on this tree layout remaining static just yet.
++ * The MPC5200 device tree conventions are still in flux
++ * Keep an eye on the linuxppc-dev mailing list for more details
++ */
++
++/ {
++	model = "tqc,tqm5200";
++	compatible = "tqc,tqm5200";
++	#address-cells = <1>;
++	#size-cells = <1>;
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		PowerPC,5200@0 {
++			device_type = "cpu";
++			reg = <0>;
++			d-cache-line-size = <20>;
++			i-cache-line-size = <20>;
++			d-cache-size = <4000>;		// L1, 16K
++			i-cache-size = <4000>;		// L1, 16K
++			timebase-frequency = <0>;	// from bootloader
++			bus-frequency = <0>;		// from bootloader
++			clock-frequency = <0>;		// from bootloader
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <00000000 04000000>;	// 64MB
++	};
++
++	soc5200@f0000000 {
++		model = "fsl,mpc5200";
++		compatible = "fsl,mpc5200";
++		revision = "";			// from bootloader
++		device_type = "soc";
++		ranges = <0 f0000000 0000c000>;
++		reg = <f0000000 00000100>;
++		bus-frequency = <0>;		// from bootloader
++		system-frequency = <0>;		// from bootloader
++
++		cdm@200 {
++			compatible = "mpc5200-cdm";
++			reg = <200 38>;
++		};
++
++		mpc5200_pic: pic@500 {
++			// 5200 interrupts are encoded into two levels;
++			interrupt-controller;
++			#interrupt-cells = <3>;
++			compatible = "mpc5200-pic";
++			reg = <500 80>;
++		};
++
++		gpt@600 {	// General Purpose Timer
++			compatible = "fsl,mpc5200-gpt";
++			reg = <600 10>;
++			interrupts = <1 9 0>;
++			interrupt-parent = <&mpc5200_pic>;
++			fsl,has-wdt;
++		};
++
++		gpio@b00 {
++			compatible = "mpc5200-gpio";
++			reg = <b00 40>;
++			interrupts = <1 7 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		usb@1000 {
++			compatible = "mpc5200-ohci","ohci-be";
++			reg = <1000 ff>;
++			interrupts = <2 6 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		dma-controller@1200 {
++			compatible = "mpc5200-bestcomm";
++			reg = <1200 80>;
++			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
++			              3 4 0  3 5 0  3 6 0  3 7 0
++			              3 8 0  3 9 0  3 a 0  3 b 0
++			              3 c 0  3 d 0  3 e 0  3 f 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		xlb@1f00 {
++			compatible = "mpc5200-xlb";
++			reg = <1f00 100>;
++		};
++
++		serial@2000 {		// PSC1
++			device_type = "serial";
++			compatible = "mpc5200-psc-uart";
++			port-number = <0>;  // Logical port assignment
++			reg = <2000 100>;
++			interrupts = <2 1 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		serial@2200 {		// PSC2
++			device_type = "serial";
++			compatible = "mpc5200-psc-uart";
++			port-number = <1>;  // Logical port assignment
++			reg = <2200 100>;
++			interrupts = <2 2 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		serial@2400 {		// PSC3
++			device_type = "serial";
++			compatible = "mpc5200-psc-uart";
++			port-number = <2>;  // Logical port assignment
++			reg = <2400 100>;
++			interrupts = <2 3 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		ethernet@3000 {
++			device_type = "network";
++			compatible = "mpc5200-fec";
++			reg = <3000 800>;
++			local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by U-Boot */
++			interrupts = <2 5 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		ata@3a00 {
++			compatible = "mpc5200-ata";
++			reg = <3a00 100>;
++			interrupts = <2 7 0>;
++			interrupt-parent = <&mpc5200_pic>;
++		};
++
++		i2c@3d40 {
++			compatible = "mpc5200-i2c","fsl-i2c";
++			reg = <3d40 40>;
++			interrupts = <2 10 0>;
++			interrupt-parent = <&mpc5200_pic>;
++			fsl5200-clocking;
++		};
++
++		sram@8000 {
++			compatible = "mpc5200-sram";
++			reg = <8000 4000>;
++		};
++	};
++
++	pci@f0000d00 {
++		#interrupt-cells = <1>;
++		#size-cells = <2>;
++		#address-cells = <3>;
++		device_type = "pci";
++		compatible = "fsl,mpc5200-pci";
++		reg = <f0000d00 100>;
++		interrupt-map-mask = <f800 0 0 7>;
++		interrupt-map = <c000 0 0 1 &mpc5200_pic 0 0 3
++				 c000 0 0 2 &mpc5200_pic 0 0 3
++				 c000 0 0 3 &mpc5200_pic 0 0 3
++				 c000 0 0 4 &mpc5200_pic 0 0 3>;
++		clock-frequency = <0>; // From boot loader
++		interrupts = <2 8 0 2 9 0 2 a 0>;
++		interrupt-parent = <&mpc5200_pic>;
++		bus-range = <0 0>;
++		ranges = <42000000 0 80000000 80000000 0 10000000
++			  02000000 0 90000000 90000000 0 10000000
++			  01000000 0 00000000 a0000000 0 01000000>;
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/walnut.dts powerpc.git/arch/powerpc/boot/dts/walnut.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/walnut.dts	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/walnut.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -14,14 +14,21 @@
+ 	#size-cells = <1>;
+ 	model = "ibm,walnut";
+ 	compatible = "ibm,walnut";
+-	dcr-parent = <&/cpus/PowerPC,405GP@0>;
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC;
++		serial0 = &UART0;
++		serial1 = &UART1;
++	};
+ 
+ 	cpus {
+ 		#address-cells = <1>;
+ 		#size-cells = <0>;
+ 
+-		PowerPC,405GP@0 {
++		cpu@0 {
+ 			device_type = "cpu";
++			model = "PowerPC,405GP";
+ 			reg = <0>;
+ 			clock-frequency = <bebc200>; /* Filled in by zImage */
+ 			timebase-frequency = <0>; /* Filled in by zImage */
+@@ -168,9 +175,10 @@
+ 				};
+ 			};
+ 
+-			ds1743@1,0 {
++			nvram@1,0 {
+ 				/* NVRAM and RTC */
+-				compatible = "ds1743";
++				compatible = "ds1743-nvram";
++				#bytes = <2000>;
+ 				reg = <1 0 2000>;
+ 			};
+ 
+@@ -190,6 +198,45 @@
+ 				virtual-reg = <f0300005>;
+ 			};
+ 		};
++
++		PCI0: pci@ec000000 {
++			device_type = "pci";
++			#interrupt-cells = <1>;
++			#size-cells = <2>;
++			#address-cells = <3>;
++			compatible = "ibm,plb405gp-pci", "ibm,plb-pci";
++			primary;
++			reg = <eec00000 8	/* Config space access */
++			       eed80000 4	/* IACK */
++			       eed80000 4	/* Special cycle */
++			       ef480000 40>;	/* Internal registers */
++
++			/* Outbound ranges, one memory and one IO,
++			 * later cannot be changed. Chip supports a second
++			 * IO range but we don't use it for now
++			 */
++			ranges = <02000000 0 80000000 80000000 0 20000000
++				  01000000 0 00000000 e8000000 0 00010000>;
++
++			/* Inbound 2GB range starting at 0 */
++			dma-ranges = <42000000 0 0 0 0 80000000>;
++
++			/* Walnut has all 4 IRQ pins tied together per slot */
++			interrupt-map-mask = <f800 0 0 0>;
++			interrupt-map = <
++				/* IDSEL 1 */
++				0800 0 0 0 &UIC0 1c 8
++
++				/* IDSEL 2 */
++				1000 0 0 0 &UIC0 1d 8
++
++				/* IDSEL 3 */
++				1800 0 0 0 &UIC0 1e 8
++
++				/* IDSEL 4 */
++				2000 0 0 0 &UIC0 1f 8
++			>;
++		};
+ 	};
+ 
+ 	chosen {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/dts/warp.dts powerpc.git/arch/powerpc/boot/dts/warp.dts
+--- linux-2.6.24/arch/powerpc/boot/dts/warp.dts	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/dts/warp.dts	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,239 @@
++/*
++ * Device Tree Source for PIKA Warp
++ *
++ * Copyright (c) 2008 PIKA Technologies
++ *   Sean MacLennan <smaclennan@pikatech.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2.  This program is licensed "as is" without
++ * any warranty of any kind, whether express or implied.
++ */
++
++/ {
++	#address-cells = <2>;
++	#size-cells = <1>;
++	model = "pika,warp";
++	compatible = "pika,warp";
++	dcr-parent = <&/cpus/cpu@0>;
++
++	aliases {
++		ethernet0 = &EMAC0;
++		serial0 = &UART0;
++	};
++
++	cpus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		cpu@0 {
++			device_type = "cpu";
++			model = "PowerPC,440EP";
++			reg = <0>;
++			clock-frequency = <0>; /* Filled in by zImage */
++			timebase-frequency = <0>; /* Filled in by zImage */
++			i-cache-line-size = <20>;
++			d-cache-line-size = <20>;
++			i-cache-size = <8000>;
++			d-cache-size = <8000>;
++			dcr-controller;
++			dcr-access-method = "native";
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0 0 0>; /* Filled in by zImage */
++	};
++
++	UIC0: interrupt-controller0 {
++		compatible = "ibm,uic-440ep","ibm,uic";
++		interrupt-controller;
++		cell-index = <0>;
++		dcr-reg = <0c0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++	};
++
++	UIC1: interrupt-controller1 {
++		compatible = "ibm,uic-440ep","ibm,uic";
++		interrupt-controller;
++		cell-index = <1>;
++		dcr-reg = <0d0 009>;
++		#address-cells = <0>;
++		#size-cells = <0>;
++		#interrupt-cells = <2>;
++		interrupts = <1e 4 1f 4>; /* cascade */
++		interrupt-parent = <&UIC0>;
++	};
++
++	SDR0: sdr {
++		compatible = "ibm,sdr-440ep";
++		dcr-reg = <00e 002>;
++	};
++
++	CPR0: cpr {
++		compatible = "ibm,cpr-440ep";
++		dcr-reg = <00c 002>;
++	};
++
++	plb {
++		compatible = "ibm,plb-440ep", "ibm,plb-440gp", "ibm,plb4";
++		#address-cells = <2>;
++		#size-cells = <1>;
++		ranges;
++		clock-frequency = <0>; /* Filled in by zImage */
++
++		SDRAM0: sdram {
++			compatible = "ibm,sdram-440ep", "ibm,sdram-405gp";
++			dcr-reg = <010 2>;
++		};
++
++		DMA0: dma {
++			compatible = "ibm,dma-440ep", "ibm,dma-440gp";
++			dcr-reg = <100 027>;
++		};
++
++		MAL0: mcmal {
++			compatible = "ibm,mcmal-440ep", "ibm,mcmal-440gp", "ibm,mcmal";
++			dcr-reg = <180 62>;
++			num-tx-chans = <4>;
++			num-rx-chans = <2>;
++			interrupt-parent = <&MAL0>;
++			interrupts = <0 1 2 3 4>;
++			#interrupt-cells = <1>;
++			#address-cells = <0>;
++			#size-cells = <0>;
++			interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
++					/*RXEOB*/ 1 &UIC0 b 4
++					/*SERR*/  2 &UIC1 0 4
++					/*TXDE*/  3 &UIC1 1 4
++					/*RXDE*/  4 &UIC1 2 4>;
++		};
++
++		POB0: opb {
++		  	compatible = "ibm,opb-440ep", "ibm,opb-440gp", "ibm,opb";
++			#address-cells = <1>;
++			#size-cells = <1>;
++		  	ranges = <00000000 0 00000000 80000000
++			          80000000 0 80000000 80000000>;
++		  	interrupt-parent = <&UIC1>;
++		  	interrupts = <7 4>;
++		  	clock-frequency = <0>; /* Filled in by zImage */
++
++			EBC0: ebc {
++				compatible = "ibm,ebc-440ep", "ibm,ebc-440gp", "ibm,ebc";
++				dcr-reg = <012 2>;
++				#address-cells = <2>;
++				#size-cells = <1>;
++				clock-frequency = <0>; /* Filled in by zImage */
++				interrupts = <5 1>;
++				interrupt-parent = <&UIC1>;
++
++				fpga@2,0 {
++					compatible = "pika,fpga";
++			   		reg = <2 0 2200>;
++					interrupts = <18 8>;
++					interrupt-parent = <&UIC0>;
++				};
++
++				nor_flash@0,0 {
++					compatible = "amd,s29gl512n", "cfi-flash";
++					bank-width = <2>;
++					reg = <0 0 4000000>;
++					#address-cells = <1>;
++					#size-cells = <1>;
++					partition@0 {
++						label = "kernel";
++						reg = <0 180000>;
++					};
++					partition@180000 {
++						label = "root";
++						reg = <180000 3480000>;
++					};
++					partition@3600000 {
++						label = "user";
++						reg = <3600000 900000>;
++					};
++					partition@3f00000 {
++						label = "fpga";
++						reg = <3f00000 40000>;
++					};
++					partition@3f40000 {
++						label = "env";
++						reg = <3f40000 40000>;
++					};
++					partition@3f80000 {
++						label = "u-boot";
++						reg = <3f80000 80000>;
++					};
++				};
++			};
++
++			UART0: serial@ef600300 {
++		   		device_type = "serial";
++		   		compatible = "ns16550";
++		   		reg = <ef600300 8>;
++		   		virtual-reg = <ef600300>;
++		   		clock-frequency = <0>; /* Filled in by zImage */
++		   		current-speed = <1c200>;
++		   		interrupt-parent = <&UIC0>;
++		   		interrupts = <0 4>;
++	   		};
++
++			IIC0: i2c@ef600700 {
++				compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic";
++				reg = <ef600700 14>;
++				interrupt-parent = <&UIC0>;
++				interrupts = <2 4>;
++			};
++
++			GPIO0: gpio@ef600b00 {
++				compatible = "ibm,gpio-440ep";
++				reg = <ef600b00 48>;
++			};
++
++			GPIO1: gpio@ef600c00 {
++				compatible = "ibm,gpio-440ep";
++				reg = <ef600c00 48>;
++			};
++
++			ZMII0: emac-zmii@ef600d00 {
++				compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii";
++				reg = <ef600d00 c>;
++			};
++
++			EMAC0: ethernet@ef600e00 {
++				linux,network-index = <0>;
++				device_type = "network";
++				compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac";
++				interrupt-parent = <&UIC1>;
++				interrupts = <1c 4 1d 4>;
++				reg = <ef600e00 70>;
++				local-mac-address = [000000000000];
++				mal-device = <&MAL0>;
++				mal-tx-channel = <0 1>;
++				mal-rx-channel = <0>;
++				cell-index = <0>;
++				max-frame-size = <5dc>;
++				rx-fifo-size = <1000>;
++				tx-fifo-size = <800>;
++				phy-mode = "rmii";
++				phy-map = <00000000>;
++				zmii-device = <&ZMII0>;
++				zmii-channel = <0>;
++			};
++
++			usb@ef601000 {
++				compatible = "ohci-be";
++				reg = <ef601000 80>;
++				interrupts = <8 1 9 1>;
++				interrupt-parent = < &UIC1 >;
++			};
++		};
++	};
++
++	chosen {
++		linux,stdout-path = "/plb/opb/serial@ef600300";
++	};
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/ebony.c powerpc.git/arch/powerpc/boot/ebony.c
+--- linux-2.6.24/arch/powerpc/boot/ebony.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/ebony.c	2008-01-28 20:25:49.000000000 +0100
+@@ -31,66 +31,6 @@
+ 
+ static u8 *ebony_mac0, *ebony_mac1;
+ 
+-/* Calculate 440GP clocks */
+-void ibm440gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
+-{
+-	u32 sys0 = mfdcr(DCRN_CPC0_SYS0);
+-	u32 cr0 = mfdcr(DCRN_CPC0_CR0);
+-	u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
+-	u32 opdv = CPC0_SYS0_OPDV(sys0);
+-	u32 epdv = CPC0_SYS0_EPDV(sys0);
+-
+-	if (sys0 & CPC0_SYS0_BYPASS) {
+-		/* Bypass system PLL */
+-		cpu = plb = sysclk;
+-	} else {
+-		if (sys0 & CPC0_SYS0_EXTSL)
+-			/* PerClk */
+-			m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv;
+-		else
+-			/* CPU clock */
+-			m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0);
+-		cpu = sysclk * m / CPC0_SYS0_FWDVA(sys0);
+-		plb = sysclk * m / CPC0_SYS0_FWDVB(sys0);
+-	}
+-
+-	opb = plb / opdv;
+-	ebc = opb / epdv;
+-
+-	/* FIXME: Check if this is for all 440GP, or just Ebony */
+-	if ((mfpvr() & 0xf0000fff) == 0x40000440)
+-		/* Rev. B 440GP, use external system clock */
+-		tb = sysclk;
+-	else
+-		/* Rev. C 440GP, errata force us to use internal clock */
+-		tb = cpu;
+-
+-	if (cr0 & CPC0_CR0_U0EC)
+-		/* External UART clock */
+-		uart0 = ser_clk;
+-	else
+-		/* Internal UART clock */
+-		uart0 = plb / CPC0_CR0_UDIV(cr0);
+-
+-	if (cr0 & CPC0_CR0_U1EC)
+-		/* External UART clock */
+-		uart1 = ser_clk;
+-	else
+-		/* Internal UART clock */
+-		uart1 = plb / CPC0_CR0_UDIV(cr0);
+-
+-	printf("PPC440GP: SysClk = %dMHz (%x)\n\r",
+-	       (sysclk + 500000) / 1000000, sysclk);
+-
+-	dt_fixup_cpu_clocks(cpu, tb, 0);
+-
+-	dt_fixup_clock("/plb", plb);
+-	dt_fixup_clock("/plb/opb", opb);
+-	dt_fixup_clock("/plb/opb/ebc", ebc);
+-	dt_fixup_clock("/plb/opb/serial@40000200", uart0);
+-	dt_fixup_clock("/plb/opb/serial@40000300", uart1);
+-}
+-
+ #define EBONY_FPGA_PATH		"/plb/opb/ebc/fpga"
+ #define	EBONY_FPGA_FLASH_SEL	0x01
+ #define EBONY_SMALL_FLASH_PATH	"/plb/opb/ebc/small-flash"
+@@ -134,7 +74,7 @@
+ 	unsigned long sysclk = 33000000;
+ 
+ 	ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
+-	ibm4xx_fixup_memsize();
++	ibm4xx_sdram_fixup_memsize();
+ 	dt_fixup_mac_addresses(ebony_mac0, ebony_mac1);
+ 	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
+ 	ebony_flashsel_fixup();
+@@ -146,6 +86,6 @@
+ 	platform_ops.exit = ibm44x_dbcr_reset;
+ 	ebony_mac0 = mac0;
+ 	ebony_mac1 = mac1;
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/ep405.c powerpc.git/arch/powerpc/boot/ep405.c
+--- linux-2.6.24/arch/powerpc/boot/ep405.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/ep405.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,74 @@
++/*
++ * Embedded Planet EP405 with PlanetCore firmware
++ *
++ * (c) Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp,\
++ *
++ * Based on ep88xc.c by
++ *
++ * Scott Wood <scottwood@freescale.com>
++ *
++ * Copyright (c) 2007 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 version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include "ops.h"
++#include "stdio.h"
++#include "planetcore.h"
++#include "dcr.h"
++#include "4xx.h"
++#include "io.h"
++
++static char *table;
++static u64 mem_size;
++
++static void platform_fixups(void)
++{
++	u64 val;
++	void *nvrtc;
++
++	dt_fixup_memory(0, mem_size);
++	planetcore_set_mac_addrs(table);
++
++	if (!planetcore_get_decimal(table, PLANETCORE_KEY_CRYSTAL_HZ, &val)) {
++		printf("No PlanetCore crystal frequency key.\r\n");
++		return;
++	}
++	ibm405gp_fixup_clocks(val, 0xa8c000);
++	ibm4xx_quiesce_eth((u32 *)0xef600800, NULL);
++	ibm4xx_fixup_ebc_ranges("/plb/ebc");
++
++	if (!planetcore_get_decimal(table, PLANETCORE_KEY_KB_NVRAM, &val)) {
++		printf("No PlanetCore NVRAM size key.\r\n");
++		return;
++	}
++	nvrtc = finddevice("/plb/ebc/nvrtc@4,200000");
++	if (nvrtc != NULL) {
++		u32 reg[3] = { 4, 0x200000, 0};
++		getprop(nvrtc, "reg", reg, 3);
++		reg[2] = (val << 10) & 0xffffffff;
++		setprop(nvrtc, "reg", reg, 3);
++	}
++}
++
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++		   unsigned long r6, unsigned long r7)
++{
++	table = (char *)r3;
++	planetcore_prepare_table(table);
++
++	if (!planetcore_get_decimal(table, PLANETCORE_KEY_MB_RAM, &mem_size))
++		return;
++
++	mem_size *= 1024 * 1024;
++	simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
++
++	fdt_init(_dtb_start);
++
++	planetcore_set_stdout_path(table);
++
++	serial_console_init();
++	platform_ops.fixups = platform_fixups;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/ep8248e.c powerpc.git/arch/powerpc/boot/ep8248e.c
+--- linux-2.6.24/arch/powerpc/boot/ep8248e.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/ep8248e.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,55 @@
++/*
++ * Embedded Planet EP8248E with PlanetCore firmware
++ *
++ * Author: Scott Wood <scottwood@freescale.com>
++ *
++ * Copyright (c) 2007 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 version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include "ops.h"
++#include "stdio.h"
++#include "planetcore.h"
++#include "pq2.h"
++
++static char *table;
++static u64 mem_size;
++
++#include <io.h>
++
++static void platform_fixups(void)
++{
++	u64 val;
++
++	dt_fixup_memory(0, mem_size);
++	planetcore_set_mac_addrs(table);
++
++	if (!planetcore_get_decimal(table, PLANETCORE_KEY_CRYSTAL_HZ, &val)) {
++		printf("No PlanetCore crystal frequency key.\r\n");
++		return;
++	}
++
++	pq2_fixup_clocks(val);
++}
++
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++                   unsigned long r6, unsigned long r7)
++{
++	table = (char *)r3;
++	planetcore_prepare_table(table);
++
++	if (!planetcore_get_decimal(table, PLANETCORE_KEY_MB_RAM, &mem_size))
++		return;
++
++	mem_size *= 1024 * 1024;
++	simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
++
++	fdt_init(_dtb_start);
++
++	planetcore_set_stdout_path(table);
++	serial_console_init();
++	platform_ops.fixups = platform_fixups;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/ep88xc.c powerpc.git/arch/powerpc/boot/ep88xc.c
+--- linux-2.6.24/arch/powerpc/boot/ep88xc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/ep88xc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -45,7 +45,7 @@
+ 	mem_size *= 1024 * 1024;
+ 	simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
+ 
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 
+ 	planetcore_set_stdout_path(table);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/flatdevtree.c powerpc.git/arch/powerpc/boot/flatdevtree.c
+--- linux-2.6.24/arch/powerpc/boot/flatdevtree.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/flatdevtree.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1036 +0,0 @@
+-/*
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- *
+- * Copyright Pantelis Antoniou 2006
+- * Copyright (C) IBM Corporation 2006
+- *
+- * Authors: Pantelis Antoniou <pantelis@embeddedalley.com>
+- *	    Hollis Blanchard <hollisb@us.ibm.com>
+- *	    Mark A. Greer <mgreer@mvista.com>
+- *	    Paul Mackerras <paulus@samba.org>
+- */
+-
+-#include <string.h>
+-#include <stddef.h>
+-#include "flatdevtree.h"
+-#include "flatdevtree_env.h"
+-
+-#define _ALIGN(x, al)	(((x) + (al) - 1) & ~((al) - 1))
+-
+-static char *ft_root_node(struct ft_cxt *cxt)
+-{
+-	return cxt->rgn[FT_STRUCT].start;
+-}
+-
+-/* Routines for keeping node ptrs returned by ft_find_device current */
+-/* First entry not used b/c it would return 0 and be taken as NULL/error */
+-static void *ft_get_phandle(struct ft_cxt *cxt, char *node)
+-{
+-	unsigned int i;
+-
+-	if (!node)
+-		return NULL;
+-
+-	for (i = 1; i < cxt->nodes_used; i++)	/* already there? */
+-		if (cxt->node_tbl[i] == node)
+-			return (void *)i;
+-
+-	if (cxt->nodes_used < cxt->node_max) {
+-		cxt->node_tbl[cxt->nodes_used] = node;
+-		return (void *)cxt->nodes_used++;
+-	}
+-
+-	return NULL;
+-}
+-
+-static char *ft_node_ph2node(struct ft_cxt *cxt, const void *phandle)
+-{
+-	unsigned int i = (unsigned int)phandle;
+-
+-	if (i < cxt->nodes_used)
+-		return cxt->node_tbl[i];
+-	return NULL;
+-}
+-
+-static void ft_node_update_before(struct ft_cxt *cxt, char *addr, int shift)
+-{
+-	unsigned int i;
+-
+-	if (shift == 0)
+-		return;
+-
+-	for (i = 1; i < cxt->nodes_used; i++)
+-		if (cxt->node_tbl[i] < addr)
+-			cxt->node_tbl[i] += shift;
+-}
+-
+-static void ft_node_update_after(struct ft_cxt *cxt, char *addr, int shift)
+-{
+-	unsigned int i;
+-
+-	if (shift == 0)
+-		return;
+-
+-	for (i = 1; i < cxt->nodes_used; i++)
+-		if (cxt->node_tbl[i] >= addr)
+-			cxt->node_tbl[i] += shift;
+-}
+-
+-/* Struct used to return info from ft_next() */
+-struct ft_atom {
+-	u32 tag;
+-	const char *name;
+-	void *data;
+-	u32 size;
+-};
+-
+-/* Set ptrs to current one's info; return addr of next one */
+-static char *ft_next(struct ft_cxt *cxt, char *p, struct ft_atom *ret)
+-{
+-	u32 sz;
+-
+-	if (p >= cxt->rgn[FT_STRUCT].start + cxt->rgn[FT_STRUCT].size)
+-		return NULL;
+-
+-	ret->tag = be32_to_cpu(*(u32 *) p);
+-	p += 4;
+-
+-	switch (ret->tag) {	/* Tag */
+-	case OF_DT_BEGIN_NODE:
+-		ret->name = p;
+-		ret->data = (void *)(p - 4);	/* start of node */
+-		p += _ALIGN(strlen(p) + 1, 4);
+-		break;
+-	case OF_DT_PROP:
+-		ret->size = sz = be32_to_cpu(*(u32 *) p);
+-		ret->name = cxt->str_anchor + be32_to_cpu(*(u32 *) (p + 4));
+-		ret->data = (void *)(p + 8);
+-		p += 8 + _ALIGN(sz, 4);
+-		break;
+-	case OF_DT_END_NODE:
+-	case OF_DT_NOP:
+-		break;
+-	case OF_DT_END:
+-	default:
+-		p = NULL;
+-		break;
+-	}
+-
+-	return p;
+-}
+-
+-#define HDR_SIZE	_ALIGN(sizeof(struct boot_param_header), 8)
+-#define EXPAND_INCR	1024	/* alloc this much extra when expanding */
+-
+-/* Copy the tree to a newly-allocated region and put things in order */
+-static int ft_reorder(struct ft_cxt *cxt, int nextra)
+-{
+-	unsigned long tot;
+-	enum ft_rgn_id r;
+-	char *p, *pend;
+-	int stroff;
+-
+-	tot = HDR_SIZE + EXPAND_INCR;
+-	for (r = FT_RSVMAP; r <= FT_STRINGS; ++r)
+-		tot += cxt->rgn[r].size;
+-	if (nextra > 0)
+-		tot += nextra;
+-	tot = _ALIGN(tot, 8);
+-
+-	if (!cxt->realloc)
+-		return 0;
+-	p = cxt->realloc(NULL, tot);
+-	if (!p)
+-		return 0;
+-
+-	memcpy(p, cxt->bph, sizeof(struct boot_param_header));
+-	/* offsets get fixed up later */
+-
+-	cxt->bph = (struct boot_param_header *)p;
+-	cxt->max_size = tot;
+-	pend = p + tot;
+-	p += HDR_SIZE;
+-
+-	memcpy(p, cxt->rgn[FT_RSVMAP].start, cxt->rgn[FT_RSVMAP].size);
+-	cxt->rgn[FT_RSVMAP].start = p;
+-	p += cxt->rgn[FT_RSVMAP].size;
+-
+-	memcpy(p, cxt->rgn[FT_STRUCT].start, cxt->rgn[FT_STRUCT].size);
+-	ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
+-			p - cxt->rgn[FT_STRUCT].start);
+-	cxt->p += p - cxt->rgn[FT_STRUCT].start;
+-	cxt->rgn[FT_STRUCT].start = p;
+-
+-	p = pend - cxt->rgn[FT_STRINGS].size;
+-	memcpy(p, cxt->rgn[FT_STRINGS].start, cxt->rgn[FT_STRINGS].size);
+-	stroff = cxt->str_anchor - cxt->rgn[FT_STRINGS].start;
+-	cxt->rgn[FT_STRINGS].start = p;
+-	cxt->str_anchor = p + stroff;
+-
+-	cxt->isordered = 1;
+-	return 1;
+-}
+-
+-static inline char *prev_end(struct ft_cxt *cxt, enum ft_rgn_id r)
+-{
+-	if (r > FT_RSVMAP)
+-		return cxt->rgn[r - 1].start + cxt->rgn[r - 1].size;
+-	return (char *)cxt->bph + HDR_SIZE;
+-}
+-
+-static inline char *next_start(struct ft_cxt *cxt, enum ft_rgn_id r)
+-{
+-	if (r < FT_STRINGS)
+-		return cxt->rgn[r + 1].start;
+-	return (char *)cxt->bph + cxt->max_size;
+-}
+-
+-/*
+- * See if we can expand region rgn by nextra bytes by using up
+- * free space after or before the region.
+- */
+-static int ft_shuffle(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
+-		int nextra)
+-{
+-	char *p = *pp;
+-	char *rgn_start, *rgn_end;
+-
+-	rgn_start = cxt->rgn[rgn].start;
+-	rgn_end = rgn_start + cxt->rgn[rgn].size;
+-	if (nextra <= 0 || rgn_end + nextra <= next_start(cxt, rgn)) {
+-		/* move following stuff */
+-		if (p < rgn_end) {
+-			if (nextra < 0)
+-				memmove(p, p - nextra, rgn_end - p + nextra);
+-			else
+-				memmove(p + nextra, p, rgn_end - p);
+-			if (rgn == FT_STRUCT)
+-				ft_node_update_after(cxt, p, nextra);
+-		}
+-		cxt->rgn[rgn].size += nextra;
+-		if (rgn == FT_STRINGS)
+-			/* assumes strings only added at beginning */
+-			cxt->str_anchor += nextra;
+-		return 1;
+-	}
+-	if (prev_end(cxt, rgn) <= rgn_start - nextra) {
+-		/* move preceding stuff */
+-		if (p > rgn_start) {
+-			memmove(rgn_start - nextra, rgn_start, p - rgn_start);
+-			if (rgn == FT_STRUCT)
+-				ft_node_update_before(cxt, p, -nextra);
+-		}
+-		*pp -= nextra;
+-		cxt->rgn[rgn].start -= nextra;
+-		cxt->rgn[rgn].size += nextra;
+-		return 1;
+-	}
+-	return 0;
+-}
+-
+-static int ft_make_space(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
+-			 int nextra)
+-{
+-	unsigned long size, ssize, tot;
+-	char *str, *next;
+-	enum ft_rgn_id r;
+-
+-	if (!cxt->isordered) {
+-		unsigned long rgn_off = *pp - cxt->rgn[rgn].start;
+-
+-		if (!ft_reorder(cxt, nextra))
+-			return 0;
+-
+-		*pp = cxt->rgn[rgn].start + rgn_off;
+-	}
+-	if (ft_shuffle(cxt, pp, rgn, nextra))
+-		return 1;
+-
+-	/* See if there is space after the strings section */
+-	ssize = cxt->rgn[FT_STRINGS].size;
+-	if (cxt->rgn[FT_STRINGS].start + ssize
+-			< (char *)cxt->bph + cxt->max_size) {
+-		/* move strings up as far as possible */
+-		str = (char *)cxt->bph + cxt->max_size - ssize;
+-		cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
+-		memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
+-		cxt->rgn[FT_STRINGS].start = str;
+-		/* enough space now? */
+-		if (rgn >= FT_STRUCT && ft_shuffle(cxt, pp, rgn, nextra))
+-			return 1;
+-	}
+-
+-	/* how much total free space is there following this region? */
+-	tot = 0;
+-	for (r = rgn; r < FT_STRINGS; ++r) {
+-		char *r_end = cxt->rgn[r].start + cxt->rgn[r].size;
+-		tot += next_start(cxt, rgn) - r_end;
+-	}
+-
+-	/* cast is to shut gcc up; we know nextra >= 0 */
+-	if (tot < (unsigned int)nextra) {
+-		/* have to reallocate */
+-		char *newp, *new_start;
+-		int shift;
+-
+-		if (!cxt->realloc)
+-			return 0;
+-		size = _ALIGN(cxt->max_size + (nextra - tot) + EXPAND_INCR, 8);
+-		newp = cxt->realloc(cxt->bph, size);
+-		if (!newp)
+-			return 0;
+-		cxt->max_size = size;
+-		shift = newp - (char *)cxt->bph;
+-
+-		if (shift) { /* realloc can return same addr */
+-			cxt->bph = (struct boot_param_header *)newp;
+-			ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
+-					shift);
+-			for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
+-				new_start = cxt->rgn[r].start + shift;
+-				cxt->rgn[r].start = new_start;
+-			}
+-			*pp += shift;
+-			cxt->str_anchor += shift;
+-		}
+-
+-		/* move strings up to the end */
+-		str = newp + size - ssize;
+-		cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
+-		memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
+-		cxt->rgn[FT_STRINGS].start = str;
+-
+-		if (ft_shuffle(cxt, pp, rgn, nextra))
+-			return 1;
+-	}
+-
+-	/* must be FT_RSVMAP and we need to move FT_STRUCT up */
+-	if (rgn == FT_RSVMAP) {
+-		next = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
+-			+ nextra;
+-		ssize = cxt->rgn[FT_STRUCT].size;
+-		if (next + ssize >= cxt->rgn[FT_STRINGS].start)
+-			return 0;	/* "can't happen" */
+-		memmove(next, cxt->rgn[FT_STRUCT].start, ssize);
+-		ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, nextra);
+-		cxt->rgn[FT_STRUCT].start = next;
+-
+-		if (ft_shuffle(cxt, pp, rgn, nextra))
+-			return 1;
+-	}
+-
+-	return 0;		/* "can't happen" */
+-}
+-
+-static void ft_put_word(struct ft_cxt *cxt, u32 v)
+-{
+-	*(u32 *) cxt->p = cpu_to_be32(v);
+-	cxt->p += 4;
+-}
+-
+-static void ft_put_bin(struct ft_cxt *cxt, const void *data, unsigned int sz)
+-{
+-	unsigned long sza = _ALIGN(sz, 4);
+-
+-	/* zero out the alignment gap if necessary */
+-	if (sz < sza)
+-		*(u32 *) (cxt->p + sza - 4) = 0;
+-
+-	/* copy in the data */
+-	memcpy(cxt->p, data, sz);
+-
+-	cxt->p += sza;
+-}
+-
+-char *ft_begin_node(struct ft_cxt *cxt, const char *name)
+-{
+-	unsigned long nlen = strlen(name) + 1;
+-	unsigned long len = 8 + _ALIGN(nlen, 4);
+-	char *ret;
+-
+-	if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
+-		return NULL;
+-
+-	ret = cxt->p;
+-
+-	ft_put_word(cxt, OF_DT_BEGIN_NODE);
+-	ft_put_bin(cxt, name, strlen(name) + 1);
+-
+-	return ret;
+-}
+-
+-void ft_end_node(struct ft_cxt *cxt)
+-{
+-	ft_put_word(cxt, OF_DT_END_NODE);
+-}
+-
+-void ft_nop(struct ft_cxt *cxt)
+-{
+-	if (ft_make_space(cxt, &cxt->p, FT_STRUCT, 4))
+-		ft_put_word(cxt, OF_DT_NOP);
+-}
+-
+-#define NO_STRING	0x7fffffff
+-
+-static int lookup_string(struct ft_cxt *cxt, const char *name)
+-{
+-	char *p, *end;
+-
+-	p = cxt->rgn[FT_STRINGS].start;
+-	end = p + cxt->rgn[FT_STRINGS].size;
+-	while (p < end) {
+-		if (strcmp(p, (char *)name) == 0)
+-			return p - cxt->str_anchor;
+-		p += strlen(p) + 1;
+-	}
+-
+-	return NO_STRING;
+-}
+-
+-/* lookup string and insert if not found */
+-static int map_string(struct ft_cxt *cxt, const char *name)
+-{
+-	int off;
+-	char *p;
+-
+-	off = lookup_string(cxt, name);
+-	if (off != NO_STRING)
+-		return off;
+-	p = cxt->rgn[FT_STRINGS].start;
+-	if (!ft_make_space(cxt, &p, FT_STRINGS, strlen(name) + 1))
+-		return NO_STRING;
+-	strcpy(p, name);
+-	return p - cxt->str_anchor;
+-}
+-
+-int ft_prop(struct ft_cxt *cxt, const char *name, const void *data,
+-		unsigned int sz)
+-{
+-	int off, len;
+-
+-	off = map_string(cxt, name);
+-	if (off == NO_STRING)
+-		return -1;
+-
+-	len = 12 + _ALIGN(sz, 4);
+-	if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
+-		return -1;
+-
+-	ft_put_word(cxt, OF_DT_PROP);
+-	ft_put_word(cxt, sz);
+-	ft_put_word(cxt, off);
+-	ft_put_bin(cxt, data, sz);
+-	return 0;
+-}
+-
+-int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
+-{
+-	return ft_prop(cxt, name, str, strlen(str) + 1);
+-}
+-
+-int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val)
+-{
+-	u32 v = cpu_to_be32((u32) val);
+-
+-	return ft_prop(cxt, name, &v, 4);
+-}
+-
+-/* Calculate the size of the reserved map */
+-static unsigned long rsvmap_size(struct ft_cxt *cxt)
+-{
+-	struct ft_reserve *res;
+-
+-	res = (struct ft_reserve *)cxt->rgn[FT_RSVMAP].start;
+-	while (res->start || res->len)
+-		++res;
+-	return (char *)(res + 1) - cxt->rgn[FT_RSVMAP].start;
+-}
+-
+-/* Calculate the size of the struct region by stepping through it */
+-static unsigned long struct_size(struct ft_cxt *cxt)
+-{
+-	char *p = cxt->rgn[FT_STRUCT].start;
+-	char *next;
+-	struct ft_atom atom;
+-
+-	/* make check in ft_next happy */
+-	if (cxt->rgn[FT_STRUCT].size == 0)
+-		cxt->rgn[FT_STRUCT].size = 0xfffffffful - (unsigned long)p;
+-
+-	while ((next = ft_next(cxt, p, &atom)) != NULL)
+-		p = next;
+-	return p + 4 - cxt->rgn[FT_STRUCT].start;
+-}
+-
+-/* add `adj' on to all string offset values in the struct area */
+-static void adjust_string_offsets(struct ft_cxt *cxt, int adj)
+-{
+-	char *p = cxt->rgn[FT_STRUCT].start;
+-	char *next;
+-	struct ft_atom atom;
+-	int off;
+-
+-	while ((next = ft_next(cxt, p, &atom)) != NULL) {
+-		if (atom.tag == OF_DT_PROP) {
+-			off = be32_to_cpu(*(u32 *) (p + 8));
+-			*(u32 *) (p + 8) = cpu_to_be32(off + adj);
+-		}
+-		p = next;
+-	}
+-}
+-
+-/* start construction of the flat OF tree from scratch */
+-void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
+-		void *(*realloc_fn) (void *, unsigned long))
+-{
+-	struct boot_param_header *bph = blob;
+-	char *p;
+-	struct ft_reserve *pres;
+-
+-	/* clear the cxt */
+-	memset(cxt, 0, sizeof(*cxt));
+-
+-	cxt->bph = bph;
+-	cxt->max_size = max_size;
+-	cxt->realloc = realloc_fn;
+-	cxt->isordered = 1;
+-
+-	/* zero everything in the header area */
+-	memset(bph, 0, sizeof(*bph));
+-
+-	bph->magic = cpu_to_be32(OF_DT_HEADER);
+-	bph->version = cpu_to_be32(0x10);
+-	bph->last_comp_version = cpu_to_be32(0x10);
+-
+-	/* start pointers */
+-	cxt->rgn[FT_RSVMAP].start = p = blob + HDR_SIZE;
+-	cxt->rgn[FT_RSVMAP].size = sizeof(struct ft_reserve);
+-	pres = (struct ft_reserve *)p;
+-	cxt->rgn[FT_STRUCT].start = p += sizeof(struct ft_reserve);
+-	cxt->rgn[FT_STRUCT].size = 4;
+-	cxt->rgn[FT_STRINGS].start = blob + max_size;
+-	cxt->rgn[FT_STRINGS].size = 0;
+-
+-	/* init rsvmap and struct */
+-	pres->start = 0;
+-	pres->len = 0;
+-	*(u32 *) p = cpu_to_be32(OF_DT_END);
+-
+-	cxt->str_anchor = blob;
+-}
+-
+-/* open up an existing blob to be examined or modified */
+-int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
+-		unsigned int max_find_device,
+-		void *(*realloc_fn) (void *, unsigned long))
+-{
+-	struct boot_param_header *bph = blob;
+-
+-	/* can't cope with version < 16 */
+-	if (be32_to_cpu(bph->version) < 16)
+-		return -1;
+-
+-	/* clear the cxt */
+-	memset(cxt, 0, sizeof(*cxt));
+-
+-	/* alloc node_tbl to track node ptrs returned by ft_find_device */
+-	++max_find_device;
+-	cxt->node_tbl = realloc_fn(NULL, max_find_device * sizeof(char *));
+-	if (!cxt->node_tbl)
+-		return -1;
+-	memset(cxt->node_tbl, 0, max_find_device * sizeof(char *));
+-	cxt->node_max = max_find_device;
+-	cxt->nodes_used = 1;	/* don't use idx 0 b/c looks like NULL */
+-
+-	cxt->bph = bph;
+-	cxt->max_size = max_size;
+-	cxt->realloc = realloc_fn;
+-
+-	cxt->rgn[FT_RSVMAP].start = blob + be32_to_cpu(bph->off_mem_rsvmap);
+-	cxt->rgn[FT_RSVMAP].size = rsvmap_size(cxt);
+-	cxt->rgn[FT_STRUCT].start = blob + be32_to_cpu(bph->off_dt_struct);
+-	cxt->rgn[FT_STRUCT].size = struct_size(cxt);
+-	cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings);
+-	cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size);
+-
+-	cxt->p = cxt->rgn[FT_STRUCT].start;
+-	cxt->str_anchor = cxt->rgn[FT_STRINGS].start;
+-
+-	return 0;
+-}
+-
+-/* add a reserver physical area to the rsvmap */
+-int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
+-{
+-	char *p;
+-	struct ft_reserve *pres;
+-
+-	p = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
+-		- sizeof(struct ft_reserve);
+-	if (!ft_make_space(cxt, &p, FT_RSVMAP, sizeof(struct ft_reserve)))
+-		return -1;
+-
+-	pres = (struct ft_reserve *)p;
+-	pres->start = cpu_to_be64(physaddr);
+-	pres->len = cpu_to_be64(size);
+-
+-	return 0;
+-}
+-
+-void ft_begin_tree(struct ft_cxt *cxt)
+-{
+-	cxt->p = ft_root_node(cxt);
+-}
+-
+-void ft_end_tree(struct ft_cxt *cxt)
+-{
+-	struct boot_param_header *bph = cxt->bph;
+-	char *p, *oldstr, *str, *endp;
+-	unsigned long ssize;
+-	int adj;
+-
+-	if (!cxt->isordered)
+-		return;		/* we haven't touched anything */
+-
+-	/* adjust string offsets */
+-	oldstr = cxt->rgn[FT_STRINGS].start;
+-	adj = cxt->str_anchor - oldstr;
+-	if (adj)
+-		adjust_string_offsets(cxt, adj);
+-
+-	/* make strings end on 8-byte boundary */
+-	ssize = cxt->rgn[FT_STRINGS].size;
+-	endp = (char *)_ALIGN((unsigned long)cxt->rgn[FT_STRUCT].start
+-			+ cxt->rgn[FT_STRUCT].size + ssize, 8);
+-	str = endp - ssize;
+-
+-	/* move strings down to end of structs */
+-	memmove(str, oldstr, ssize);
+-	cxt->str_anchor = str;
+-	cxt->rgn[FT_STRINGS].start = str;
+-
+-	/* fill in header fields */
+-	p = (char *)bph;
+-	bph->totalsize = cpu_to_be32(endp - p);
+-	bph->off_mem_rsvmap = cpu_to_be32(cxt->rgn[FT_RSVMAP].start - p);
+-	bph->off_dt_struct = cpu_to_be32(cxt->rgn[FT_STRUCT].start - p);
+-	bph->off_dt_strings = cpu_to_be32(cxt->rgn[FT_STRINGS].start - p);
+-	bph->dt_strings_size = cpu_to_be32(ssize);
+-}
+-
+-void *ft_find_device(struct ft_cxt *cxt, const void *top, const char *srch_path)
+-{
+-	char *node;
+-
+-	if (top) {
+-		node = ft_node_ph2node(cxt, top);
+-		if (node == NULL)
+-			return NULL;
+-	} else {
+-		node = ft_root_node(cxt);
+-	}
+-
+-	node = ft_find_descendent(cxt, node, srch_path);
+-	return ft_get_phandle(cxt, node);
+-}
+-
+-void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path)
+-{
+-	struct ft_atom atom;
+-	char *p;
+-	const char *cp, *q;
+-	int cl;
+-	int depth = -1;
+-	int dmatch = 0;
+-	const char *path_comp[FT_MAX_DEPTH];
+-
+-	cp = srch_path;
+-	cl = 0;
+-	p = top;
+-
+-	while ((p = ft_next(cxt, p, &atom)) != NULL) {
+-		switch (atom.tag) {
+-		case OF_DT_BEGIN_NODE:
+-			++depth;
+-			if (depth != dmatch)
+-				break;
+-			cxt->genealogy[depth] = atom.data;
+-			cxt->genealogy[depth + 1] = NULL;
+-			if (depth && !(strncmp(atom.name, cp, cl) == 0
+-					&& (atom.name[cl] == '/'
+-						|| atom.name[cl] == '\0'
+-						|| atom.name[cl] == '@')))
+-				break;
+-			path_comp[dmatch] = cp;
+-			/* it matches so far, advance to next path component */
+-			cp += cl;
+-			/* skip slashes */
+-			while (*cp == '/')
+-				++cp;
+-			/* we're done if this is the end of the string */
+-			if (*cp == 0)
+-				return atom.data;
+-			/* look for end of this component */
+-			q = strchr(cp, '/');
+-			if (q)
+-				cl = q - cp;
+-			else
+-				cl = strlen(cp);
+-			++dmatch;
+-			break;
+-		case OF_DT_END_NODE:
+-			if (depth == 0)
+-				return NULL;
+-			if (dmatch > depth) {
+-				--dmatch;
+-				cl = cp - path_comp[dmatch] - 1;
+-				cp = path_comp[dmatch];
+-				while (cl > 0 && cp[cl - 1] == '/')
+-					--cl;
+-			}
+-			--depth;
+-			break;
+-		}
+-	}
+-	return NULL;
+-}
+-
+-void *__ft_get_parent(struct ft_cxt *cxt, void *node)
+-{
+-	int d;
+-	struct ft_atom atom;
+-	char *p;
+-
+-	for (d = 0; cxt->genealogy[d] != NULL; ++d)
+-		if (cxt->genealogy[d] == node)
+-			return d > 0 ? cxt->genealogy[d - 1] : NULL;
+-
+-	/* have to do it the hard way... */
+-	p = ft_root_node(cxt);
+-	d = 0;
+-	while ((p = ft_next(cxt, p, &atom)) != NULL) {
+-		switch (atom.tag) {
+-		case OF_DT_BEGIN_NODE:
+-			cxt->genealogy[d] = atom.data;
+-			if (node == atom.data) {
+-				/* found it */
+-				cxt->genealogy[d + 1] = NULL;
+-				return d > 0 ? cxt->genealogy[d - 1] : NULL;
+-			}
+-			++d;
+-			break;
+-		case OF_DT_END_NODE:
+-			--d;
+-			break;
+-		}
+-	}
+-	return NULL;
+-}
+-
+-void *ft_get_parent(struct ft_cxt *cxt, const void *phandle)
+-{
+-	void *node = ft_node_ph2node(cxt, phandle);
+-	if (node == NULL)
+-		return NULL;
+-
+-	node = __ft_get_parent(cxt, node);
+-	return ft_get_phandle(cxt, node);
+-}
+-
+-static const void *__ft_get_prop(struct ft_cxt *cxt, void *node,
+-                                 const char *propname, unsigned int *len)
+-{
+-	struct ft_atom atom;
+-	int depth = 0;
+-
+-	while ((node = ft_next(cxt, node, &atom)) != NULL) {
+-		switch (atom.tag) {
+-		case OF_DT_BEGIN_NODE:
+-			++depth;
+-			break;
+-
+-		case OF_DT_PROP:
+-			if (depth != 1 || strcmp(atom.name, propname))
+-				break;
+-
+-			if (len)
+-				*len = atom.size;
+-
+-			return atom.data;
+-
+-		case OF_DT_END_NODE:
+-			if (--depth <= 0)
+-				return NULL;
+-		}
+-	}
+-
+-	return NULL;
+-}
+-
+-int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
+-		void *buf, const unsigned int buflen)
+-{
+-	const void *data;
+-	unsigned int size;
+-
+-	void *node = ft_node_ph2node(cxt, phandle);
+-	if (!node)
+-		return -1;
+-
+-	data = __ft_get_prop(cxt, node, propname, &size);
+-	if (data) {
+-		unsigned int clipped_size = min(size, buflen);
+-		memcpy(buf, data, clipped_size);
+-		return size;
+-	}
+-
+-	return -1;
+-}
+-
+-void *__ft_find_node_by_prop_value(struct ft_cxt *cxt, void *prev,
+-                                   const char *propname, const char *propval,
+-                                   unsigned int proplen)
+-{
+-	struct ft_atom atom;
+-	char *p = ft_root_node(cxt);
+-	char *next;
+-	int past_prev = prev ? 0 : 1;
+-	int depth = -1;
+-
+-	while ((next = ft_next(cxt, p, &atom)) != NULL) {
+-		const void *data;
+-		unsigned int size;
+-
+-		switch (atom.tag) {
+-		case OF_DT_BEGIN_NODE:
+-			depth++;
+-
+-			if (prev == p) {
+-				past_prev = 1;
+-				break;
+-			}
+-
+-			if (!past_prev || depth < 1)
+-				break;
+-
+-			data = __ft_get_prop(cxt, p, propname, &size);
+-			if (!data || size != proplen)
+-				break;
+-			if (memcmp(data, propval, size))
+-				break;
+-
+-			return p;
+-
+-		case OF_DT_END_NODE:
+-			if (depth-- == 0)
+-				return NULL;
+-
+-			break;
+-		}
+-
+-		p = next;
+-	}
+-
+-	return NULL;
+-}
+-
+-void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev,
+-                                 const char *propname, const char *propval,
+-                                 int proplen)
+-{
+-	void *node = NULL;
+-
+-	if (prev) {
+-		node = ft_node_ph2node(cxt, prev);
+-
+-		if (!node)
+-			return NULL;
+-	}
+-
+-	node = __ft_find_node_by_prop_value(cxt, node, propname,
+-	                                    propval, proplen);
+-	return ft_get_phandle(cxt, node);
+-}
+-
+-int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
+-		const void *buf, const unsigned int buflen)
+-{
+-	struct ft_atom atom;
+-	void *node;
+-	char *p, *next;
+-	int nextra;
+-
+-	node = ft_node_ph2node(cxt, phandle);
+-	if (node == NULL)
+-		return -1;
+-
+-	next = ft_next(cxt, node, &atom);
+-	if (atom.tag != OF_DT_BEGIN_NODE)
+-		/* phandle didn't point to a node */
+-		return -1;
+-	p = next;
+-
+-	while ((next = ft_next(cxt, p, &atom)) != NULL) {
+-		switch (atom.tag) {
+-		case OF_DT_BEGIN_NODE: /* properties must go before subnodes */
+-		case OF_DT_END_NODE:
+-			/* haven't found the property, insert here */
+-			cxt->p = p;
+-			return ft_prop(cxt, propname, buf, buflen);
+-		case OF_DT_PROP:
+-			if (strcmp(atom.name, propname))
+-				break;
+-			/* found an existing property, overwrite it */
+-			nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4);
+-			cxt->p = atom.data;
+-			if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT,
+-						nextra))
+-				return -1;
+-			*(u32 *) (cxt->p - 8) = cpu_to_be32(buflen);
+-			ft_put_bin(cxt, buf, buflen);
+-			return 0;
+-		}
+-		p = next;
+-	}
+-	return -1;
+-}
+-
+-int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname)
+-{
+-	struct ft_atom atom;
+-	void *node;
+-	char *p, *next;
+-	int size;
+-
+-	node = ft_node_ph2node(cxt, phandle);
+-	if (node == NULL)
+-		return -1;
+-
+-	p = node;
+-	while ((next = ft_next(cxt, p, &atom)) != NULL) {
+-		switch (atom.tag) {
+-		case OF_DT_BEGIN_NODE:
+-		case OF_DT_END_NODE:
+-			return -1;
+-		case OF_DT_PROP:
+-			if (strcmp(atom.name, propname))
+-				break;
+-			/* found the property, remove it */
+-			size = 12 + -_ALIGN(atom.size, 4);
+-			cxt->p = p;
+-			if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size))
+-				return -1;
+-			return 0;
+-		}
+-		p = next;
+-	}
+-	return -1;
+-}
+-
+-void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name)
+-{
+-	struct ft_atom atom;
+-	char *p, *next, *ret;
+-	int depth = 0;
+-
+-	if (parent) {
+-		p = ft_node_ph2node(cxt, parent);
+-		if (!p)
+-			return NULL;
+-	} else {
+-		p = ft_root_node(cxt);
+-	}
+-
+-	while ((next = ft_next(cxt, p, &atom)) != NULL) {
+-		switch (atom.tag) {
+-		case OF_DT_BEGIN_NODE:
+-			++depth;
+-			if (depth == 1 && strcmp(atom.name, name) == 0)
+-				/* duplicate node name, return error */
+-				return NULL;
+-			break;
+-		case OF_DT_END_NODE:
+-			--depth;
+-			if (depth > 0)
+-				break;
+-			/* end of node, insert here */
+-			cxt->p = p;
+-			ret = ft_begin_node(cxt, name);
+-			ft_end_node(cxt);
+-			return ft_get_phandle(cxt, ret);
+-		}
+-		p = next;
+-	}
+-	return NULL;
+-}
+-
+-/* Returns the start of the path within the provided buffer, or NULL on
+- * error.
+- */
+-char *ft_get_path(struct ft_cxt *cxt, const void *phandle,
+-                  char *buf, int len)
+-{
+-	const char *path_comp[FT_MAX_DEPTH];
+-	struct ft_atom atom;
+-	char *p, *next, *pos;
+-	int depth = 0, i;
+-	void *node;
+-
+-	node = ft_node_ph2node(cxt, phandle);
+-	if (node == NULL)
+-		return NULL;
+-
+-	p = ft_root_node(cxt);
+-
+-	while ((next = ft_next(cxt, p, &atom)) != NULL) {
+-		switch (atom.tag) {
+-		case OF_DT_BEGIN_NODE:
+-			path_comp[depth++] = atom.name;
+-			if (p == node)
+-				goto found;
+-
+-			break;
+-
+-		case OF_DT_END_NODE:
+-			if (--depth == 0)
+-				return NULL;
+-		}
+-
+-		p = next;
+-	}
+-
+-found:
+-	pos = buf;
+-	for (i = 1; i < depth; i++) {
+-		int this_len;
+-
+-		if (len <= 1)
+-			return NULL;
+-
+-		*pos++ = '/';
+-		len--;
+-
+-		strncpy(pos, path_comp[i], len);
+-
+-		if (pos[len - 1] != 0)
+-			return NULL;
+-
+-		this_len = strlen(pos);
+-		len -= this_len;
+-		pos += this_len;
+-	}
+-
+-	return buf;
+-}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/flatdevtree.h powerpc.git/arch/powerpc/boot/flatdevtree.h
+--- linux-2.6.24/arch/powerpc/boot/flatdevtree.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/flatdevtree.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,113 +0,0 @@
+-/*
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-#ifndef FLATDEVTREE_H
+-#define FLATDEVTREE_H
+-
+-#include "flatdevtree_env.h"
+-
+-/* Definitions used by the flattened device tree */
+-#define OF_DT_HEADER            0xd00dfeed      /* marker */
+-#define OF_DT_BEGIN_NODE        0x1     /* Start of node, full name */
+-#define OF_DT_END_NODE          0x2     /* End node */
+-#define OF_DT_PROP              0x3     /* Property: name off, size, content */
+-#define OF_DT_NOP               0x4     /* nop */
+-#define OF_DT_END               0x9
+-
+-#define OF_DT_VERSION           0x10
+-
+-struct boot_param_header {
+-	u32 magic;              /* magic word OF_DT_HEADER */
+-	u32 totalsize;          /* total size of DT block */
+-	u32 off_dt_struct;      /* offset to structure */
+-	u32 off_dt_strings;     /* offset to strings */
+-	u32 off_mem_rsvmap;     /* offset to memory reserve map */
+-	u32 version;            /* format version */
+-	u32 last_comp_version;  /* last compatible version */
+-	/* version 2 fields below */
+-	u32 boot_cpuid_phys;    /* Physical CPU id we're booting on */
+-	/* version 3 fields below */
+-	u32 dt_strings_size;    /* size of the DT strings block */
+-};
+-
+-struct ft_reserve {
+-	u64 start;
+-	u64 len;
+-};
+-
+-struct ft_region {
+-	char *start;
+-	unsigned long size;
+-};
+-
+-enum ft_rgn_id {
+-	FT_RSVMAP,
+-	FT_STRUCT,
+-	FT_STRINGS,
+-	FT_N_REGION
+-};
+-
+-#define FT_MAX_DEPTH	50
+-
+-struct ft_cxt {
+-	struct boot_param_header *bph;
+-	int max_size;           /* maximum size of tree */
+-	int isordered;		/* everything in standard order */
+-	void *(*realloc)(void *, unsigned long);
+-	char *str_anchor;
+-	char *p;		/* current insertion point in structs */
+-	struct ft_region rgn[FT_N_REGION];
+-	void *genealogy[FT_MAX_DEPTH+1];
+-	char **node_tbl;
+-	unsigned int node_max;
+-	unsigned int nodes_used;
+-};
+-
+-char *ft_begin_node(struct ft_cxt *cxt, const char *name);
+-void ft_end_node(struct ft_cxt *cxt);
+-
+-void ft_begin_tree(struct ft_cxt *cxt);
+-void ft_end_tree(struct ft_cxt *cxt);
+-
+-void ft_nop(struct ft_cxt *cxt);
+-int ft_prop(struct ft_cxt *cxt, const char *name,
+-	    const void *data, unsigned int sz);
+-int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
+-int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
+-void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
+-	      void *(*realloc_fn)(void *, unsigned long));
+-int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
+-		unsigned int max_find_device,
+-		void *(*realloc_fn)(void *, unsigned long));
+-int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
+-
+-void ft_dump_blob(const void *bphp);
+-void ft_merge_blob(struct ft_cxt *cxt, void *blob);
+-void *ft_find_device(struct ft_cxt *cxt, const void *top,
+-                     const char *srch_path);
+-void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path);
+-int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
+-		void *buf, const unsigned int buflen);
+-int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
+-		const void *buf, const unsigned int buflen);
+-void *ft_get_parent(struct ft_cxt *cxt, const void *phandle);
+-void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev,
+-                                 const char *propname, const char *propval,
+-                                 int proplen);
+-void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name);
+-char *ft_get_path(struct ft_cxt *cxt, const void *phandle, char *buf, int len);
+-
+-#endif /* FLATDEVTREE_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/flatdevtree_misc.c powerpc.git/arch/powerpc/boot/flatdevtree_misc.c
+--- linux-2.6.24/arch/powerpc/boot/flatdevtree_misc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/flatdevtree_misc.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,79 +0,0 @@
+-/*
+- * This file does the necessary interface mapping between the bootwrapper
+- * device tree operations and the interface provided by shared source
+- * files flatdevicetree.[ch].
+- *
+- * Author: Mark A. Greer <mgreer@mvista.com>
+- *
+- * 2006 (c) MontaVista Software, Inc.  This file is licensed under
+- * the terms of the GNU General Public License version 2.  This program
+- * is licensed "as is" without any warranty of any kind, whether express
+- * or implied.
+- */
+-#include <stddef.h>
+-#include "flatdevtree.h"
+-#include "ops.h"
+-
+-static struct ft_cxt cxt;
+-
+-static void *fdtm_finddevice(const char *name)
+-{
+-	return ft_find_device(&cxt, NULL, name);
+-}
+-
+-static int fdtm_getprop(const void *phandle, const char *propname,
+-                        void *buf, const int buflen)
+-{
+-	return ft_get_prop(&cxt, phandle, propname, buf, buflen);
+-}
+-
+-static int fdtm_setprop(const void *phandle, const char *propname,
+-                        const void *buf, const int buflen)
+-{
+-	return ft_set_prop(&cxt, phandle, propname, buf, buflen);
+-}
+-
+-static void *fdtm_get_parent(const void *phandle)
+-{
+-	return ft_get_parent(&cxt, phandle);
+-}
+-
+-static void *fdtm_create_node(const void *phandle, const char *name)
+-{
+-	return ft_create_node(&cxt, phandle, name);
+-}
+-
+-static void *fdtm_find_node_by_prop_value(const void *prev,
+-                                          const char *propname,
+-                                          const char *propval,
+-                                          int proplen)
+-{
+-	return ft_find_node_by_prop_value(&cxt, prev, propname,
+-	                                  propval, proplen);
+-}
+-
+-static unsigned long fdtm_finalize(void)
+-{
+-	ft_end_tree(&cxt);
+-	return (unsigned long)cxt.bph;
+-}
+-
+-static char *fdtm_get_path(const void *phandle, char *buf, int len)
+-{
+-	return ft_get_path(&cxt, phandle, buf, len);
+-}
+-
+-int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device)
+-{
+-	dt_ops.finddevice = fdtm_finddevice;
+-	dt_ops.getprop = fdtm_getprop;
+-	dt_ops.setprop = fdtm_setprop;
+-	dt_ops.get_parent = fdtm_get_parent;
+-	dt_ops.create_node = fdtm_create_node;
+-	dt_ops.find_node_by_prop_value = fdtm_find_node_by_prop_value;
+-	dt_ops.finalize = fdtm_finalize;
+-	dt_ops.get_path = fdtm_get_path;
+-
+-	return ft_open(&cxt, dt_blob, max_size, max_find_device,
+-			platform_ops.realloc);
+-}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/holly.c powerpc.git/arch/powerpc/boot/holly.c
+--- linux-2.6.24/arch/powerpc/boot/holly.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/holly.c	2008-01-28 20:25:49.000000000 +0100
+@@ -28,6 +28,6 @@
+ 	u32 heapsize = 0x8000000 - (u32)_end; /* 128M */
+ 
+ 	simple_alloc_init(_end, heapsize, 32, 64);
+-	ft_init(_dtb_start, 0, 4);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/Makefile.libfdt powerpc.git/arch/powerpc/boot/libfdt/Makefile.libfdt
+--- linux-2.6.24/arch/powerpc/boot/libfdt/Makefile.libfdt	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/Makefile.libfdt	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,14 @@
++# Makefile.libfdt
++#
++# This is not a complete Makefile of itself.  Instead, it is designed to
++# be easily embeddable into other systems of Makefiles.
++#
++LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
++LIBFDT_INCLUDES = fdt.h libfdt.h
++LIBFDT_EXTRA = libfdt_internal.h
++LIBFDT_LIB = libfdt/libfdt.a
++
++LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
++
++$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/fdt.c powerpc.git/arch/powerpc/boot/libfdt/fdt.c
+--- linux-2.6.24/arch/powerpc/boot/libfdt/fdt.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/fdt.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,156 @@
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2006 David Gibson, IBM Corporation.
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License as
++ *     published by the Free Software Foundation; either version 2 of the
++ *     License, or (at your option) any later version.
++ *
++ *     This library is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++#include "libfdt_env.h"
++
++#include <fdt.h>
++#include <libfdt.h>
++
++#include "libfdt_internal.h"
++
++int fdt_check_header(const void *fdt)
++{
++	if (fdt_magic(fdt) == FDT_MAGIC) {
++		/* Complete tree */
++		if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
++			return -FDT_ERR_BADVERSION;
++		if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
++			return -FDT_ERR_BADVERSION;
++	} else if (fdt_magic(fdt) == SW_MAGIC) {
++		/* Unfinished sequential-write blob */
++		if (fdt_size_dt_struct(fdt) == 0)
++			return -FDT_ERR_BADSTATE;
++	} else {
++		return -FDT_ERR_BADMAGIC;
++	}
++
++	return 0;
++}
++
++const void *fdt_offset_ptr(const void *fdt, int offset, int len)
++{
++	const void *p;
++
++	if (fdt_version(fdt) >= 0x11)
++		if (((offset + len) < offset)
++		    || ((offset + len) > fdt_size_dt_struct(fdt)))
++			return NULL;
++
++	p = _fdt_offset_ptr(fdt, offset);
++
++	if (p + len < p)
++		return NULL;
++	return p;
++}
++
++uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
++{
++	const uint32_t *tagp, *lenp;
++	uint32_t tag;
++	const char *p;
++
++	if (offset % FDT_TAGSIZE)
++		return -1;
++
++	tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
++	if (! tagp)
++		return FDT_END; /* premature end */
++	tag = fdt32_to_cpu(*tagp);
++	offset += FDT_TAGSIZE;
++
++	switch (tag) {
++	case FDT_BEGIN_NODE:
++		/* skip name */
++		do {
++			p = fdt_offset_ptr(fdt, offset++, 1);
++		} while (p && (*p != '\0'));
++		if (! p)
++			return FDT_END;
++		break;
++	case FDT_PROP:
++		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
++		if (! lenp)
++			return FDT_END;
++		/* skip name offset, length and value */
++		offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp);
++		break;
++	}
++
++	if (nextoffset)
++		*nextoffset = ALIGN(offset, FDT_TAGSIZE);
++
++	return tag;
++}
++
++const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
++{
++	int len = strlen(s) + 1;
++	const char *last = strtab + tabsize - len;
++	const char *p;
++
++	for (p = strtab; p <= last; p++)
++		if (memeq(p, s, len))
++			return p;
++	return NULL;
++}
++
++int fdt_move(const void *fdt, void *buf, int bufsize)
++{
++	int err = fdt_check_header(fdt);
++
++	if (err)
++		return err;
++
++	if (fdt_totalsize(fdt) > bufsize)
++		return -FDT_ERR_NOSPACE;
++
++	memmove(buf, fdt, fdt_totalsize(fdt));
++	return 0;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/fdt.h powerpc.git/arch/powerpc/boot/libfdt/fdt.h
+--- linux-2.6.24/arch/powerpc/boot/libfdt/fdt.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/fdt.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,60 @@
++#ifndef _FDT_H
++#define _FDT_H
++
++#ifndef __ASSEMBLY__
++
++struct fdt_header {
++	uint32_t magic;			 /* magic word FDT_MAGIC */
++	uint32_t totalsize;		 /* total size of DT block */
++	uint32_t off_dt_struct;		 /* offset to structure */
++	uint32_t off_dt_strings;	 /* offset to strings */
++	uint32_t off_mem_rsvmap;	 /* offset to memory reserve map */
++	uint32_t version;		 /* format version */
++	uint32_t last_comp_version;	 /* last compatible version */
++
++	/* version 2 fields below */
++	uint32_t boot_cpuid_phys;	 /* Which physical CPU id we're
++					    booting on */
++	/* version 3 fields below */
++	uint32_t size_dt_strings;	 /* size of the strings block */
++
++	/* version 17 fields below */
++	uint32_t size_dt_struct;	 /* size of the structure block */
++};
++
++struct fdt_reserve_entry {
++	uint64_t address;
++	uint64_t size;
++};
++
++struct fdt_node_header {
++	uint32_t tag;
++	char name[0];
++};
++
++struct fdt_property {
++	uint32_t tag;
++	uint32_t len;
++	uint32_t nameoff;
++	char data[0];
++};
++
++#endif /* !__ASSEMBLY */
++
++#define FDT_MAGIC	0xd00dfeed	/* 4: version, 4: total size */
++#define FDT_TAGSIZE	sizeof(uint32_t)
++
++#define FDT_BEGIN_NODE	0x1		/* Start node: full name */
++#define FDT_END_NODE	0x2		/* End node */
++#define FDT_PROP	0x3		/* Property: name off,
++					   size, content */
++#define FDT_NOP		0x4		/* nop */
++#define FDT_END		0x9
++
++#define FDT_V1_SIZE	(7*sizeof(uint32_t))
++#define FDT_V2_SIZE	(FDT_V1_SIZE + sizeof(uint32_t))
++#define FDT_V3_SIZE	(FDT_V2_SIZE + sizeof(uint32_t))
++#define FDT_V16_SIZE	FDT_V3_SIZE
++#define FDT_V17_SIZE	(FDT_V16_SIZE + sizeof(uint32_t))
++
++#endif /* _FDT_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/fdt_ro.c powerpc.git/arch/powerpc/boot/libfdt/fdt_ro.c
+--- linux-2.6.24/arch/powerpc/boot/libfdt/fdt_ro.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/fdt_ro.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,583 @@
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2006 David Gibson, IBM Corporation.
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License as
++ *     published by the Free Software Foundation; either version 2 of the
++ *     License, or (at your option) any later version.
++ *
++ *     This library is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++#include "libfdt_env.h"
++
++#include <fdt.h>
++#include <libfdt.h>
++
++#include "libfdt_internal.h"
++
++#define CHECK_HEADER(fdt) \
++	{ \
++		int err; \
++		if ((err = fdt_check_header(fdt)) != 0) \
++			return err; \
++	}
++
++static int nodename_eq(const void *fdt, int offset,
++		       const char *s, int len)
++{
++	const char *p = fdt_offset_ptr(fdt, offset, len+1);
++
++	if (! p)
++		/* short match */
++		return 0;
++
++	if (memcmp(p, s, len) != 0)
++		return 0;
++
++	if (p[len] == '\0')
++		return 1;
++	else if (!memchr(s, '@', len) && (p[len] == '@'))
++		return 1;
++	else
++		return 0;
++}
++
++const char *fdt_string(const void *fdt, int stroffset)
++{
++	return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
++}
++
++int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
++{
++	CHECK_HEADER(fdt);
++	*address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
++	*size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
++	return 0;
++}
++
++int fdt_num_mem_rsv(const void *fdt)
++{
++	int i = 0;
++
++	while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
++		i++;
++	return i;
++}
++
++int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
++			       const char *name, int namelen)
++{
++	int level = 0;
++	uint32_t tag;
++	int offset, nextoffset;
++
++	CHECK_HEADER(fdt);
++
++	tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
++	if (tag != FDT_BEGIN_NODE)
++		return -FDT_ERR_BADOFFSET;
++
++	do {
++		offset = nextoffset;
++		tag = fdt_next_tag(fdt, offset, &nextoffset);
++
++		switch (tag) {
++		case FDT_END:
++			return -FDT_ERR_TRUNCATED;
++
++		case FDT_BEGIN_NODE:
++			level++;
++			if (level != 1)
++				continue;
++			if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen))
++				/* Found it! */
++				return offset;
++			break;
++
++		case FDT_END_NODE:
++			level--;
++			break;
++
++		case FDT_PROP:
++		case FDT_NOP:
++			break;
++
++		default:
++			return -FDT_ERR_BADSTRUCTURE;
++		}
++	} while (level >= 0);
++
++	return -FDT_ERR_NOTFOUND;
++}
++
++int fdt_subnode_offset(const void *fdt, int parentoffset,
++		       const char *name)
++{
++	return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
++}
++
++int fdt_path_offset(const void *fdt, const char *path)
++{
++	const char *end = path + strlen(path);
++	const char *p = path;
++	int offset = 0;
++
++	CHECK_HEADER(fdt);
++
++	if (*path != '/')
++		return -FDT_ERR_BADPATH;
++
++	while (*p) {
++		const char *q;
++
++		while (*p == '/')
++			p++;
++		if (! *p)
++			return offset;
++		q = strchr(p, '/');
++		if (! q)
++			q = end;
++
++		offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
++		if (offset < 0)
++			return offset;
++
++		p = q;
++	}
++
++	return offset;
++}
++
++const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
++{
++	const struct fdt_node_header *nh;
++	int err;
++
++	if ((err = fdt_check_header(fdt)) != 0)
++		goto fail;
++
++	err = -FDT_ERR_BADOFFSET;
++	nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh));
++	if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE))
++		goto fail;
++
++	if (len)
++		*len = strlen(nh->name);
++
++	return nh->name;
++
++ fail:
++	if (len)
++		*len = err;
++	return NULL;
++}
++
++const struct fdt_property *fdt_get_property(const void *fdt,
++					    int nodeoffset,
++					    const char *name, int *lenp)
++{
++	uint32_t tag;
++	const struct fdt_property *prop;
++	int namestroff;
++	int offset, nextoffset;
++	int err;
++
++	if ((err = fdt_check_header(fdt)) != 0)
++		goto fail;
++
++	err = -FDT_ERR_BADOFFSET;
++	if (nodeoffset % FDT_TAGSIZE)
++		goto fail;
++
++	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
++	if (tag != FDT_BEGIN_NODE)
++		goto fail;
++
++	do {
++		offset = nextoffset;
++
++		tag = fdt_next_tag(fdt, offset, &nextoffset);
++		switch (tag) {
++		case FDT_END:
++			err = -FDT_ERR_TRUNCATED;
++			goto fail;
++
++		case FDT_BEGIN_NODE:
++		case FDT_END_NODE:
++		case FDT_NOP:
++			break;
++
++		case FDT_PROP:
++			err = -FDT_ERR_BADSTRUCTURE;
++			prop = fdt_offset_ptr(fdt, offset, sizeof(*prop));
++			if (! prop)
++				goto fail;
++			namestroff = fdt32_to_cpu(prop->nameoff);
++			if (streq(fdt_string(fdt, namestroff), name)) {
++				/* Found it! */
++				int len = fdt32_to_cpu(prop->len);
++				prop = fdt_offset_ptr(fdt, offset,
++						      sizeof(*prop)+len);
++				if (! prop)
++					goto fail;
++
++				if (lenp)
++					*lenp = len;
++
++				return prop;
++			}
++			break;
++
++		default:
++			err = -FDT_ERR_BADSTRUCTURE;
++			goto fail;
++		}
++	} while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
++
++	err = -FDT_ERR_NOTFOUND;
++ fail:
++	if (lenp)
++		*lenp = err;
++	return NULL;
++}
++
++const void *fdt_getprop(const void *fdt, int nodeoffset,
++		  const char *name, int *lenp)
++{
++	const struct fdt_property *prop;
++
++	prop = fdt_get_property(fdt, nodeoffset, name, lenp);
++	if (! prop)
++		return NULL;
++
++	return prop->data;
++}
++
++uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
++{
++	const uint32_t *php;
++	int len;
++
++	php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
++	if (!php || (len != sizeof(*php)))
++		return 0;
++
++	return fdt32_to_cpu(*php);
++}
++
++int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
++{
++	uint32_t tag;
++	int p = 0, overflow = 0;
++	int offset, nextoffset, namelen;
++	const char *name;
++
++	CHECK_HEADER(fdt);
++
++	tag = fdt_next_tag(fdt, 0, &nextoffset);
++	if (tag != FDT_BEGIN_NODE)
++		return -FDT_ERR_BADSTRUCTURE;
++
++	if (buflen < 2)
++		return -FDT_ERR_NOSPACE;
++	buf[0] = '/';
++	p = 1;
++
++	while (nextoffset <= nodeoffset) {
++		offset = nextoffset;
++		tag = fdt_next_tag(fdt, offset, &nextoffset);
++		switch (tag) {
++		case FDT_END:
++			return -FDT_ERR_BADOFFSET;
++
++		case FDT_BEGIN_NODE:
++			name = fdt_get_name(fdt, offset, &namelen);
++			if (!name)
++				return namelen;
++			if (overflow || ((p + namelen + 1) > buflen)) {
++				overflow++;
++				break;
++			}
++			memcpy(buf + p, name, namelen);
++			p += namelen;
++			buf[p++] = '/';
++			break;
++
++		case FDT_END_NODE:
++			if (overflow) {
++				overflow--;
++				break;
++			}
++			do {
++				p--;
++			} while  (buf[p-1] != '/');
++			break;
++
++		case FDT_PROP:
++		case FDT_NOP:
++			break;
++
++		default:
++			return -FDT_ERR_BADSTRUCTURE;
++		}
++	}
++
++	if (overflow)
++		return -FDT_ERR_NOSPACE;
++
++	if (p > 1) /* special case so that root path is "/", not "" */
++		p--;
++	buf[p] = '\0';
++	return p;
++}
++
++int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
++				 int supernodedepth, int *nodedepth)
++{
++	int level = -1;
++	uint32_t tag;
++	int offset, nextoffset = 0;
++	int supernodeoffset = -FDT_ERR_INTERNAL;
++
++	CHECK_HEADER(fdt);
++
++	if (supernodedepth < 0)
++		return -FDT_ERR_NOTFOUND;
++
++	do {
++		offset = nextoffset;
++		tag = fdt_next_tag(fdt, offset, &nextoffset);
++		switch (tag) {
++		case FDT_END:
++			return -FDT_ERR_BADOFFSET;
++
++		case FDT_BEGIN_NODE:
++			level++;
++			if (level == supernodedepth)
++				supernodeoffset = offset;
++			break;
++
++		case FDT_END_NODE:
++			level--;
++			break;
++
++		case FDT_PROP:
++		case FDT_NOP:
++			break;
++
++		default:
++			return -FDT_ERR_BADSTRUCTURE;
++		}
++	} while (offset < nodeoffset);
++
++	if (nodedepth)
++		*nodedepth = level;
++
++	if (supernodedepth > level)
++		return -FDT_ERR_NOTFOUND;
++	return supernodeoffset;
++}
++
++int fdt_node_depth(const void *fdt, int nodeoffset)
++{
++	int nodedepth;
++	int err;
++
++	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
++	if (err)
++		return (err < 0) ? err : -FDT_ERR_INTERNAL;
++	return nodedepth;
++}
++
++int fdt_parent_offset(const void *fdt, int nodeoffset)
++{
++	int nodedepth = fdt_node_depth(fdt, nodeoffset);
++
++	if (nodedepth < 0)
++		return nodedepth;
++	return fdt_supernode_atdepth_offset(fdt, nodeoffset,
++					    nodedepth - 1, NULL);
++}
++
++int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
++				  const char *propname,
++				  const void *propval, int proplen)
++{
++	uint32_t tag;
++	int offset, nextoffset;
++	const void *val;
++	int len;
++
++	CHECK_HEADER(fdt);
++
++	if (startoffset >= 0) {
++		tag = fdt_next_tag(fdt, startoffset, &nextoffset);
++		if (tag != FDT_BEGIN_NODE)
++			return -FDT_ERR_BADOFFSET;
++	} else {
++		nextoffset = 0;
++	}
++
++	/* FIXME: The algorithm here is pretty horrible: we scan each
++	 * property of a node in fdt_getprop(), then if that didn't
++	 * find what we want, we scan over them again making our way
++	 * to the next node.  Still it's the easiest to implement
++	 * approach; performance can come later. */
++	do {
++		offset = nextoffset;
++		tag = fdt_next_tag(fdt, offset, &nextoffset);
++
++		switch (tag) {
++		case FDT_BEGIN_NODE:
++			val = fdt_getprop(fdt, offset, propname, &len);
++			if (val
++			    && (len == proplen)
++			    && (memcmp(val, propval, len) == 0))
++				return offset;
++			break;
++
++		case FDT_PROP:
++		case FDT_END:
++		case FDT_END_NODE:
++		case FDT_NOP:
++			break;
++
++		default:
++			return -FDT_ERR_BADSTRUCTURE;
++		}
++	} while (tag != FDT_END);
++
++	return -FDT_ERR_NOTFOUND;
++}
++
++int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
++{
++	if ((phandle == 0) || (phandle == -1))
++		return -FDT_ERR_BADPHANDLE;
++	phandle = cpu_to_fdt32(phandle);
++	return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
++					     &phandle, sizeof(phandle));
++}
++
++int _stringlist_contains(const void *strlist, int listlen, const char *str)
++{
++	int len = strlen(str);
++	const void *p;
++
++	while (listlen >= len) {
++		if (memcmp(str, strlist, len+1) == 0)
++			return 1;
++		p = memchr(strlist, '\0', listlen);
++		if (!p)
++			return 0; /* malformed strlist.. */
++		listlen -= (p-strlist) + 1;
++		strlist = p + 1;
++	}
++	return 0;
++}
++
++int fdt_node_check_compatible(const void *fdt, int nodeoffset,
++			      const char *compatible)
++{
++	const void *prop;
++	int len;
++
++	prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
++	if (!prop)
++		return len;
++	if (_stringlist_contains(prop, len, compatible))
++		return 0;
++	else
++		return 1;
++}
++
++int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
++				  const char *compatible)
++{
++	uint32_t tag;
++	int offset, nextoffset;
++	int err;
++
++	CHECK_HEADER(fdt);
++
++	if (startoffset >= 0) {
++		tag = fdt_next_tag(fdt, startoffset, &nextoffset);
++		if (tag != FDT_BEGIN_NODE)
++			return -FDT_ERR_BADOFFSET;
++	} else {
++		nextoffset = 0;
++	}
++
++	/* FIXME: The algorithm here is pretty horrible: we scan each
++	 * property of a node in fdt_node_check_compatible(), then if
++	 * that didn't find what we want, we scan over them again
++	 * making our way to the next node.  Still it's the easiest to
++	 * implement approach; performance can come later. */
++	do {
++		offset = nextoffset;
++		tag = fdt_next_tag(fdt, offset, &nextoffset);
++
++		switch (tag) {
++		case FDT_BEGIN_NODE:
++			err = fdt_node_check_compatible(fdt, offset,
++							compatible);
++			if ((err < 0)
++			    && (err != -FDT_ERR_NOTFOUND))
++				return err;
++			else if (err == 0)
++				return offset;
++			break;
++
++		case FDT_PROP:
++		case FDT_END:
++		case FDT_END_NODE:
++		case FDT_NOP:
++			break;
++
++		default:
++			return -FDT_ERR_BADSTRUCTURE;
++		}
++	} while (tag != FDT_END);
++
++	return -FDT_ERR_NOTFOUND;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/fdt_rw.c powerpc.git/arch/powerpc/boot/libfdt/fdt_rw.c
+--- linux-2.6.24/arch/powerpc/boot/libfdt/fdt_rw.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/fdt_rw.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,447 @@
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2006 David Gibson, IBM Corporation.
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License as
++ *     published by the Free Software Foundation; either version 2 of the
++ *     License, or (at your option) any later version.
++ *
++ *     This library is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++#include "libfdt_env.h"
++
++#include <fdt.h>
++#include <libfdt.h>
++
++#include "libfdt_internal.h"
++
++static int _blocks_misordered(const void *fdt,
++			      int mem_rsv_size, int struct_size)
++{
++	return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
++		|| (fdt_off_dt_struct(fdt) <
++		    (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
++		|| (fdt_off_dt_strings(fdt) <
++		    (fdt_off_dt_struct(fdt) + struct_size))
++		|| (fdt_totalsize(fdt) <
++		    (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
++}
++
++static int rw_check_header(void *fdt)
++{
++	int err;
++
++	if ((err = fdt_check_header(fdt)))
++		return err;
++	if (fdt_version(fdt) < 17)
++		return -FDT_ERR_BADVERSION;
++	if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
++			       fdt_size_dt_struct(fdt)))
++		return -FDT_ERR_BADLAYOUT;
++	if (fdt_version(fdt) > 17)
++		fdt_set_version(fdt, 17);
++
++	return 0;
++}
++
++#define RW_CHECK_HEADER(fdt) \
++	{ \
++		int err; \
++		if ((err = rw_check_header(fdt)) != 0) \
++			return err; \
++	}
++
++static inline int _blob_data_size(void *fdt)
++{
++	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
++}
++
++static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
++{
++	void *end = fdt + _blob_data_size(fdt);
++
++	if (((p + oldlen) < p) || ((p + oldlen) > end))
++		return -FDT_ERR_BADOFFSET;
++	if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt)))
++		return -FDT_ERR_NOSPACE;
++	memmove(p + newlen, p + oldlen, end - p - oldlen);
++	return 0;
++}
++
++static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
++				int oldn, int newn)
++{
++	int delta = (newn - oldn) * sizeof(*p);
++	int err;
++	err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
++	if (err)
++		return err;
++	fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
++	fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
++	return 0;
++}
++
++static int _blob_splice_struct(void *fdt, void *p,
++			       int oldlen, int newlen)
++{
++	int delta = newlen - oldlen;
++	int err;
++
++	if ((err = _blob_splice(fdt, p, oldlen, newlen)))
++		return err;
++
++	fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
++	fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
++	return 0;
++}
++
++static int _blob_splice_string(void *fdt, int newlen)
++{
++	void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
++	int err;
++
++	if ((err = _blob_splice(fdt, p, 0, newlen)))
++		return err;
++
++	fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
++	return 0;
++}
++
++static int _find_add_string(void *fdt, const char *s)
++{
++	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
++	const char *p;
++	char *new;
++	int len = strlen(s) + 1;
++	int err;
++
++	p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
++	if (p)
++		/* found it */
++		return (p - strtab);
++
++	new = strtab + fdt_size_dt_strings(fdt);
++	err = _blob_splice_string(fdt, len);
++	if (err)
++		return err;
++
++	memcpy(new, s, len);
++	return (new - strtab);
++}
++
++int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
++{
++	struct fdt_reserve_entry *re;
++	int err;
++
++	if ((err = rw_check_header(fdt)))
++		return err;
++
++	re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
++	err = _blob_splice_mem_rsv(fdt, re, 0, 1);
++	if (err)
++		return err;
++
++	re->address = cpu_to_fdt64(address);
++	re->size = cpu_to_fdt64(size);
++	return 0;
++}
++
++int fdt_del_mem_rsv(void *fdt, int n)
++{
++	struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
++	int err;
++
++	if ((err = rw_check_header(fdt)))
++		return err;
++	if (n >= fdt_num_mem_rsv(fdt))
++		return -FDT_ERR_NOTFOUND;
++
++	err = _blob_splice_mem_rsv(fdt, re, 1, 0);
++	if (err)
++		return err;
++	return 0;
++}
++
++static int _resize_property(void *fdt, int nodeoffset, const char *name, int len,
++			    struct fdt_property **prop)
++{
++	int oldlen;
++	int err;
++
++	*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
++	if (! (*prop))
++		return oldlen;
++
++	if ((err = _blob_splice_struct(fdt, (*prop)->data,
++				       ALIGN(oldlen, FDT_TAGSIZE),
++				       ALIGN(len, FDT_TAGSIZE))))
++		return err;
++
++	(*prop)->len = cpu_to_fdt32(len);
++	return 0;
++}
++
++static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
++			 struct fdt_property **prop)
++{
++	uint32_t tag;
++	int proplen;
++	int nextoffset;
++	int namestroff;
++	int err;
++
++	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
++	if (tag != FDT_BEGIN_NODE)
++		return -FDT_ERR_BADOFFSET;
++
++	namestroff = _find_add_string(fdt, name);
++	if (namestroff < 0)
++		return namestroff;
++
++	*prop = _fdt_offset_ptr_w(fdt, nextoffset);
++	proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE);
++
++	err = _blob_splice_struct(fdt, *prop, 0, proplen);
++	if (err)
++		return err;
++
++	(*prop)->tag = cpu_to_fdt32(FDT_PROP);
++	(*prop)->nameoff = cpu_to_fdt32(namestroff);
++	(*prop)->len = cpu_to_fdt32(len);
++	return 0;
++}
++
++int fdt_setprop(void *fdt, int nodeoffset, const char *name,
++		const void *val, int len)
++{
++	struct fdt_property *prop;
++	int err;
++
++	if ((err = rw_check_header(fdt)))
++		return err;
++
++	err = _resize_property(fdt, nodeoffset, name, len, &prop);
++	if (err == -FDT_ERR_NOTFOUND)
++		err = _add_property(fdt, nodeoffset, name, len, &prop);
++	if (err)
++		return err;
++
++	memcpy(prop->data, val, len);
++	return 0;
++}
++
++int fdt_delprop(void *fdt, int nodeoffset, const char *name)
++{
++	struct fdt_property *prop;
++	int len, proplen;
++
++	RW_CHECK_HEADER(fdt);
++
++	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
++	if (! prop)
++		return len;
++
++	proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE);
++	return _blob_splice_struct(fdt, prop, proplen, 0);
++}
++
++int fdt_add_subnode_namelen(void *fdt, int parentoffset,
++			    const char *name, int namelen)
++{
++	struct fdt_node_header *nh;
++	int offset, nextoffset;
++	int nodelen;
++	int err;
++	uint32_t tag;
++	uint32_t *endtag;
++
++	RW_CHECK_HEADER(fdt);
++
++	offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
++	if (offset >= 0)
++		return -FDT_ERR_EXISTS;
++	else if (offset != -FDT_ERR_NOTFOUND)
++		return offset;
++
++	/* Try to place the new node after the parent's properties */
++	fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
++	do {
++		offset = nextoffset;
++		tag = fdt_next_tag(fdt, offset, &nextoffset);
++	} while (tag == FDT_PROP);
++
++	nh = _fdt_offset_ptr_w(fdt, offset);
++	nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE;
++
++	err = _blob_splice_struct(fdt, nh, 0, nodelen);
++	if (err)
++		return err;
++
++	nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
++	memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE));
++	memcpy(nh->name, name, namelen);
++	endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE);
++	*endtag = cpu_to_fdt32(FDT_END_NODE);
++
++	return offset;
++}
++
++int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
++{
++	return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
++}
++
++int fdt_del_node(void *fdt, int nodeoffset)
++{
++	int endoffset;
++
++	RW_CHECK_HEADER(fdt);
++
++	endoffset = _fdt_node_end_offset(fdt, nodeoffset);
++	if (endoffset < 0)
++		return endoffset;
++
++	return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
++				   endoffset - nodeoffset, 0);
++}
++
++static void _packblocks(const void *fdt, void *buf,
++		       int mem_rsv_size, int struct_size)
++{
++	int mem_rsv_off, struct_off, strings_off;
++
++	mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8);
++	struct_off = mem_rsv_off + mem_rsv_size;
++	strings_off = struct_off + struct_size;
++
++	memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size);
++	fdt_set_off_mem_rsvmap(buf, mem_rsv_off);
++
++	memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
++	fdt_set_off_dt_struct(buf, struct_off);
++	fdt_set_size_dt_struct(buf, struct_size);
++
++	memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
++		fdt_size_dt_strings(fdt));
++	fdt_set_off_dt_strings(buf, strings_off);
++	fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt));
++}
++
++int fdt_open_into(const void *fdt, void *buf, int bufsize)
++{
++	int err;
++	int mem_rsv_size, struct_size;
++	int newsize;
++	void *tmp;
++
++	err = fdt_check_header(fdt);
++	if (err)
++		return err;
++
++	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
++		* sizeof(struct fdt_reserve_entry);
++
++	if (fdt_version(fdt) >= 17) {
++		struct_size = fdt_size_dt_struct(fdt);
++	} else {
++		struct_size = 0;
++		while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
++			;
++	}
++
++	if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
++		/* no further work necessary */
++		err = fdt_move(fdt, buf, bufsize);
++		if (err)
++			return err;
++		fdt_set_version(buf, 17);
++		fdt_set_size_dt_struct(buf, struct_size);
++		fdt_set_totalsize(buf, bufsize);
++		return 0;
++	}
++
++	/* Need to reorder */
++	newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
++		+ struct_size + fdt_size_dt_strings(fdt);
++
++	if (bufsize < newsize)
++		return -FDT_ERR_NOSPACE;
++
++	if (((buf + newsize) <= fdt)
++	    || (buf >= (fdt + fdt_totalsize(fdt)))) {
++		tmp = buf;
++	} else {
++		tmp = (void *)fdt + fdt_totalsize(fdt);
++		if ((tmp + newsize) > (buf + bufsize))
++			return -FDT_ERR_NOSPACE;
++	}
++
++	_packblocks(fdt, tmp, mem_rsv_size, struct_size);
++	memmove(buf, tmp, newsize);
++
++	fdt_set_magic(buf, FDT_MAGIC);
++	fdt_set_totalsize(buf, bufsize);
++	fdt_set_version(buf, 17);
++	fdt_set_last_comp_version(buf, 16);
++	fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
++
++	return 0;
++}
++
++int fdt_pack(void *fdt)
++{
++	int mem_rsv_size;
++	int err;
++
++	err = rw_check_header(fdt);
++	if (err)
++		return err;
++
++	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
++		* sizeof(struct fdt_reserve_entry);
++	_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
++	fdt_set_totalsize(fdt, _blob_data_size(fdt));
++
++	return 0;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/fdt_strerror.c powerpc.git/arch/powerpc/boot/libfdt/fdt_strerror.c
+--- linux-2.6.24/arch/powerpc/boot/libfdt/fdt_strerror.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/fdt_strerror.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,96 @@
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2006 David Gibson, IBM Corporation.
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License as
++ *     published by the Free Software Foundation; either version 2 of the
++ *     License, or (at your option) any later version.
++ *
++ *     This library is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++#include "libfdt_env.h"
++
++#include <fdt.h>
++#include <libfdt.h>
++
++#include "libfdt_internal.h"
++
++struct errtabent {
++	const char *str;
++};
++
++#define ERRTABENT(val) \
++	[(val)] = { .str = #val, }
++
++static struct errtabent errtable[] = {
++	ERRTABENT(FDT_ERR_NOTFOUND),
++	ERRTABENT(FDT_ERR_EXISTS),
++	ERRTABENT(FDT_ERR_NOSPACE),
++
++	ERRTABENT(FDT_ERR_BADOFFSET),
++	ERRTABENT(FDT_ERR_BADPATH),
++	ERRTABENT(FDT_ERR_BADSTATE),
++
++	ERRTABENT(FDT_ERR_TRUNCATED),
++	ERRTABENT(FDT_ERR_BADMAGIC),
++	ERRTABENT(FDT_ERR_BADVERSION),
++	ERRTABENT(FDT_ERR_BADSTRUCTURE),
++	ERRTABENT(FDT_ERR_BADLAYOUT),
++};
++#define ERRTABSIZE	(sizeof(errtable) / sizeof(errtable[0]))
++
++const char *fdt_strerror(int errval)
++{
++	if (errval > 0)
++		return "<valid offset/length>";
++	else if (errval == 0)
++		return "<no error>";
++	else if (errval > -ERRTABSIZE) {
++		const char *s = errtable[-errval].str;
++
++		if (s)
++			return s;
++	}
++
++	return "<unknown error>";
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/fdt_sw.c powerpc.git/arch/powerpc/boot/libfdt/fdt_sw.c
+--- linux-2.6.24/arch/powerpc/boot/libfdt/fdt_sw.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/fdt_sw.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,258 @@
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2006 David Gibson, IBM Corporation.
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License as
++ *     published by the Free Software Foundation; either version 2 of the
++ *     License, or (at your option) any later version.
++ *
++ *     This library is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++#include "libfdt_env.h"
++
++#include <fdt.h>
++#include <libfdt.h>
++
++#include "libfdt_internal.h"
++
++static int check_header_sw(void *fdt)
++{
++	if (fdt_magic(fdt) != SW_MAGIC)
++		return -FDT_ERR_BADMAGIC;
++	return 0;
++}
++
++static void *grab_space(void *fdt, int len)
++{
++	int offset = fdt_size_dt_struct(fdt);
++	int spaceleft;
++
++	spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
++		- fdt_size_dt_strings(fdt);
++
++	if ((offset + len < offset) || (offset + len > spaceleft))
++		return NULL;
++
++	fdt_set_size_dt_struct(fdt, offset + len);
++	return fdt_offset_ptr_w(fdt, offset, len);
++}
++
++int fdt_create(void *buf, int bufsize)
++{
++	void *fdt = buf;
++
++	if (bufsize < sizeof(struct fdt_header))
++		return -FDT_ERR_NOSPACE;
++
++	memset(buf, 0, bufsize);
++
++	fdt_set_magic(fdt, SW_MAGIC);
++	fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
++	fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
++	fdt_set_totalsize(fdt,  bufsize);
++
++	fdt_set_off_mem_rsvmap(fdt, ALIGN(sizeof(struct fdt_header),
++					  sizeof(struct fdt_reserve_entry)));
++	fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
++	fdt_set_off_dt_strings(fdt, bufsize);
++
++	return 0;
++}
++
++int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
++{
++	struct fdt_reserve_entry *re;
++	int err = check_header_sw(fdt);
++	int offset;
++
++	if (err)
++		return err;
++	if (fdt_size_dt_struct(fdt))
++		return -FDT_ERR_BADSTATE;
++
++	offset = fdt_off_dt_struct(fdt);
++	if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
++		return -FDT_ERR_NOSPACE;
++
++	re = (struct fdt_reserve_entry *)(fdt + offset);
++	re->address = cpu_to_fdt64(addr);
++	re->size = cpu_to_fdt64(size);
++
++	fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
++
++	return 0;
++}
++
++int fdt_finish_reservemap(void *fdt)
++{
++	return fdt_add_reservemap_entry(fdt, 0, 0);
++}
++
++int fdt_begin_node(void *fdt, const char *name)
++{
++	struct fdt_node_header *nh;
++	int err = check_header_sw(fdt);
++	int namelen = strlen(name) + 1;
++
++	if (err)
++		return err;
++
++	nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE));
++	if (! nh)
++		return -FDT_ERR_NOSPACE;
++
++	nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
++	memcpy(nh->name, name, namelen);
++	return 0;
++}
++
++int fdt_end_node(void *fdt)
++{
++	uint32_t *en;
++	int err = check_header_sw(fdt);
++
++	if (err)
++		return err;
++
++	en = grab_space(fdt, FDT_TAGSIZE);
++	if (! en)
++		return -FDT_ERR_NOSPACE;
++
++	*en = cpu_to_fdt32(FDT_END_NODE);
++	return 0;
++}
++
++static int find_add_string(void *fdt, const char *s)
++{
++	char *strtab = (char *)fdt + fdt_totalsize(fdt);
++	const char *p;
++	int strtabsize = fdt_size_dt_strings(fdt);
++	int len = strlen(s) + 1;
++	int struct_top, offset;
++
++	p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
++	if (p)
++		return p - strtab;
++
++	/* Add it */
++	offset = -strtabsize - len;
++	struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
++	if (fdt_totalsize(fdt) + offset < struct_top)
++		return 0; /* no more room :( */
++
++	memcpy(strtab + offset, s, len);
++	fdt_set_size_dt_strings(fdt, strtabsize + len);
++	return offset;
++}
++
++int fdt_property(void *fdt, const char *name, const void *val, int len)
++{
++	struct fdt_property *prop;
++	int err = check_header_sw(fdt);
++	int nameoff;
++
++	if (err)
++		return err;
++
++	nameoff = find_add_string(fdt, name);
++	if (nameoff == 0)
++		return -FDT_ERR_NOSPACE;
++
++	prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE));
++	if (! prop)
++		return -FDT_ERR_NOSPACE;
++
++	prop->tag = cpu_to_fdt32(FDT_PROP);
++	prop->nameoff = cpu_to_fdt32(nameoff);
++	prop->len = cpu_to_fdt32(len);
++	memcpy(prop->data, val, len);
++	return 0;
++}
++
++int fdt_finish(void *fdt)
++{
++	int err = check_header_sw(fdt);
++	char *p = (char *)fdt;
++	uint32_t *end;
++	int oldstroffset, newstroffset;
++	uint32_t tag;
++	int offset, nextoffset;
++
++	if (err)
++		return err;
++
++	/* Add terminator */
++	end = grab_space(fdt, sizeof(*end));
++	if (! end)
++		return -FDT_ERR_NOSPACE;
++	*end = cpu_to_fdt32(FDT_END);
++
++	/* Relocate the string table */
++	oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
++	newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
++	memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
++	fdt_set_off_dt_strings(fdt, newstroffset);
++
++	/* Walk the structure, correcting string offsets */
++	offset = 0;
++	while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
++		if (tag == FDT_PROP) {
++			struct fdt_property *prop =
++				fdt_offset_ptr_w(fdt, offset, sizeof(*prop));
++			int nameoff;
++
++			if (! prop)
++				return -FDT_ERR_BADSTRUCTURE;
++
++			nameoff = fdt32_to_cpu(prop->nameoff);
++			nameoff += fdt_size_dt_strings(fdt);
++			prop->nameoff = cpu_to_fdt32(nameoff);
++		}
++		offset = nextoffset;
++	}
++
++	/* Finally, adjust the header */
++	fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
++	fdt_set_magic(fdt, FDT_MAGIC);
++	return 0;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/fdt_wip.c powerpc.git/arch/powerpc/boot/libfdt/fdt_wip.c
+--- linux-2.6.24/arch/powerpc/boot/libfdt/fdt_wip.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/fdt_wip.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,144 @@
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2006 David Gibson, IBM Corporation.
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License as
++ *     published by the Free Software Foundation; either version 2 of the
++ *     License, or (at your option) any later version.
++ *
++ *     This library is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++#include "libfdt_env.h"
++
++#include <fdt.h>
++#include <libfdt.h>
++
++#include "libfdt_internal.h"
++
++int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
++			const void *val, int len)
++{
++	void *propval;
++	int proplen;
++
++	propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
++	if (! propval)
++		return proplen;
++
++	if (proplen != len)
++		return -FDT_ERR_NOSPACE;
++
++	memcpy(propval, val, len);
++	return 0;
++}
++
++static void nop_region(void *start, int len)
++{
++	uint32_t *p;
++
++	for (p = start; (void *)p < (start + len); p++)
++		*p = cpu_to_fdt32(FDT_NOP);
++}
++
++int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
++{
++	struct fdt_property *prop;
++	int len;
++
++	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
++	if (! prop)
++		return len;
++
++	nop_region(prop, len + sizeof(*prop));
++
++	return 0;
++}
++
++int _fdt_node_end_offset(void *fdt, int nodeoffset)
++{
++	int level = 0;
++	uint32_t tag;
++	int offset, nextoffset;
++
++	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
++	if (tag != FDT_BEGIN_NODE)
++		return -FDT_ERR_BADOFFSET;
++	do {
++		offset = nextoffset;
++		tag = fdt_next_tag(fdt, offset, &nextoffset);
++
++		switch (tag) {
++		case FDT_END:
++			return offset;
++
++		case FDT_BEGIN_NODE:
++			level++;
++			break;
++
++		case FDT_END_NODE:
++			level--;
++			break;
++
++		case FDT_PROP:
++		case FDT_NOP:
++			break;
++
++		default:
++			return -FDT_ERR_BADSTRUCTURE;
++		}
++	} while (level >= 0);
++
++	return nextoffset;
++}
++
++int fdt_nop_node(void *fdt, int nodeoffset)
++{
++	int endoffset;
++
++	endoffset = _fdt_node_end_offset(fdt, nodeoffset);
++	if (endoffset < 0)
++		return endoffset;
++
++	nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset);
++	return 0;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/libfdt.h powerpc.git/arch/powerpc/boot/libfdt/libfdt.h
+--- linux-2.6.24/arch/powerpc/boot/libfdt/libfdt.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/libfdt.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,721 @@
++#ifndef _LIBFDT_H
++#define _LIBFDT_H
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2006 David Gibson, IBM Corporation.
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License as
++ *     published by the Free Software Foundation; either version 2 of the
++ *     License, or (at your option) any later version.
++ *
++ *     This library is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <libfdt_env.h>
++#include <fdt.h>
++
++#define FDT_FIRST_SUPPORTED_VERSION	0x10
++#define FDT_LAST_SUPPORTED_VERSION	0x11
++
++/* Error codes: informative error codes */
++#define FDT_ERR_NOTFOUND	1
++	/* FDT_ERR_NOTFOUND: The requested node or property does not exist */
++#define FDT_ERR_EXISTS		2
++	/* FDT_ERR_EXISTS: Attemped to create a node or property which
++	 * already exists */
++#define FDT_ERR_NOSPACE		3
++	/* FDT_ERR_NOSPACE: Operation needed to expand the device
++	 * tree, but its buffer did not have sufficient space to
++	 * contain the expanded tree. Use fdt_open_into() to move the
++	 * device tree to a buffer with more space. */
++
++/* Error codes: codes for bad parameters */
++#define FDT_ERR_BADOFFSET	4
++	/* FDT_ERR_BADOFFSET: Function was passed a structure block
++	 * offset which is out-of-bounds, or which points to an
++	 * unsuitable part of the structure for the operation. */
++#define FDT_ERR_BADPATH		5
++	/* FDT_ERR_BADPATH: Function was passed a badly formatted path
++	 * (e.g. missing a leading / for a function which requires an
++	 * absolute path) */
++#define FDT_ERR_BADPHANDLE	6
++	/* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
++	 * value.  phandle values of 0 and -1 are not permitted. */
++#define FDT_ERR_BADSTATE	7
++	/* FDT_ERR_BADSTATE: Function was passed an incomplete device
++	 * tree created by the sequential-write functions, which is
++	 * not sufficiently complete for the requested operation. */
++
++/* Error codes: codes for bad device tree blobs */
++#define FDT_ERR_TRUNCATED	8
++	/* FDT_ERR_TRUNCATED: Structure block of the given device tree
++	 * ends without an FDT_END tag. */
++#define FDT_ERR_BADMAGIC	9
++	/* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
++	 * device tree at all - it is missing the flattened device
++	 * tree magic number. */
++#define FDT_ERR_BADVERSION	10
++	/* FDT_ERR_BADVERSION: Given device tree has a version which
++	 * can't be handled by the requested operation.  For
++	 * read-write functions, this may mean that fdt_open_into() is
++	 * required to convert the tree to the expected version. */
++#define FDT_ERR_BADSTRUCTURE	11
++	/* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
++	 * structure block or other serious error (e.g. misnested
++	 * nodes, or subnodes preceding properties). */
++#define FDT_ERR_BADLAYOUT	12
++	/* FDT_ERR_BADLAYOUT: For read-write functions, the given
++	 * device tree has it's sub-blocks in an order that the
++	 * function can't handle (memory reserve map, then structure,
++	 * then strings).  Use fdt_open_into() to reorganize the tree
++	 * into a form suitable for the read-write operations. */
++
++/* "Can't happen" error indicating a bug in libfdt */
++#define FDT_ERR_INTERNAL	13
++	/* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
++	 * Should never be returned, if it is, it indicates a bug in
++	 * libfdt itself. */
++
++#define FDT_ERR_MAX		13
++
++/**********************************************************************/
++/* Low-level functions (you probably don't need these)                */
++/**********************************************************************/
++
++const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
++static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
++{
++	return (void *)fdt_offset_ptr(fdt, offset, checklen);
++}
++
++uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
++
++/**********************************************************************/
++/* General functions                                                  */
++/**********************************************************************/
++
++#define fdt_get_header(fdt, field) \
++	(fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
++#define fdt_magic(fdt) 			(fdt_get_header(fdt, magic))
++#define fdt_totalsize(fdt)		(fdt_get_header(fdt, totalsize))
++#define fdt_off_dt_struct(fdt)		(fdt_get_header(fdt, off_dt_struct))
++#define fdt_off_dt_strings(fdt)		(fdt_get_header(fdt, off_dt_strings))
++#define fdt_off_mem_rsvmap(fdt)		(fdt_get_header(fdt, off_mem_rsvmap))
++#define fdt_version(fdt)		(fdt_get_header(fdt, version))
++#define fdt_last_comp_version(fdt) 	(fdt_get_header(fdt, last_comp_version))
++#define fdt_boot_cpuid_phys(fdt) 	(fdt_get_header(fdt, boot_cpuid_phys))
++#define fdt_size_dt_strings(fdt) 	(fdt_get_header(fdt, size_dt_strings))
++#define fdt_size_dt_struct(fdt)		(fdt_get_header(fdt, size_dt_struct))
++
++#define __fdt_set_hdr(name) \
++	static inline void fdt_set_##name(void *fdt, uint32_t val) \
++	{ \
++		struct fdt_header *fdth = fdt; \
++		fdth->name = cpu_to_fdt32(val); \
++	}
++__fdt_set_hdr(magic);
++__fdt_set_hdr(totalsize);
++__fdt_set_hdr(off_dt_struct);
++__fdt_set_hdr(off_dt_strings);
++__fdt_set_hdr(off_mem_rsvmap);
++__fdt_set_hdr(version);
++__fdt_set_hdr(last_comp_version);
++__fdt_set_hdr(boot_cpuid_phys);
++__fdt_set_hdr(size_dt_strings);
++__fdt_set_hdr(size_dt_struct);
++#undef __fdt_set_hdr
++
++/**
++ * fdt_check_header - sanity check a device tree or possible device tree
++ * @fdt: pointer to data which might be a flattened device tree
++ *
++ * fdt_check_header() checks that the given buffer contains what
++ * appears to be a flattened device tree with sane information in its
++ * header.
++ *
++ * returns:
++ *     0, if the buffer appears to contain a valid device tree
++ *     -FDT_ERR_BADMAGIC,
++ *     -FDT_ERR_BADVERSION,
++ *     -FDT_ERR_BADSTATE, standard meanings, as above
++ */
++int fdt_check_header(const void *fdt);
++
++/**
++ * fdt_move - move a device tree around in memory
++ * @fdt: pointer to the device tree to move
++ * @buf: pointer to memory where the device is to be moved
++ * @bufsize: size of the memory space at buf
++ *
++ * fdt_move() relocates, if possible, the device tree blob located at
++ * fdt to the buffer at buf of size bufsize.  The buffer may overlap
++ * with the existing device tree blob at fdt.  Therefore,
++ *     fdt_move(fdt, fdt, fdt_totalsize(fdt))
++ * should always succeed.
++ *
++ * returns:
++ *     0, on success
++ *     -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
++ *     -FDT_ERR_BADMAGIC,
++ *     -FDT_ERR_BADVERSION,
++ *     -FDT_ERR_BADSTATE, standard meanings
++ */
++int fdt_move(const void *fdt, void *buf, int bufsize);
++
++/**********************************************************************/
++/* Read-only functions                                                */
++/**********************************************************************/
++
++/**
++ * fdt_string - retreive a string from the strings block of a device tree
++ * @fdt: pointer to the device tree blob
++ * @stroffset: offset of the string within the strings block (native endian)
++ *
++ * fdt_string() retrieves a pointer to a single string from the
++ * strings block of the device tree blob at fdt.
++ *
++ * returns:
++ *     a pointer to the string, on success
++ *     NULL, if stroffset is out of bounds
++ */
++const char *fdt_string(const void *fdt, int stroffset);
++
++/**
++ * fdt_num_mem_rsv - retreive the number of memory reserve map entries
++ * @fdt: pointer to the device tree blob
++ *
++ * Returns the number of entries in the device tree blob's memory
++ * reservation map.  This does not include the terminating 0,0 entry
++ * or any other (0,0) entries reserved for expansion.
++ *
++ * returns:
++ *     the number of entries
++ */
++int fdt_num_mem_rsv(const void *fdt);
++
++/**
++ * fdt_get_mem_rsv - retreive one memory reserve map entry
++ * @fdt: pointer to the device tree blob
++ * @address, @size: pointers to 64-bit variables
++ *
++ * On success, *address and *size will contain the address and size of
++ * the n-th reserve map entry from the device tree blob, in
++ * native-endian format.
++ *
++ * returns:
++ *     0, on success
++ *     -FDT_ERR_BADMAGIC,
++ *     -FDT_ERR_BADVERSION,
++ *     -FDT_ERR_BADSTATE, standard meanings
++ */
++int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
++
++/**
++ * fdt_subnode_offset_namelen - find a subnode based on substring
++ * @fdt: pointer to the device tree blob
++ * @parentoffset: structure block offset of a node
++ * @name: name of the subnode to locate
++ * @namelen: number of characters of name to consider
++ *
++ * Identical to fdt_subnode_offset(), but only examine the first
++ * namelen characters of name for matching the subnode name.  This is
++ * useful for finding subnodes based on a portion of a larger string,
++ * such as a full path.
++ */
++int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
++			       const char *name, int namelen);
++/**
++ * fdt_subnode_offset - find a subnode of a given node
++ * @fdt: pointer to the device tree blob
++ * @parentoffset: structure block offset of a node
++ * @name: name of the subnode to locate
++ *
++ * fdt_subnode_offset() finds a subnode of the node at structure block
++ * offset parentoffset with the given name.  name may include a unit
++ * address, in which case fdt_subnode_offset() will find the subnode
++ * with that unit address, or the unit address may be omitted, in
++ * which case fdt_subnode_offset() will find an arbitrary subnode
++ * whose name excluding unit address matches the given name.
++ *
++ * returns:
++ *	structure block offset of the requested subnode (>=0), on success
++ *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
++ *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
++ *      -FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE,
++ *	-FDT_ERR_TRUNCATED, standard meanings.
++ */
++int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
++
++/**
++ * fdt_path_offset - find a tree node by its full path
++ * @fdt: pointer to the device tree blob
++ * @path: full path of the node to locate
++ *
++ * fdt_path_offset() finds a node of a given path in the device tree.
++ * Each path component may omit the unit address portion, but the
++ * results of this are undefined if any such path component is
++ * ambiguous (that is if there are multiple nodes at the relevant
++ * level matching the given component, differentiated only by unit
++ * address).
++ *
++ * returns:
++ *	structure block offset of the node with the requested path (>=0), on success
++ *	-FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
++ *	-FDT_ERR_NOTFOUND, if the requested node does not exist
++ *      -FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE,
++ *	-FDT_ERR_TRUNCATED, standard meanings.
++ */
++int fdt_path_offset(const void *fdt, const char *path);
++
++/**
++ * fdt_get_name - retreive the name of a given node
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: structure block offset of the starting node
++ * @lenp: pointer to an integer variable (will be overwritten) or NULL
++ *
++ * fdt_get_name() retrieves the name (including unit address) of the
++ * device tree node at structure block offset nodeoffset.  If lenp is
++ * non-NULL, the length of this name is also returned, in the integer
++ * pointed to by lenp.
++ *
++ * returns:
++ *	pointer to the node's name, on success
++ *		If lenp is non-NULL, *lenp contains the length of that name (>=0)
++ *	NULL, on error
++ *		if lenp is non-NULL *lenp contains an error code (<0):
++ *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
++ *		-FDT_ERR_BADMAGIC,
++ *		-FDT_ERR_BADVERSION,
++ *		-FDT_ERR_BADSTATE, standard meanings
++ */
++const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
++
++/**
++ * fdt_get_property - find a given property in a given node
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: offset of the node whose property to find
++ * @name: name of the property to find
++ * @lenp: pointer to an integer variable (will be overwritten) or NULL
++ *
++ * fdt_get_property() retrieves a pointer to the fdt_property
++ * structure within the device tree blob corresponding to the property
++ * named 'name' of the node at offset nodeoffset.  If lenp is
++ * non-NULL, the length of the property value also returned, in the
++ * integer pointed to by lenp.
++ *
++ * returns:
++ *	pointer to the structure representing the property
++ *		if lenp is non-NULL, *lenp contains the length of the property
++ *		value (>=0)
++ *	NULL, on error
++ *		if lenp is non-NULL, *lenp contains an error code (<0):
++ *		-FDT_ERR_NOTFOUND, node does not have named property
++ *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
++ *		-FDT_ERR_BADMAGIC,
++ *		-FDT_ERR_BADVERSION,
++ *		-FDT_ERR_BADSTATE,
++ *		-FDT_ERR_BADSTRUCTURE,
++ *		-FDT_ERR_TRUNCATED, standard meanings
++ */
++const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
++					    const char *name, int *lenp);
++static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
++						      const char *name,
++						      int *lenp)
++{
++	return (struct fdt_property *)fdt_get_property(fdt, nodeoffset,
++						       name, lenp);
++}
++
++/**
++ * fdt_getprop - retrieve the value of a given property
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: offset of the node whose property to find
++ * @name: name of the property to find
++ * @lenp: pointer to an integer variable (will be overwritten) or NULL
++ *
++ * fdt_getprop() retrieves a pointer to the value of the property
++ * named 'name' of the node at offset nodeoffset (this will be a
++ * pointer to within the device blob itself, not a copy of the value).
++ * If lenp is non-NULL, the length of the property value also
++ * returned, in the integer pointed to by lenp.
++ *
++ * returns:
++ *	pointer to the property's value
++ *		if lenp is non-NULL, *lenp contains the length of the property
++ *		value (>=0)
++ *	NULL, on error
++ *		if lenp is non-NULL, *lenp contains an error code (<0):
++ *		-FDT_ERR_NOTFOUND, node does not have named property
++ *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
++ *		-FDT_ERR_BADMAGIC,
++ *		-FDT_ERR_BADVERSION,
++ *		-FDT_ERR_BADSTATE,
++ *		-FDT_ERR_BADSTRUCTURE,
++ *		-FDT_ERR_TRUNCATED, standard meanings
++ */
++const void *fdt_getprop(const void *fdt, int nodeoffset,
++			const char *name, int *lenp);
++static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
++				  const char *name, int *lenp)
++{
++	return (void *)fdt_getprop(fdt, nodeoffset, name, lenp);
++}
++
++/**
++ * fdt_get_phandle - retreive the phandle of a given node
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: structure block offset of the node
++ *
++ * fdt_get_phandle() retrieves the phandle of the device tree node at
++ * structure block offset nodeoffset.
++ *
++ * returns:
++ *	the phandle of the node at nodeoffset, on succes (!= 0, != -1)
++ *	0, if the node has no phandle, or another error occurs
++ */
++uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
++
++/**
++ * fdt_get_path - determine the full path of a node
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: offset of the node whose path to find
++ * @buf: character buffer to contain the returned path (will be overwritten)
++ * @buflen: size of the character buffer at buf
++ *
++ * fdt_get_path() computes the full path of the node at offset
++ * nodeoffset, and records that path in the buffer at buf.
++ *
++ * NOTE: This function is expensive, as it must scan the device tree
++ * structure from the start to nodeoffset.
++ *
++ * returns:
++ *	0, on success
++ *		buf contains the absolute path of the node at
++ *		nodeoffset, as a NUL-terminated string.
++ * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
++ *	-FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
++ *		characters and will not fit in the given buffer.
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE, standard meanings
++ */
++int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
++
++/**
++ * fdt_supernode_atdepth_offset - find a specific ancestor of a node
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: offset of the node whose parent to find
++ * @supernodedepth: depth of the ancestor to find
++ * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
++ *
++ * fdt_supernode_atdepth_offset() finds an ancestor of the given node
++ * at a specific depth from the root (where the root itself has depth
++ * 0, its immediate subnodes depth 1 and so forth).  So
++ *	fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
++ * will always return 0, the offset of the root node.  If the node at
++ * nodeoffset has depth D, then:
++ *	fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
++ * will return nodeoffset itself.
++ *
++ * NOTE: This function is expensive, as it must scan the device tree
++ * structure from the start to nodeoffset.
++ *
++ * returns:
++
++ *	structure block offset of the node at node offset's ancestor
++ *		of depth supernodedepth (>=0), on success
++ * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
++*	-FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE, standard meanings
++ */
++int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
++				 int supernodedepth, int *nodedepth);
++
++/**
++ * fdt_node_depth - find the depth of a given node
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: offset of the node whose parent to find
++ *
++ * fdt_node_depth() finds the depth of a given node.  The root node
++ * has depth 0, its immediate subnodes depth 1 and so forth.
++ *
++ * NOTE: This function is expensive, as it must scan the device tree
++ * structure from the start to nodeoffset.
++ *
++ * returns:
++ *	depth of the node at nodeoffset (>=0), on success
++ * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE, standard meanings
++ */
++int fdt_node_depth(const void *fdt, int nodeoffset);
++
++/**
++ * fdt_parent_offset - find the parent of a given node
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: offset of the node whose parent to find
++ *
++ * fdt_parent_offset() locates the parent node of a given node (that
++ * is, it finds the offset of the node which contains the node at
++ * nodeoffset as a subnode).
++ *
++ * NOTE: This function is expensive, as it must scan the device tree
++ * structure from the start to nodeoffset, *twice*.
++ *
++ * returns:
++ *	stucture block offset of the parent of the node at nodeoffset
++ *		(>=0), on success
++ * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE, standard meanings
++ */
++int fdt_parent_offset(const void *fdt, int nodeoffset);
++
++/**
++ * fdt_node_offset_by_prop_value - find nodes with a given property value
++ * @fdt: pointer to the device tree blob
++ * @startoffset: only find nodes after this offset
++ * @propname: property name to check
++ * @propval: property value to search for
++ * @proplen: length of the value in propval
++ *
++ * fdt_node_offset_by_prop_value() returns the offset of the first
++ * node after startoffset, which has a property named propname whose
++ * value is of length proplen and has value equal to propval; or if
++ * startoffset is -1, the very first such node in the tree.
++ *
++ * To iterate through all nodes matching the criterion, the following
++ * idiom can be used:
++ *	offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
++ *					       propval, proplen);
++ *	while (offset != -FDT_ERR_NOTFOUND) {
++ *		// other code here
++ *		offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
++ *						       propval, proplen);
++ *	}
++ *
++ * Note the -1 in the first call to the function, if 0 is used here
++ * instead, the function will never locate the root node, even if it
++ * matches the criterion.
++ *
++ * returns:
++ *	structure block offset of the located node (>= 0, >startoffset),
++ *		 on success
++ *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
++ *		tree after startoffset
++ * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE, standard meanings
++ */
++int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
++				  const char *propname,
++				  const void *propval, int proplen);
++
++/**
++ * fdt_node_offset_by_phandle - find the node with a given phandle
++ * @fdt: pointer to the device tree blob
++ * @phandle: phandle value
++ *
++ * fdt_node_offset_by_prop_value() returns the offset of the node
++ * which has the given phandle value.  If there is more than one node
++ * in the tree with the given phandle (an invalid tree), results are
++ * undefined.
++ *
++ * returns:
++ *	structure block offset of the located node (>= 0), on success
++ *	-FDT_ERR_NOTFOUND, no node with that phandle exists
++ *	-FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE, standard meanings
++ */
++int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
++
++/**
++ * fdt_node_check_compatible: check a node's compatible property
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: offset of a tree node
++ * @compatible: string to match against
++ *
++ *
++ * fdt_node_check_compatible() returns 0 if the given node contains a
++ * 'compatible' property with the given string as one of its elements,
++ * it returns non-zero otherwise, or on error.
++ *
++ * returns:
++ *	0, if the node has a 'compatible' property listing the given string
++ *	1, if the node has a 'compatible' property, but it does not list
++ *		the given string
++ *	-FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
++ * 	-FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE, standard meanings
++ */
++int fdt_node_check_compatible(const void *fdt, int nodeoffset,
++			      const char *compatible);
++
++/**
++ * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
++ * @fdt: pointer to the device tree blob
++ * @startoffset: only find nodes after this offset
++ * @compatible: 'compatible' string to match against
++ *
++ * fdt_node_offset_by_compatible() returns the offset of the first
++ * node after startoffset, which has a 'compatible' property which
++ * lists the given compatible string; or if startoffset is -1, the
++ * very first such node in the tree.
++ *
++ * To iterate through all nodes matching the criterion, the following
++ * idiom can be used:
++ *	offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
++ *	while (offset != -FDT_ERR_NOTFOUND) {
++ *		// other code here
++ *		offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
++ *	}
++ *
++ * Note the -1 in the first call to the function, if 0 is used here
++ * instead, the function will never locate the root node, even if it
++ * matches the criterion.
++ *
++ * returns:
++ *	structure block offset of the located node (>= 0, >startoffset),
++ *		 on success
++ *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
++ *		tree after startoffset
++ * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE, standard meanings
++ */
++int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
++				  const char *compatible);
++
++/**********************************************************************/
++/* Write-in-place functions                                           */
++/**********************************************************************/
++
++int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
++			const void *val, int len);
++static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
++					   const char *name, uint32_t val)
++{
++	val = cpu_to_fdt32(val);
++	return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
++}
++
++int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
++int fdt_nop_node(void *fdt, int nodeoffset);
++
++/**********************************************************************/
++/* Sequential write functions                                         */
++/**********************************************************************/
++
++int fdt_create(void *buf, int bufsize);
++int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
++int fdt_finish_reservemap(void *fdt);
++int fdt_begin_node(void *fdt, const char *name);
++int fdt_property(void *fdt, const char *name, const void *val, int len);
++static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
++{
++	val = cpu_to_fdt32(val);
++	return fdt_property(fdt, name, &val, sizeof(val));
++}
++#define fdt_property_string(fdt, name, str) \
++	fdt_property(fdt, name, str, strlen(str)+1)
++int fdt_end_node(void *fdt);
++int fdt_finish(void *fdt);
++
++/**********************************************************************/
++/* Read-write functions                                               */
++/**********************************************************************/
++
++int fdt_open_into(const void *fdt, void *buf, int bufsize);
++int fdt_pack(void *fdt);
++
++int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
++int fdt_del_mem_rsv(void *fdt, int n);
++
++int fdt_setprop(void *fdt, int nodeoffset, const char *name,
++		const void *val, int len);
++static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
++				   uint32_t val)
++{
++	val = cpu_to_fdt32(val);
++	return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
++}
++#define fdt_setprop_string(fdt, nodeoffset, name, str) \
++	fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
++int fdt_delprop(void *fdt, int nodeoffset, const char *name);
++int fdt_add_subnode_namelen(void *fdt, int parentoffset,
++			    const char *name, int namelen);
++int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
++int fdt_del_node(void *fdt, int nodeoffset);
++
++/**********************************************************************/
++/* Debugging / informational functions                                */
++/**********************************************************************/
++
++const char *fdt_strerror(int errval);
++
++#endif /* _LIBFDT_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt/libfdt_internal.h powerpc.git/arch/powerpc/boot/libfdt/libfdt_internal.h
+--- linux-2.6.24/arch/powerpc/boot/libfdt/libfdt_internal.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt/libfdt_internal.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,89 @@
++#ifndef _LIBFDT_INTERNAL_H
++#define _LIBFDT_INTERNAL_H
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2006 David Gibson, IBM Corporation.
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License as
++ *     published by the Free Software Foundation; either version 2 of the
++ *     License, or (at your option) any later version.
++ *
++ *     This library is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++#include <fdt.h>
++
++#define ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
++#define PALIGN(p, a)	((void *)ALIGN((unsigned long)(p), (a)))
++
++#define memeq(p, q, n)	(memcmp((p), (q), (n)) == 0)
++#define streq(p, q)	(strcmp((p), (q)) == 0)
++
++uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
++const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
++int _fdt_node_end_offset(void *fdt, int nodeoffset);
++
++static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
++{
++	return fdt + fdt_off_dt_struct(fdt) + offset;
++}
++
++static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
++{
++	return (void *)_fdt_offset_ptr(fdt, offset);
++}
++
++static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
++{
++	const struct fdt_reserve_entry *rsv_table =
++		fdt + fdt_off_mem_rsvmap(fdt);
++
++	return rsv_table + n;
++}
++static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
++{
++	return (void *)_fdt_mem_rsv(fdt, n);
++}
++
++#define SW_MAGIC		(~FDT_MAGIC)
++
++#endif /* _LIBFDT_INTERNAL_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt-wrapper.c powerpc.git/arch/powerpc/boot/libfdt-wrapper.c
+--- linux-2.6.24/arch/powerpc/boot/libfdt-wrapper.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt-wrapper.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,184 @@
++/*
++ * This file does the necessary interface mapping between the bootwrapper
++ * device tree operations and the interface provided by shared source
++ * files flatdevicetree.[ch].
++ *
++ * Copyright 2007 David Gibson, IBM Corporation.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ */
++
++#include <stddef.h>
++#include <stdio.h>
++#include <page.h>
++#include <libfdt.h>
++#include "ops.h"
++
++#define DEBUG	0
++#define BAD_ERROR(err)	(((err) < 0) \
++			 && ((err) != -FDT_ERR_NOTFOUND) \
++			 && ((err) != -FDT_ERR_EXISTS))
++
++#define check_err(err) \
++	({ \
++		if (BAD_ERROR(err) || ((err < 0) && DEBUG)) \
++			printf("%s():%d  %s\n\r", __FUNCTION__, __LINE__, \
++			       fdt_strerror(err)); \
++		if (BAD_ERROR(err)) \
++			exit(); \
++		(err < 0) ? -1 : 0; \
++	})
++
++#define offset_devp(off)	\
++	({ \
++		int _offset = (off); \
++		check_err(_offset) ? NULL : (void *)(_offset+1); \
++	})
++
++#define devp_offset_find(devp)	(((int)(devp))-1)
++#define devp_offset(devp)	(devp ? ((int)(devp))-1 : 0)
++
++static void *fdt;
++static void *buf; /* = NULL */
++
++#define EXPAND_GRANULARITY	1024
++
++static void expand_buf(int minexpand)
++{
++	int size = fdt_totalsize(fdt);
++	int rc;
++
++	size = _ALIGN(size + minexpand, EXPAND_GRANULARITY);
++	buf = platform_ops.realloc(buf, size);
++	if (!buf)
++		fatal("Couldn't find %d bytes to expand device tree\n\r", size);
++	rc = fdt_open_into(fdt, buf, size);
++	if (rc != 0)
++		fatal("Couldn't expand fdt into new buffer: %s\n\r",
++		      fdt_strerror(rc));
++
++	fdt = buf;
++}
++
++static void *fdt_wrapper_finddevice(const char *path)
++{
++	return offset_devp(fdt_path_offset(fdt, path));
++}
++
++static int fdt_wrapper_getprop(const void *devp, const char *name,
++			       void *buf, const int buflen)
++{
++	const void *p;
++	int len;
++
++	p = fdt_getprop(fdt, devp_offset(devp), name, &len);
++	if (!p)
++		return check_err(len);
++	memcpy(buf, p, min(len, buflen));
++	return len;
++}
++
++static int fdt_wrapper_setprop(const void *devp, const char *name,
++			       const void *buf, const int len)
++{
++	int rc;
++
++	rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
++	if (rc == -FDT_ERR_NOSPACE) {
++		expand_buf(len + 16);
++		rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
++	}
++
++	return check_err(rc);
++}
++
++static void *fdt_wrapper_get_parent(const void *devp)
++{
++	return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
++}
++
++static void *fdt_wrapper_create_node(const void *devp, const char *name)
++{
++	int offset;
++
++	offset = fdt_add_subnode(fdt, devp_offset(devp), name);
++	if (offset == -FDT_ERR_NOSPACE) {
++		expand_buf(strlen(name) + 16);
++		offset = fdt_add_subnode(fdt, devp_offset(devp), name);
++	}
++
++	return offset_devp(offset);
++}
++
++static void *fdt_wrapper_find_node_by_prop_value(const void *prev,
++						 const char *name,
++						 const char *val,
++						 int len)
++{
++	int offset = fdt_node_offset_by_prop_value(fdt, devp_offset_find(prev),
++	                                           name, val, len);
++	return offset_devp(offset);
++}
++
++static char *fdt_wrapper_get_path(const void *devp, char *buf, int len)
++{
++	int rc;
++
++	rc = fdt_get_path(fdt, devp_offset(devp), buf, len);
++	if (check_err(rc))
++		return NULL;
++	return buf;
++}
++
++static unsigned long fdt_wrapper_finalize(void)
++{
++	int rc;
++
++	rc = fdt_pack(fdt);
++	if (rc != 0)
++		fatal("Couldn't pack flat tree: %s\n\r",
++		      fdt_strerror(rc));
++	return (unsigned long)fdt;
++}
++
++void fdt_init(void *blob)
++{
++	int err;
++
++	dt_ops.finddevice = fdt_wrapper_finddevice;
++	dt_ops.getprop = fdt_wrapper_getprop;
++	dt_ops.setprop = fdt_wrapper_setprop;
++	dt_ops.get_parent = fdt_wrapper_get_parent;
++	dt_ops.create_node = fdt_wrapper_create_node;
++	dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
++	dt_ops.get_path = fdt_wrapper_get_path;
++	dt_ops.finalize = fdt_wrapper_finalize;
++
++	/* Make sure the dt blob is the right version and so forth */
++	fdt = blob;
++	err = fdt_open_into(fdt, fdt, fdt_totalsize(blob));
++	if (err == -FDT_ERR_NOSPACE) {
++		int bufsize = fdt_totalsize(fdt) + 4;
++		buf = malloc(bufsize);
++		err = fdt_open_into(fdt, buf, bufsize);
++	}
++
++	if (err != 0)
++		fatal("fdt_init(): %s\n\r", fdt_strerror(err));
++
++	if (buf)
++		fdt = buf;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/libfdt_env.h powerpc.git/arch/powerpc/boot/libfdt_env.h
+--- linux-2.6.24/arch/powerpc/boot/libfdt_env.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/libfdt_env.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,17 @@
++#ifndef _ARCH_POWERPC_BOOT_LIBFDT_ENV_H
++#define _ARCH_POWERPC_BOOT_LIBFDT_ENV_H
++
++#include <types.h>
++#include <string.h>
++
++typedef u32 uint32_t;
++typedef u64 uint64_t;
++
++#define fdt16_to_cpu(x)		(x)
++#define cpu_to_fdt16(x)		(x)
++#define fdt32_to_cpu(x)		(x)
++#define cpu_to_fdt32(x)		(x)
++#define fdt64_to_cpu(x)		(x)
++#define cpu_to_fdt64(x)		(x)
++
++#endif /* _ARCH_POWERPC_BOOT_LIBFDT_ENV_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/main.c powerpc.git/arch/powerpc/boot/main.c
+--- linux-2.6.24/arch/powerpc/boot/main.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/main.c	2008-01-28 20:25:49.000000000 +0100
+@@ -16,7 +16,6 @@
+ #include "stdio.h"
+ #include "ops.h"
+ #include "gunzip_util.h"
+-#include "flatdevtree.h"
+ #include "reg.h"
+ 
+ static struct gunzip_state gzstate;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/ops.h powerpc.git/arch/powerpc/boot/ops.h
+--- linux-2.6.24/arch/powerpc/boot/ops.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/ops.h	2008-01-28 20:25:49.000000000 +0100
+@@ -79,7 +79,7 @@
+ extern struct loader_info loader_info;
+ 
+ void start(void);
+-int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
++void fdt_init(void *blob);
+ int serial_console_init(void);
+ int ns16550_console_init(void *devp, struct serial_console_data *scdp);
+ int mpsc_console_init(void *devp, struct serial_console_data *scdp);
+@@ -159,9 +159,23 @@
+ 	return find_node_by_prop_value_str(prev, "device_type", type);
+ }
+ 
++static inline void *find_node_by_alias(const char *alias)
++{
++	void *devp = finddevice("/aliases");
++
++	if (devp) {
++		char path[MAX_PATH_LEN];
++		if (getprop(devp, alias, path, MAX_PATH_LEN) > 0)
++			return finddevice(path);
++	}
++
++	return NULL;
++}
++
+ void dt_fixup_memory(u64 start, u64 size);
+ void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq);
+ void dt_fixup_clock(const char *path, u32 freq);
++void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr);
+ void dt_fixup_mac_address(u32 index, const u8 *addr);
+ void __dt_fixup_mac_addresses(u32 startindex, ...);
+ #define dt_fixup_mac_addresses(...) \
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/prpmc2800.c powerpc.git/arch/powerpc/boot/prpmc2800.c
+--- linux-2.6.24/arch/powerpc/boot/prpmc2800.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/prpmc2800.c	2008-01-28 20:25:49.000000000 +0100
+@@ -547,8 +547,7 @@
+ 	if (!dtb)
+ 		exit();
+ 	memmove(dtb, _dtb_start, dt_size);
+-	if (ft_init(dtb, dt_size, 16))
+-		exit();
++	fdt_init(dtb);
+ 
+ 	bridge_base = mv64x60_get_bridge_base();
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/ps3.c powerpc.git/arch/powerpc/boot/ps3.c
+--- linux-2.6.24/arch/powerpc/boot/ps3.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/ps3.c	2008-01-28 20:25:49.000000000 +0100
+@@ -131,7 +131,7 @@
+ 	printf("\n-- PS3 bootwrapper --\n");
+ 
+ 	simple_alloc_init(_end, heapsize, 32, 64);
+-	ft_init(_dtb_start, 0, 4);
++	fdt_init(_dtb_start);
+ 
+ 	chosen = finddevice("/chosen");
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/redboot-8xx.c powerpc.git/arch/powerpc/boot/redboot-8xx.c
+--- linux-2.6.24/arch/powerpc/boot/redboot-8xx.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/redboot-8xx.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,58 @@
++/*
++ * RedBoot firmware support
++ *
++ * Author: Scott Wood <scottwood@freescale.com>
++ *
++ * Copyright (c) 2007 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 version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include "ops.h"
++#include "stdio.h"
++#include "redboot.h"
++#include "fsl-soc.h"
++#include "io.h"
++
++static bd_t bd;
++BSS_STACK(4096);
++
++#define MHZ(x)	((x + 500000) / 1000000)
++
++static void platform_fixups(void)
++{
++	void *node;
++
++	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
++	dt_fixup_mac_addresses(bd.bi_enetaddr);
++	dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 16, bd.bi_busfreq);
++
++	node = finddevice("/soc/cpm/brg");
++	if (node) {
++		printf("BRG clock-frequency <- 0x%x (%dMHz)\r\n",
++		       bd.bi_busfreq, MHZ(bd.bi_busfreq));
++		setprop(node, "clock-frequency",  &bd.bi_busfreq, 4);
++	}
++}
++
++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
++                   unsigned long r6, unsigned long r7)
++{
++	memcpy(&bd, (char *)r3, sizeof(bd));
++
++	if (bd.bi_tag != 0x42444944)
++		return;
++
++	simple_alloc_init(_end,
++	                  bd.bi_memstart + bd.bi_memsize - (unsigned long)_end,
++	                  32, 64);
++
++	fdt_init(_dtb_start);
++	serial_console_init();
++	platform_ops.fixups = platform_fixups;
++
++	loader_info.cmdline = (char *)bd.bi_cmdline;
++	loader_info.cmdline_len = strlen((char *)bd.bi_cmdline);
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/redboot.h powerpc.git/arch/powerpc/boot/redboot.h
+--- linux-2.6.24/arch/powerpc/boot/redboot.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/redboot.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,56 @@
++#ifndef _PPC_REDBOOT_H
++#define _PPC_REDBOOT_H
++
++//=========================================================================
++// include/asm-ppc/redboot.h
++//   Copyright (c) 2002, 2003 Gary Thomas (<gary@mlbassoc.com>
++//   Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
++
++//
++// Board specific details, as provided by RedBoot
++//
++
++/* A Board Information structure that is given to a program when
++ * RedBoot starts it up.  Note: not all fields make sense for all
++ * architectures and it's up to the platform specific code to fill
++ * in the details.
++ */
++typedef struct bd_info {
++    unsigned int   bi_tag;        /* Should be 0x42444944 "BDID" */
++    unsigned int   bi_size;       /* Size of this structure */
++    unsigned int   bi_revision;   /* revision of this structure */
++    unsigned int   bi_bdate;      /* bootstrap date, i.e. 0x19971106 */
++    unsigned int   bi_memstart;   /* Memory start address */
++    unsigned int   bi_memsize;    /* Memory (end) size in bytes */
++    unsigned int   bi_intfreq;    /* Internal Freq, in Hz */
++    unsigned int   bi_busfreq;    /* Bus Freq, in Hz */
++    unsigned int   bi_cpmfreq;    /* CPM Freq, in Hz */
++    unsigned int   bi_brgfreq;    /* BRG Freq, in Hz */
++    unsigned int   bi_vco;        /* VCO Out from PLL */
++    unsigned int   bi_pci_freq;   /* PCI Freq, in Hz */
++    unsigned int   bi_baudrate;   /* Default console baud rate */
++    unsigned int   bi_immr;       /* IMMR when called from boot rom */
++    unsigned char  bi_enetaddr[6];
++    unsigned int   bi_flashbase;  /* Physical address of FLASH memory */
++    unsigned int   bi_flashsize;  /* Length of FLASH memory */
++    int            bi_flashwidth; /* Width (8,16,32,64) */
++    unsigned char *bi_cmdline;    /* Pointer to command line */
++    unsigned char  bi_esa[3][6];  /* Ethernet station addresses */
++    unsigned int   bi_ramdisk_begin, bi_ramdisk_end;
++    struct {                      /* Information about [main] video screen */
++        short x_res;              /*   Horizontal resolution in pixels */
++        short y_res;              /*   Vertical resolution in pixels */
++        short bpp;                /*   Bits/pixel */
++        short mode;               /*   Type of pixels (packed, indexed) */
++        unsigned long fb;         /*   Pointer to frame buffer (pixel) memory */
++    } bi_video;
++    void         (*bi_cputc)(char);   /* Write a character to the RedBoot console */
++    char         (*bi_cgetc)(void);   /* Read a character from the RedBoot console */
++    int          (*bi_ctstc)(void);   /* Test for input on the RedBoot console */
++} bd_t;
++
++#define BI_REV 0x0102    /* Version 1.02 */
++
++#define bi_pci_busfreq bi_pci_freq
++#define bi_immr_base   bi_immr
++#endif
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/reg.h powerpc.git/arch/powerpc/boot/reg.h
+--- linux-2.6.24/arch/powerpc/boot/reg.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/reg.h	2008-01-28 20:25:49.000000000 +0100
+@@ -16,6 +16,14 @@
+ 	return pvr;
+ }
+ 
++#define __stringify_1(x)	#x
++#define __stringify(x)		__stringify_1(x)
++
++#define mfspr(rn)	({unsigned long rval; \
++			asm volatile("mfspr %0," __stringify(rn) \
++				: "=r" (rval)); rval; })
++#define mtspr(rn, v)	asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
++
+ register void *__stack_pointer asm("r1");
+ #define get_sp()	(__stack_pointer)
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/serial.c powerpc.git/arch/powerpc/boot/serial.c
+--- linux-2.6.24/arch/powerpc/boot/serial.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/serial.c	2008-01-28 20:25:49.000000000 +0100
+@@ -128,7 +128,8 @@
+ 		rc = cpm_console_init(devp, &serial_cd);
+ 	else if (dt_is_compatible(devp, "mpc5200-psc-uart"))
+ 		rc = mpc5200_psc_console_init(devp, &serial_cd);
+-	else if (dt_is_compatible(devp, "xilinx,uartlite"))
++	else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") ||
++		 dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a"))
+ 		rc = uartlite_console_init(devp, &serial_cd);
+ 
+ 	/* Add other serial console driver calls here */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/treeboot-walnut.c powerpc.git/arch/powerpc/boot/treeboot-walnut.c
+--- linux-2.6.24/arch/powerpc/boot/treeboot-walnut.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/treeboot-walnut.c	2008-01-28 20:25:49.000000000 +0100
+@@ -20,55 +20,6 @@
+ 
+ BSS_STACK(4096);
+ 
+-void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
+-{
+-	u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
+-	u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
+-	u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
+-	u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
+-	u32 fwdv, fbdv, cbdv, opdv, epdv, udiv;
+-
+-	fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
+-	fbdv = (pllmr & 0x1e000000) >> 25;
+-	cbdv = ((pllmr & 0x00060000) >> 17) + 1;
+-	opdv = ((pllmr & 0x00018000) >> 15) + 1;
+-	epdv = ((pllmr & 0x00001800) >> 13) + 2;
+-	udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
+-
+-	m = fwdv * fbdv * cbdv;
+-
+-	cpu = sysclk * m / fwdv;
+-	plb = cpu / cbdv;
+-	opb = plb / opdv;
+-	ebc = plb / epdv;
+-
+-	if (cpc0_cr0 & 0x80) {
+-		/* uart0 uses the external clock */
+-		uart0 = ser_clk;
+-	} else {
+-		uart0 = cpu / udiv;
+-	}
+-
+-	if (cpc0_cr0 & 0x40) {
+-		/* uart1 uses the external clock */
+-		uart1 = ser_clk;
+-	} else {
+-		uart1 = cpu / udiv;
+-	}
+-
+-	/* setup the timebase clock to tick at the cpu frequency */
+-	cpc0_cr1 = cpc0_cr1 & ~0x00800000;
+-	mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
+-	tb = cpu;
+-
+-	dt_fixup_cpu_clocks(cpu, tb, 0);
+-	dt_fixup_clock("/plb", plb);
+-	dt_fixup_clock("/plb/opb", opb);
+-	dt_fixup_clock("/plb/ebc", ebc);
+-	dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
+-	dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
+-}
+-
+ static void walnut_flashsel_fixup(void)
+ {
+ 	void *devp, *sram;
+@@ -112,7 +63,7 @@
+ #define WALNUT_OPENBIOS_MAC_OFF 0xfffffe0b
+ static void walnut_fixups(void)
+ {
+-	ibm4xx_fixup_memsize();
++	ibm4xx_sdram_fixup_memsize();
+ 	ibm405gp_fixup_clocks(33330000, 0xa8c000);
+ 	ibm4xx_quiesce_eth((u32 *)0xef600800, NULL);
+ 	ibm4xx_fixup_ebc_ranges("/plb/ebc");
+@@ -128,6 +79,6 @@
+ 	simple_alloc_init(_end, avail_ram, 32, 32);
+ 	platform_ops.fixups = walnut_fixups;
+ 	platform_ops.exit = ibm40x_dbcr_reset;
+-	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
++	fdt_init(_dtb_start);
+ 	serial_console_init();
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/boot/wrapper powerpc.git/arch/powerpc/boot/wrapper
+--- linux-2.6.24/arch/powerpc/boot/wrapper	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/boot/wrapper	2008-01-28 20:25:49.000000000 +0100
+@@ -45,6 +45,7 @@
+ 
+ # directory for object and other files used by this script
+ object=arch/powerpc/boot
++objbin=$object
+ 
+ # directory for working files
+ tmpdir=.
+@@ -95,6 +96,7 @@
+ 	shift
+ 	[ "$#" -gt 0 ] || usage
+ 	object="$1"
++	objbin="$1"
+ 	;;
+     -W)
+ 	shift
+@@ -116,10 +118,13 @@
+ done
+ 
+ if [ -n "$dts" ]; then
++    if [ ! -r "$dts" -a -r "$object/dts/$dts" ]; then
++	dts="$object/dts/$dts"
++    fi
+     if [ -z "$dtb" ]; then
+ 	dtb="$platform.dtb"
+     fi
+-    dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts"
++    $object/dtc -O dtb -o "$dtb" -b 0 "$dts"
+ fi
+ 
+ if [ -z "$kernel" ]; then
+@@ -163,7 +168,7 @@
+     ksection=.kernel:vmlinux.bin
+     isection=.kernel:initrd
+     ;;
+-ep88xc)
++ep88xc|ep405|redboot*|ep8248e)
+     platformo="$object/fixed-head.o $object/$platform.o"
+     binary=y
+     ;;
+@@ -246,11 +251,11 @@
+ # post-processing needed for some platforms
+ case "$platform" in
+ pseries|chrp)
+-    $object/addnote "$ofile"
++    $objbin/addnote "$ofile"
+     ;;
+ coff)
+     ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile"
+-    $object/hack-coff "$ofile"
++    $objbin/hack-coff "$ofile"
+     ;;
+ cuboot*)
+     gzip -f -9 "$ofile"
+@@ -259,7 +264,7 @@
+     ;;
+ treeboot*)
+     mv "$ofile" "$ofile.elf"
+-    $object/mktree "$ofile.elf" "$ofile" "$base" "$entry"
++    $objbin/mktree "$ofile.elf" "$ofile" "$base" "$entry"
+     if [ -z "$cacheit" ]; then
+ 	rm -f "$ofile.elf"
+     fi
+@@ -287,8 +292,6 @@
+     overlay_dest="256"
+     overlay_size="256"
+ 
+-    rm -f "$object/otheros.bld"
+-
+     ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
+ 
+     dd if="$ofile.bin" of="$ofile.bin" conv=notrunc   \
+@@ -299,6 +302,8 @@
+         skip=$system_reset_overlay seek=$overlay_dest \
+         count=$overlay_size bs=1
+ 
+-    gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
++    odir="$(dirname "$ofile.bin")"
++    rm -f "$odir/otheros.bld"
++    gzip --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld"
+     ;;
+ esac
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/adder875-redboot_defconfig powerpc.git/arch/powerpc/configs/adder875-redboot_defconfig
+--- linux-2.6.24/arch/powerpc/configs/adder875-redboot_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/adder875-redboot_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,798 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Thu Jan 17 16:17:38 2008
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++# CONFIG_6xx is not set
++# CONFIG_PPC_85xx is not set
++CONFIG_PPC_8xx=y
++# CONFIG_40x is not set
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_8xx=y
++# CONFIG_PPC_MM_SLICES is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++# CONFIG_PPC_UDBG_16550 is not set
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++CONFIG_REDBOOT=y
++# CONFIG_PPC_DCR_NATIVE is not set
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++# CONFIG_ELF_CORE is not set
++# CONFIG_BASE_FULL is not set
++# CONFIG_FUTEX is not set
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++# CONFIG_VM_EVENT_COUNTERS is not set
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=1
++# CONFIG_MODULES is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++CONFIG_IOSCHED_DEADLINE=y
++# CONFIG_IOSCHED_CFQ is not set
++# CONFIG_DEFAULT_AS is not set
++CONFIG_DEFAULT_DEADLINE=y
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="deadline"
++
++#
++# Platform support
++#
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++CONFIG_CPM1=y
++# CONFIG_MPC8XXFADS is not set
++# CONFIG_MPC86XADS is not set
++# CONFIG_MPC885ADS is not set
++# CONFIG_PPC_EP88XC is not set
++CONFIG_PPC_ADDER875=y
++
++#
++# MPC8xx CPM Options
++#
++
++#
++# Generic MPC8xx Options
++#
++CONFIG_8xx_COPYBACK=y
++# CONFIG_8xx_CPU6 is not set
++CONFIG_8xx_CPU15=y
++CONFIG_NO_UCODE_PATCH=y
++# CONFIG_USB_SOF_UCODE_PATCH is not set
++# CONFIG_I2C_SPI_UCODE_PATCH is not set
++# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++CONFIG_PPC_CPM_NEW_BINDING=y
++# CONFIG_FSL_ULI1575 is not set
++CONFIG_CPM=y
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_250 is not set
++# CONFIG_HZ_300 is not set
++CONFIG_HZ_1000=y
++CONFIG_HZ=1000
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_MATH_EMULATION is not set
++# CONFIG_8XX_MINIMAL_FPEMU is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++# CONFIG_PROC_DEVICETREE is not set
++# CONFIG_CMDLINE_BOOL is not set
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++CONFIG_HIBERNATION_UP_POSSIBLE=y
++# CONFIG_SECCOMP is not set
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="adder875-redboot.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_FSL_SOC=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_DOMAINS is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCI_QSPAN is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0x80000000
++CONFIG_CONSISTENT_START=0xfd000000
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_BOOT_LOAD=0x00400000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++# CONFIG_MTD_PARTITIONS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++# CONFIG_BLK_DEV is not set
++# CONFIG_MISC_DEVICES is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_MARVELL_PHY is not set
++CONFIG_DAVICOM_PHY=y
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_FS_ENET=y
++# CONFIG_FS_ENET_HAS_SCC is not set
++CONFIG_FS_ENET_HAS_FEC=y
++CONFIG_FS_ENET_MDIO_FEC=y
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++CONFIG_SERIO_SERPORT=y
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_CPM=y
++CONFIG_SERIAL_CPM_CONSOLE=y
++# CONFIG_SERIAL_CPM_SCC1 is not set
++# CONFIG_SERIAL_CPM_SCC2 is not set
++# CONFIG_SERIAL_CPM_SCC3 is not set
++# CONFIG_SERIAL_CPM_SCC4 is not set
++CONFIG_SERIAL_CPM_SMC1=y
++CONFIG_SERIAL_CPM_SMC2=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_NVRAM is not set
++CONFIG_GEN_RTC=y
++# CONFIG_GEN_RTC_X is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=y
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_INOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_DNOTIFY is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++# CONFIG_PROC_KCORE is not set
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++# CONFIG_NLS is not set
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++# CONFIG_CRC32 is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_INSTRUMENTATION=y
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_DEBUGGER is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++# CONFIG_CRYPTO is not set
++# CONFIG_PPC_CLOCK is not set
++CONFIG_PPC_LIB_RHEAP=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/adder875-uboot_defconfig powerpc.git/arch/powerpc/configs/adder875-uboot_defconfig
+--- linux-2.6.24/arch/powerpc/configs/adder875-uboot_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/adder875-uboot_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,798 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Thu Jan 17 16:17:18 2008
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++# CONFIG_6xx is not set
++# CONFIG_PPC_85xx is not set
++CONFIG_PPC_8xx=y
++# CONFIG_40x is not set
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_8xx=y
++# CONFIG_PPC_MM_SLICES is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++# CONFIG_PPC_UDBG_16550 is not set
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++CONFIG_REDBOOT=y
++# CONFIG_PPC_DCR_NATIVE is not set
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++# CONFIG_ELF_CORE is not set
++# CONFIG_BASE_FULL is not set
++# CONFIG_FUTEX is not set
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++# CONFIG_VM_EVENT_COUNTERS is not set
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=1
++# CONFIG_MODULES is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++CONFIG_IOSCHED_DEADLINE=y
++# CONFIG_IOSCHED_CFQ is not set
++# CONFIG_DEFAULT_AS is not set
++CONFIG_DEFAULT_DEADLINE=y
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="deadline"
++
++#
++# Platform support
++#
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++CONFIG_CPM1=y
++# CONFIG_MPC8XXFADS is not set
++# CONFIG_MPC86XADS is not set
++# CONFIG_MPC885ADS is not set
++# CONFIG_PPC_EP88XC is not set
++CONFIG_PPC_ADDER875=y
++
++#
++# MPC8xx CPM Options
++#
++
++#
++# Generic MPC8xx Options
++#
++CONFIG_8xx_COPYBACK=y
++# CONFIG_8xx_CPU6 is not set
++CONFIG_8xx_CPU15=y
++CONFIG_NO_UCODE_PATCH=y
++# CONFIG_USB_SOF_UCODE_PATCH is not set
++# CONFIG_I2C_SPI_UCODE_PATCH is not set
++# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++CONFIG_PPC_CPM_NEW_BINDING=y
++# CONFIG_FSL_ULI1575 is not set
++CONFIG_CPM=y
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_250 is not set
++# CONFIG_HZ_300 is not set
++CONFIG_HZ_1000=y
++CONFIG_HZ=1000
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_MATH_EMULATION is not set
++# CONFIG_8XX_MINIMAL_FPEMU is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++# CONFIG_PROC_DEVICETREE is not set
++# CONFIG_CMDLINE_BOOL is not set
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++CONFIG_HIBERNATION_UP_POSSIBLE=y
++# CONFIG_SECCOMP is not set
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="adder875-uboot.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_FSL_SOC=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_DOMAINS is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCI_QSPAN is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0x80000000
++CONFIG_CONSISTENT_START=0xfd000000
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_BOOT_LOAD=0x00400000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++# CONFIG_MTD_PARTITIONS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_CFI_FLAGADM is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++# CONFIG_BLK_DEV is not set
++# CONFIG_MISC_DEVICES is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_MARVELL_PHY is not set
++CONFIG_DAVICOM_PHY=y
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_FS_ENET=y
++# CONFIG_FS_ENET_HAS_SCC is not set
++CONFIG_FS_ENET_HAS_FEC=y
++CONFIG_FS_ENET_MDIO_FEC=y
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_I8042=y
++CONFIG_SERIO_SERPORT=y
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_CPM=y
++CONFIG_SERIAL_CPM_CONSOLE=y
++# CONFIG_SERIAL_CPM_SCC1 is not set
++# CONFIG_SERIAL_CPM_SCC2 is not set
++# CONFIG_SERIAL_CPM_SCC3 is not set
++# CONFIG_SERIAL_CPM_SCC4 is not set
++CONFIG_SERIAL_CPM_SMC1=y
++CONFIG_SERIAL_CPM_SMC2=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_NVRAM is not set
++CONFIG_GEN_RTC=y
++# CONFIG_GEN_RTC_X is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=y
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_INOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_DNOTIFY is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++# CONFIG_PROC_KCORE is not set
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++# CONFIG_NLS is not set
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++# CONFIG_CRC32 is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_INSTRUMENTATION=y
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_DEBUGGER is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++# CONFIG_CRYPTO is not set
++# CONFIG_PPC_CLOCK is not set
++CONFIG_PPC_LIB_RHEAP=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/bamboo_defconfig powerpc.git/arch/powerpc/configs/bamboo_defconfig
+--- linux-2.6.24/arch/powerpc/configs/bamboo_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/bamboo_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:48:04 2007
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 10:49:50 2007
+ #
+ # CONFIG_PPC64 is not set
+ 
+@@ -131,6 +131,7 @@
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_PPC4xx_PCI_EXPRESS is not set
+ 
+ #
+ # Platform support
+@@ -143,6 +144,9 @@
+ CONFIG_BAMBOO=y
+ # CONFIG_EBONY is not set
+ # CONFIG_SEQUOIA is not set
++# CONFIG_TAISHAN is not set
++# CONFIG_KATMAI is not set
++# CONFIG_RAINIER is not set
+ CONFIG_440EP=y
+ CONFIG_IBM440EP_ERR42=y
+ # CONFIG_MPIC is not set
+@@ -372,9 +376,7 @@
+ # CONFIG_FIREWIRE is not set
+ # CONFIG_IEEE1394 is not set
+ # CONFIG_I2O is not set
+-CONFIG_MACINTOSH_DRIVERS=y
+-# CONFIG_MAC_EMUMOUSEBTN is not set
+-# CONFIG_WINDFARM is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
+ CONFIG_NETDEVICES=y
+ # CONFIG_NETDEVICES_MULTIQUEUE is not set
+ # CONFIG_DUMMY is not set
+@@ -736,19 +738,7 @@
+ # CONFIG_KGDB is not set
+ # CONFIG_XMON is not set
+ # CONFIG_BDI_SWITCH is not set
+-CONFIG_PPC_EARLY_DEBUG=y
+-# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+-# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+-# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
+-# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
+-# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+-# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+-# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+-# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
+-CONFIG_PPC_EARLY_DEBUG_44x=y
+-# CONFIG_PPC_EARLY_DEBUG_CPM is not set
+-CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
+-CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x0
++# CONFIG_PPC_EARLY_DEBUG is not set
+ 
+ #
+ # Security options
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/celleb_defconfig powerpc.git/arch/powerpc/configs/celleb_defconfig
+--- linux-2.6.24/arch/powerpc/configs/celleb_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/celleb_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -50,7 +50,8 @@
+ CONFIG_GENERIC_BUG=y
+ # CONFIG_DEFAULT_UIMAGE is not set
+ # CONFIG_PPC_DCR_NATIVE is not set
+-# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_PPC_DCR_MMIO=y
++CONFIG_PPC_DCR=y
+ CONFIG_PPC_OF_PLATFORM_PCI=y
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ 
+@@ -148,7 +149,7 @@
+ CONFIG_PPC_CELLEB=y
+ # CONFIG_PPC_PS3 is not set
+ CONFIG_PPC_CELL=y
+-# CONFIG_PPC_CELL_NATIVE is not set
++CONFIG_PPC_CELL_NATIVE=y
+ # CONFIG_PPC_IBM_CELL_BLADE is not set
+ 
+ #
+@@ -157,13 +158,19 @@
+ CONFIG_SPU_FS=y
+ CONFIG_SPU_FS_64K_LS=y
+ CONFIG_SPU_BASE=y
++CONFIG_CBE_RAS=y
++# CONFIG_CBE_THERM is not set
+ # CONFIG_PQ2ADS is not set
++CONFIG_PPC_NATIVE=y
++CONFIG_UDBG_RTAS_CONSOLE=y
+ CONFIG_PPC_UDBG_BEAT=y
+-# CONFIG_MPIC is not set
++CONFIG_MPIC=y
+ # CONFIG_MPIC_WEIRD is not set
+ # CONFIG_PPC_I8259 is not set
+ # CONFIG_U3_DART is not set
+-# CONFIG_PPC_RTAS is not set
++CONFIG_PPC_RTAS=y
++# CONFIG_RTAS_ERROR_LOGGING is not set
++# CONFIG_RTAS_PROC is not set
+ # CONFIG_MMIO_NVRAM is not set
+ # CONFIG_PPC_MPC106 is not set
+ # CONFIG_PPC_970_NAP is not set
+@@ -593,10 +600,11 @@
+ # CONFIG_NET_VENDOR_3COM is not set
+ # CONFIG_NET_TULIP is not set
+ # CONFIG_HP100 is not set
+-# CONFIG_IBM_NEW_EMAC_ZMII is not set
+-# CONFIG_IBM_NEW_EMAC_RGMII is not set
+-# CONFIG_IBM_NEW_EMAC_TAH is not set
+-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_IBM_NEW_EMAC is not set
++CONFIG_IBM_NEW_EMAC_ZMII=y
++CONFIG_IBM_NEW_EMAC_RGMII=y
++CONFIG_IBM_NEW_EMAC_TAH=y
++CONFIG_IBM_NEW_EMAC_EMAC4=y
+ # CONFIG_NET_PCI is not set
+ # CONFIG_B44 is not set
+ CONFIG_NETDEV_1000=y
+@@ -741,6 +749,7 @@
+ CONFIG_UNIX98_PTYS=y
+ # CONFIG_LEGACY_PTYS is not set
+ CONFIG_HVC_DRIVER=y
++CONFIG_HVC_RTAS=y
+ CONFIG_HVC_BEAT=y
+ # CONFIG_IPMI_HANDLER is not set
+ # CONFIG_HW_RANDOM is not set
+@@ -822,6 +831,7 @@
+ # Watchdog Device Drivers
+ #
+ # CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_WATCHDOG_RTAS is not set
+ 
+ #
+ # PCI-based Watchdog Cards
+@@ -1245,17 +1255,7 @@
+ CONFIG_IRQSTACKS=y
+ # CONFIG_VIRQ_DEBUG is not set
+ # CONFIG_BOOTX_TEXT is not set
+-CONFIG_PPC_EARLY_DEBUG=y
+-# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+-# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+-# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
+-# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
+-# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+-# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+-# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+-CONFIG_PPC_EARLY_DEBUG_BEAT=y
+-# CONFIG_PPC_EARLY_DEBUG_44x is not set
+-# CONFIG_PPC_EARLY_DEBUG_CPM is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
+ 
+ #
+ # Security options
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/ebony_defconfig powerpc.git/arch/powerpc/configs/ebony_defconfig
+--- linux-2.6.24/arch/powerpc/configs/ebony_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/ebony_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:48:11 2007
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 11:16:26 2007
+ #
+ # CONFIG_PPC64 is not set
+ 
+@@ -130,6 +130,7 @@
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_PPC4xx_PCI_EXPRESS is not set
+ 
+ #
+ # Platform support
+@@ -142,6 +143,9 @@
+ # CONFIG_BAMBOO is not set
+ CONFIG_EBONY=y
+ # CONFIG_SEQUOIA is not set
++# CONFIG_TAISHAN is not set
++# CONFIG_KATMAI is not set
++# CONFIG_RAINIER is not set
+ CONFIG_440GP=y
+ # CONFIG_MPIC is not set
+ # CONFIG_MPIC_WEIRD is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/ep405_defconfig powerpc.git/arch/powerpc/configs/ep405_defconfig
+--- linux-2.6.24/arch/powerpc/configs/ep405_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/ep405_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,952 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 11:17:13 2007
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++# CONFIG_6xx is not set
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++CONFIG_40x=y
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_4xx=y
++# CONFIG_PPC_MM_SLICES is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++CONFIG_PPC_UDBG_16550=y
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++CONFIG_PPC_DCR_NATIVE=y
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_PPC_DCR=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++CONFIG_LBD=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_PPC4xx_PCI_EXPRESS is not set
++
++#
++# Platform support
++#
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++CONFIG_EP405=y
++# CONFIG_KILAUEA is not set
++# CONFIG_MAKALU is not set
++# CONFIG_WALNUT is not set
++# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
++CONFIG_405GP=y
++CONFIG_IBM405_ERR77=y
++CONFIG_IBM405_ERR51=y
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_MATH_EMULATION is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_CMDLINE_BOOL is not set
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++CONFIG_HIBERNATION_UP_POSSIBLE=y
++CONFIG_SECCOMP=y
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="ep405.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_DEBUG is not set
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_CONSISTENT_START=0xff100000
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_BOOT_LOAD=0x00400000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=m
++CONFIG_MTD_BLOCK=m
++# CONFIG_MTD_BLOCK_RO is not set
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++CONFIG_MTD_JEDECPROBE=y
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_INTEL_VR_NOR is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=35000
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_XILINX_SYSACE is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_PHANTOM is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_SGI_IOC4 is not set
++# CONFIG_TIFM_CORE is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_IBM_NEW_EMAC=y
++CONFIG_IBM_NEW_EMAC_RXB=128
++CONFIG_IBM_NEW_EMAC_TXB=64
++CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
++CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
++CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
++# CONFIG_IBM_NEW_EMAC_DEBUG is not set
++CONFIG_IBM_NEW_EMAC_ZMII=y
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++CONFIG_NETDEV_10000=y
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_CHELSIO_T3 is not set
++# CONFIG_IXGBE is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO is not set
++# CONFIG_MYRI10GE is not set
++# CONFIG_NETXEN_NIC is not set
++# CONFIG_NIU is not set
++# CONFIG_MLX4_CORE is not set
++# CONFIG_TEHUTI is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_PCI=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_EXTENDED=y
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++CONFIG_SERIAL_8250_SHARE_IRQ=y
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_NVRAM is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++CONFIG_USB_OHCI_HCD_PPC_OF=y
++CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
++CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
++CONFIG_USB_OHCI_HCD_PCI=y
++CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
++CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_UHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_INFINIBAND is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_INSTRUMENTATION=y
++# CONFIG_PROFILING is not set
++# CONFIG_KPROBES is not set
++# CONFIG_MARKERS is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_DEBUGGER is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_PPC_CLOCK is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/ep8248e_defconfig powerpc.git/arch/powerpc/configs/ep8248e_defconfig
+--- linux-2.6.24/arch/powerpc/configs/ep8248e_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/ep8248e_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,821 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Fri Jan 11 14:02:06 2008
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++CONFIG_6xx=y
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_PPC_FPU=y
++CONFIG_PPC_STD_MMU=y
++CONFIG_PPC_STD_MMU_32=y
++# CONFIG_PPC_MM_SLICES is not set
++# CONFIG_SMP is not set
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++# CONFIG_PPC_UDBG_16550 is not set
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++# CONFIG_PPC_DCR_NATIVE is not set
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++# CONFIG_EXPERIMENTAL is not set
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++# CONFIG_MODULES is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++CONFIG_IOSCHED_DEADLINE=y
++# CONFIG_IOSCHED_CFQ is not set
++# CONFIG_DEFAULT_AS is not set
++CONFIG_DEFAULT_DEADLINE=y
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="deadline"
++
++#
++# Platform support
++#
++# CONFIG_PPC_MULTIPLATFORM is not set
++CONFIG_PPC_82xx=y
++# CONFIG_PPC_83xx is not set
++# CONFIG_PPC_86xx is not set
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_MPC8272_ADS is not set
++# CONFIG_PQ2FADS is not set
++CONFIG_EP8248E=y
++# CONFIG_PQ2ADS is not set
++CONFIG_8260=y
++CONFIG_8272=y
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++CONFIG_CPM2=y
++CONFIG_PPC_CPM_NEW_BINDING=y
++# CONFIG_FSL_ULI1575 is not set
++CONFIG_CPM=y
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++CONFIG_BINFMT_MISC=y
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_CMDLINE_BOOL is not set
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++CONFIG_HIBERNATION_UP_POSSIBLE=y
++# CONFIG_SECCOMP is not set
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="ep8248e.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_FSL_SOC=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_DOMAINS is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_BOOT_LOAD=0x00400000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_IP_VS is not set
++CONFIG_IPV6=y
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=y
++CONFIG_INET6_XFRM_MODE_TUNNEL=y
++CONFIG_INET6_XFRM_MODE_BEET=y
++CONFIG_IPV6_SIT=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++# CONFIG_NF_CONNTRACK_ENABLED is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++# CONFIG_MTD_PARTITIONS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++# CONFIG_MTD_CFI_I1 is not set
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MISC_DEVICES is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_MARVELL_PHY is not set
++CONFIG_DAVICOM_PHY=y
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_FIXED_PHY is not set
++CONFIG_MDIO_BITBANG=y
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_FS_ENET=y
++# CONFIG_FS_ENET_HAS_SCC is not set
++CONFIG_FS_ENET_HAS_FCC=y
++# CONFIG_FS_ENET_MDIO_FCC is not set
++CONFIG_NETDEV_1000=y
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_CPM=y
++CONFIG_SERIAL_CPM_CONSOLE=y
++CONFIG_SERIAL_CPM_SCC1=y
++# CONFIG_SERIAL_CPM_SCC2 is not set
++# CONFIG_SERIAL_CPM_SCC3 is not set
++CONFIG_SERIAL_CPM_SCC4=y
++# CONFIG_SERIAL_CPM_SMC1 is not set
++# CONFIG_SERIAL_CPM_SMC2 is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_NVRAM is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++CONFIG_AUTOFS4_FS=y
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++# CONFIG_CRC32 is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_INSTRUMENTATION=y
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++# CONFIG_DETECT_SOFTLOCKUP is not set
++# CONFIG_SCHED_DEBUG is not set
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_DEBUGGER is not set
++# CONFIG_KGDB_CONSOLE is not set
++CONFIG_BDI_SWITCH=y
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++CONFIG_CRYPTO_ECB=y
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_HW is not set
++# CONFIG_PPC_CLOCK is not set
++CONFIG_PPC_LIB_RHEAP=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/katmai_defconfig powerpc.git/arch/powerpc/configs/katmai_defconfig
+--- linux-2.6.24/arch/powerpc/configs/katmai_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/katmai_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,790 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 11:17:43 2007
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++# CONFIG_6xx is not set
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++CONFIG_44x=y
++# CONFIG_E200 is not set
++CONFIG_4xx=y
++CONFIG_BOOKE=y
++CONFIG_PTE_64BIT=y
++CONFIG_PHYS_64BIT=y
++# CONFIG_PPC_MM_SLICES is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++CONFIG_PPC_UDBG_16550=y
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++CONFIG_PPC_DCR_NATIVE=y
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_PPC_DCR=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++CONFIG_LBD=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_PPC4xx_PCI_EXPRESS=y
++
++#
++# Platform support
++#
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_BAMBOO is not set
++# CONFIG_EBONY is not set
++# CONFIG_SEQUOIA is not set
++# CONFIG_TAISHAN is not set
++CONFIG_KATMAI=y
++# CONFIG_RAINIER is not set
++CONFIG_440SPe=y
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_MATH_EMULATION is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_RESOURCES_64BIT=y
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++CONFIG_CMDLINE_BOOL=y
++CONFIG_CMDLINE=""
++CONFIG_SECCOMP=y
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="katmai.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_DEBUG is not set
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_CONSISTENT_START=0xff100000
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_BOOT_LOAD=0x01000000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++# CONFIG_MTD is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=35000
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_XILINX_SYSACE is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_PHANTOM is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_SGI_IOC4 is not set
++# CONFIG_TIFM_CORE is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_MACINTOSH_DRIVERS=y
++# CONFIG_MAC_EMUMOUSEBTN is not set
++# CONFIG_WINDFARM is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_IBM_NEW_EMAC=y
++CONFIG_IBM_NEW_EMAC_RXB=128
++CONFIG_IBM_NEW_EMAC_TXB=64
++CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
++CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
++CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
++# CONFIG_IBM_NEW_EMAC_DEBUG is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++CONFIG_IBM_NEW_EMAC_EMAC4=y
++# CONFIG_NET_PCI is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++CONFIG_NETDEV_10000=y
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_CHELSIO_T3 is not set
++# CONFIG_IXGBE is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO is not set
++# CONFIG_MYRI10GE is not set
++# CONFIG_NETXEN_NIC is not set
++# CONFIG_NIU is not set
++# CONFIG_MLX4_CORE is not set
++# CONFIG_TEHUTI is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_EXTENDED=y
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++CONFIG_SERIAL_8250_SHARE_IRQ=y
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_NVRAM is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_INFINIBAND is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_INSTRUMENTATION=y
++# CONFIG_PROFILING is not set
++# CONFIG_KPROBES is not set
++# CONFIG_MARKERS is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++CONFIG_DEBUGGER=y
++# CONFIG_KGDB is not set
++# CONFIG_XMON is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_PPC_CLOCK is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/kilauea_defconfig powerpc.git/arch/powerpc/configs/kilauea_defconfig
+--- linux-2.6.24/arch/powerpc/configs/kilauea_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/kilauea_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:48:20 2007
++# Linux kernel version: 2.6.24-rc6
++# Thu Jan  3 14:21:31 2008
+ #
+ # CONFIG_PPC64 is not set
+ 
+@@ -40,7 +40,7 @@
+ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+ CONFIG_PPC_OF=y
+ CONFIG_OF=y
+-# CONFIG_PPC_UDBG_16550 is not set
++CONFIG_PPC_UDBG_16550=y
+ # CONFIG_GENERIC_TBSYNC is not set
+ CONFIG_AUDIT_ARCH=y
+ CONFIG_GENERIC_BUG=y
+@@ -125,6 +125,7 @@
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_PPC4xx_PCI_EXPRESS=y
+ 
+ #
+ # Platform support
+@@ -134,9 +135,12 @@
+ # CONFIG_PPC_CELL is not set
+ # CONFIG_PPC_CELL_NATIVE is not set
+ # CONFIG_PQ2ADS is not set
++# CONFIG_EP405 is not set
+ CONFIG_KILAUEA=y
++# CONFIG_MAKALU is not set
+ # CONFIG_WALNUT is not set
+ # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
++CONFIG_405EX=y
+ # CONFIG_MPIC is not set
+ # CONFIG_MPIC_WEIRD is not set
+ # CONFIG_PPC_I8259 is not set
+@@ -199,11 +203,17 @@
+ # Bus options
+ #
+ CONFIG_ZONE_DMA=y
+-# CONFIG_PCI is not set
+-# CONFIG_PCI_DOMAINS is not set
+-# CONFIG_PCI_SYSCALL is not set
+-# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_DEBUG is not set
+ # CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
+ 
+ #
+ # Advanced setup
+@@ -368,11 +378,13 @@
+ # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+ # CONFIG_MTD_PHYSMAP is not set
+ CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_INTEL_VR_NOR is not set
+ # CONFIG_MTD_PLATRAM is not set
+ 
+ #
+ # Self-contained MTD device drivers
+ #
++# CONFIG_MTD_PMC551 is not set
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_PHRAM is not set
+ # CONFIG_MTD_MTDRAM is not set
+@@ -395,9 +407,14 @@
+ # CONFIG_PARPORT is not set
+ CONFIG_BLK_DEV=y
+ # CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=35000
+@@ -417,6 +434,14 @@
+ # CONFIG_SCSI_NETLINK is not set
+ # CONFIG_ATA is not set
+ # CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
+ # CONFIG_MACINTOSH_DRIVERS is not set
+ CONFIG_NETDEVICES=y
+ # CONFIG_NETDEVICES_MULTIQUEUE is not set
+@@ -426,9 +451,33 @@
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
+ # CONFIG_VETH is not set
+-# CONFIG_NET_ETHERNET is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_IBM_NEW_EMAC=y
++CONFIG_IBM_NEW_EMAC_RXB=256
++CONFIG_IBM_NEW_EMAC_TXB=256
++CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
++CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
++CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
++# CONFIG_IBM_NEW_EMAC_DEBUG is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++CONFIG_IBM_NEW_EMAC_RGMII=y
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++CONFIG_IBM_NEW_EMAC_EMAC4=y
++# CONFIG_NET_PCI is not set
++# CONFIG_B44 is not set
+ # CONFIG_NETDEV_1000 is not set
+ # CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
+ 
+ #
+ # Wireless LAN
+@@ -436,6 +485,8 @@
+ # CONFIG_WLAN_PRE80211 is not set
+ # CONFIG_WLAN_80211 is not set
+ # CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+ # CONFIG_SHAPER is not set
+@@ -467,6 +518,7 @@
+ #
+ CONFIG_SERIAL_8250=y
+ CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_PCI=y
+ CONFIG_SERIAL_8250_NR_UARTS=4
+ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+ CONFIG_SERIAL_8250_EXTENDED=y
+@@ -481,6 +533,7 @@
+ # CONFIG_SERIAL_UARTLITE is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_SERIAL_OF_PLATFORM=y
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+@@ -490,8 +543,10 @@
+ # CONFIG_NVRAM is not set
+ # CONFIG_GEN_RTC is not set
+ # CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
+ # CONFIG_I2C is not set
+ 
+ #
+@@ -525,6 +580,8 @@
+ #
+ # Graphics support
+ #
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
+ # CONFIG_VGASTATE is not set
+ # CONFIG_VIDEO_OUTPUT_CONTROL is not set
+ # CONFIG_FB is not set
+@@ -542,6 +599,7 @@
+ # CONFIG_USB_SUPPORT is not set
+ # CONFIG_MMC is not set
+ # CONFIG_NEW_LEDS is not set
++# CONFIG_INFINIBAND is not set
+ # CONFIG_EDAC is not set
+ # CONFIG_RTC_CLASS is not set
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/lite5200_defconfig powerpc.git/arch/powerpc/configs/lite5200_defconfig
+--- linux-2.6.24/arch/powerpc/configs/lite5200_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/lite5200_defconfig	1970-01-01 01:00:00.000000000 +0100
+@@ -1,847 +0,0 @@
+-#
+-# Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:48:24 2007
+-#
+-# CONFIG_PPC64 is not set
+-
+-#
+-# Processor support
+-#
+-CONFIG_6xx=y
+-# CONFIG_PPC_85xx is not set
+-# CONFIG_PPC_8xx is not set
+-# CONFIG_40x is not set
+-# CONFIG_44x is not set
+-# CONFIG_E200 is not set
+-CONFIG_PPC_FPU=y
+-# CONFIG_ALTIVEC is not set
+-CONFIG_PPC_STD_MMU=y
+-CONFIG_PPC_STD_MMU_32=y
+-# CONFIG_PPC_MM_SLICES is not set
+-# CONFIG_SMP is not set
+-CONFIG_PPC32=y
+-CONFIG_WORD_SIZE=32
+-CONFIG_PPC_MERGE=y
+-CONFIG_MMU=y
+-CONFIG_GENERIC_CMOS_UPDATE=y
+-CONFIG_GENERIC_TIME=y
+-CONFIG_GENERIC_TIME_VSYSCALL=y
+-CONFIG_GENERIC_CLOCKEVENTS=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_IRQ_PER_CPU=y
+-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+-CONFIG_ARCH_HAS_ILOG2_U32=y
+-CONFIG_GENERIC_HWEIGHT=y
+-CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_GENERIC_FIND_NEXT_BIT=y
+-# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+-CONFIG_PPC=y
+-CONFIG_EARLY_PRINTK=y
+-CONFIG_GENERIC_NVRAM=y
+-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+-CONFIG_PPC_OF=y
+-CONFIG_OF=y
+-# CONFIG_PPC_UDBG_16550 is not set
+-# CONFIG_GENERIC_TBSYNC is not set
+-CONFIG_AUDIT_ARCH=y
+-CONFIG_GENERIC_BUG=y
+-# CONFIG_DEFAULT_UIMAGE is not set
+-# CONFIG_PPC_DCR_NATIVE is not set
+-# CONFIG_PPC_DCR_MMIO is not set
+-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+-
+-#
+-# General setup
+-#
+-CONFIG_EXPERIMENTAL=y
+-CONFIG_BROKEN_ON_SMP=y
+-CONFIG_INIT_ENV_ARG_LIMIT=32
+-CONFIG_LOCALVERSION=""
+-CONFIG_LOCALVERSION_AUTO=y
+-CONFIG_SWAP=y
+-CONFIG_SYSVIPC=y
+-CONFIG_SYSVIPC_SYSCTL=y
+-# CONFIG_POSIX_MQUEUE is not set
+-# CONFIG_BSD_PROCESS_ACCT is not set
+-# CONFIG_TASKSTATS is not set
+-# CONFIG_USER_NS is not set
+-# CONFIG_PID_NS is not set
+-# CONFIG_AUDIT is not set
+-# CONFIG_IKCONFIG is not set
+-CONFIG_LOG_BUF_SHIFT=14
+-# CONFIG_CGROUPS is not set
+-# CONFIG_FAIR_GROUP_SCHED is not set
+-CONFIG_SYSFS_DEPRECATED=y
+-# CONFIG_RELAY is not set
+-CONFIG_BLK_DEV_INITRD=y
+-CONFIG_INITRAMFS_SOURCE=""
+-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+-CONFIG_SYSCTL=y
+-CONFIG_EMBEDDED=y
+-# CONFIG_SYSCTL_SYSCALL is not set
+-# CONFIG_KALLSYMS is not set
+-CONFIG_HOTPLUG=y
+-CONFIG_PRINTK=y
+-CONFIG_BUG=y
+-CONFIG_ELF_CORE=y
+-CONFIG_BASE_FULL=y
+-CONFIG_FUTEX=y
+-CONFIG_ANON_INODES=y
+-# CONFIG_EPOLL is not set
+-CONFIG_SIGNALFD=y
+-CONFIG_EVENTFD=y
+-CONFIG_SHMEM=y
+-CONFIG_VM_EVENT_COUNTERS=y
+-CONFIG_SLUB_DEBUG=y
+-# CONFIG_SLAB is not set
+-CONFIG_SLUB=y
+-# CONFIG_SLOB is not set
+-CONFIG_RT_MUTEXES=y
+-# CONFIG_TINY_SHMEM is not set
+-CONFIG_BASE_SMALL=0
+-CONFIG_MODULES=y
+-CONFIG_MODULE_UNLOAD=y
+-# CONFIG_MODULE_FORCE_UNLOAD is not set
+-# CONFIG_MODVERSIONS is not set
+-# CONFIG_MODULE_SRCVERSION_ALL is not set
+-# CONFIG_KMOD is not set
+-CONFIG_BLOCK=y
+-# CONFIG_LBD is not set
+-# CONFIG_BLK_DEV_IO_TRACE is not set
+-# CONFIG_LSF is not set
+-# CONFIG_BLK_DEV_BSG is not set
+-
+-#
+-# IO Schedulers
+-#
+-CONFIG_IOSCHED_NOOP=y
+-CONFIG_IOSCHED_AS=y
+-CONFIG_IOSCHED_DEADLINE=y
+-CONFIG_IOSCHED_CFQ=y
+-CONFIG_DEFAULT_AS=y
+-# CONFIG_DEFAULT_DEADLINE is not set
+-# CONFIG_DEFAULT_CFQ is not set
+-# CONFIG_DEFAULT_NOOP is not set
+-CONFIG_DEFAULT_IOSCHED="anticipatory"
+-
+-#
+-# Platform support
+-#
+-CONFIG_PPC_MULTIPLATFORM=y
+-# CONFIG_PPC_82xx is not set
+-# CONFIG_PPC_83xx is not set
+-# CONFIG_PPC_86xx is not set
+-CONFIG_CLASSIC32=y
+-# CONFIG_PPC_CHRP is not set
+-CONFIG_PPC_MPC52xx=y
+-CONFIG_PPC_MPC5200=y
+-CONFIG_PPC_MPC5200_BUGFIX=y
+-# CONFIG_PPC_EFIKA is not set
+-CONFIG_PPC_LITE5200=y
+-# CONFIG_PPC_PMAC is not set
+-# CONFIG_PPC_CELL is not set
+-# CONFIG_PPC_CELL_NATIVE is not set
+-# CONFIG_PQ2ADS is not set
+-# CONFIG_EMBEDDED6xx is not set
+-# CONFIG_MPIC is not set
+-# CONFIG_MPIC_WEIRD is not set
+-# CONFIG_PPC_I8259 is not set
+-# CONFIG_PPC_RTAS is not set
+-# CONFIG_MMIO_NVRAM is not set
+-# CONFIG_PPC_MPC106 is not set
+-# CONFIG_PPC_970_NAP is not set
+-# CONFIG_PPC_INDIRECT_IO is not set
+-# CONFIG_GENERIC_IOMAP is not set
+-# CONFIG_CPU_FREQ is not set
+-# CONFIG_TAU is not set
+-# CONFIG_CPM2 is not set
+-# CONFIG_FSL_ULI1575 is not set
+-CONFIG_PPC_BESTCOMM=y
+-CONFIG_PPC_BESTCOMM_ATA=y
+-CONFIG_PPC_BESTCOMM_FEC=y
+-CONFIG_PPC_BESTCOMM_GEN_BD=y
+-
+-#
+-# Kernel options
+-#
+-# CONFIG_HIGHMEM is not set
+-CONFIG_TICK_ONESHOT=y
+-CONFIG_NO_HZ=y
+-CONFIG_HIGH_RES_TIMERS=y
+-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+-# CONFIG_HZ_100 is not set
+-CONFIG_HZ_250=y
+-# CONFIG_HZ_300 is not set
+-# CONFIG_HZ_1000 is not set
+-CONFIG_HZ=250
+-CONFIG_PREEMPT_NONE=y
+-# CONFIG_PREEMPT_VOLUNTARY is not set
+-# CONFIG_PREEMPT is not set
+-CONFIG_BINFMT_ELF=y
+-# CONFIG_BINFMT_MISC is not set
+-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+-# CONFIG_KEXEC is not set
+-CONFIG_ARCH_FLATMEM_ENABLE=y
+-CONFIG_ARCH_POPULATES_NODE_MAP=y
+-CONFIG_SELECT_MEMORY_MODEL=y
+-CONFIG_FLATMEM_MANUAL=y
+-# CONFIG_DISCONTIGMEM_MANUAL is not set
+-# CONFIG_SPARSEMEM_MANUAL is not set
+-CONFIG_FLATMEM=y
+-CONFIG_FLAT_NODE_MEM_MAP=y
+-# CONFIG_SPARSEMEM_STATIC is not set
+-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+-CONFIG_SPLIT_PTLOCK_CPUS=4
+-# CONFIG_RESOURCES_64BIT is not set
+-CONFIG_ZONE_DMA_FLAG=1
+-CONFIG_BOUNCE=y
+-CONFIG_VIRT_TO_BUS=y
+-CONFIG_PROC_DEVICETREE=y
+-# CONFIG_CMDLINE_BOOL is not set
+-CONFIG_PM=y
+-# CONFIG_PM_LEGACY is not set
+-# CONFIG_PM_DEBUG is not set
+-CONFIG_PM_SLEEP=y
+-CONFIG_SUSPEND_UP_POSSIBLE=y
+-CONFIG_SUSPEND=y
+-CONFIG_HIBERNATION_UP_POSSIBLE=y
+-# CONFIG_HIBERNATION is not set
+-CONFIG_SECCOMP=y
+-CONFIG_WANT_DEVICE_TREE=y
+-CONFIG_DEVICE_TREE=""
+-CONFIG_ISA_DMA_API=y
+-
+-#
+-# Bus options
+-#
+-CONFIG_ZONE_DMA=y
+-CONFIG_GENERIC_ISA_DMA=y
+-# CONFIG_PPC_INDIRECT_PCI is not set
+-CONFIG_FSL_SOC=y
+-CONFIG_PCI=y
+-CONFIG_PCI_DOMAINS=y
+-CONFIG_PCI_SYSCALL=y
+-# CONFIG_PCIEPORTBUS is not set
+-CONFIG_ARCH_SUPPORTS_MSI=y
+-# CONFIG_PCI_MSI is not set
+-CONFIG_PCI_LEGACY=y
+-# CONFIG_PCI_DEBUG is not set
+-# CONFIG_PCCARD is not set
+-# CONFIG_HOTPLUG_PCI is not set
+-
+-#
+-# Advanced setup
+-#
+-# CONFIG_ADVANCED_OPTIONS is not set
+-
+-#
+-# Default settings for advanced configuration options are used
+-#
+-CONFIG_HIGHMEM_START=0xfe000000
+-CONFIG_LOWMEM_SIZE=0x30000000
+-CONFIG_KERNEL_START=0xc0000000
+-CONFIG_TASK_SIZE=0xc0000000
+-CONFIG_BOOT_LOAD=0x00800000
+-
+-#
+-# Networking
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-# CONFIG_PACKET_MMAP is not set
+-CONFIG_UNIX=y
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-# CONFIG_XFRM_SUB_POLICY is not set
+-# CONFIG_XFRM_MIGRATE is not set
+-# CONFIG_NET_KEY is not set
+-CONFIG_INET=y
+-CONFIG_IP_MULTICAST=y
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-CONFIG_IP_FIB_HASH=y
+-CONFIG_IP_PNP=y
+-CONFIG_IP_PNP_DHCP=y
+-CONFIG_IP_PNP_BOOTP=y
+-# CONFIG_IP_PNP_RARP is not set
+-# CONFIG_NET_IPIP is not set
+-# CONFIG_NET_IPGRE is not set
+-# CONFIG_IP_MROUTE is not set
+-# CONFIG_ARPD is not set
+-CONFIG_SYN_COOKIES=y
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-# CONFIG_INET_XFRM_TUNNEL is not set
+-# CONFIG_INET_TUNNEL is not set
+-CONFIG_INET_XFRM_MODE_TRANSPORT=y
+-CONFIG_INET_XFRM_MODE_TUNNEL=y
+-CONFIG_INET_XFRM_MODE_BEET=y
+-# CONFIG_INET_LRO is not set
+-CONFIG_INET_DIAG=y
+-CONFIG_INET_TCP_DIAG=y
+-# CONFIG_TCP_CONG_ADVANCED is not set
+-CONFIG_TCP_CONG_CUBIC=y
+-CONFIG_DEFAULT_TCP_CONG="cubic"
+-# CONFIG_TCP_MD5SIG is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_INET6_XFRM_TUNNEL is not set
+-# CONFIG_INET6_TUNNEL is not set
+-# CONFIG_NETWORK_SECMARK is not set
+-# CONFIG_NETFILTER is not set
+-# CONFIG_IP_DCCP is not set
+-# CONFIG_IP_SCTP is not set
+-# CONFIG_TIPC is not set
+-# CONFIG_ATM is not set
+-# CONFIG_BRIDGE is not set
+-# CONFIG_VLAN_8021Q is not set
+-# CONFIG_DECNET is not set
+-# CONFIG_LLC2 is not set
+-# CONFIG_IPX is not set
+-# CONFIG_ATALK is not set
+-# CONFIG_X25 is not set
+-# CONFIG_LAPB is not set
+-# CONFIG_ECONET is not set
+-# CONFIG_WAN_ROUTER is not set
+-# CONFIG_NET_SCHED is not set
+-
+-#
+-# Network testing
+-#
+-# CONFIG_NET_PKTGEN is not set
+-# CONFIG_HAMRADIO is not set
+-# CONFIG_IRDA is not set
+-# CONFIG_BT is not set
+-# CONFIG_AF_RXRPC is not set
+-
+-#
+-# Wireless
+-#
+-# CONFIG_CFG80211 is not set
+-# CONFIG_WIRELESS_EXT is not set
+-# CONFIG_MAC80211 is not set
+-# CONFIG_IEEE80211 is not set
+-# CONFIG_RFKILL is not set
+-# CONFIG_NET_9P is not set
+-
+-#
+-# Device Drivers
+-#
+-
+-#
+-# Generic Driver Options
+-#
+-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+-CONFIG_STANDALONE=y
+-CONFIG_PREVENT_FIRMWARE_BUILD=y
+-# CONFIG_FW_LOADER is not set
+-# CONFIG_DEBUG_DRIVER is not set
+-# CONFIG_DEBUG_DEVRES is not set
+-# CONFIG_SYS_HYPERVISOR is not set
+-# CONFIG_CONNECTOR is not set
+-# CONFIG_MTD is not set
+-CONFIG_OF_DEVICE=y
+-# CONFIG_PARPORT is not set
+-CONFIG_BLK_DEV=y
+-# CONFIG_BLK_DEV_FD is not set
+-# CONFIG_BLK_CPQ_DA is not set
+-# CONFIG_BLK_CPQ_CISS_DA is not set
+-# CONFIG_BLK_DEV_DAC960 is not set
+-# CONFIG_BLK_DEV_UMEM is not set
+-# CONFIG_BLK_DEV_COW_COMMON is not set
+-CONFIG_BLK_DEV_LOOP=y
+-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+-# CONFIG_BLK_DEV_NBD is not set
+-# CONFIG_BLK_DEV_SX8 is not set
+-CONFIG_BLK_DEV_RAM=y
+-CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_BLK_DEV_RAM_SIZE=32768
+-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+-# CONFIG_CDROM_PKTCDVD is not set
+-# CONFIG_ATA_OVER_ETH is not set
+-CONFIG_MISC_DEVICES=y
+-# CONFIG_PHANTOM is not set
+-# CONFIG_EEPROM_93CX6 is not set
+-# CONFIG_SGI_IOC4 is not set
+-# CONFIG_TIFM_CORE is not set
+-# CONFIG_IDE is not set
+-
+-#
+-# SCSI device support
+-#
+-# CONFIG_RAID_ATTRS is not set
+-CONFIG_SCSI=y
+-CONFIG_SCSI_DMA=y
+-# CONFIG_SCSI_TGT is not set
+-# CONFIG_SCSI_NETLINK is not set
+-# CONFIG_SCSI_PROC_FS is not set
+-
+-#
+-# SCSI support type (disk, tape, CD-ROM)
+-#
+-# CONFIG_BLK_DEV_SD is not set
+-# CONFIG_CHR_DEV_ST is not set
+-# CONFIG_CHR_DEV_OSST is not set
+-# CONFIG_BLK_DEV_SR is not set
+-# CONFIG_CHR_DEV_SG is not set
+-# CONFIG_CHR_DEV_SCH is not set
+-
+-#
+-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+-#
+-# CONFIG_SCSI_MULTI_LUN is not set
+-# CONFIG_SCSI_CONSTANTS is not set
+-# CONFIG_SCSI_LOGGING is not set
+-# CONFIG_SCSI_SCAN_ASYNC is not set
+-CONFIG_SCSI_WAIT_SCAN=m
+-
+-#
+-# SCSI Transports
+-#
+-# CONFIG_SCSI_SPI_ATTRS is not set
+-# CONFIG_SCSI_FC_ATTRS is not set
+-# CONFIG_SCSI_ISCSI_ATTRS is not set
+-# CONFIG_SCSI_SAS_LIBSAS is not set
+-# CONFIG_SCSI_SRP_ATTRS is not set
+-CONFIG_SCSI_LOWLEVEL=y
+-# CONFIG_ISCSI_TCP is not set
+-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+-# CONFIG_SCSI_3W_9XXX is not set
+-# CONFIG_SCSI_ACARD is not set
+-# CONFIG_SCSI_AACRAID is not set
+-# CONFIG_SCSI_AIC7XXX is not set
+-# CONFIG_SCSI_AIC7XXX_OLD is not set
+-# CONFIG_SCSI_AIC79XX is not set
+-# CONFIG_SCSI_AIC94XX is not set
+-# CONFIG_SCSI_DPT_I2O is not set
+-# CONFIG_SCSI_ADVANSYS is not set
+-# CONFIG_SCSI_ARCMSR is not set
+-# CONFIG_MEGARAID_NEWGEN is not set
+-# CONFIG_MEGARAID_LEGACY is not set
+-# CONFIG_MEGARAID_SAS is not set
+-# CONFIG_SCSI_HPTIOP is not set
+-# CONFIG_SCSI_BUSLOGIC is not set
+-# CONFIG_SCSI_DMX3191D is not set
+-# CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_FUTURE_DOMAIN is not set
+-# CONFIG_SCSI_GDTH is not set
+-# CONFIG_SCSI_IPS is not set
+-# CONFIG_SCSI_INITIO is not set
+-# CONFIG_SCSI_INIA100 is not set
+-# CONFIG_SCSI_STEX is not set
+-# CONFIG_SCSI_SYM53C8XX_2 is not set
+-# CONFIG_SCSI_IPR is not set
+-# CONFIG_SCSI_QLOGIC_1280 is not set
+-# CONFIG_SCSI_QLA_FC is not set
+-# CONFIG_SCSI_QLA_ISCSI is not set
+-# CONFIG_SCSI_LPFC is not set
+-# CONFIG_SCSI_DC395x is not set
+-# CONFIG_SCSI_DC390T is not set
+-# CONFIG_SCSI_NSP32 is not set
+-# CONFIG_SCSI_DEBUG is not set
+-# CONFIG_SCSI_SRP is not set
+-CONFIG_ATA=y
+-# CONFIG_ATA_NONSTANDARD is not set
+-# CONFIG_SATA_AHCI is not set
+-# CONFIG_SATA_SVW is not set
+-# CONFIG_ATA_PIIX is not set
+-# CONFIG_SATA_MV is not set
+-# CONFIG_SATA_NV is not set
+-# CONFIG_PDC_ADMA is not set
+-# CONFIG_SATA_QSTOR is not set
+-# CONFIG_SATA_PROMISE is not set
+-# CONFIG_SATA_SX4 is not set
+-# CONFIG_SATA_SIL is not set
+-# CONFIG_SATA_SIL24 is not set
+-# CONFIG_SATA_SIS is not set
+-# CONFIG_SATA_ULI is not set
+-# CONFIG_SATA_VIA is not set
+-# CONFIG_SATA_VITESSE is not set
+-# CONFIG_SATA_INIC162X is not set
+-# CONFIG_PATA_ALI is not set
+-# CONFIG_PATA_AMD is not set
+-# CONFIG_PATA_ARTOP is not set
+-# CONFIG_PATA_ATIIXP is not set
+-# CONFIG_PATA_CMD640_PCI is not set
+-# CONFIG_PATA_CMD64X is not set
+-# CONFIG_PATA_CS5520 is not set
+-# CONFIG_PATA_CS5530 is not set
+-# CONFIG_PATA_CYPRESS is not set
+-# CONFIG_PATA_EFAR is not set
+-# CONFIG_ATA_GENERIC is not set
+-# CONFIG_PATA_HPT366 is not set
+-# CONFIG_PATA_HPT37X is not set
+-# CONFIG_PATA_HPT3X2N is not set
+-# CONFIG_PATA_HPT3X3 is not set
+-# CONFIG_PATA_IT821X is not set
+-# CONFIG_PATA_IT8213 is not set
+-# CONFIG_PATA_JMICRON is not set
+-# CONFIG_PATA_TRIFLEX is not set
+-# CONFIG_PATA_MARVELL is not set
+-CONFIG_PATA_MPC52xx=y
+-# CONFIG_PATA_MPIIX is not set
+-# CONFIG_PATA_OLDPIIX is not set
+-# CONFIG_PATA_NETCELL is not set
+-# CONFIG_PATA_NS87410 is not set
+-# CONFIG_PATA_NS87415 is not set
+-# CONFIG_PATA_OPTI is not set
+-# CONFIG_PATA_OPTIDMA is not set
+-# CONFIG_PATA_PDC_OLD is not set
+-# CONFIG_PATA_RADISYS is not set
+-# CONFIG_PATA_RZ1000 is not set
+-# CONFIG_PATA_SC1200 is not set
+-# CONFIG_PATA_SERVERWORKS is not set
+-# CONFIG_PATA_PDC2027X is not set
+-# CONFIG_PATA_SIL680 is not set
+-# CONFIG_PATA_SIS is not set
+-# CONFIG_PATA_VIA is not set
+-# CONFIG_PATA_WINBOND is not set
+-# CONFIG_PATA_PLATFORM is not set
+-# CONFIG_MD is not set
+-# CONFIG_FUSION is not set
+-
+-#
+-# IEEE 1394 (FireWire) support
+-#
+-# CONFIG_FIREWIRE is not set
+-# CONFIG_IEEE1394 is not set
+-# CONFIG_I2O is not set
+-# CONFIG_MACINTOSH_DRIVERS is not set
+-CONFIG_NETDEVICES=y
+-# CONFIG_NETDEVICES_MULTIQUEUE is not set
+-# CONFIG_DUMMY is not set
+-# CONFIG_BONDING is not set
+-# CONFIG_MACVLAN is not set
+-# CONFIG_EQUALIZER is not set
+-# CONFIG_TUN is not set
+-# CONFIG_VETH is not set
+-# CONFIG_IP1000 is not set
+-# CONFIG_ARCNET is not set
+-# CONFIG_NET_ETHERNET is not set
+-CONFIG_NETDEV_1000=y
+-# CONFIG_ACENIC is not set
+-# CONFIG_DL2K is not set
+-# CONFIG_E1000 is not set
+-# CONFIG_E1000E is not set
+-# CONFIG_NS83820 is not set
+-# CONFIG_HAMACHI is not set
+-# CONFIG_YELLOWFIN is not set
+-# CONFIG_R8169 is not set
+-# CONFIG_SIS190 is not set
+-# CONFIG_SKGE is not set
+-# CONFIG_SKY2 is not set
+-# CONFIG_SK98LIN is not set
+-# CONFIG_VIA_VELOCITY is not set
+-# CONFIG_TIGON3 is not set
+-# CONFIG_BNX2 is not set
+-# CONFIG_MV643XX_ETH is not set
+-# CONFIG_QLA3XXX is not set
+-# CONFIG_ATL1 is not set
+-CONFIG_NETDEV_10000=y
+-# CONFIG_CHELSIO_T1 is not set
+-# CONFIG_CHELSIO_T3 is not set
+-# CONFIG_IXGBE is not set
+-# CONFIG_IXGB is not set
+-# CONFIG_S2IO is not set
+-# CONFIG_MYRI10GE is not set
+-# CONFIG_NETXEN_NIC is not set
+-# CONFIG_NIU is not set
+-# CONFIG_MLX4_CORE is not set
+-# CONFIG_TEHUTI is not set
+-# CONFIG_TR is not set
+-
+-#
+-# Wireless LAN
+-#
+-# CONFIG_WLAN_PRE80211 is not set
+-# CONFIG_WLAN_80211 is not set
+-# CONFIG_WAN is not set
+-# CONFIG_FDDI is not set
+-# CONFIG_HIPPI is not set
+-# CONFIG_PPP is not set
+-# CONFIG_SLIP is not set
+-# CONFIG_NET_FC is not set
+-# CONFIG_SHAPER is not set
+-# CONFIG_NETCONSOLE is not set
+-# CONFIG_NETPOLL is not set
+-# CONFIG_NET_POLL_CONTROLLER is not set
+-# CONFIG_ISDN is not set
+-# CONFIG_PHONE is not set
+-
+-#
+-# Input device support
+-#
+-# CONFIG_INPUT is not set
+-
+-#
+-# Hardware I/O ports
+-#
+-# CONFIG_SERIO is not set
+-# CONFIG_GAMEPORT is not set
+-
+-#
+-# Character devices
+-#
+-# CONFIG_VT is not set
+-# CONFIG_SERIAL_NONSTANDARD is not set
+-
+-#
+-# Serial drivers
+-#
+-# CONFIG_SERIAL_8250 is not set
+-
+-#
+-# Non-8250 serial port support
+-#
+-# CONFIG_SERIAL_UARTLITE is not set
+-CONFIG_SERIAL_CORE=y
+-CONFIG_SERIAL_CORE_CONSOLE=y
+-CONFIG_SERIAL_MPC52xx=y
+-CONFIG_SERIAL_MPC52xx_CONSOLE=y
+-CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600
+-# CONFIG_SERIAL_JSM is not set
+-CONFIG_UNIX98_PTYS=y
+-CONFIG_LEGACY_PTYS=y
+-CONFIG_LEGACY_PTY_COUNT=256
+-# CONFIG_IPMI_HANDLER is not set
+-# CONFIG_HW_RANDOM is not set
+-# CONFIG_NVRAM is not set
+-# CONFIG_GEN_RTC is not set
+-# CONFIG_R3964 is not set
+-# CONFIG_APPLICOM is not set
+-# CONFIG_RAW_DRIVER is not set
+-# CONFIG_TCG_TPM is not set
+-CONFIG_DEVPORT=y
+-# CONFIG_I2C is not set
+-
+-#
+-# SPI support
+-#
+-# CONFIG_SPI is not set
+-# CONFIG_SPI_MASTER is not set
+-# CONFIG_W1 is not set
+-# CONFIG_POWER_SUPPLY is not set
+-# CONFIG_HWMON is not set
+-# CONFIG_WATCHDOG is not set
+-
+-#
+-# Sonics Silicon Backplane
+-#
+-CONFIG_SSB_POSSIBLE=y
+-# CONFIG_SSB is not set
+-
+-#
+-# Multifunction device drivers
+-#
+-# CONFIG_MFD_SM501 is not set
+-
+-#
+-# Multimedia devices
+-#
+-# CONFIG_VIDEO_DEV is not set
+-# CONFIG_DVB_CORE is not set
+-# CONFIG_DAB is not set
+-
+-#
+-# Graphics support
+-#
+-# CONFIG_AGP is not set
+-# CONFIG_DRM is not set
+-# CONFIG_VGASTATE is not set
+-CONFIG_VIDEO_OUTPUT_CONTROL=m
+-# CONFIG_FB is not set
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+-
+-#
+-# Display device support
+-#
+-# CONFIG_DISPLAY_SUPPORT is not set
+-
+-#
+-# Sound
+-#
+-# CONFIG_SOUND is not set
+-CONFIG_USB_SUPPORT=y
+-CONFIG_USB_ARCH_HAS_HCD=y
+-CONFIG_USB_ARCH_HAS_OHCI=y
+-CONFIG_USB_ARCH_HAS_EHCI=y
+-# CONFIG_USB is not set
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+-#
+-
+-#
+-# USB Gadget Support
+-#
+-# CONFIG_USB_GADGET is not set
+-# CONFIG_MMC is not set
+-# CONFIG_NEW_LEDS is not set
+-# CONFIG_INFINIBAND is not set
+-# CONFIG_EDAC is not set
+-# CONFIG_RTC_CLASS is not set
+-
+-#
+-# Userspace I/O
+-#
+-# CONFIG_UIO is not set
+-
+-#
+-# File systems
+-#
+-CONFIG_EXT2_FS=y
+-# CONFIG_EXT2_FS_XATTR is not set
+-# CONFIG_EXT2_FS_XIP is not set
+-CONFIG_EXT3_FS=y
+-CONFIG_EXT3_FS_XATTR=y
+-# CONFIG_EXT3_FS_POSIX_ACL is not set
+-# CONFIG_EXT3_FS_SECURITY is not set
+-# CONFIG_EXT4DEV_FS is not set
+-CONFIG_JBD=y
+-CONFIG_FS_MBCACHE=y
+-# CONFIG_REISERFS_FS is not set
+-# CONFIG_JFS_FS is not set
+-# CONFIG_FS_POSIX_ACL is not set
+-# CONFIG_XFS_FS is not set
+-# CONFIG_GFS2_FS is not set
+-# CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
+-CONFIG_INOTIFY=y
+-CONFIG_INOTIFY_USER=y
+-# CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+-# CONFIG_AUTOFS_FS is not set
+-# CONFIG_AUTOFS4_FS is not set
+-# CONFIG_FUSE_FS is not set
+-
+-#
+-# CD-ROM/DVD Filesystems
+-#
+-# CONFIG_ISO9660_FS is not set
+-# CONFIG_UDF_FS is not set
+-
+-#
+-# DOS/FAT/NT Filesystems
+-#
+-# CONFIG_MSDOS_FS is not set
+-# CONFIG_VFAT_FS is not set
+-# CONFIG_NTFS_FS is not set
+-
+-#
+-# Pseudo filesystems
+-#
+-CONFIG_PROC_FS=y
+-CONFIG_PROC_KCORE=y
+-CONFIG_PROC_SYSCTL=y
+-CONFIG_SYSFS=y
+-CONFIG_TMPFS=y
+-# CONFIG_TMPFS_POSIX_ACL is not set
+-# CONFIG_HUGETLB_PAGE is not set
+-# CONFIG_CONFIGFS_FS is not set
+-
+-#
+-# Miscellaneous filesystems
+-#
+-# CONFIG_ADFS_FS is not set
+-# CONFIG_AFFS_FS is not set
+-# CONFIG_HFS_FS is not set
+-# CONFIG_HFSPLUS_FS is not set
+-# CONFIG_BEFS_FS is not set
+-# CONFIG_BFS_FS is not set
+-# CONFIG_EFS_FS is not set
+-# CONFIG_CRAMFS is not set
+-# CONFIG_VXFS_FS is not set
+-# CONFIG_HPFS_FS is not set
+-# CONFIG_QNX4FS_FS is not set
+-# CONFIG_SYSV_FS is not set
+-# CONFIG_UFS_FS is not set
+-CONFIG_NETWORK_FILESYSTEMS=y
+-# CONFIG_NFS_FS is not set
+-# CONFIG_NFSD is not set
+-# CONFIG_SMB_FS is not set
+-# CONFIG_CIFS is not set
+-# CONFIG_NCP_FS is not set
+-# CONFIG_CODA_FS is not set
+-# CONFIG_AFS_FS is not set
+-
+-#
+-# Partition Types
+-#
+-# CONFIG_PARTITION_ADVANCED is not set
+-CONFIG_MSDOS_PARTITION=y
+-# CONFIG_NLS is not set
+-# CONFIG_DLM is not set
+-# CONFIG_UCC_SLOW is not set
+-
+-#
+-# Library routines
+-#
+-# CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC16 is not set
+-# CONFIG_CRC_ITU_T is not set
+-# CONFIG_CRC32 is not set
+-# CONFIG_CRC7 is not set
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_PLIST=y
+-CONFIG_HAS_IOMEM=y
+-CONFIG_HAS_IOPORT=y
+-CONFIG_HAS_DMA=y
+-# CONFIG_INSTRUMENTATION is not set
+-
+-#
+-# Kernel hacking
+-#
+-CONFIG_PRINTK_TIME=y
+-CONFIG_ENABLE_WARN_DEPRECATED=y
+-CONFIG_ENABLE_MUST_CHECK=y
+-# CONFIG_MAGIC_SYSRQ is not set
+-# CONFIG_UNUSED_SYMBOLS is not set
+-# CONFIG_DEBUG_FS is not set
+-# CONFIG_HEADERS_CHECK is not set
+-CONFIG_DEBUG_KERNEL=y
+-# CONFIG_DEBUG_SHIRQ is not set
+-CONFIG_DETECT_SOFTLOCKUP=y
+-CONFIG_SCHED_DEBUG=y
+-# CONFIG_SCHEDSTATS is not set
+-# CONFIG_TIMER_STATS is not set
+-# CONFIG_SLUB_DEBUG_ON is not set
+-# CONFIG_DEBUG_RT_MUTEXES is not set
+-# CONFIG_RT_MUTEX_TESTER is not set
+-# CONFIG_DEBUG_SPINLOCK is not set
+-# CONFIG_DEBUG_MUTEXES is not set
+-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+-# CONFIG_DEBUG_KOBJECT is not set
+-# CONFIG_DEBUG_BUGVERBOSE is not set
+-CONFIG_DEBUG_INFO=y
+-# CONFIG_DEBUG_VM is not set
+-# CONFIG_DEBUG_LIST is not set
+-# CONFIG_DEBUG_SG is not set
+-CONFIG_FORCED_INLINING=y
+-# CONFIG_BOOT_PRINTK_DELAY is not set
+-# CONFIG_RCU_TORTURE_TEST is not set
+-# CONFIG_FAULT_INJECTION is not set
+-# CONFIG_SAMPLES is not set
+-# CONFIG_DEBUG_STACKOVERFLOW is not set
+-# CONFIG_DEBUG_STACK_USAGE is not set
+-# CONFIG_DEBUG_PAGEALLOC is not set
+-# CONFIG_DEBUGGER is not set
+-# CONFIG_BDI_SWITCH is not set
+-# CONFIG_BOOTX_TEXT is not set
+-# CONFIG_PPC_EARLY_DEBUG is not set
+-
+-#
+-# Security options
+-#
+-# CONFIG_KEYS is not set
+-# CONFIG_SECURITY is not set
+-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+-# CONFIG_CRYPTO is not set
+-CONFIG_PPC_CLOCK=y
+-CONFIG_PPC_LIB_RHEAP=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/makalu_defconfig powerpc.git/arch/powerpc/configs/makalu_defconfig
+--- linux-2.6.24/arch/powerpc/configs/makalu_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/makalu_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,812 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 11:18:32 2007
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++# CONFIG_6xx is not set
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++CONFIG_40x=y
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_4xx=y
++# CONFIG_PPC_MM_SLICES is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++CONFIG_PPC_UDBG_16550=y
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++CONFIG_PPC_DCR_NATIVE=y
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_PPC_DCR=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++# CONFIG_FAIR_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++CONFIG_LBD=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++CONFIG_PPC4xx_PCI_EXPRESS=y
++
++#
++# Platform support
++#
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_EP405 is not set
++# CONFIG_KILAUEA is not set
++CONFIG_MAKALU=y
++# CONFIG_WALNUT is not set
++# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
++CONFIG_405EX=y
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_MATH_EMULATION is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_CMDLINE_BOOL is not set
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++CONFIG_HIBERNATION_UP_POSSIBLE=y
++CONFIG_SECCOMP=y
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="kilauea.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_DEBUG is not set
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_CONSISTENT_START=0xff100000
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_BOOT_LOAD=0x00400000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=m
++CONFIG_MTD_BLOCK=m
++# CONFIG_MTD_BLOCK_RO is not set
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++CONFIG_MTD_JEDECPROBE=y
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_INTEL_VR_NOR is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=35000
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_XILINX_SYSACE is not set
++# CONFIG_MISC_DEVICES is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_IBM_NEW_EMAC=y
++CONFIG_IBM_NEW_EMAC_RXB=256
++CONFIG_IBM_NEW_EMAC_TXB=256
++CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
++CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
++CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
++# CONFIG_IBM_NEW_EMAC_DEBUG is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++CONFIG_IBM_NEW_EMAC_RGMII=y
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++CONFIG_IBM_NEW_EMAC_EMAC4=y
++# CONFIG_NET_PCI is not set
++# CONFIG_B44 is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_PCI=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_EXTENDED=y
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++CONFIG_SERIAL_8250_SHARE_IRQ=y
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_NVRAM is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_INFINIBAND is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_JFFS2_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_DEBUGGER is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_PPC_CLOCK is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/mpc5200_defconfig powerpc.git/arch/powerpc/configs/mpc5200_defconfig
+--- linux-2.6.24/arch/powerpc/configs/mpc5200_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/mpc5200_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,1286 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Fri Jan 18 14:19:54 2008
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++CONFIG_6xx=y
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_PPC_FPU=y
++# CONFIG_ALTIVEC is not set
++CONFIG_PPC_STD_MMU=y
++CONFIG_PPC_STD_MMU_32=y
++# CONFIG_PPC_MM_SLICES is not set
++# CONFIG_SMP is not set
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++# CONFIG_PPC_UDBG_16550 is not set
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++# CONFIG_PPC_DCR_NATIVE is not set
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++# CONFIG_SYSCTL_SYSCALL is not set
++# CONFIG_KALLSYMS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++# CONFIG_EPOLL is not set
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++
++#
++# Platform support
++#
++CONFIG_PPC_MULTIPLATFORM=y
++# CONFIG_PPC_82xx is not set
++# CONFIG_PPC_83xx is not set
++# CONFIG_PPC_86xx is not set
++CONFIG_CLASSIC32=y
++# CONFIG_PPC_CHRP is not set
++CONFIG_PPC_MPC52xx=y
++CONFIG_PPC_MPC5200=y
++CONFIG_PPC_MPC5200_BUGFIX=y
++CONFIG_PPC_MPC5200_SIMPLE=y
++CONFIG_PPC_EFIKA=y
++CONFIG_PPC_LITE5200=y
++# CONFIG_PPC_PMAC is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_EMBEDDED6xx is not set
++CONFIG_PPC_NATIVE=y
++# CONFIG_UDBG_RTAS_CONSOLE is not set
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++CONFIG_PPC_RTAS=y
++# CONFIG_RTAS_ERROR_LOGGING is not set
++CONFIG_RTAS_PROC=y
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_TAU is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++CONFIG_PPC_BESTCOMM=y
++CONFIG_PPC_BESTCOMM_ATA=y
++CONFIG_PPC_BESTCOMM_FEC=y
++CONFIG_PPC_BESTCOMM_GEN_BD=y
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++# CONFIG_KEXEC is not set
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_CMDLINE_BOOL is not set
++CONFIG_PM=y
++# CONFIG_PM_LEGACY is not set
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND_UP_POSSIBLE=y
++CONFIG_SUSPEND=y
++CONFIG_HIBERNATION_UP_POSSIBLE=y
++# CONFIG_HIBERNATION is not set
++CONFIG_SECCOMP=y
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE=""
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_ISA_DMA=y
++# CONFIG_PPC_INDIRECT_PCI is not set
++CONFIG_FSL_SOC=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_DEBUG is not set
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_BOOT_LOAD=0x00800000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++CONFIG_MTD_RAM=y
++CONFIG_MTD_ROM=y
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_INTEL_VR_NOR is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=32768
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_PHANTOM is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_SGI_IOC4 is not set
++# CONFIG_TIFM_CORE is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AACRAID is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_AIC79XX is not set
++# CONFIG_SCSI_AIC94XX is not set
++# CONFIG_SCSI_DPT_I2O is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_ARCMSR is not set
++# CONFIG_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY is not set
++# CONFIG_MEGARAID_SAS is not set
++# CONFIG_SCSI_HPTIOP is not set
++# CONFIG_SCSI_BUSLOGIC is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_EATA is not set
++# CONFIG_SCSI_FUTURE_DOMAIN is not set
++# CONFIG_SCSI_GDTH is not set
++# CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++# CONFIG_SCSI_STEX is not set
++# CONFIG_SCSI_SYM53C8XX_2 is not set
++# CONFIG_SCSI_IPR is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++# CONFIG_SCSI_QLA_FC is not set
++# CONFIG_SCSI_QLA_ISCSI is not set
++# CONFIG_SCSI_LPFC is not set
++# CONFIG_SCSI_DC395x is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_SRP is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++# CONFIG_SATA_AHCI is not set
++# CONFIG_SATA_SVW is not set
++# CONFIG_ATA_PIIX is not set
++# CONFIG_SATA_MV is not set
++# CONFIG_SATA_NV is not set
++# CONFIG_PDC_ADMA is not set
++# CONFIG_SATA_QSTOR is not set
++# CONFIG_SATA_PROMISE is not set
++# CONFIG_SATA_SX4 is not set
++# CONFIG_SATA_SIL is not set
++# CONFIG_SATA_SIL24 is not set
++# CONFIG_SATA_SIS is not set
++# CONFIG_SATA_ULI is not set
++# CONFIG_SATA_VIA is not set
++# CONFIG_SATA_VITESSE is not set
++# CONFIG_SATA_INIC162X is not set
++# CONFIG_PATA_ALI is not set
++# CONFIG_PATA_AMD is not set
++# CONFIG_PATA_ARTOP is not set
++# CONFIG_PATA_ATIIXP is not set
++# CONFIG_PATA_CMD640_PCI is not set
++# CONFIG_PATA_CMD64X is not set
++# CONFIG_PATA_CS5520 is not set
++# CONFIG_PATA_CS5530 is not set
++# CONFIG_PATA_CYPRESS is not set
++# CONFIG_PATA_EFAR is not set
++# CONFIG_ATA_GENERIC is not set
++# CONFIG_PATA_HPT366 is not set
++# CONFIG_PATA_HPT37X is not set
++# CONFIG_PATA_HPT3X2N is not set
++# CONFIG_PATA_HPT3X3 is not set
++# CONFIG_PATA_IT821X is not set
++# CONFIG_PATA_IT8213 is not set
++# CONFIG_PATA_JMICRON is not set
++# CONFIG_PATA_TRIFLEX is not set
++# CONFIG_PATA_MARVELL is not set
++CONFIG_PATA_MPC52xx=y
++# CONFIG_PATA_MPIIX is not set
++# CONFIG_PATA_OLDPIIX is not set
++# CONFIG_PATA_NETCELL is not set
++# CONFIG_PATA_NS87410 is not set
++# CONFIG_PATA_NS87415 is not set
++# CONFIG_PATA_OPTI is not set
++# CONFIG_PATA_OPTIDMA is not set
++# CONFIG_PATA_PDC_OLD is not set
++# CONFIG_PATA_RADISYS is not set
++# CONFIG_PATA_RZ1000 is not set
++# CONFIG_PATA_SC1200 is not set
++# CONFIG_PATA_SERVERWORKS is not set
++# CONFIG_PATA_PDC2027X is not set
++# CONFIG_PATA_SIL680 is not set
++# CONFIG_PATA_SIS is not set
++# CONFIG_PATA_VIA is not set
++# CONFIG_PATA_WINBOND is not set
++CONFIG_PATA_PLATFORM=y
++# CONFIG_PATA_OF_PLATFORM is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_NET_PCI is not set
++# CONFIG_B44 is not set
++CONFIG_FEC_MPC52xx=y
++CONFIG_FEC_MPC52xx_MDIO=y
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_MPC52xx=y
++CONFIG_SERIAL_MPC52xx_CONSOLE=y
++CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_HVC_RTAS is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_NVRAM is not set
++CONFIG_GEN_RTC=y
++# CONFIG_GEN_RTC_X is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_ALI1535 is not set
++# CONFIG_I2C_ALI1563 is not set
++# CONFIG_I2C_ALI15X3 is not set
++# CONFIG_I2C_AMD756 is not set
++# CONFIG_I2C_AMD8111 is not set
++# CONFIG_I2C_I801 is not set
++# CONFIG_I2C_I810 is not set
++# CONFIG_I2C_PIIX4 is not set
++CONFIG_I2C_MPC=y
++# CONFIG_I2C_NFORCE2 is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_SIS5595 is not set
++# CONFIG_I2C_SIS630 is not set
++# CONFIG_I2C_SIS96X is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++# CONFIG_I2C_VIA is not set
++# CONFIG_I2C_VIAPRO is not set
++# CONFIG_I2C_VOODOO3 is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_M41T00 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_I5K_AMB is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SIS5595 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VIA686A is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_VT8231 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_MPC5200_WDT is not set
++# CONFIG_WATCHDOG_RTAS is not set
++
++#
++# PCI-based Watchdog Cards
++#
++# CONFIG_PCIPCWATCHDOG is not set
++# CONFIG_WDTPCI is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++# CONFIG_USB_DABUSB is not set
++
++#
++# Graphics support
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_DEVICE_CLASS is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_PERSIST is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++CONFIG_USB_OHCI_HCD_PPC_SOC=y
++CONFIG_USB_OHCI_HCD_PPC_OF=y
++CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
++# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
++CONFIG_USB_OHCI_HCD_PCI=y
++CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
++CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_UHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
++# CONFIG_INFINIBAND is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++CONFIG_NFS_V4=y
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++# CONFIG_SUNRPC_BIND34 is not set
++CONFIG_RPCSEC_GSS_KRB5=y
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_DEBUGGER is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_BOOTX_TEXT is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_ECB is not set
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++CONFIG_PPC_CLOCK=y
++CONFIG_PPC_LIB_RHEAP=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/mpc8313_rdb_defconfig powerpc.git/arch/powerpc/configs/mpc8313_rdb_defconfig
+--- linux-2.6.24/arch/powerpc/configs/mpc8313_rdb_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/mpc8313_rdb_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:48:31 2007
++# Linux kernel version: 2.6.24-rc6
++# Thu Jan 17 16:35:55 2008
+ #
+ # CONFIG_PPC64 is not set
+ 
+@@ -144,6 +144,7 @@
+ # CONFIG_MPC834x_MDS is not set
+ # CONFIG_MPC834x_ITX is not set
+ # CONFIG_MPC836x_MDS is not set
++# CONFIG_MPC837x_MDS is not set
+ CONFIG_PPC_MPC831x=y
+ # CONFIG_MPIC is not set
+ # CONFIG_MPIC_WEIRD is not set
+@@ -336,15 +337,16 @@
+ CONFIG_MTD=y
+ # CONFIG_MTD_DEBUG is not set
+ # CONFIG_MTD_CONCAT is not set
+-# CONFIG_MTD_PARTITIONS is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
+ 
+ #
+ # User Modules And Translation Layers
+ #
+ CONFIG_MTD_CHAR=y
+-# CONFIG_MTD_BLKDEVS is not set
+-# CONFIG_MTD_BLOCK is not set
+-# CONFIG_MTD_BLOCK_RO is not set
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
+ # CONFIG_FTL is not set
+ # CONFIG_NFTL is not set
+ # CONFIG_INFTL is not set
+@@ -381,11 +383,8 @@
+ # Mapping drivers for chip access
+ #
+ # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+-CONFIG_MTD_PHYSMAP=y
+-CONFIG_MTD_PHYSMAP_START=0xfe000000
+-CONFIG_MTD_PHYSMAP_LEN=0x1000000
+-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+-# CONFIG_MTD_PHYSMAP_OF is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
+ # CONFIG_MTD_INTEL_VR_NOR is not set
+ # CONFIG_MTD_PLATRAM is not set
+ 
+@@ -406,7 +405,16 @@
+ # CONFIG_MTD_DOC2000 is not set
+ # CONFIG_MTD_DOC2001 is not set
+ # CONFIG_MTD_DOC2001PLUS is not set
+-# CONFIG_MTD_NAND is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_VERIFY_WRITE=y
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_CAFE is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
+ # CONFIG_MTD_ONENAND is not set
+ 
+ #
+@@ -1178,7 +1186,17 @@
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-# CONFIG_JFFS2_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
+ # CONFIG_CRAMFS is not set
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+@@ -1242,6 +1260,8 @@
+ CONFIG_CRC32=y
+ # CONFIG_CRC7 is not set
+ # CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
+ CONFIG_PLIST=y
+ CONFIG_HAS_IOMEM=y
+ CONFIG_HAS_IOPORT=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/mpc834x_itx_defconfig powerpc.git/arch/powerpc/configs/mpc834x_itx_defconfig
+--- linux-2.6.24/arch/powerpc/configs/mpc834x_itx_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/mpc834x_itx_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -570,7 +570,8 @@
+ # CONFIG_PATA_SIS is not set
+ # CONFIG_PATA_VIA is not set
+ # CONFIG_PATA_WINBOND is not set
+-# CONFIG_PATA_PLATFORM is not set
++CONFIG_PATA_PLATFORM=y
++CONFIG_PATA_OF_PLATFORM=y
+ CONFIG_MD=y
+ CONFIG_BLK_DEV_MD=y
+ CONFIG_MD_LINEAR=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/mpc837x_mds_defconfig powerpc.git/arch/powerpc/configs/mpc837x_mds_defconfig
+--- linux-2.6.24/arch/powerpc/configs/mpc837x_mds_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/mpc837x_mds_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,878 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.23
++# Wed Oct 10 16:31:39 2007
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++CONFIG_6xx=y
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_83xx=y
++CONFIG_PPC_FPU=y
++CONFIG_PPC_STD_MMU=y
++CONFIG_PPC_STD_MMU_32=y
++# CONFIG_PPC_MM_SLICES is not set
++# CONFIG_SMP is not set
++CONFIG_PPC32=y
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++CONFIG_PPC_UDBG_16550=y
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFAULT_UIMAGE=y
++# CONFIG_PPC_DCR_NATIVE is not set
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++# CONFIG_EPOLL is not set
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_KMOD is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++
++#
++# Platform support
++#
++# CONFIG_PPC_MULTIPLATFORM is not set
++# CONFIG_EMBEDDED6xx is not set
++# CONFIG_PPC_82xx is not set
++CONFIG_PPC_83xx=y
++# CONFIG_PPC_86xx is not set
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_MPC8313_RDB is not set
++# CONFIG_MPC832x_MDS is not set
++# CONFIG_MPC832x_RDB is not set
++# CONFIG_MPC834x_MDS is not set
++# CONFIG_MPC834x_ITX is not set
++# CONFIG_MPC836x_MDS is not set
++CONFIG_MPC837x_MDS=y
++CONFIG_PPC_MPC837x=y
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++CONFIG_FSL_SERDES=y
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_CMDLINE_BOOL is not set
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++CONFIG_HIBERNATION_UP_POSSIBLE=y
++CONFIG_SECCOMP=y
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE=""
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_FSL_SOC=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_DOMAINS is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0x80000000
++CONFIG_BOOT_LOAD=0x00800000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++
++#
++# QoS and/or fair queueing
++#
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=32768
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++CONFIG_SATA_FSL=y
++# CONFIG_PATA_PLATFORM is not set
++# CONFIG_MD is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=y
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_FIXED_PHY is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_NETDEV_1000=y
++CONFIG_GIANFAR=y
++# CONFIG_GFAR_NAPI is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++# CONFIG_INPUT_MOUSEDEV is not set
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_OF_PLATFORM is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_83xx_WDT=y
++# CONFIG_HW_RANDOM is not set
++# CONFIG_NVRAM is not set
++CONFIG_GEN_RTC=y
++# CONFIG_GEN_RTC_X is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_MPC=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_M41T00 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_ABITUGURU is not set
++# CONFIG_SENSORS_ABITUGURU3 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ASB100 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_FSCHER is not set
++# CONFIG_SENSORS_FSCPOS is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_FB_IBM_GXT4500 is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HID_DEBUG is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# DMA Engine support
++#
++# CONFIG_DMA_ENGINE is not set
++
++#
++# DMA Clients
++#
++
++#
++# DMA Devices
++#
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++CONFIG_NFS_V4=y
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++# CONFIG_SUNRPC_BIND34 is not set
++CONFIG_RPCSEC_GSS_KRB5=y
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++
++#
++# Native Language Support
++#
++# CONFIG_NLS is not set
++
++#
++# Distributed Lock Manager
++#
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++
++#
++# Instrumentation Support
++#
++# CONFIG_PROFILING is not set
++# CONFIG_KPROBES is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=m
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++CONFIG_CRYPTO_HW=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/mpc8610_hpcd_defconfig powerpc.git/arch/powerpc/configs/mpc8610_hpcd_defconfig
+--- linux-2.6.24/arch/powerpc/configs/mpc8610_hpcd_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/mpc8610_hpcd_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -696,7 +696,7 @@
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ # CONFIG_SERIAL_JSM is not set
+-CONFIG_SERIAL_OF_PLATFORM=y
++# CONFIG_SERIAL_OF_PLATFORM is not set
+ CONFIG_UNIX98_PTYS=y
+ # CONFIG_LEGACY_PTYS is not set
+ # CONFIG_IPMI_HANDLER is not set
+@@ -708,7 +708,60 @@
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_TCG_TPM is not set
+ CONFIG_DEVPORT=y
+-# CONFIG_I2C is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_ALI1535 is not set
++# CONFIG_I2C_ALI1563 is not set
++# CONFIG_I2C_ALI15X3 is not set
++# CONFIG_I2C_AMD756 is not set
++# CONFIG_I2C_AMD8111 is not set
++# CONFIG_I2C_I801 is not set
++# CONFIG_I2C_I810 is not set
++# CONFIG_I2C_PIIX4 is not set
++CONFIG_I2C_MPC=y
++# CONFIG_I2C_NFORCE2 is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_SIS5595 is not set
++# CONFIG_I2C_SIS630 is not set
++# CONFIG_I2C_SIS96X is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_VIA is not set
++# CONFIG_I2C_VIAPRO is not set
++# CONFIG_I2C_VOODOO3 is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_M41T00 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
+ 
+ #
+ # SPI support
+@@ -763,7 +816,119 @@
+ #
+ # Sound
+ #
+-# CONFIG_SOUND is not set
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++# CONFIG_SND_PCM_OSS_PLUGINS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++# CONFIG_SND_SUPPORT_OLD_API is not set
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# PCI devices
++#
++# CONFIG_SND_AD1889 is not set
++# CONFIG_SND_ALS300 is not set
++# CONFIG_SND_ALS4000 is not set
++# CONFIG_SND_ALI5451 is not set
++# CONFIG_SND_ATIIXP is not set
++# CONFIG_SND_ATIIXP_MODEM is not set
++# CONFIG_SND_AU8810 is not set
++# CONFIG_SND_AU8820 is not set
++# CONFIG_SND_AU8830 is not set
++# CONFIG_SND_AZT3328 is not set
++# CONFIG_SND_BT87X is not set
++# CONFIG_SND_CA0106 is not set
++# CONFIG_SND_CMIPCI is not set
++# CONFIG_SND_CS4281 is not set
++# CONFIG_SND_CS46XX is not set
++# CONFIG_SND_CS5530 is not set
++# CONFIG_SND_DARLA20 is not set
++# CONFIG_SND_GINA20 is not set
++# CONFIG_SND_LAYLA20 is not set
++# CONFIG_SND_DARLA24 is not set
++# CONFIG_SND_GINA24 is not set
++# CONFIG_SND_LAYLA24 is not set
++# CONFIG_SND_MONA is not set
++# CONFIG_SND_MIA is not set
++# CONFIG_SND_ECHO3G is not set
++# CONFIG_SND_INDIGO is not set
++# CONFIG_SND_INDIGOIO is not set
++# CONFIG_SND_INDIGODJ is not set
++# CONFIG_SND_EMU10K1 is not set
++# CONFIG_SND_EMU10K1X is not set
++# CONFIG_SND_ENS1370 is not set
++# CONFIG_SND_ENS1371 is not set
++# CONFIG_SND_ES1938 is not set
++# CONFIG_SND_ES1968 is not set
++# CONFIG_SND_FM801 is not set
++# CONFIG_SND_HDA_INTEL is not set
++# CONFIG_SND_HDSP is not set
++# CONFIG_SND_HDSPM is not set
++# CONFIG_SND_ICE1712 is not set
++# CONFIG_SND_ICE1724 is not set
++# CONFIG_SND_INTEL8X0 is not set
++# CONFIG_SND_INTEL8X0M is not set
++# CONFIG_SND_KORG1212 is not set
++# CONFIG_SND_MAESTRO3 is not set
++# CONFIG_SND_MIXART is not set
++# CONFIG_SND_NM256 is not set
++# CONFIG_SND_PCXHR is not set
++# CONFIG_SND_RIPTIDE is not set
++# CONFIG_SND_RME32 is not set
++# CONFIG_SND_RME96 is not set
++# CONFIG_SND_RME9652 is not set
++# CONFIG_SND_SONICVIBES is not set
++# CONFIG_SND_TRIDENT is not set
++# CONFIG_SND_VIA82XX is not set
++# CONFIG_SND_VIA82XX_MODEM is not set
++# CONFIG_SND_VX222 is not set
++# CONFIG_SND_YMFPCI is not set
++
++#
++# ALSA PowerMac devices
++#
++
++#
++# ALSA PowerPC devices
++#
++
++#
++# System on Chip audio support
++#
++CONFIG_SND_SOC=y
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++CONFIG_SND_SOC_MPC8610=y
++CONFIG_SND_SOC_MPC8610_HPCD=y
++CONFIG_SND_SOC_CS4270=y
++CONFIG_SND_SOC_CS4270_VD33_ERRATA=y
++
+ CONFIG_HID_SUPPORT=y
+ CONFIG_HID=y
+ # CONFIG_HID_DEBUG is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/pasemi_defconfig powerpc.git/arch/powerpc/configs/pasemi_defconfig
+--- linux-2.6.24/arch/powerpc/configs/pasemi_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/pasemi_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:49:03 2007
++# Linux kernel version: 2.6.24-rc6
++# Tue Jan 15 10:26:10 2008
+ #
+ CONFIG_PPC64=y
+ 
+@@ -152,7 +152,6 @@
+ CONFIG_PPC_PASEMI_IOMMU=y
+ # CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set
+ CONFIG_PPC_PASEMI_MDIO=y
+-CONFIG_ELECTRA_IDE=y
+ # CONFIG_PPC_CELLEB is not set
+ # CONFIG_PPC_PS3 is not set
+ # CONFIG_PPC_CELL is not set
+@@ -256,7 +255,7 @@
+ CONFIG_PCI_SYSCALL=y
+ # CONFIG_PCIEPORTBUS is not set
+ CONFIG_ARCH_SUPPORTS_MSI=y
+-# CONFIG_PCI_MSI is not set
++CONFIG_PCI_MSI=y
+ CONFIG_PCI_LEGACY=y
+ # CONFIG_PCI_DEBUG is not set
+ CONFIG_PCCARD=y
+@@ -663,7 +662,26 @@
+ # CONFIG_PATA_VIA is not set
+ # CONFIG_PATA_WINBOND is not set
+ CONFIG_PATA_PLATFORM=y
+-# CONFIG_MD is not set
++CONFIG_PATA_OF_PLATFORM=y
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++CONFIG_MD_RAID0=y
++CONFIG_MD_RAID1=y
++CONFIG_MD_RAID10=y
++CONFIG_MD_RAID456=y
++CONFIG_MD_RAID5_RESHAPE=y
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++CONFIG_DM_CRYPT=y
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
+ # CONFIG_FUSION is not set
+ 
+ #
+@@ -1686,6 +1704,10 @@
+ # CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
+ # CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_XOR_BLOCKS=y
++CONFIG_ASYNC_CORE=y
++CONFIG_ASYNC_MEMCPY=y
++CONFIG_ASYNC_XOR=y
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_ALGAPI=y
+ CONFIG_CRYPTO_BLKCIPHER=y
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/ppc64_defconfig powerpc.git/arch/powerpc/configs/ppc64_defconfig
+--- linux-2.6.24/arch/powerpc/configs/ppc64_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/ppc64_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+ # Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:49:07 2007
++# Fri Dec 21 14:47:29 2007
+ #
+ CONFIG_PPC64=y
+ 
+@@ -211,7 +211,7 @@
+ CONFIG_MPIC_U3_HT_IRQS=y
+ CONFIG_MPIC_BROKEN_REGREAD=y
+ CONFIG_IBMVIO=y
+-# CONFIG_IBMEBUS is not set
++CONFIG_IBMEBUS=y
+ # CONFIG_PPC_MPC106 is not set
+ CONFIG_PPC_970_NAP=y
+ CONFIG_PPC_INDIRECT_IO=y
+@@ -375,7 +375,7 @@
+ CONFIG_INET_XFRM_MODE_TRANSPORT=y
+ CONFIG_INET_XFRM_MODE_TUNNEL=y
+ CONFIG_INET_XFRM_MODE_BEET=y
+-# CONFIG_INET_LRO is not set
++CONFIG_INET_LRO=m
+ CONFIG_INET_DIAG=y
+ CONFIG_INET_TCP_DIAG=y
+ # CONFIG_TCP_CONG_ADVANCED is not set
+@@ -929,6 +929,7 @@
+ CONFIG_NETDEV_10000=y
+ # CONFIG_CHELSIO_T1 is not set
+ # CONFIG_CHELSIO_T3 is not set
++CONFIG_EHEA=m
+ # CONFIG_IXGBE is not set
+ CONFIG_IXGB=m
+ # CONFIG_IXGB_NAPI is not set
+@@ -1558,6 +1559,7 @@
+ CONFIG_INFINIBAND_MTHCA=m
+ CONFIG_INFINIBAND_MTHCA_DEBUG=y
+ # CONFIG_INFINIBAND_IPATH is not set
++CONFIG_INFINIBAND_EHCA=m
+ # CONFIG_INFINIBAND_AMSO1100 is not set
+ # CONFIG_MLX4_INFINIBAND is not set
+ CONFIG_INFINIBAND_IPOIB=m
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/ps3_defconfig powerpc.git/arch/powerpc/configs/ps3_defconfig
+--- linux-2.6.24/arch/powerpc/configs/ps3_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/ps3_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Tue Dec  4 22:49:57 2007
++# Linux kernel version: 2.6.24-rc8
++# Wed Jan 16 14:31:21 2008
+ #
+ CONFIG_PPC64=y
+ 
+@@ -103,6 +103,7 @@
+ CONFIG_SLAB=y
+ # CONFIG_SLUB is not set
+ # CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
+ CONFIG_RT_MUTEXES=y
+ # CONFIG_TINY_SHMEM is not set
+ CONFIG_BASE_SMALL=0
+@@ -154,7 +155,6 @@
+ # CONFIG_PS3_ADVANCED is not set
+ CONFIG_PS3_HTAB_SIZE=20
+ # CONFIG_PS3_DYNAMIC_DMA is not set
+-CONFIG_PS3_USE_LPAR_ADDR=y
+ CONFIG_PS3_VUART=y
+ CONFIG_PS3_PS3AV=y
+ CONFIG_PS3_SYS_MANAGER=y
+@@ -162,6 +162,7 @@
+ CONFIG_PS3_DISK=y
+ CONFIG_PS3_ROM=y
+ CONFIG_PS3_FLASH=y
++CONFIG_PS3_LPM=m
+ CONFIG_PPC_CELL=y
+ # CONFIG_PPC_CELL_NATIVE is not set
+ # CONFIG_PPC_IBM_CELL_BLADE is not set
+@@ -225,7 +226,7 @@
+ # CONFIG_SPARSEMEM_STATIC is not set
+ CONFIG_SPARSEMEM_EXTREME=y
+ CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+-CONFIG_SPARSEMEM_VMEMMAP=y
++# CONFIG_SPARSEMEM_VMEMMAP is not set
+ CONFIG_MEMORY_HOTPLUG=y
+ CONFIG_MEMORY_HOTPLUG_SPARSE=y
+ CONFIG_SPLIT_PTLOCK_CPUS=4
+@@ -338,7 +339,26 @@
+ # CONFIG_NET_PKTGEN is not set
+ # CONFIG_HAMRADIO is not set
+ # CONFIG_IRDA is not set
+-# CONFIG_BT is not set
++CONFIG_BT=m
++CONFIG_BT_L2CAP=m
++CONFIG_BT_SCO=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++CONFIG_BT_HIDP=m
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIUSB=m
++CONFIG_BT_HCIUSB_SCO=y
++# CONFIG_BT_HCIUART is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++# CONFIG_BT_HCIVHCI is not set
+ # CONFIG_AF_RXRPC is not set
+ 
+ #
+@@ -666,14 +686,14 @@
+ #
+ # Sound
+ #
+-CONFIG_SOUND=y
++CONFIG_SOUND=m
+ 
+ #
+ # Advanced Linux Sound Architecture
+ #
+-CONFIG_SND=y
+-CONFIG_SND_TIMER=y
+-CONFIG_SND_PCM=y
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
+ # CONFIG_SND_SEQUENCER is not set
+ # CONFIG_SND_MIXER_OSS is not set
+ # CONFIG_SND_PCM_OSS is not set
+@@ -702,7 +722,7 @@
+ #
+ # ALSA PowerPC devices
+ #
+-CONFIG_SND_PS3=y
++CONFIG_SND_PS3=m
+ CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
+ 
+ #
+@@ -747,7 +767,7 @@
+ CONFIG_USB_ARCH_HAS_HCD=y
+ CONFIG_USB_ARCH_HAS_OHCI=y
+ CONFIG_USB_ARCH_HAS_EHCI=y
+-CONFIG_USB=y
++CONFIG_USB=m
+ # CONFIG_USB_DEBUG is not set
+ 
+ #
+@@ -761,13 +781,13 @@
+ #
+ # USB Host Controller Drivers
+ #
+-CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_HCD=m
+ # CONFIG_USB_EHCI_SPLIT_ISO is not set
+ # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+ # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+ CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+ # CONFIG_USB_ISP116X_HCD is not set
+-CONFIG_USB_OHCI_HCD=y
++CONFIG_USB_OHCI_HCD=m
+ # CONFIG_USB_OHCI_HCD_PPC_OF is not set
+ # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+@@ -1033,7 +1053,8 @@
+ CONFIG_HAS_IOPORT=y
+ CONFIG_HAS_DMA=y
+ CONFIG_INSTRUMENTATION=y
+-# CONFIG_PROFILING is not set
++CONFIG_PROFILING=y
++CONFIG_OPROFILE=m
+ # CONFIG_KPROBES is not set
+ # CONFIG_MARKERS is not set
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/rainier_defconfig powerpc.git/arch/powerpc/configs/rainier_defconfig
+--- linux-2.6.24/arch/powerpc/configs/rainier_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/rainier_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,873 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 11:22:40 2007
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++# CONFIG_6xx is not set
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++CONFIG_44x=y
++# CONFIG_E200 is not set
++CONFIG_4xx=y
++CONFIG_BOOKE=y
++CONFIG_PTE_64BIT=y
++CONFIG_PHYS_64BIT=y
++# CONFIG_PPC_MM_SLICES is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++CONFIG_PPC_UDBG_16550=y
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++CONFIG_PPC_DCR_NATIVE=y
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_PPC_DCR=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++CONFIG_LBD=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_PPC4xx_PCI_EXPRESS is not set
++
++#
++# Platform support
++#
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_BAMBOO is not set
++# CONFIG_EBONY is not set
++# CONFIG_SEQUOIA is not set
++# CONFIG_TAISHAN is not set
++# CONFIG_KATMAI is not set
++CONFIG_RAINIER=y
++CONFIG_440GRX=y
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_MATH_EMULATION=y
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_RESOURCES_64BIT=y
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++CONFIG_CMDLINE_BOOL=y
++CONFIG_CMDLINE=""
++CONFIG_SECCOMP=y
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="rainier.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_DEBUG is not set
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_CONSISTENT_START=0xff100000
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_BOOT_LOAD=0x01000000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++# CONFIG_MTD_BLKDEVS is not set
++# CONFIG_MTD_BLOCK is not set
++# CONFIG_MTD_BLOCK_RO is not set
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++CONFIG_MTD_JEDECPROBE=y
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++CONFIG_MTD_CFI_INTELEXT=y
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_INTEL_VR_NOR is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=35000
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_XILINX_SYSACE is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_PHANTOM is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_SGI_IOC4 is not set
++# CONFIG_TIFM_CORE is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_MACINTOSH_DRIVERS=y
++# CONFIG_MAC_EMUMOUSEBTN is not set
++# CONFIG_WINDFARM is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_IBM_NEW_EMAC_ZMII=y
++CONFIG_IBM_NEW_EMAC_RGMII=y
++CONFIG_IBM_NEW_EMAC_EMAC4=y
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++CONFIG_NETDEV_10000=y
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_CHELSIO_T3 is not set
++# CONFIG_IXGBE is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO is not set
++# CONFIG_MYRI10GE is not set
++# CONFIG_NETXEN_NIC is not set
++# CONFIG_NIU is not set
++# CONFIG_MLX4_CORE is not set
++# CONFIG_TEHUTI is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_EXTENDED=y
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++CONFIG_SERIAL_8250_SHARE_IRQ=y
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_NVRAM is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_INFINIBAND is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_INSTRUMENTATION=y
++# CONFIG_PROFILING is not set
++# CONFIG_KPROBES is not set
++# CONFIG_MARKERS is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++CONFIG_DEBUGGER=y
++# CONFIG_KGDB is not set
++# CONFIG_XMON is not set
++# CONFIG_BDI_SWITCH is not set
++CONFIG_PPC_EARLY_DEBUG=y
++# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
++# CONFIG_PPC_EARLY_DEBUG_G5 is not set
++# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
++# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
++# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
++# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
++# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
++# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
++CONFIG_PPC_EARLY_DEBUG_44x=y
++# CONFIG_PPC_EARLY_DEBUG_40x is not set
++# CONFIG_PPC_EARLY_DEBUG_CPM is not set
++CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
++CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_PPC_CLOCK is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/sequoia_defconfig powerpc.git/arch/powerpc/configs/sequoia_defconfig
+--- linux-2.6.24/arch/powerpc/configs/sequoia_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/sequoia_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:49:17 2007
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 11:23:22 2007
+ #
+ # CONFIG_PPC64 is not set
+ 
+@@ -129,6 +129,7 @@
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_PPC4xx_PCI_EXPRESS is not set
+ 
+ #
+ # Platform support
+@@ -141,8 +142,10 @@
+ # CONFIG_BAMBOO is not set
+ # CONFIG_EBONY is not set
+ CONFIG_SEQUOIA=y
++# CONFIG_TAISHAN is not set
++# CONFIG_KATMAI is not set
++# CONFIG_RAINIER is not set
+ CONFIG_440EPX=y
+-CONFIG_440A=y
+ # CONFIG_MPIC is not set
+ # CONFIG_MPIC_WEIRD is not set
+ # CONFIG_PPC_I8259 is not set
+@@ -446,9 +449,7 @@
+ # CONFIG_FIREWIRE is not set
+ # CONFIG_IEEE1394 is not set
+ # CONFIG_I2O is not set
+-CONFIG_MACINTOSH_DRIVERS=y
+-# CONFIG_MAC_EMUMOUSEBTN is not set
+-# CONFIG_WINDFARM is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
+ CONFIG_NETDEVICES=y
+ # CONFIG_NETDEVICES_MULTIQUEUE is not set
+ # CONFIG_DUMMY is not set
+@@ -459,10 +460,28 @@
+ # CONFIG_VETH is not set
+ # CONFIG_IP1000 is not set
+ # CONFIG_ARCNET is not set
+-# CONFIG_NET_ETHERNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_IBM_NEW_EMAC=y
++CONFIG_IBM_NEW_EMAC_RXB=128
++CONFIG_IBM_NEW_EMAC_TXB=64
++CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
++CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
++CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
++# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+ CONFIG_IBM_NEW_EMAC_ZMII=y
+ CONFIG_IBM_NEW_EMAC_RGMII=y
++# CONFIG_IBM_NEW_EMAC_TAH is not set
+ CONFIG_IBM_NEW_EMAC_EMAC4=y
++# CONFIG_NET_PCI is not set
++# CONFIG_B44 is not set
+ CONFIG_NETDEV_1000=y
+ # CONFIG_ACENIC is not set
+ # CONFIG_DL2K is not set
+@@ -811,6 +830,7 @@
+ # CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+ # CONFIG_PPC_EARLY_DEBUG_BEAT is not set
+ CONFIG_PPC_EARLY_DEBUG_44x=y
++# CONFIG_PPC_EARLY_DEBUG_40x is not set
+ # CONFIG_PPC_EARLY_DEBUG_CPM is not set
+ CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
+ CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/storcenter_defconfig powerpc.git/arch/powerpc/configs/storcenter_defconfig
+--- linux-2.6.24/arch/powerpc/configs/storcenter_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/storcenter_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,1174 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Tue Jan  8 09:33:54 2008
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++CONFIG_6xx=y
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++# CONFIG_44x is not set
++# CONFIG_E200 is not set
++CONFIG_PPC_FPU=y
++# CONFIG_ALTIVEC is not set
++CONFIG_PPC_STD_MMU=y
++CONFIG_PPC_STD_MMU_32=y
++# CONFIG_PPC_MM_SLICES is not set
++# CONFIG_SMP is not set
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++CONFIG_PPC_UDBG_16550=y
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++# CONFIG_PPC_DCR_NATIVE is not set
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++# CONFIG_KALLSYMS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++CONFIG_LBD=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++
++#
++# Platform support
++#
++CONFIG_PPC_MULTIPLATFORM=y
++# CONFIG_PPC_82xx is not set
++# CONFIG_PPC_83xx is not set
++# CONFIG_PPC_86xx is not set
++CONFIG_CLASSIC32=y
++# CONFIG_PPC_CHRP is not set
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_EFIKA is not set
++# CONFIG_PPC_LITE5200 is not set
++# CONFIG_PPC_PMAC is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++CONFIG_EMBEDDED6xx=y
++# CONFIG_LINKSTATION is not set
++CONFIG_STORCENTER=y
++# CONFIG_MPC7448HPC2 is not set
++# CONFIG_PPC_HOLLY is not set
++# CONFIG_PPC_PRPMC2800 is not set
++CONFIG_MPC10X_BRIDGE=y
++CONFIG_MPC10X_OPENPIC=y
++# CONFIG_MPC10X_STORE_GATHERING is not set
++CONFIG_MPIC=y
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_TAU is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_HZ_100=y
++# CONFIG_HZ_250 is not set
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=100
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++CONFIG_BINFMT_MISC=y
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++# CONFIG_KEXEC is not set
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++CONFIG_CMDLINE_BOOL=y
++CONFIG_CMDLINE="console=ttyS0,115200"
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++CONFIG_HIBERNATION_UP_POSSIBLE=y
++# CONFIG_SECCOMP is not set
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="storcenter.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_FSL_SOC=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_BOOT_LOAD=0x00800000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=m
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++CONFIG_FTL=y
++CONFIG_NFTL=y
++CONFIG_NFTL_RW=y
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0xFF800000
++CONFIG_MTD_PHYSMAP_LEN=0x00800000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=1
++# CONFIG_MTD_PHYSMAP_OF is not set
++# CONFIG_MTD_INTEL_VR_NOR is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_PMC551 is not set
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_PHANTOM is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_SGI_IOC4 is not set
++# CONFIG_TIFM_CORE is not set
++CONFIG_IDE=y
++CONFIG_IDE_MAX_HWIFS=4
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++CONFIG_IDEDISK_MULTI_MODE=y
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++CONFIG_IDE_GENERIC=y
++# CONFIG_BLK_DEV_PLATFORM is not set
++
++#
++# PCI IDE chipsets support
++#
++CONFIG_BLK_DEV_IDEPCI=y
++# CONFIG_IDEPCI_SHARE_IRQ is not set
++CONFIG_IDEPCI_PCIBUS_ORDER=y
++# CONFIG_BLK_DEV_GENERIC is not set
++# CONFIG_BLK_DEV_OPTI621 is not set
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++# CONFIG_BLK_DEV_AEC62XX is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++# CONFIG_BLK_DEV_AMD74XX is not set
++# CONFIG_BLK_DEV_CMD64X is not set
++# CONFIG_BLK_DEV_TRIFLEX is not set
++# CONFIG_BLK_DEV_CY82C693 is not set
++# CONFIG_BLK_DEV_CS5520 is not set
++# CONFIG_BLK_DEV_CS5530 is not set
++# CONFIG_BLK_DEV_HPT34X is not set
++# CONFIG_BLK_DEV_HPT366 is not set
++# CONFIG_BLK_DEV_JMICRON is not set
++# CONFIG_BLK_DEV_SC1200 is not set
++# CONFIG_BLK_DEV_PIIX is not set
++# CONFIG_BLK_DEV_IT8213 is not set
++# CONFIG_BLK_DEV_IT821X is not set
++# CONFIG_BLK_DEV_NS87415 is not set
++# CONFIG_BLK_DEV_PDC202XX_OLD is not set
++# CONFIG_BLK_DEV_PDC202XX_NEW is not set
++# CONFIG_BLK_DEV_SVWKS is not set
++# CONFIG_BLK_DEV_SIIMAGE is not set
++# CONFIG_BLK_DEV_SL82C105 is not set
++# CONFIG_BLK_DEV_SLC90E66 is not set
++# CONFIG_BLK_DEV_TRM290 is not set
++CONFIG_BLK_DEV_VIA82CXXX=y
++# CONFIG_BLK_DEV_TC86C001 is not set
++# CONFIG_IDE_ARM is not set
++CONFIG_BLK_DEV_IDEDMA=y
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=y
++# CONFIG_BLK_DEV_SR_VENDOR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++CONFIG_SCSI_SPI_ATTRS=y
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AACRAID is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_AIC79XX is not set
++# CONFIG_SCSI_AIC94XX is not set
++# CONFIG_SCSI_DPT_I2O is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_ARCMSR is not set
++# CONFIG_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY is not set
++# CONFIG_MEGARAID_SAS is not set
++# CONFIG_SCSI_HPTIOP is not set
++# CONFIG_SCSI_BUSLOGIC is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_EATA is not set
++# CONFIG_SCSI_FUTURE_DOMAIN is not set
++# CONFIG_SCSI_GDTH is not set
++# CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++# CONFIG_SCSI_STEX is not set
++# CONFIG_SCSI_SYM53C8XX_2 is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++# CONFIG_SCSI_QLA_FC is not set
++# CONFIG_SCSI_QLA_ISCSI is not set
++# CONFIG_SCSI_LPFC is not set
++# CONFIG_SCSI_DC395x is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_SRP is not set
++# CONFIG_ATA is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++CONFIG_MD_RAID0=y
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++CONFIG_MD_RAID456=y
++CONFIG_MD_RAID5_RESHAPE=y
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++# CONFIG_BLK_DEV_DM is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++CONFIG_DUMMY=m
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++CONFIG_R8169=y
++# CONFIG_R8169_NAPI is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_MV643XX_ETH is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=2
++CONFIG_SERIAL_8250_RUNTIME_UARTS=2
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++# CONFIG_SERIAL_OF_PLATFORM is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++CONFIG_NVRAM=y
++CONFIG_GEN_RTC=y
++# CONFIG_GEN_RTC_X is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_ALI1535 is not set
++# CONFIG_I2C_ALI1563 is not set
++# CONFIG_I2C_ALI15X3 is not set
++# CONFIG_I2C_AMD756 is not set
++# CONFIG_I2C_AMD8111 is not set
++# CONFIG_I2C_I801 is not set
++# CONFIG_I2C_I810 is not set
++# CONFIG_I2C_PIIX4 is not set
++CONFIG_I2C_MPC=y
++# CONFIG_I2C_NFORCE2 is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_SIS5595 is not set
++# CONFIG_I2C_SIS630 is not set
++# CONFIG_I2C_SIS96X is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++# CONFIG_I2C_VIA is not set
++# CONFIG_I2C_VIAPRO is not set
++# CONFIG_I2C_VOODOO3 is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_M41T00 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_PPC_OF is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_UHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_INFINIBAND is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++CONFIG_XFS_FS=m
++# CONFIG_XFS_QUOTA is not set
++# CONFIG_XFS_SECURITY is not set
++# CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_INSTRUMENTATION=y
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++# CONFIG_ENABLE_MUST_CHECK is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_BOOTX_TEXT is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_XOR_BLOCKS=y
++CONFIG_ASYNC_CORE=y
++CONFIG_ASYNC_MEMCPY=y
++CONFIG_ASYNC_XOR=y
++# CONFIG_CRYPTO is not set
++# CONFIG_PPC_CLOCK is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/taishan_defconfig powerpc.git/arch/powerpc/configs/taishan_defconfig
+--- linux-2.6.24/arch/powerpc/configs/taishan_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/taishan_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,790 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 11:23:39 2007
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++# CONFIG_6xx is not set
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++CONFIG_44x=y
++# CONFIG_E200 is not set
++CONFIG_4xx=y
++CONFIG_BOOKE=y
++CONFIG_PTE_64BIT=y
++CONFIG_PHYS_64BIT=y
++# CONFIG_PPC_MM_SLICES is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++CONFIG_PPC_UDBG_16550=y
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++CONFIG_PPC_DCR_NATIVE=y
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_PPC_DCR=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++CONFIG_LBD=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_PPC4xx_PCI_EXPRESS is not set
++
++#
++# Platform support
++#
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_BAMBOO is not set
++# CONFIG_EBONY is not set
++# CONFIG_SEQUOIA is not set
++CONFIG_TAISHAN=y
++# CONFIG_KATMAI is not set
++# CONFIG_RAINIER is not set
++CONFIG_440GX=y
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_300 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_MATH_EMULATION is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_RESOURCES_64BIT=y
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++CONFIG_CMDLINE_BOOL=y
++CONFIG_CMDLINE=""
++CONFIG_SECCOMP=y
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="taishan.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCI_DEBUG is not set
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_CONSISTENT_START=0xff100000
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_BOOT_LOAD=0x01000000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++# CONFIG_MTD is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=35000
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_XILINX_SYSACE is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_PHANTOM is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_SGI_IOC4 is not set
++# CONFIG_TIFM_CORE is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_MACINTOSH_DRIVERS=y
++# CONFIG_MAC_EMUMOUSEBTN is not set
++# CONFIG_WINDFARM is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++# CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_IBM_NEW_EMAC=y
++CONFIG_IBM_NEW_EMAC_RXB=128
++CONFIG_IBM_NEW_EMAC_TXB=64
++CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
++CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
++CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
++# CONFIG_IBM_NEW_EMAC_DEBUG is not set
++CONFIG_IBM_NEW_EMAC_ZMII=y
++CONFIG_IBM_NEW_EMAC_RGMII=y
++CONFIG_IBM_NEW_EMAC_TAH=y
++CONFIG_IBM_NEW_EMAC_EMAC4=y
++# CONFIG_NET_PCI is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++CONFIG_NETDEV_10000=y
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_CHELSIO_T3 is not set
++# CONFIG_IXGBE is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO is not set
++# CONFIG_MYRI10GE is not set
++# CONFIG_NETXEN_NIC is not set
++# CONFIG_NIU is not set
++# CONFIG_MLX4_CORE is not set
++# CONFIG_TEHUTI is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_EXTENDED=y
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++CONFIG_SERIAL_8250_SHARE_IRQ=y
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_NVRAM is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_INFINIBAND is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_NLS is not set
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_INSTRUMENTATION=y
++# CONFIG_PROFILING is not set
++# CONFIG_KPROBES is not set
++# CONFIG_MARKERS is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++CONFIG_DEBUGGER=y
++# CONFIG_KGDB is not set
++# CONFIG_XMON is not set
++# CONFIG_BDI_SWITCH is not set
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_PPC_CLOCK is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/walnut_defconfig powerpc.git/arch/powerpc/configs/walnut_defconfig
+--- linux-2.6.24/arch/powerpc/configs/walnut_defconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/walnut_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc4
+-# Thu Dec  6 16:49:33 2007
++# Linux kernel version: 2.6.24-rc6
++# Mon Dec 24 11:23:58 2007
+ #
+ # CONFIG_PPC64 is not set
+ 
+@@ -40,7 +40,7 @@
+ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+ CONFIG_PPC_OF=y
+ CONFIG_OF=y
+-# CONFIG_PPC_UDBG_16550 is not set
++CONFIG_PPC_UDBG_16550=y
+ # CONFIG_GENERIC_TBSYNC is not set
+ CONFIG_AUDIT_ARCH=y
+ CONFIG_GENERIC_BUG=y
+@@ -127,6 +127,7 @@
+ # CONFIG_DEFAULT_CFQ is not set
+ # CONFIG_DEFAULT_NOOP is not set
+ CONFIG_DEFAULT_IOSCHED="anticipatory"
++# CONFIG_PPC4xx_PCI_EXPRESS is not set
+ 
+ #
+ # Platform support
+@@ -136,7 +137,9 @@
+ # CONFIG_PPC_CELL is not set
+ # CONFIG_PPC_CELL_NATIVE is not set
+ # CONFIG_PQ2ADS is not set
++# CONFIG_EP405 is not set
+ # CONFIG_KILAUEA is not set
++# CONFIG_MAKALU is not set
+ CONFIG_WALNUT=y
+ # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
+ CONFIG_405GP=y
+@@ -204,11 +207,17 @@
+ # Bus options
+ #
+ CONFIG_ZONE_DMA=y
+-# CONFIG_PCI is not set
+-# CONFIG_PCI_DOMAINS is not set
+-# CONFIG_PCI_SYSCALL is not set
+-# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PPC_INDIRECT_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_PCIEPORTBUS is not set
++CONFIG_ARCH_SUPPORTS_MSI=y
++# CONFIG_PCI_MSI is not set
++# CONFIG_PCI_LEGACY is not set
++# CONFIG_PCI_DEBUG is not set
+ # CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
+ 
+ #
+ # Advanced setup
+@@ -373,11 +382,13 @@
+ # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+ # CONFIG_MTD_PHYSMAP is not set
+ CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_INTEL_VR_NOR is not set
+ # CONFIG_MTD_PLATRAM is not set
+ 
+ #
+ # Self-contained MTD device drivers
+ #
++# CONFIG_MTD_PMC551 is not set
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_PHRAM is not set
+ # CONFIG_MTD_MTDRAM is not set
+@@ -400,9 +411,14 @@
+ # CONFIG_PARPORT is not set
+ CONFIG_BLK_DEV=y
+ # CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=35000
+@@ -411,7 +427,10 @@
+ # CONFIG_ATA_OVER_ETH is not set
+ # CONFIG_XILINX_SYSACE is not set
+ CONFIG_MISC_DEVICES=y
++# CONFIG_PHANTOM is not set
+ # CONFIG_EEPROM_93CX6 is not set
++# CONFIG_SGI_IOC4 is not set
++# CONFIG_TIFM_CORE is not set
+ # CONFIG_IDE is not set
+ 
+ #
+@@ -423,6 +442,14 @@
+ # CONFIG_SCSI_NETLINK is not set
+ # CONFIG_ATA is not set
+ # CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
+ # CONFIG_MACINTOSH_DRIVERS is not set
+ CONFIG_NETDEVICES=y
+ # CONFIG_NETDEVICES_MULTIQUEUE is not set
+@@ -432,9 +459,17 @@
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
+ # CONFIG_VETH is not set
++# CONFIG_IP1000 is not set
++# CONFIG_ARCNET is not set
+ # CONFIG_PHYLIB is not set
+ CONFIG_NET_ETHERNET=y
+ # CONFIG_MII is not set
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
+ CONFIG_IBM_NEW_EMAC=y
+ CONFIG_IBM_NEW_EMAC_RXB=128
+ CONFIG_IBM_NEW_EMAC_TXB=64
+@@ -446,9 +481,38 @@
+ # CONFIG_IBM_NEW_EMAC_RGMII is not set
+ # CONFIG_IBM_NEW_EMAC_TAH is not set
+ # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_NET_PCI is not set
+ # CONFIG_B44 is not set
+ CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
+ CONFIG_NETDEV_10000=y
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_CHELSIO_T3 is not set
++# CONFIG_IXGBE is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO is not set
++# CONFIG_MYRI10GE is not set
++# CONFIG_NETXEN_NIC is not set
++# CONFIG_NIU is not set
++# CONFIG_MLX4_CORE is not set
++# CONFIG_TEHUTI is not set
++# CONFIG_TR is not set
+ 
+ #
+ # Wireless LAN
+@@ -456,6 +520,8 @@
+ # CONFIG_WLAN_PRE80211 is not set
+ # CONFIG_WLAN_80211 is not set
+ # CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+ # CONFIG_SHAPER is not set
+@@ -487,6 +553,7 @@
+ #
+ CONFIG_SERIAL_8250=y
+ CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_PCI=y
+ CONFIG_SERIAL_8250_NR_UARTS=4
+ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+ CONFIG_SERIAL_8250_EXTENDED=y
+@@ -501,6 +568,7 @@
+ # CONFIG_SERIAL_UARTLITE is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_SERIAL_OF_PLATFORM=y
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+@@ -510,8 +578,10 @@
+ # CONFIG_NVRAM is not set
+ # CONFIG_GEN_RTC is not set
+ # CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
+ # CONFIG_RAW_DRIVER is not set
+ # CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
+ # CONFIG_I2C is not set
+ 
+ #
+@@ -545,6 +615,8 @@
+ #
+ # Graphics support
+ #
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
+ # CONFIG_VGASTATE is not set
+ CONFIG_VIDEO_OUTPUT_CONTROL=m
+ # CONFIG_FB is not set
+@@ -560,9 +632,10 @@
+ #
+ # CONFIG_SOUND is not set
+ CONFIG_USB_SUPPORT=y
+-# CONFIG_USB_ARCH_HAS_HCD is not set
+-# CONFIG_USB_ARCH_HAS_OHCI is not set
+-# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB is not set
+ 
+ #
+ # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+@@ -574,6 +647,7 @@
+ # CONFIG_USB_GADGET is not set
+ # CONFIG_MMC is not set
+ # CONFIG_NEW_LEDS is not set
++# CONFIG_INFINIBAND is not set
+ # CONFIG_EDAC is not set
+ # CONFIG_RTC_CLASS is not set
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/configs/warp_defconfig powerpc.git/arch/powerpc/configs/warp_defconfig
+--- linux-2.6.24/arch/powerpc/configs/warp_defconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/configs/warp_defconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,1057 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24-rc6
++# Tue Jan  8 12:23:23 2008
++#
++# CONFIG_PPC64 is not set
++
++#
++# Processor support
++#
++# CONFIG_6xx is not set
++# CONFIG_PPC_85xx is not set
++# CONFIG_PPC_8xx is not set
++# CONFIG_40x is not set
++CONFIG_44x=y
++# CONFIG_E200 is not set
++CONFIG_PPC_FPU=y
++CONFIG_4xx=y
++CONFIG_BOOKE=y
++CONFIG_PTE_64BIT=y
++CONFIG_PHYS_64BIT=y
++# CONFIG_PPC_MM_SLICES is not set
++CONFIG_NOT_COHERENT_CACHE=y
++CONFIG_PPC32=y
++CONFIG_WORD_SIZE=32
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_TIME_VSYSCALL=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_ARCH_HAS_ILOG2_U32=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_OF=y
++CONFIG_PPC_UDBG_16550=y
++# CONFIG_GENERIC_TBSYNC is not set
++CONFIG_AUDIT_ARCH=y
++CONFIG_GENERIC_BUG=y
++# CONFIG_DEFAULT_UIMAGE is not set
++CONFIG_PPC_DCR_NATIVE=y
++# CONFIG_PPC_DCR_MMIO is not set
++CONFIG_PPC_DCR=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION="-pika"
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++# CONFIG_HOTPLUG is not set
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++CONFIG_DEFAULT_AS=y
++# CONFIG_DEFAULT_DEADLINE is not set
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="anticipatory"
++
++#
++# Platform support
++#
++# CONFIG_PPC_MPC52xx is not set
++# CONFIG_PPC_MPC5200 is not set
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PQ2ADS is not set
++# CONFIG_BAMBOO is not set
++# CONFIG_EBONY is not set
++# CONFIG_SEQUOIA is not set
++# CONFIG_TAISHAN is not set
++# CONFIG_KATMAI is not set
++# CONFIG_RAINIER is not set
++CONFIG_WARP=y
++CONFIG_440EP=y
++CONFIG_IBM440EP_ERR42=y
++# CONFIG_MPIC is not set
++# CONFIG_MPIC_WEIRD is not set
++# CONFIG_PPC_I8259 is not set
++# CONFIG_PPC_RTAS is not set
++# CONFIG_MMIO_NVRAM is not set
++# CONFIG_PPC_MPC106 is not set
++# CONFIG_PPC_970_NAP is not set
++# CONFIG_PPC_INDIRECT_IO is not set
++# CONFIG_GENERIC_IOMAP is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPM2 is not set
++# CONFIG_FSL_ULI1575 is not set
++
++#
++# Kernel options
++#
++# CONFIG_HIGHMEM is not set
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_250 is not set
++# CONFIG_HZ_300 is not set
++CONFIG_HZ_1000=y
++CONFIG_HZ=1000
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_MATH_EMULATION is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_RESOURCES_64BIT=y
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_PROC_DEVICETREE=y
++CONFIG_CMDLINE_BOOL=y
++CONFIG_CMDLINE="ip=on"
++CONFIG_SECCOMP=y
++CONFIG_WANT_DEVICE_TREE=y
++CONFIG_DEVICE_TREE="warp.dts"
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_ZONE_DMA=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_DOMAINS is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++
++#
++# Advanced setup
++#
++# CONFIG_ADVANCED_OPTIONS is not set
++
++#
++# Default settings for advanced configuration options are used
++#
++CONFIG_HIGHMEM_START=0xfe000000
++CONFIG_LOWMEM_SIZE=0x30000000
++CONFIG_KERNEL_START=0xc0000000
++CONFIG_TASK_SIZE=0xc0000000
++CONFIG_CONSISTENT_START=0xff100000
++CONFIG_CONSISTENT_SIZE=0x00200000
++CONFIG_BOOT_LOAD=0x01000000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++# CONFIG_IP_PNP_BOOTP is not set
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++# CONFIG_NF_CONNTRACK_ENABLED is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++CONFIG_VLAN_8021Q=y
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++# CONFIG_STANDALONE is not set
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++CONFIG_MTD_OOPS=m
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_CFI_INTELEXT is not set
++CONFIG_MTD_CFI_AMDSTD=y
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PHYSMAP is not set
++CONFIG_MTD_PHYSMAP_OF=y
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++CONFIG_MTD_NAND_ECC_SMC=y
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++CONFIG_MTD_NAND_IDS=y
++CONFIG_MTD_NAND_NDFC=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++CONFIG_OF_DEVICE=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=4096
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_XILINX_SYSACE is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++# CONFIG_CHR_DEV_SG is not set
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++# CONFIG_SCSI_WAIT_SCAN is not set
++
++#
++# SCSI Transports
++#
++CONFIG_SCSI_SPI_ATTRS=y
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_MACINTOSH_DRIVERS is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_IBM_NEW_EMAC=y
++CONFIG_IBM_NEW_EMAC_RXB=128
++CONFIG_IBM_NEW_EMAC_TXB=64
++CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
++CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
++CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
++# CONFIG_IBM_NEW_EMAC_DEBUG is not set
++CONFIG_IBM_NEW_EMAC_ZMII=y
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++# CONFIG_NETDEV_1000 is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++# CONFIG_VT is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++CONFIG_SERIAL_8250_EXTENDED=y
++# CONFIG_SERIAL_8250_MANY_PORTS is not set
++CONFIG_SERIAL_8250_SHARE_IRQ=y
++# CONFIG_SERIAL_8250_DETECT_IRQ is not set
++# CONFIG_SERIAL_8250_RSA is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_UARTLITE is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_OF_PLATFORM is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_NVRAM is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_IBM_IIC=y
++# CONFIG_I2C_MPC is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++CONFIG_SENSORS_EEPROM=y
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_M41T00 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++CONFIG_SENSORS_AD7414=y
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++CONFIG_USB_OHCI_HCD_PPC_OF=y
++CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
++# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
++CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
++CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++# CONFIG_MMC_WBSD is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_EDAC is not set
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++CONFIG_NLS_ISO8859_15=y
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++# CONFIG_UCC_SLOW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_SCHED_DEBUG is not set
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_STACKOVERFLOW is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++# CONFIG_DEBUGGER is not set
++CONFIG_BDI_SWITCH=y
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++# CONFIG_CRYPTO is not set
++# CONFIG_PPC_CLOCK is not set
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/Makefile powerpc.git/arch/powerpc/kernel/Makefile
+--- linux-2.6.24/arch/powerpc/kernel/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -3,7 +3,7 @@
+ #
+ 
+ ifeq ($(CONFIG_PPC64),y)
+-EXTRA_CFLAGS	+= -mno-minimal-toc
++CFLAGS_prom_init.o	+= -mno-minimal-toc
+ endif
+ ifeq ($(CONFIG_PPC32),y)
+ CFLAGS_prom_init.o      += -fPIC
+@@ -70,6 +70,7 @@
+ obj-$(CONFIG_PCI)		+= pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
+ 				   pci-common.o
+ obj-$(CONFIG_PCI_MSI)		+= msi.o
++obj-$(CONFIG_RAPIDIO)		+= rio.o
+ obj-$(CONFIG_KEXEC)		+= machine_kexec.o crash.o \
+ 				   machine_kexec_$(CONFIG_WORD_SIZE).o
+ obj-$(CONFIG_AUDIT)		+= audit.o
+@@ -91,3 +92,13 @@
+ 
+ extra-$(CONFIG_PPC_FPU)		+= fpu.o
+ extra-$(CONFIG_PPC64)		+= entry_64.o
++
++extra-y				+= systbl_chk.i
++$(obj)/systbl.o:		systbl_chk
++
++quiet_cmd_systbl_chk = CALL    $<
++      cmd_systbl_chk = $(CONFIG_SHELL) $< $(obj)/systbl_chk.i
++
++PHONY += systbl_chk
++systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i
++	$(call cmd,systbl_chk)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/btext.c powerpc.git/arch/powerpc/kernel/btext.c
+--- linux-2.6.24/arch/powerpc/kernel/btext.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/btext.c	2008-01-28 20:25:49.000000000 +0100
+@@ -236,7 +236,7 @@
+ 	if (rc == 0 || !allow_nonstdout)
+ 		return rc;
+ 
+-	for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
++	for_each_node_by_type(np, "display") {
+ 		if (of_get_property(np, "linux,opened", NULL)) {
+ 			printk("trying %s ...\n", np->full_name);
+ 			rc = btext_initialize(np);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/cpu_setup_44x.S powerpc.git/arch/powerpc/kernel/cpu_setup_44x.S
+--- linux-2.6.24/arch/powerpc/kernel/cpu_setup_44x.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/cpu_setup_44x.S	2008-01-28 20:25:49.000000000 +0100
+@@ -23,11 +23,24 @@
+ 	mflr	r4
+ 	bl	__init_fpu_44x
+ 	bl	__plb_disable_wrp
++	bl	__fixup_440A_mcheck
+ 	mtlr	r4
+ 	blr
+ _GLOBAL(__setup_cpu_440grx)
+-	b	__plb_disable_wrp
++	mflr	r4
++	bl	__plb_disable_wrp
++	bl	__fixup_440A_mcheck
++	mtlr	r4
++	blr
++_GLOBAL(__setup_cpu_440gx)
++_GLOBAL(__setup_cpu_440spe)
++	b	__fixup_440A_mcheck
+ 
++ /* Temporary fixup for arch/ppc until we kill the whole thing */
++#ifndef CONFIG_PPC_MERGE
++_GLOBAL(__fixup_440A_mcheck)
++	blr
++#endif
+ 
+ /* enable APU between CPU and FPU */
+ _GLOBAL(__init_fpu_44x)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/cputable.c powerpc.git/arch/powerpc/kernel/cputable.c
+--- linux-2.6.24/arch/powerpc/kernel/cputable.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/cputable.c	2008-01-28 20:25:49.000000000 +0100
+@@ -33,7 +33,9 @@
+ #ifdef CONFIG_PPC32
+ extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
+ extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
+ extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
++extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec);
+ extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
+ extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
+ extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
+@@ -85,6 +87,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/power3",
+ 		.oprofile_type		= PPC_OPROFILE_RS64,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power3",
+ 	},
+ 	{	/* Power3+ */
+@@ -99,6 +102,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/power3",
+ 		.oprofile_type		= PPC_OPROFILE_RS64,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power3",
+ 	},
+ 	{	/* Northstar */
+@@ -113,6 +117,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/rs64",
+ 		.oprofile_type		= PPC_OPROFILE_RS64,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "rs64",
+ 	},
+ 	{	/* Pulsar */
+@@ -127,6 +132,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/rs64",
+ 		.oprofile_type		= PPC_OPROFILE_RS64,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "rs64",
+ 	},
+ 	{	/* I-star */
+@@ -141,6 +147,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/rs64",
+ 		.oprofile_type		= PPC_OPROFILE_RS64,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "rs64",
+ 	},
+ 	{	/* S-star */
+@@ -155,6 +162,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/rs64",
+ 		.oprofile_type		= PPC_OPROFILE_RS64,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "rs64",
+ 	},
+ 	{	/* Power4 */
+@@ -169,6 +177,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/power4",
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power4",
+ 	},
+ 	{	/* Power4+ */
+@@ -183,6 +192,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/power4",
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power4",
+ 	},
+ 	{	/* PPC970 */
+@@ -200,6 +210,7 @@
+ 		.cpu_restore		= __restore_cpu_ppc970,
+ 		.oprofile_cpu_type	= "ppc64/970",
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc970",
+ 	},
+ 	{	/* PPC970FX */
+@@ -217,6 +228,7 @@
+ 		.cpu_restore		= __restore_cpu_ppc970,
+ 		.oprofile_cpu_type	= "ppc64/970",
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc970",
+ 	},
+ 	{	/* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */
+@@ -234,6 +246,7 @@
+ 		.cpu_restore		= __restore_cpu_ppc970,
+ 		.oprofile_cpu_type	= "ppc64/970MP",
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc970",
+ 	},
+ 	{	/* PPC970MP */
+@@ -251,6 +264,7 @@
+ 		.cpu_restore		= __restore_cpu_ppc970,
+ 		.oprofile_cpu_type	= "ppc64/970MP",
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc970",
+ 	},
+ 	{	/* PPC970GX */
+@@ -267,6 +281,7 @@
+ 		.cpu_setup		= __setup_cpu_ppc970,
+ 		.oprofile_cpu_type	= "ppc64/970",
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc970",
+ 	},
+ 	{	/* Power5 GR */
+@@ -286,6 +301,7 @@
+ 		 */
+ 		.oprofile_mmcra_sihv	= MMCRA_SIHV,
+ 		.oprofile_mmcra_sipr	= MMCRA_SIPR,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power5",
+ 	},
+ 	{	/* Power5++ */
+@@ -301,6 +317,7 @@
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
+ 		.oprofile_mmcra_sihv	= MMCRA_SIHV,
+ 		.oprofile_mmcra_sipr	= MMCRA_SIPR,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power5+",
+ 	},
+ 	{	/* Power5 GS */
+@@ -317,6 +334,7 @@
+ 		.oprofile_type		= PPC_OPROFILE_POWER4,
+ 		.oprofile_mmcra_sihv	= MMCRA_SIHV,
+ 		.oprofile_mmcra_sipr	= MMCRA_SIPR,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power5+",
+ 	},
+ 	{	/* POWER6 in P5+ mode; 2.04-compliant processor */
+@@ -327,6 +345,7 @@
+ 		.cpu_user_features	= COMMON_USER_POWER5_PLUS,
+ 		.icache_bsize		= 128,
+ 		.dcache_bsize		= 128,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power5+",
+ 	},
+ 	{	/* Power6 */
+@@ -346,6 +365,7 @@
+ 		.oprofile_mmcra_sipr	= POWER6_MMCRA_SIPR,
+ 		.oprofile_mmcra_clear	= POWER6_MMCRA_THRM |
+ 			POWER6_MMCRA_OTHER,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power6x",
+ 	},
+ 	{	/* 2.05-compliant processor, i.e. Power6 "architected" mode */
+@@ -356,6 +376,7 @@
+ 		.cpu_user_features	= COMMON_USER_POWER6,
+ 		.icache_bsize		= 128,
+ 		.dcache_bsize		= 128,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power6",
+ 	},
+ 	{	/* Cell Broadband Engine */
+@@ -372,6 +393,7 @@
+ 		.pmc_type		= PPC_PMC_IBM,
+ 		.oprofile_cpu_type	= "ppc64/cell-be",
+ 		.oprofile_type		= PPC_OPROFILE_CELL,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc-cell-be",
+ 	},
+ 	{	/* PA Semi PA6T */
+@@ -388,6 +410,7 @@
+ 		.cpu_restore		= __restore_cpu_pa6t,
+ 		.oprofile_cpu_type	= "ppc64/pa6t",
+ 		.oprofile_type		= PPC_OPROFILE_PA6T,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "pa6t",
+ 	},
+ 	{	/* default match */
+@@ -400,6 +423,7 @@
+ 		.dcache_bsize		= 128,
+ 		.num_pmcs		= 6,
+ 		.pmc_type		= PPC_PMC_IBM,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "power4",
+ 	}
+ #endif	/* CONFIG_PPC64 */
+@@ -414,6 +438,7 @@
+ 			PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc601",
+ 	},
+ 	{	/* 603 */
+@@ -425,6 +450,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_603,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc603",
+ 	},
+ 	{	/* 603e */
+@@ -436,6 +462,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_603,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc603",
+ 	},
+ 	{	/* 603ev */
+@@ -447,6 +474,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_603,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc603",
+ 	},
+ 	{	/* 604 */
+@@ -459,6 +487,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 2,
+ 		.cpu_setup		= __setup_cpu_604,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc604",
+ 	},
+ 	{	/* 604e */
+@@ -471,6 +500,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_604,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc604",
+ 	},
+ 	{	/* 604r */
+@@ -483,6 +513,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_604,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc604",
+ 	},
+ 	{	/* 604ev */
+@@ -495,6 +526,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_604,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc604",
+ 	},
+ 	{	/* 740/750 (0x4202, don't support TAU ?) */
+@@ -507,6 +539,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750CX (80100 and 8010x?) */
+@@ -519,6 +552,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750cx,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750CX (82201 and 82202) */
+@@ -531,6 +565,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750cx,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750CXe (82214) */
+@@ -543,6 +578,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750cx,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750CXe "Gekko" (83214) */
+@@ -555,6 +591,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750cx,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750CL */
+@@ -567,6 +604,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 745/755 */
+@@ -579,6 +617,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750FX rev 1.x */
+@@ -591,6 +630,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750FX rev 2.0 must disable HID0[DPM] */
+@@ -603,6 +643,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750FX (All revs except 2.0) */
+@@ -615,6 +656,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750fx,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 750GX */
+@@ -627,6 +669,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750fx,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 740/750 (L2CR bit need fixup for 740) */
+@@ -639,6 +682,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc750",
+ 	},
+ 	{	/* 7400 rev 1.1 ? (no TAU) */
+@@ -652,6 +696,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_7400,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7400",
+ 	},
+ 	{	/* 7400 */
+@@ -665,6 +710,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_7400,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7400",
+ 	},
+ 	{	/* 7410 */
+@@ -678,6 +724,7 @@
+ 		.dcache_bsize		= 32,
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_7410,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7400",
+ 	},
+ 	{	/* 7450 2.0 - no doze/nap */
+@@ -693,6 +740,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7450 2.1 */
+@@ -708,6 +756,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7450 2.3 and newer */
+@@ -723,6 +772,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7455 rev 1.x */
+@@ -738,6 +788,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7455 rev 2.0 */
+@@ -753,6 +804,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7455 others */
+@@ -768,6 +820,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7447/7457 Rev 1.0 */
+@@ -783,6 +836,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7447/7457 Rev 1.1 */
+@@ -798,6 +852,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7447/7457 Rev 1.2 and later */
+@@ -812,6 +867,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7447A */
+@@ -827,6 +883,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 7448 */
+@@ -842,6 +899,7 @@
+ 		.cpu_setup		= __setup_cpu_745x,
+ 		.oprofile_cpu_type      = "ppc/7450",
+ 		.oprofile_type		= PPC_OPROFILE_G4,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc7450",
+ 	},
+ 	{	/* 82xx (8240, 8245, 8260 are all 603e cores) */
+@@ -853,6 +911,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_603,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc603",
+ 	},
+ 	{	/* All G2_LE (603e core, plus some) have the same pvr */
+@@ -864,6 +923,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_603,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc603",
+ 	},
+ 	{	/* e300c1 (a 603e core, plus some) on 83xx */
+@@ -875,6 +935,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_603,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc603",
+ 	},
+ 	{	/* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */
+@@ -886,9 +947,10 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_603,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc603",
+ 	},
+-	{	/* e300c3 on 83xx  */
++	{	/* e300c3 (e300c1, plus one IU, half cache size) on 83xx */
+ 		.pvr_mask		= 0x7fff0000,
+ 		.pvr_value		= 0x00850000,
+ 		.cpu_name		= "e300c3",
+@@ -899,6 +961,18 @@
+ 		.cpu_setup		= __setup_cpu_603,
+ 		.platform		= "ppc603",
+ 	},
++	{	/* e300c4 (e300c1, plus one IU) */
++		.pvr_mask		= 0x7fff0000,
++		.pvr_value		= 0x00860000,
++		.cpu_name		= "e300c4",
++		.cpu_features		= CPU_FTRS_E300,
++		.cpu_user_features	= COMMON_USER,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_603,
++		.machine_check		= machine_check_generic,
++		.platform		= "ppc603",
++	},
+ 	{	/* default match, we assume split I/D cache & TB (non-601)... */
+ 		.pvr_mask		= 0x00000000,
+ 		.pvr_value		= 0x00000000,
+@@ -907,6 +981,7 @@
+ 		.cpu_user_features	= COMMON_USER,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_generic,
+ 		.platform		= "ppc603",
+ 	},
+ #endif /* CLASSIC_PPC */
+@@ -933,6 +1008,7 @@
+ 		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 		.icache_bsize		= 16,
+ 		.dcache_bsize		= 16,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc403",
+ 	},
+ 	{	/* 403GCX */
+@@ -944,6 +1020,7 @@
+ 		 	PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
+ 		.icache_bsize		= 16,
+ 		.dcache_bsize		= 16,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc403",
+ 	},
+ 	{	/* 403G ?? */
+@@ -954,6 +1031,7 @@
+ 		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 		.icache_bsize		= 16,
+ 		.dcache_bsize		= 16,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc403",
+ 	},
+ 	{	/* 405GP */
+@@ -965,6 +1043,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* STB 03xxx */
+@@ -976,6 +1055,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* STB 04xxx */
+@@ -987,6 +1067,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* NP405L */
+@@ -998,6 +1079,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* NP4GS3 */
+@@ -1009,6 +1091,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{   /* NP405H */
+@@ -1020,6 +1103,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* 405GPr */
+@@ -1031,6 +1115,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{   /* STBx25xx */
+@@ -1042,6 +1127,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* 405LP */
+@@ -1052,6 +1138,7 @@
+ 		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* Xilinx Virtex-II Pro  */
+@@ -1063,6 +1150,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* Xilinx Virtex-4 FX */
+@@ -1074,6 +1162,7 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* 405EP */
+@@ -1085,17 +1174,31 @@
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 	{	/* 405EX */
+-		.pvr_mask		= 0xffff0000,
+-		.pvr_value		= 0x12910000,
++		.pvr_mask		= 0xffff0004,
++		.pvr_value		= 0x12910004,
+ 		.cpu_name		= "405EX",
+ 		.cpu_features		= CPU_FTRS_40X,
+ 		.cpu_user_features	= PPC_FEATURE_32 |
+ 			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
++		.platform		= "ppc405",
++	},
++	{	/* 405EXr */
++		.pvr_mask		= 0xffff0004,
++		.pvr_value		= 0x12910000,
++		.cpu_name		= "405EXr",
++		.cpu_features		= CPU_FTRS_40X,
++		.cpu_user_features	= PPC_FEATURE_32 |
++			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc405",
+ 	},
+ 
+@@ -1109,6 +1212,7 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
+@@ -1120,6 +1224,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_440ep,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc440",
+ 	},
+ 	{
+@@ -1130,6 +1235,19 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
++		.platform		= "ppc440",
++	},
++	{ /* Matches both physical and logical PVR for 440EP (logical pvr = pvr | 0x8) */
++		.pvr_mask		= 0xf0000ff7,
++		.pvr_value		= 0x400008d4,
++		.cpu_name		= "440EP Rev. C",
++		.cpu_features		= CPU_FTRS_44X,
++		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_440ep,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
+@@ -1141,6 +1259,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_440ep,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* 440GRX */
+@@ -1152,6 +1271,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_440grx,
++		.machine_check		= machine_check_440A,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */
+@@ -1163,6 +1283,7 @@
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
+ 		.cpu_setup		= __setup_cpu_440epx,
++		.machine_check		= machine_check_440A,
+ 		.platform		= "ppc440",
+ 	},
+ 	{	/* 440GP Rev. B */
+@@ -1173,6 +1294,7 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc440gp",
+ 	},
+ 	{	/* 440GP Rev. C */
+@@ -1183,6 +1305,7 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc440gp",
+ 	},
+ 	{ /* 440GX Rev. A */
+@@ -1193,6 +1316,8 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_440gx,
++		.machine_check		= machine_check_440A,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* 440GX Rev. B */
+@@ -1203,6 +1328,8 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_440gx,
++		.machine_check		= machine_check_440A,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* 440GX Rev. C */
+@@ -1213,6 +1340,8 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_440gx,
++		.machine_check		= machine_check_440A,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* 440GX Rev. F */
+@@ -1223,6 +1352,8 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_440gx,
++		.machine_check		= machine_check_440A,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* 440SP Rev. A */
+@@ -1233,6 +1364,7 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_4xx,
+ 		.platform		= "ppc440",
+ 	},
+ 	{ /* 440SPe Rev. A */
+@@ -1243,6 +1375,8 @@
+ 		.cpu_user_features      = COMMON_USER_BOOKE,
+ 		.icache_bsize           = 32,
+ 		.dcache_bsize           = 32,
++		.cpu_setup		= __setup_cpu_440spe,
++		.machine_check		= machine_check_440A,
+ 		.platform               = "ppc440",
+ 	},
+ 	{ /* 440SPe Rev. B */
+@@ -1253,10 +1387,13 @@
+ 		.cpu_user_features	= COMMON_USER_BOOKE,
+ 		.icache_bsize		= 32,
+ 		.dcache_bsize		= 32,
++		.cpu_setup		= __setup_cpu_440spe,
++		.machine_check		= machine_check_440A,
+ 		.platform		= "ppc440",
+ 	},
+ #endif /* CONFIG_44x */
+ #ifdef CONFIG_FSL_BOOKE
++#ifdef CONFIG_E200
+ 	{	/* e200z5 */
+ 		.pvr_mask		= 0xfff00000,
+ 		.pvr_value		= 0x81000000,
+@@ -1267,6 +1404,7 @@
+ 			PPC_FEATURE_HAS_EFP_SINGLE |
+ 			PPC_FEATURE_UNIFIED_CACHE,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_e200,
+ 		.platform		= "ppc5554",
+ 	},
+ 	{	/* e200z6 */
+@@ -1280,8 +1418,10 @@
+ 			PPC_FEATURE_HAS_EFP_SINGLE_COMP |
+ 			PPC_FEATURE_UNIFIED_CACHE,
+ 		.dcache_bsize		= 32,
++		.machine_check		= machine_check_e200,
+ 		.platform		= "ppc5554",
+ 	},
++#elif defined(CONFIG_E500)
+ 	{	/* e500 */
+ 		.pvr_mask		= 0xffff0000,
+ 		.pvr_value		= 0x80200000,
+@@ -1296,6 +1436,7 @@
+ 		.num_pmcs		= 4,
+ 		.oprofile_cpu_type	= "ppc/e500",
+ 		.oprofile_type		= PPC_OPROFILE_BOOKE,
++		.machine_check		= machine_check_e500,
+ 		.platform		= "ppc8540",
+ 	},
+ 	{	/* e500v2 */
+@@ -1313,9 +1454,11 @@
+ 		.num_pmcs		= 4,
+ 		.oprofile_cpu_type	= "ppc/e500",
+ 		.oprofile_type		= PPC_OPROFILE_BOOKE,
++		.machine_check		= machine_check_e500,
+ 		.platform		= "ppc8548",
+ 	},
+ #endif
++#endif
+ #if !CLASSIC_PPC
+ 	{	/* default match */
+ 		.pvr_mask		= 0x00000000,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/crash.c powerpc.git/arch/powerpc/kernel/crash.c
+--- linux-2.6.24/arch/powerpc/kernel/crash.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/crash.c	2008-01-28 20:25:49.000000000 +0100
+@@ -32,6 +32,8 @@
+ #include <asm/lmb.h>
+ #include <asm/firmware.h>
+ #include <asm/smp.h>
++#include <asm/system.h>
++#include <asm/setjmp.h>
+ 
+ #ifdef DEBUG
+ #include <asm/udbg.h>
+@@ -45,6 +47,11 @@
+ static cpumask_t cpus_in_crash = CPU_MASK_NONE;
+ cpumask_t cpus_in_sr = CPU_MASK_NONE;
+ 
++#define CRASH_HANDLER_MAX 1
++/* NULL terminated list of shutdown handles */
++static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX+1];
++static DEFINE_SPINLOCK(crash_handlers_lock);
++
+ #ifdef CONFIG_SMP
+ static atomic_t enter_on_soft_reset = ATOMIC_INIT(0);
+ 
+@@ -285,9 +292,72 @@
+ }
+ #endif /* CONFIG_SPU_BASE */
+ 
++/*
++ * Register a function to be called on shutdown.  Only use this if you
++ * can't reset your device in the second kernel.
++ */
++int crash_shutdown_register(crash_shutdown_t handler)
++{
++	unsigned int i, rc;
++
++	spin_lock(&crash_handlers_lock);
++	for (i = 0 ; i < CRASH_HANDLER_MAX; i++)
++		if (!crash_shutdown_handles[i]) {
++			/* Insert handle at first empty entry */
++			crash_shutdown_handles[i] = handler;
++			rc = 0;
++			break;
++		}
++
++	if (i == CRASH_HANDLER_MAX) {
++		printk(KERN_ERR "Crash shutdown handles full, "
++		       "not registered.\n");
++		rc = 1;
++	}
++
++	spin_unlock(&crash_handlers_lock);
++	return rc;
++}
++EXPORT_SYMBOL(crash_shutdown_register);
++
++int crash_shutdown_unregister(crash_shutdown_t handler)
++{
++	unsigned int i, rc;
++
++	spin_lock(&crash_handlers_lock);
++	for (i = 0 ; i < CRASH_HANDLER_MAX; i++)
++		if (crash_shutdown_handles[i] == handler)
++			break;
++
++	if (i == CRASH_HANDLER_MAX) {
++		printk(KERN_ERR "Crash shutdown handle not found\n");
++		rc = 1;
++	} else {
++		/* Shift handles down */
++		for (; crash_shutdown_handles[i]; i++)
++			crash_shutdown_handles[i] =
++				crash_shutdown_handles[i+1];
++		rc = 0;
++	}
++
++	spin_unlock(&crash_handlers_lock);
++	return rc;
++}
++EXPORT_SYMBOL(crash_shutdown_unregister);
++
++static unsigned long crash_shutdown_buf[JMP_BUF_LEN];
++
++static int handle_fault(struct pt_regs *regs)
++{
++	longjmp(crash_shutdown_buf, 1);
++	return 0;
++}
++
+ void default_machine_crash_shutdown(struct pt_regs *regs)
+ {
+-	unsigned int irq;
++	unsigned int i;
++	int (*old_handler)(struct pt_regs *regs);
++
+ 
+ 	/*
+ 	 * This function is only called after the system
+@@ -301,15 +371,36 @@
+ 	 */
+ 	hard_irq_disable();
+ 
+-	for_each_irq(irq) {
+-		struct irq_desc *desc = irq_desc + irq;
++	for_each_irq(i) {
++		struct irq_desc *desc = irq_desc + i;
+ 
+ 		if (desc->status & IRQ_INPROGRESS)
+-			desc->chip->eoi(irq);
++			desc->chip->eoi(i);
+ 
+ 		if (!(desc->status & IRQ_DISABLED))
+-			desc->chip->disable(irq);
++			desc->chip->disable(i);
++	}
++
++	/*
++	 * Call registered shutdown routines savely.  Swap out
++	 * __debugger_fault_handler, and replace on exit.
++	 */
++	old_handler = __debugger_fault_handler;
++	__debugger_fault_handler = handle_fault;
++	for (i = 0; crash_shutdown_handles[i]; i++) {
++		if (setjmp(crash_shutdown_buf) == 0) {
++			/*
++			 * Insert syncs and delay to ensure
++			 * instructions in the dangerous region don't
++			 * leak away from this protected region.
++			 */
++			asm volatile("sync; isync");
++			/* dangerous region */
++			crash_shutdown_handles[i]();
++			asm volatile("sync; isync");
++		}
+ 	}
++	__debugger_fault_handler = old_handler;
+ 
+ 	/*
+ 	 * Make a note of crashing cpu. Will be used in machine_kexec
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/dma_64.c powerpc.git/arch/powerpc/kernel/dma_64.c
+--- linux-2.6.24/arch/powerpc/kernel/dma_64.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/dma_64.c	2008-01-28 20:25:49.000000000 +0100
+@@ -112,10 +112,16 @@
+ /*
+  * Generic direct DMA implementation
+  *
+- * This implementation supports a global offset that can be applied if
+- * the address at which memory is visible to devices is not 0.
++ * This implementation supports a per-device offset that can be applied if
++ * the address at which memory is visible to devices is not 0. Platform code
++ * can set archdata.dma_data to an unsigned long holding the offset. By
++ * default the offset is zero.
+  */
+-unsigned long dma_direct_offset;
++
++static unsigned long get_dma_direct_offset(struct device *dev)
++{
++	return (unsigned long)dev->archdata.dma_data;
++}
+ 
+ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+ 				       dma_addr_t *dma_handle, gfp_t flag)
+@@ -124,13 +130,12 @@
+ 	void *ret;
+ 	int node = dev->archdata.numa_node;
+ 
+-	/* TODO: Maybe use the numa node here too ? */
+ 	page = alloc_pages_node(node, flag, get_order(size));
+ 	if (page == NULL)
+ 		return NULL;
+ 	ret = page_address(page);
+ 	memset(ret, 0, size);
+-	*dma_handle = virt_to_abs(ret) | dma_direct_offset;
++	*dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev);
+ 
+ 	return ret;
+ }
+@@ -145,7 +150,7 @@
+ 					size_t size,
+ 					enum dma_data_direction direction)
+ {
+-	return virt_to_abs(ptr) | dma_direct_offset;
++	return virt_to_abs(ptr) + get_dma_direct_offset(dev);
+ }
+ 
+ static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
+@@ -161,7 +166,7 @@
+ 	int i;
+ 
+ 	for_each_sg(sgl, sg, nents, i) {
+-		sg->dma_address = sg_phys(sg) | dma_direct_offset;
++		sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
+ 		sg->dma_length = sg->length;
+ 	}
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/head_44x.S powerpc.git/arch/powerpc/kernel/head_44x.S
+--- linux-2.6.24/arch/powerpc/kernel/head_44x.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/head_44x.S	2008-01-28 20:25:49.000000000 +0100
+@@ -289,11 +289,8 @@
+ 	CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
+ 
+ 	/* Machine Check Interrupt */
+-#ifdef CONFIG_440A
+-	MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+-#else
+ 	CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
+-#endif
++	MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception)
+ 
+ 	/* Data Storage Interrupt */
+ 	START_EXCEPTION(DataStorage)
+@@ -674,6 +671,15 @@
+  */
+ 
+ /*
++ * Adjust the machine check IVOR on 440A cores
++ */
++_GLOBAL(__fixup_440A_mcheck)
++	li	r3,MachineCheckA@l
++	mtspr	SPRN_IVOR1,r3
++	sync
++	blr
++
++/*
+  * extern void giveup_altivec(struct task_struct *prev)
+  *
+  * The 44x core does not have an AltiVec unit.
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/head_booke.h powerpc.git/arch/powerpc/kernel/head_booke.h
+--- linux-2.6.24/arch/powerpc/kernel/head_booke.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/head_booke.h	2008-01-28 20:25:49.000000000 +0100
+@@ -166,7 +166,7 @@
+ 	mfspr	r5,SPRN_ESR;					\
+ 	stw	r5,_ESR(r11);					\
+ 	addi	r3,r1,STACK_FRAME_OVERHEAD;			\
+-	EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
++	EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ 			  NOCOPY, mcheck_transfer_to_handler,   \
+ 			  ret_from_mcheck_exc)
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/head_fsl_booke.S powerpc.git/arch/powerpc/kernel/head_fsl_booke.S
+--- linux-2.6.24/arch/powerpc/kernel/head_fsl_booke.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/head_fsl_booke.S	2008-01-28 20:25:49.000000000 +0100
+@@ -73,8 +73,8 @@
+ /* We try to not make any assumptions about how the boot loader
+  * setup or used the TLBs.  We invalidate all mappings from the
+  * boot loader and load a single entry in TLB1[0] to map the
+- * first 16M of kernel memory.  Any boot info passed from the
+- * bootloader needs to live in this first 16M.
++ * first 64M of kernel memory.  Any boot info passed from the
++ * bootloader needs to live in this first 64M.
+  *
+  * Requirement on bootloader:
+  *  - The page we're executing in needs to reside in TLB1 and
+@@ -167,7 +167,7 @@
+ 	mtspr	SPRN_MAS0,r7
+ 	tlbre
+ 
+-	/* Just modify the entry ID and EPN for the temp mapping */
++	/* Just modify the entry ID, EPN and RPN for the temp mapping */
+ 	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
+ 	rlwimi	r7,r5,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
+ 	mtspr	SPRN_MAS0,r7
+@@ -177,9 +177,12 @@
+ 	ori	r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
+ 	mtspr	SPRN_MAS1,r6
+ 	mfspr	r6,SPRN_MAS2
+-	li	r7,0		/* temp EPN = 0 */
++	lis	r7,PHYSICAL_START@h
+ 	rlwimi	r7,r6,0,20,31
+ 	mtspr	SPRN_MAS2,r7
++	mfspr	r6,SPRN_MAS3
++	rlwimi	r7,r6,0,20,31
++	mtspr	SPRN_MAS3,r7
+ 	tlbwe
+ 
+ 	xori	r6,r4,1
+@@ -222,11 +225,11 @@
+ 	lis	r6,0x1000		/* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
+ 	mtspr	SPRN_MAS0,r6
+ 	lis	r6,(MAS1_VALID|MAS1_IPROT)@h
+-	ori	r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l
++	ori	r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
+ 	mtspr	SPRN_MAS1,r6
+ 	li	r7,0
+-	lis	r6,KERNELBASE@h
+-	ori	r6,r6,KERNELBASE@l
++	lis	r6,PAGE_OFFSET@h
++	ori	r6,r6,PAGE_OFFSET@l
+ 	rlwimi	r6,r7,0,20,31
+ 	mtspr	SPRN_MAS2,r6
+ 	li	r7,(MAS3_SX|MAS3_SW|MAS3_SR)
+@@ -234,6 +237,9 @@
+ 	tlbwe
+ 
+ /* 7. Jump to KERNELBASE mapping */
++	lis	r6,KERNELBASE@h
++	ori	r6,r6,KERNELBASE@l
++	rlwimi	r6,r7,0,20,31
+ 	lis	r7,MSR_KERNEL@h
+ 	ori	r7,r7,MSR_KERNEL@l
+ 	bl	1f			/* Find our address */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/ibmebus.c powerpc.git/arch/powerpc/kernel/ibmebus.c
+--- linux-2.6.24/arch/powerpc/kernel/ibmebus.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/ibmebus.c	2008-01-28 20:25:49.000000000 +0100
+@@ -41,6 +41,7 @@
+ #include <linux/kobject.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/interrupt.h>
++#include <linux/of.h>
+ #include <linux/of_platform.h>
+ #include <asm/ibmebus.h>
+ #include <asm/abs_addr.h>
+@@ -52,7 +53,7 @@
+ struct bus_type ibmebus_bus_type;
+ 
+ /* These devices will automatically be added to the bus during init */
+-static struct of_device_id builtin_matches[] = {
++static struct of_device_id __initdata builtin_matches[] = {
+ 	{ .compatible = "IBM,lhca" },
+ 	{ .compatible = "IBM,lhea" },
+ 	{},
+@@ -171,7 +172,7 @@
+ 
+ 	root = of_find_node_by_path("/");
+ 
+-	for (child = NULL; (child = of_get_next_child(root, child)); ) {
++	for_each_child_of_node(root, child) {
+ 		if (!of_match_node(matches, child))
+ 			continue;
+ 
+@@ -197,16 +198,13 @@
+ 	/* If the driver uses devices that ibmebus doesn't know, add them */
+ 	ibmebus_create_devices(drv->match_table);
+ 
+-	drv->driver.name   = drv->name;
+-	drv->driver.bus    = &ibmebus_bus_type;
+-
+-	return driver_register(&drv->driver);
++	return of_register_driver(drv, &ibmebus_bus_type);
+ }
+ EXPORT_SYMBOL(ibmebus_register_driver);
+ 
+ void ibmebus_unregister_driver(struct of_platform_driver *drv)
+ {
+-	driver_unregister(&drv->driver);
++	of_unregister_driver(drv);
+ }
+ EXPORT_SYMBOL(ibmebus_unregister_driver);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/iommu.c powerpc.git/arch/powerpc/kernel/iommu.c
+--- linux-2.6.24/arch/powerpc/kernel/iommu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/iommu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -532,16 +532,14 @@
+ 	return tbl;
+ }
+ 
+-void iommu_free_table(struct device_node *dn)
++void iommu_free_table(struct iommu_table *tbl, const char *node_name)
+ {
+-	struct pci_dn *pdn = dn->data;
+-	struct iommu_table *tbl = pdn->iommu_table;
+ 	unsigned long bitmap_sz, i;
+ 	unsigned int order;
+ 
+ 	if (!tbl || !tbl->it_map) {
+ 		printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
+-				dn->full_name);
++				node_name);
+ 		return;
+ 	}
+ 
+@@ -550,7 +548,7 @@
+ 	for (i = 0; i < (tbl->it_size/64); i++) {
+ 		if (tbl->it_map[i] != 0) {
+ 			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
+-				__FUNCTION__, dn->full_name);
++				__FUNCTION__, node_name);
+ 			break;
+ 		}
+ 	}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/isa-bridge.c powerpc.git/arch/powerpc/kernel/isa-bridge.c
+--- linux-2.6.24/arch/powerpc/kernel/isa-bridge.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/isa-bridge.c	2008-01-28 20:25:49.000000000 +0100
+@@ -108,7 +108,7 @@
+ 	if (size > 0x10000)
+ 		size = 0x10000;
+ 
+-	printk(KERN_ERR "no ISA IO ranges or unexpected isa range,"
++	printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
+ 	       "mapping 64k\n");
+ 
+ 	__ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
+@@ -116,7 +116,7 @@
+ 	return;
+ 
+ inval_range:
+-	printk(KERN_ERR "no ISA IO ranges or unexpected isa range,"
++	printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
+ 	       "mapping 64k\n");
+ 	__ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
+ 		     0x10000, _PAGE_NO_CACHE|_PAGE_GUARDED);
+@@ -145,7 +145,7 @@
+ 	for_each_node_by_type(np, "isa") {
+ 		/* Look for our hose being a parent */
+ 		for (parent = of_get_parent(np); parent;) {
+-			if (parent == hose->arch_data) {
++			if (parent == hose->dn) {
+ 				of_node_put(parent);
+ 				break;
+ 			}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/legacy_serial.c powerpc.git/arch/powerpc/kernel/legacy_serial.c
+--- linux-2.6.24/arch/powerpc/kernel/legacy_serial.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/legacy_serial.c	2008-01-28 20:25:49.000000000 +0100
+@@ -307,7 +307,7 @@
+ 	}
+ 
+ 	/* First fill our array with SOC ports */
+-	for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
++	for_each_compatible_node(np, "serial", "ns16550") {
+ 		struct device_node *soc = of_get_parent(np);
+ 		if (soc && !strcmp(soc->type, "soc")) {
+ 			index = add_legacy_soc_port(np, np);
+@@ -318,7 +318,7 @@
+ 	}
+ 
+ 	/* First fill our array with ISA ports */
+-	for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
++	for_each_node_by_type(np, "serial") {
+ 		struct device_node *isa = of_get_parent(np);
+ 		if (isa && !strcmp(isa->name, "isa")) {
+ 			index = add_legacy_isa_port(np, isa);
+@@ -329,7 +329,7 @@
+ 	}
+ 
+ 	/* First fill our array with tsi-bridge ports */
+-	for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
++	for_each_compatible_node(np, "serial", "ns16550") {
+ 		struct device_node *tsi = of_get_parent(np);
+ 		if (tsi && !strcmp(tsi->type, "tsi-bridge")) {
+ 			index = add_legacy_soc_port(np, np);
+@@ -340,7 +340,7 @@
+ 	}
+ 
+ 	/* First fill our array with opb bus ports */
+-	for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
++	for_each_compatible_node(np, "serial", "ns16550") {
+ 		struct device_node *opb = of_get_parent(np);
+ 		if (opb && (!strcmp(opb->type, "opb") ||
+ 			    of_device_is_compatible(opb, "ibm,opb"))) {
+@@ -474,7 +474,7 @@
+ 
+ 	/*
+ 	 * Before we register the platfrom serial devices, we need
+-	 * to fixup their interrutps and their IO ports.
++	 * to fixup their interrupts and their IO ports.
+ 	 */
+ 	DBG("Fixing serial ports interrupts and IO ports ...\n");
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/lparcfg.c powerpc.git/arch/powerpc/kernel/lparcfg.c
+--- linux-2.6.24/arch/powerpc/kernel/lparcfg.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/lparcfg.c	2008-01-28 20:25:49.000000000 +0100
+@@ -41,7 +41,6 @@
+ /* #define LPARCFG_DEBUG */
+ 
+ static struct proc_dir_entry *proc_ppc64_lparcfg;
+-#define LPARCFG_BUFF_SIZE 4096
+ 
+ /*
+  * Track sum of all purrs across all processors. This is used to further
+@@ -595,13 +594,6 @@
+ 	ent = create_proc_entry("ppc64/lparcfg", mode, NULL);
+ 	if (ent) {
+ 		ent->proc_fops = &lparcfg_fops;
+-		ent->data = kmalloc(LPARCFG_BUFF_SIZE, GFP_KERNEL);
+-		if (!ent->data) {
+-			printk(KERN_ERR
+-			       "Failed to allocate buffer for lparcfg\n");
+-			remove_proc_entry("lparcfg", ent->parent);
+-			return -ENOMEM;
+-		}
+ 	} else {
+ 		printk(KERN_ERR "Failed to create ppc64/lparcfg\n");
+ 		return -EIO;
+@@ -613,10 +605,8 @@
+ 
+ void __exit lparcfg_cleanup(void)
+ {
+-	if (proc_ppc64_lparcfg) {
+-		kfree(proc_ppc64_lparcfg->data);
++	if (proc_ppc64_lparcfg)
+ 		remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
+-	}
+ }
+ 
+ module_init(lparcfg_init);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/misc.S powerpc.git/arch/powerpc/kernel/misc.S
+--- linux-2.6.24/arch/powerpc/kernel/misc.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/misc.S	2008-01-28 20:25:49.000000000 +0100
+@@ -8,12 +8,17 @@
+  * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+  * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
+  *
++ * setjmp/longjmp code by Paul Mackerras.
++ *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version
+  * 2 of the License, or (at your option) any later version.
+  */
+ #include <asm/ppc_asm.h>
++#include <asm/unistd.h>
++#include <asm/asm-compat.h>
++#include <asm/asm-offsets.h>
+ 
+ 	.text
+ 
+@@ -43,3 +48,71 @@
+ 	add	r3,r3,r5
+ 	mtlr	r0
+ 	blr
++
++_GLOBAL(kernel_execve)
++	li	r0,__NR_execve
++	sc
++	bnslr
++	neg	r3,r3
++	blr
++
++_GLOBAL(setjmp)
++	mflr	r0
++	PPC_STL	r0,0(r3)
++	PPC_STL	r1,SZL(r3)
++	PPC_STL	r2,2*SZL(r3)
++	mfcr	r0
++	PPC_STL	r0,3*SZL(r3)
++	PPC_STL	r13,4*SZL(r3)
++	PPC_STL	r14,5*SZL(r3)
++	PPC_STL	r15,6*SZL(r3)
++	PPC_STL	r16,7*SZL(r3)
++	PPC_STL	r17,8*SZL(r3)
++	PPC_STL	r18,9*SZL(r3)
++	PPC_STL	r19,10*SZL(r3)
++	PPC_STL	r20,11*SZL(r3)
++	PPC_STL	r21,12*SZL(r3)
++	PPC_STL	r22,13*SZL(r3)
++	PPC_STL	r23,14*SZL(r3)
++	PPC_STL	r24,15*SZL(r3)
++	PPC_STL	r25,16*SZL(r3)
++	PPC_STL	r26,17*SZL(r3)
++	PPC_STL	r27,18*SZL(r3)
++	PPC_STL	r28,19*SZL(r3)
++	PPC_STL	r29,20*SZL(r3)
++	PPC_STL	r30,21*SZL(r3)
++	PPC_STL	r31,22*SZL(r3)
++	li	r3,0
++	blr
++
++_GLOBAL(longjmp)
++	PPC_LCMPI r4,0
++	bne	1f
++	li	r4,1
++1:	PPC_LL	r13,4*SZL(r3)
++	PPC_LL	r14,5*SZL(r3)
++	PPC_LL	r15,6*SZL(r3)
++	PPC_LL	r16,7*SZL(r3)
++	PPC_LL	r17,8*SZL(r3)
++	PPC_LL	r18,9*SZL(r3)
++	PPC_LL	r19,10*SZL(r3)
++	PPC_LL	r20,11*SZL(r3)
++	PPC_LL	r21,12*SZL(r3)
++	PPC_LL	r22,13*SZL(r3)
++	PPC_LL	r23,14*SZL(r3)
++	PPC_LL	r24,15*SZL(r3)
++	PPC_LL	r25,16*SZL(r3)
++	PPC_LL	r26,17*SZL(r3)
++	PPC_LL	r27,18*SZL(r3)
++	PPC_LL	r28,19*SZL(r3)
++	PPC_LL	r29,20*SZL(r3)
++	PPC_LL	r30,21*SZL(r3)
++	PPC_LL	r31,22*SZL(r3)
++	PPC_LL	r0,3*SZL(r3)
++	mtcrf	0x38,r0
++	PPC_LL	r0,0(r3)
++	PPC_LL	r1,SZL(r3)
++	PPC_LL	r2,2*SZL(r3)
++	mtlr	r0
++	mr	r3,r4
++	blr
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/misc_32.S powerpc.git/arch/powerpc/kernel/misc_32.S
+--- linux-2.6.24/arch/powerpc/kernel/misc_32.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/misc_32.S	2008-01-28 20:25:49.000000000 +0100
+@@ -206,6 +206,45 @@
+ 	isync
+ 	blr			/* Done */
+ 
++#ifdef CONFIG_40x
++
++/*
++ * Do an IO access in real mode
++ */
++_GLOBAL(real_readb)
++	mfmsr	r7
++	ori	r0,r7,MSR_DR
++	xori	r0,r0,MSR_DR
++	sync
++	mtmsr	r0
++	sync
++	isync
++	lbz	r3,0(r3)
++	sync
++	mtmsr	r7
++	sync
++	isync
++	blr
++
++	/*
++ * Do an IO access in real mode
++ */
++_GLOBAL(real_writeb)
++	mfmsr	r7
++	ori	r0,r7,MSR_DR
++	xori	r0,r0,MSR_DR
++	sync
++	mtmsr	r0
++	sync
++	isync
++	stb	r3,0(r4)
++	sync
++	mtmsr	r7
++	sync
++	isync
++	blr
++
++#endif /* CONFIG_40x */
+ 
+ /*
+  * Flush MMU TLB
+@@ -793,13 +832,6 @@
+ 	addi	r1,r1,16
+ 	blr
+ 
+-_GLOBAL(kernel_execve)
+-	li	r0,__NR_execve
+-	sc
+-	bnslr
+-	neg	r3,r3
+-	blr
+-
+ /*
+  * This routine is just here to keep GCC happy - sigh...
+  */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/misc_64.S powerpc.git/arch/powerpc/kernel/misc_64.S
+--- linux-2.6.24/arch/powerpc/kernel/misc_64.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/misc_64.S	2008-01-28 20:25:49.000000000 +0100
+@@ -518,13 +518,6 @@
+ 
+ #endif /* CONFIG_ALTIVEC */
+ 
+-_GLOBAL(kernel_execve)
+-	li	r0,__NR_execve
+-	sc
+-	bnslr
+-	neg	r3,r3
+-	blr
+-
+ /* kexec_wait(phys_cpu)
+  *
+  * wait for the flag to change, indicating this kernel is going away but
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/module_32.c powerpc.git/arch/powerpc/kernel/module_32.c
+--- linux-2.6.24/arch/powerpc/kernel/module_32.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/module_32.c	2008-01-28 20:25:49.000000000 +0100
+@@ -24,6 +24,7 @@
+ #include <linux/kernel.h>
+ #include <linux/cache.h>
+ #include <linux/bug.h>
++#include <linux/sort.h>
+ 
+ #include "setup.h"
+ 
+@@ -54,22 +55,60 @@
+    addend) */
+ static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num)
+ {
+-	unsigned int i, j, ret = 0;
++	unsigned int i, r_info, r_addend, _count_relocs;
+ 
+-	/* Sure, this is order(n^2), but it's usually short, and not
+-           time critical */
+-	for (i = 0; i < num; i++) {
+-		for (j = 0; j < i; j++) {
+-			/* If this addend appeared before, it's
+-                           already been counted */
+-			if (ELF32_R_SYM(rela[i].r_info)
+-			    == ELF32_R_SYM(rela[j].r_info)
+-			    && rela[i].r_addend == rela[j].r_addend)
+-				break;
++	_count_relocs = 0;
++	r_info = 0;
++	r_addend = 0;
++	for (i = 0; i < num; i++)
++		/* Only count 24-bit relocs, others don't need stubs */
++		if (ELF32_R_TYPE(rela[i].r_info) == R_PPC_REL24 &&
++		    (r_info != ELF32_R_SYM(rela[i].r_info) ||
++		     r_addend != rela[i].r_addend)) {
++			_count_relocs++;
++			r_info = ELF32_R_SYM(rela[i].r_info);
++			r_addend = rela[i].r_addend;
+ 		}
+-		if (j == i) ret++;
++
++	return _count_relocs;
++}
++
++static int relacmp(const void *_x, const void *_y)
++{
++	const Elf32_Rela *x, *y;
++
++	y = (Elf32_Rela *)_x;
++	x = (Elf32_Rela *)_y;
++
++	/* Compare the entire r_info (as opposed to ELF32_R_SYM(r_info) only) to
++	 * make the comparison cheaper/faster. It won't affect the sorting or
++	 * the counting algorithms' performance
++	 */
++	if (x->r_info < y->r_info)
++		return -1;
++	else if (x->r_info > y->r_info)
++		return 1;
++	else if (x->r_addend < y->r_addend)
++		return -1;
++	else if (x->r_addend > y->r_addend)
++		return 1;
++	else
++		return 0;
++}
++
++static void relaswap(void *_x, void *_y, int size)
++{
++	uint32_t *x, *y, tmp;
++	int i;
++
++	y = (uint32_t *)_x;
++	x = (uint32_t *)_y;
++
++	for (i = 0; i < sizeof(Elf32_Rela) / sizeof(uint32_t); i++) {
++		tmp = x[i];
++		x[i] = y[i];
++		y[i] = tmp;
+ 	}
+-	return ret;
+ }
+ 
+ /* Get the potential trampolines size required of the init and
+@@ -100,6 +139,16 @@
+ 			DEBUGP("Ptr: %p.  Number: %u\n",
+ 			       (void *)hdr + sechdrs[i].sh_offset,
+ 			       sechdrs[i].sh_size / sizeof(Elf32_Rela));
++
++			/* Sort the relocation information based on a symbol and
++			 * addend key. This is a stable O(n*log n) complexity
++			 * alogrithm but it will reduce the complexity of
++			 * count_relocs() to linear complexity O(n)
++			 */
++			sort((void *)hdr + sechdrs[i].sh_offset,
++			     sechdrs[i].sh_size / sizeof(Elf32_Rela),
++			     sizeof(Elf32_Rela), relacmp, relaswap);
++
+ 			ret += count_relocs((void *)hdr
+ 					     + sechdrs[i].sh_offset,
+ 					     sechdrs[i].sh_size
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/module_64.c powerpc.git/arch/powerpc/kernel/module_64.c
+--- linux-2.6.24/arch/powerpc/kernel/module_64.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/module_64.c	2008-01-28 20:25:49.000000000 +0100
+@@ -24,6 +24,7 @@
+ #include <asm/module.h>
+ #include <asm/uaccess.h>
+ #include <asm/firmware.h>
++#include <linux/sort.h>
+ 
+ #include "setup.h"
+ 
+@@ -81,25 +82,23 @@
+    different addend) */
+ static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num)
+ {
+-	unsigned int i, j, ret = 0;
++	unsigned int i, r_info, r_addend, _count_relocs;
+ 
+ 	/* FIXME: Only count external ones --RR */
+-	/* Sure, this is order(n^2), but it's usually short, and not
+-           time critical */
+-	for (i = 0; i < num; i++) {
++	_count_relocs = 0;
++	r_info = 0;
++	r_addend = 0;
++	for (i = 0; i < num; i++)
+ 		/* Only count 24-bit relocs, others don't need stubs */
+-		if (ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24)
+-			continue;
+-		for (j = 0; j < i; j++) {
+-			/* If this addend appeared before, it's
+-                           already been counted */
+-			if (rela[i].r_info == rela[j].r_info
+-			    && rela[i].r_addend == rela[j].r_addend)
+-				break;
++		if (ELF64_R_TYPE(rela[i].r_info) == R_PPC_REL24 &&
++		    (r_info != ELF64_R_SYM(rela[i].r_info) ||
++		     r_addend != rela[i].r_addend)) {
++			_count_relocs++;
++			r_info = ELF64_R_SYM(rela[i].r_info);
++			r_addend = rela[i].r_addend;
+ 		}
+-		if (j == i) ret++;
+-	}
+-	return ret;
++
++	return _count_relocs;
+ }
+ 
+ void *module_alloc(unsigned long size)
+@@ -118,6 +117,44 @@
+            table entries. */
+ }
+ 
++static int relacmp(const void *_x, const void *_y)
++{
++	const Elf64_Rela *x, *y;
++
++	y = (Elf64_Rela *)_x;
++	x = (Elf64_Rela *)_y;
++
++	/* Compare the entire r_info (as opposed to ELF64_R_SYM(r_info) only) to
++	 * make the comparison cheaper/faster. It won't affect the sorting or
++	 * the counting algorithms' performance
++	 */
++	if (x->r_info < y->r_info)
++		return -1;
++	else if (x->r_info > y->r_info)
++		return 1;
++	else if (x->r_addend < y->r_addend)
++		return -1;
++	else if (x->r_addend > y->r_addend)
++		return 1;
++	else
++		return 0;
++}
++
++static void relaswap(void *_x, void *_y, int size)
++{
++	uint64_t *x, *y, tmp;
++	int i;
++
++	y = (uint64_t *)_x;
++	x = (uint64_t *)_y;
++
++	for (i = 0; i < sizeof(Elf64_Rela) / sizeof(uint64_t); i++) {
++		tmp = x[i];
++		x[i] = y[i];
++		y[i] = tmp;
++	}
++}
++
+ /* Get size of potential trampolines required. */
+ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
+ 				    const Elf64_Shdr *sechdrs)
+@@ -133,6 +170,16 @@
+ 			DEBUGP("Ptr: %p.  Number: %lu\n",
+ 			       (void *)sechdrs[i].sh_addr,
+ 			       sechdrs[i].sh_size / sizeof(Elf64_Rela));
++
++			/* Sort the relocation information based on a symbol and
++			 * addend key. This is a stable O(n*log n) complexity
++			 * alogrithm but it will reduce the complexity of
++			 * count_relocs() to linear complexity O(n)
++			 */
++			sort((void *)sechdrs[i].sh_addr,
++			     sechdrs[i].sh_size / sizeof(Elf64_Rela),
++			     sizeof(Elf64_Rela), relacmp, relaswap);
++
+ 			relocs += count_relocs((void *)sechdrs[i].sh_addr,
+ 					       sechdrs[i].sh_size
+ 					       / sizeof(Elf64_Rela));
+@@ -343,7 +390,7 @@
+ 			/* Simply set it */
+ 			*(u32 *)location = value;
+ 			break;
+-			
++
+ 		case R_PPC64_ADDR64:
+ 			/* Simply set it */
+ 			*(unsigned long *)location = value;
+@@ -399,7 +446,7 @@
+ 			}
+ 
+ 			/* Only replace bits 2 through 26 */
+-			*(uint32_t *)location 
++			*(uint32_t *)location
+ 				= (*(uint32_t *)location & ~0x03fffffc)
+ 				| (value & 0x03fffffc);
+ 			break;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/of_device.c powerpc.git/arch/powerpc/kernel/of_device.c
+--- linux-2.6.24/arch/powerpc/kernel/of_device.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/of_device.c	2008-01-28 20:25:49.000000000 +0100
+@@ -5,10 +5,10 @@
+ #include <linux/module.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/slab.h>
++#include <linux/of_device.h>
+ 
+ #include <asm/errno.h>
+ #include <asm/dcr.h>
+-#include <asm/of_device.h>
+ 
+ static void of_device_make_bus_id(struct of_device *dev)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/of_platform.c powerpc.git/arch/powerpc/kernel/of_platform.c
+--- linux-2.6.24/arch/powerpc/kernel/of_platform.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/of_platform.c	2008-01-28 20:25:49.000000000 +0100
+@@ -19,6 +19,7 @@
+ #include <linux/mod_devicetable.h>
+ #include <linux/slab.h>
+ #include <linux/pci.h>
++#include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/of_platform.h>
+ 
+@@ -40,7 +41,7 @@
+  * a bus type in the list
+  */
+ 
+-static struct of_device_id of_default_bus_ids[] = {
++static const struct of_device_id of_default_bus_ids[] = {
+ 	{ .type = "soc", },
+ 	{ .compatible = "soc", },
+ 	{ .type = "spider", },
+@@ -64,26 +65,6 @@
+ 
+ postcore_initcall(of_bus_driver_init);
+ 
+-int of_register_platform_driver(struct of_platform_driver *drv)
+-{
+-	/* initialize common driver fields */
+-	if (!drv->driver.name)
+-		drv->driver.name = drv->name;
+-	if (!drv->driver.owner)
+-		drv->driver.owner = drv->owner;
+-	drv->driver.bus = &of_platform_bus_type;
+-
+-	/* register with core */
+-	return driver_register(&drv->driver);
+-}
+-EXPORT_SYMBOL(of_register_platform_driver);
+-
+-void of_unregister_platform_driver(struct of_platform_driver *drv)
+-{
+-	driver_unregister(&drv->driver);
+-}
+-EXPORT_SYMBOL(of_unregister_platform_driver);
+-
+ struct of_device* of_platform_device_create(struct device_node *np,
+ 					    const char *bus_id,
+ 					    struct device *parent)
+@@ -120,15 +101,15 @@
+  * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
+  * disallow recursive creation of child busses
+  */
+-static int of_platform_bus_create(struct device_node *bus,
+-				  struct of_device_id *matches,
++static int of_platform_bus_create(const struct device_node *bus,
++				  const struct of_device_id *matches,
+ 				  struct device *parent)
+ {
+ 	struct device_node *child;
+ 	struct of_device *dev;
+ 	int rc = 0;
+ 
+-	for (child = NULL; (child = of_get_next_child(bus, child)); ) {
++	for_each_child_of_node(bus, child) {
+ 		pr_debug("   create child: %s\n", child->full_name);
+ 		dev = of_platform_device_create(child, NULL, parent);
+ 		if (dev == NULL)
+@@ -157,7 +138,7 @@
+  */
+ 
+ int of_platform_bus_probe(struct device_node *root,
+-			  struct of_device_id *matches,
++			  const struct of_device_id *matches,
+ 			  struct device *parent)
+ {
+ 	struct device_node *child;
+@@ -190,7 +171,7 @@
+ 		rc = of_platform_bus_create(root, matches, &dev->dev);
+ 		goto bail;
+ 	}
+-	for (child = NULL; (child = of_get_next_child(root, child)); ) {
++	for_each_child_of_node(root, child) {
+ 		if (!of_match_node(matches, child))
+ 			continue;
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/pci-common.c powerpc.git/arch/powerpc/kernel/pci-common.c
+--- linux-2.6.24/arch/powerpc/kernel/pci-common.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/pci-common.c	2008-01-28 20:25:49.000000000 +0100
+@@ -48,32 +48,26 @@
+ static DEFINE_SPINLOCK(hose_spinlock);
+ 
+ /* XXX kill that some day ... */
+-int global_phb_number;		/* Global phb counter */
++static int global_phb_number;		/* Global phb counter */
+ 
+-extern struct list_head hose_list;
++/* ISA Memory physical address */
++resource_size_t isa_mem_base;
+ 
+-/*
+- * pci_controller(phb) initialized common variables.
+- */
+-static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
+-{
+-	memset(hose, 0, sizeof(struct pci_controller));
+-
+-	spin_lock(&hose_spinlock);
+-	hose->global_number = global_phb_number++;
+-	list_add_tail(&hose->list_node, &hose_list);
+-	spin_unlock(&hose_spinlock);
+-}
++/* Default PCI flags is 0 */
++unsigned int ppc_pci_flags;
+ 
+-struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
++struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
+ {
+ 	struct pci_controller *phb;
+ 
+-	phb = alloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL);
++	phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL);
+ 	if (phb == NULL)
+ 		return NULL;
+-	pci_setup_pci_controller(phb);
+-	phb->arch_data = dev;
++	spin_lock(&hose_spinlock);
++	phb->global_number = global_phb_number++;
++	list_add_tail(&phb->list_node, &hose_list);
++	spin_unlock(&hose_spinlock);
++	phb->dn = dev;
+ 	phb->is_dynamic = mem_init_done;
+ #ifdef CONFIG_PPC64
+ 	if (dev) {
+@@ -126,15 +120,10 @@
+  */
+ int pci_domain_nr(struct pci_bus *bus)
+ {
+-	if (firmware_has_feature(FW_FEATURE_ISERIES))
+-		return 0;
+-	else {
+-		struct pci_controller *hose = pci_bus_to_host(bus);
++	struct pci_controller *hose = pci_bus_to_host(bus);
+ 
+-		return hose->global_number;
+-	}
++	return hose->global_number;
+ }
+-
+ EXPORT_SYMBOL(pci_domain_nr);
+ 
+ #ifdef CONFIG_PPC_OF
+@@ -153,7 +142,7 @@
+ 	while(node) {
+ 		struct pci_controller *hose, *tmp;
+ 		list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+-			if (hose->arch_data == node)
++			if (hose->dn == node)
+ 				return hose;
+ 		node = node->parent;
+ 	}
+@@ -201,6 +190,20 @@
+ 	struct of_irq oirq;
+ 	unsigned int virq;
+ 
++	/* The current device-tree that iSeries generates from the HV
++	 * PCI informations doesn't contain proper interrupt routing,
++	 * and all the fallback would do is print out crap, so we
++	 * don't attempt to resolve the interrupts here at all, some
++	 * iSeries specific fixup does it.
++	 *
++	 * In the long run, we will hopefully fix the generated device-tree
++	 * instead.
++	 */
++#ifdef CONFIG_PPC_ISERIES
++	if (firmware_has_feature(FW_FEATURE_ISERIES))
++		return -1;
++#endif
++
+ 	DBG("Try to map irq for %s...\n", pci_name(pci_dev));
+ 
+ #ifdef DEBUG
+@@ -222,10 +225,11 @@
+ 		if (pin == 0)
+ 			return -1;
+ 		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
+-		    line == 0xff) {
++		    line == 0xff || line == 0) {
+ 			return -1;
+ 		}
+-		DBG(" -> no map ! Using irq line %d from PCI config\n", line);
++		DBG(" -> no map ! Using line %d (pin %d) from PCI config\n",
++		    line, pin);
+ 
+ 		virq = irq_create_mapping(NULL, line);
+ 		if (virq != NO_IRQ)
+@@ -475,3 +479,717 @@
+ 	*start = rsrc->start - offset;
+ 	*end = rsrc->end - offset;
+ }
++
++/**
++ * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
++ * @hose: newly allocated pci_controller to be setup
++ * @dev: device node of the host bridge
++ * @primary: set if primary bus (32 bits only, soon to be deprecated)
++ *
++ * This function will parse the "ranges" property of a PCI host bridge device
++ * node and setup the resource mapping of a pci controller based on its
++ * content.
++ *
++ * Life would be boring if it wasn't for a few issues that we have to deal
++ * with here:
++ *
++ *   - We can only cope with one IO space range and up to 3 Memory space
++ *     ranges. However, some machines (thanks Apple !) tend to split their
++ *     space into lots of small contiguous ranges. So we have to coalesce.
++ *
++ *   - We can only cope with all memory ranges having the same offset
++ *     between CPU addresses and PCI addresses. Unfortunately, some bridges
++ *     are setup for a large 1:1 mapping along with a small "window" which
++ *     maps PCI address 0 to some arbitrary high address of the CPU space in
++ *     order to give access to the ISA memory hole.
++ *     The way out of here that I've chosen for now is to always set the
++ *     offset based on the first resource found, then override it if we
++ *     have a different offset and the previous was set by an ISA hole.
++ *
++ *   - Some busses have IO space not starting at 0, which causes trouble with
++ *     the way we do our IO resource renumbering. The code somewhat deals with
++ *     it for 64 bits but I would expect problems on 32 bits.
++ *
++ *   - Some 32 bits platforms such as 4xx can have physical space larger than
++ *     32 bits so we need to use 64 bits values for the parsing
++ */
++void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
++					    struct device_node *dev,
++					    int primary)
++{
++	const u32 *ranges;
++	int rlen;
++	int pna = of_n_addr_cells(dev);
++	int np = pna + 5;
++	int memno = 0, isa_hole = -1;
++	u32 pci_space;
++	unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
++	unsigned long long isa_mb = 0;
++	struct resource *res;
++
++	printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
++	       dev->full_name, primary ? "(primary)" : "");
++
++	/* Get ranges property */
++	ranges = of_get_property(dev, "ranges", &rlen);
++	if (ranges == NULL)
++		return;
++
++	/* Parse it */
++	while ((rlen -= np * 4) >= 0) {
++		/* Read next ranges element */
++		pci_space = ranges[0];
++		pci_addr = of_read_number(ranges + 1, 2);
++		cpu_addr = of_translate_address(dev, ranges + 3);
++		size = of_read_number(ranges + pna + 3, 2);
++		ranges += np;
++		if (cpu_addr == OF_BAD_ADDR || size == 0)
++			continue;
++
++		/* Now consume following elements while they are contiguous */
++		for (; rlen >= np * sizeof(u32);
++		     ranges += np, rlen -= np * 4) {
++			if (ranges[0] != pci_space)
++				break;
++			pci_next = of_read_number(ranges + 1, 2);
++			cpu_next = of_translate_address(dev, ranges + 3);
++			if (pci_next != pci_addr + size ||
++			    cpu_next != cpu_addr + size)
++				break;
++			size += of_read_number(ranges + pna + 3, 2);
++		}
++
++		/* Act based on address space type */
++		res = NULL;
++		switch ((pci_space >> 24) & 0x3) {
++		case 1:		/* PCI IO space */
++			printk(KERN_INFO
++			       "  IO 0x%016llx..0x%016llx -> 0x%016llx\n",
++			       cpu_addr, cpu_addr + size - 1, pci_addr);
++
++			/* We support only one IO range */
++			if (hose->pci_io_size) {
++				printk(KERN_INFO
++				       " \\--> Skipped (too many) !\n");
++				continue;
++			}
++#ifdef CONFIG_PPC32
++			/* On 32 bits, limit I/O space to 16MB */
++			if (size > 0x01000000)
++				size = 0x01000000;
++
++			/* 32 bits needs to map IOs here */
++			hose->io_base_virt = ioremap(cpu_addr, size);
++
++			/* Expect trouble if pci_addr is not 0 */
++			if (primary)
++				isa_io_base =
++					(unsigned long)hose->io_base_virt;
++#endif /* CONFIG_PPC32 */
++			/* pci_io_size and io_base_phys always represent IO
++			 * space starting at 0 so we factor in pci_addr
++			 */
++			hose->pci_io_size = pci_addr + size;
++			hose->io_base_phys = cpu_addr - pci_addr;
++
++			/* Build resource */
++			res = &hose->io_resource;
++			res->flags = IORESOURCE_IO;
++			res->start = pci_addr;
++			break;
++		case 2:		/* PCI Memory space */
++			printk(KERN_INFO
++			       " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
++			       cpu_addr, cpu_addr + size - 1, pci_addr,
++			       (pci_space & 0x40000000) ? "Prefetch" : "");
++
++			/* We support only 3 memory ranges */
++			if (memno >= 3) {
++				printk(KERN_INFO
++				       " \\--> Skipped (too many) !\n");
++				continue;
++			}
++			/* Handles ISA memory hole space here */
++			if (pci_addr == 0) {
++				isa_mb = cpu_addr;
++				isa_hole = memno;
++				if (primary || isa_mem_base == 0)
++					isa_mem_base = cpu_addr;
++			}
++
++			/* We get the PCI/Mem offset from the first range or
++			 * the, current one if the offset came from an ISA
++			 * hole. If they don't match, bugger.
++			 */
++			if (memno == 0 ||
++			    (isa_hole >= 0 && pci_addr != 0 &&
++			     hose->pci_mem_offset == isa_mb))
++				hose->pci_mem_offset = cpu_addr - pci_addr;
++			else if (pci_addr != 0 &&
++				 hose->pci_mem_offset != cpu_addr - pci_addr) {
++				printk(KERN_INFO
++				       " \\--> Skipped (offset mismatch) !\n");
++				continue;
++			}
++
++			/* Build resource */
++			res = &hose->mem_resources[memno++];
++			res->flags = IORESOURCE_MEM;
++			if (pci_space & 0x40000000)
++				res->flags |= IORESOURCE_PREFETCH;
++			res->start = cpu_addr;
++			break;
++		}
++		if (res != NULL) {
++			res->name = dev->full_name;
++			res->end = res->start + size - 1;
++			res->parent = NULL;
++			res->sibling = NULL;
++			res->child = NULL;
++		}
++	}
++
++	/* Out of paranoia, let's put the ISA hole last if any */
++	if (isa_hole >= 0 && memno > 0 && isa_hole != (memno-1)) {
++		struct resource tmp = hose->mem_resources[isa_hole];
++		hose->mem_resources[isa_hole] = hose->mem_resources[memno-1];
++		hose->mem_resources[memno-1] = tmp;
++	}
++}
++
++/* Decide whether to display the domain number in /proc */
++int pci_proc_domain(struct pci_bus *bus)
++{
++	struct pci_controller *hose = pci_bus_to_host(bus);
++#ifdef CONFIG_PPC64
++	return hose->buid != 0;
++#else
++	if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS))
++		return 0;
++	if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0)
++		return hose->global_number != 0;
++	return 1;
++#endif
++}
++
++void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
++			     struct resource *res)
++{
++	resource_size_t offset = 0, mask = (resource_size_t)-1;
++	struct pci_controller *hose = pci_bus_to_host(dev->bus);
++
++	if (!hose)
++		return;
++	if (res->flags & IORESOURCE_IO) {
++		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
++		mask = 0xffffffffu;
++	} else if (res->flags & IORESOURCE_MEM)
++		offset = hose->pci_mem_offset;
++
++	region->start = (res->start - offset) & mask;
++	region->end = (res->end - offset) & mask;
++}
++EXPORT_SYMBOL(pcibios_resource_to_bus);
++
++void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
++			     struct pci_bus_region *region)
++{
++	resource_size_t offset = 0, mask = (resource_size_t)-1;
++	struct pci_controller *hose = pci_bus_to_host(dev->bus);
++
++	if (!hose)
++		return;
++	if (res->flags & IORESOURCE_IO) {
++		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
++		mask = 0xffffffffu;
++	} else if (res->flags & IORESOURCE_MEM)
++		offset = hose->pci_mem_offset;
++	res->start = (region->start + offset) & mask;
++	res->end = (region->end + offset) & mask;
++}
++EXPORT_SYMBOL(pcibios_bus_to_resource);
++
++/* Fixup a bus resource into a linux resource */
++static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
++{
++	struct pci_controller *hose = pci_bus_to_host(dev->bus);
++	resource_size_t offset = 0, mask = (resource_size_t)-1;
++
++	if (res->flags & IORESOURCE_IO) {
++		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
++		mask = 0xffffffffu;
++	} else if (res->flags & IORESOURCE_MEM)
++		offset = hose->pci_mem_offset;
++
++	res->start = (res->start + offset) & mask;
++	res->end = (res->end + offset) & mask;
++
++	pr_debug("PCI:%s            %016llx-%016llx\n",
++		 pci_name(dev),
++		 (unsigned long long)res->start,
++		 (unsigned long long)res->end);
++}
++
++
++/* This header fixup will do the resource fixup for all devices as they are
++ * probed, but not for bridge ranges
++ */
++static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
++{
++	struct pci_controller *hose = pci_bus_to_host(dev->bus);
++	int i;
++
++	if (!hose) {
++		printk(KERN_ERR "No host bridge for PCI dev %s !\n",
++		       pci_name(dev));
++		return;
++	}
++	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
++		struct resource *res = dev->resource + i;
++		if (!res->flags)
++			continue;
++		if (res->end == 0xffffffff) {
++			pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n",
++				 pci_name(dev), i,
++				 (unsigned long long)res->start,
++				 (unsigned long long)res->end,
++				 (unsigned int)res->flags);
++			res->end -= res->start;
++			res->start = 0;
++			res->flags |= IORESOURCE_UNSET;
++			continue;
++		}
++
++		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
++			 pci_name(dev), i,
++			 (unsigned long long)res->start,\
++			 (unsigned long long)res->end,
++			 (unsigned int)res->flags);
++
++		fixup_resource(res, dev);
++	}
++
++	/* Call machine specific resource fixup */
++	if (ppc_md.pcibios_fixup_resources)
++		ppc_md.pcibios_fixup_resources(dev);
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
++
++static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
++{
++	struct pci_controller *hose = pci_bus_to_host(bus);
++	struct pci_dev *dev = bus->self;
++
++	pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
++
++	/* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
++	 * now differently between 32 and 64 bits.
++	 */
++	if (dev != NULL) {
++		struct resource *res;
++		int i;
++
++		for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
++			if ((res = bus->resource[i]) == NULL)
++				continue;
++			if (!res->flags)
++				continue;
++			if (i >= 3 && bus->self->transparent)
++				continue;
++			/* On PowerMac, Apple leaves bridge windows open over
++			 * an inaccessible region of memory space (0...fffff)
++			 * which is somewhat bogus, but that's what they think
++			 * means disabled...
++			 *
++			 * We clear those to force them to be reallocated later
++			 *
++			 * We detect such regions by the fact that the base is
++			 * equal to the pci_mem_offset of the host bridge and
++			 * their size is smaller than 1M.
++			 */
++			if (res->flags & IORESOURCE_MEM &&
++			    res->start == hose->pci_mem_offset &&
++			    res->end < 0x100000) {
++				printk(KERN_INFO
++				       "PCI: Closing bogus Apple Firmware"
++				       " region %d on bus 0x%02x\n",
++				       i, bus->number);
++				res->flags = 0;
++				continue;
++			}
++
++			pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
++				 pci_name(dev), i,
++				 (unsigned long long)res->start,\
++				 (unsigned long long)res->end,
++				 (unsigned int)res->flags);
++
++			fixup_resource(res, dev);
++		}
++	}
++
++	/* Additional setup that is different between 32 and 64 bits for now */
++	pcibios_do_bus_setup(bus);
++
++	/* Platform specific bus fixups */
++	if (ppc_md.pcibios_fixup_bus)
++		ppc_md.pcibios_fixup_bus(bus);
++
++	/* Read default IRQs and fixup if necessary */
++	list_for_each_entry(dev, &bus->devices, bus_list) {
++		pci_read_irq_line(dev);
++		if (ppc_md.pci_irq_fixup)
++			ppc_md.pci_irq_fixup(dev);
++	}
++}
++
++void __devinit pcibios_fixup_bus(struct pci_bus *bus)
++{
++	/* When called from the generic PCI probe, read PCI<->PCI bridge
++	 * bases before proceeding
++	 */
++	if (bus->self != NULL)
++		pci_read_bridge_bases(bus);
++	__pcibios_fixup_bus(bus);
++}
++EXPORT_SYMBOL(pcibios_fixup_bus);
++
++/* When building a bus from the OF tree rather than probing, we need a
++ * slightly different version of the fixup which doesn't read the
++ * bridge bases using config space accesses
++ */
++void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus)
++{
++	__pcibios_fixup_bus(bus);
++}
++
++static int skip_isa_ioresource_align(struct pci_dev *dev)
++{
++	if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
++	    !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
++		return 1;
++	return 0;
++}
++
++/*
++ * We need to avoid collisions with `mirrored' VGA ports
++ * and other strange ISA hardware, so we always want the
++ * addresses to be allocated in the 0x000-0x0ff region
++ * modulo 0x400.
++ *
++ * Why? Because some silly external IO cards only decode
++ * the low 10 bits of the IO address. The 0x00-0xff region
++ * is reserved for motherboard devices that decode all 16
++ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
++ * but we want to try to avoid allocating at 0x2900-0x2bff
++ * which might have be mirrored at 0x0100-0x03ff..
++ */
++void pcibios_align_resource(void *data, struct resource *res,
++				resource_size_t size, resource_size_t align)
++{
++	struct pci_dev *dev = data;
++
++	if (res->flags & IORESOURCE_IO) {
++		resource_size_t start = res->start;
++
++		if (skip_isa_ioresource_align(dev))
++			return;
++		if (start & 0x300) {
++			start = (start + 0x3ff) & ~0x3ff;
++			res->start = start;
++		}
++	}
++}
++EXPORT_SYMBOL(pcibios_align_resource);
++
++/*
++ * Reparent resource children of pr that conflict with res
++ * under res, and make res replace those children.
++ */
++static int __init reparent_resources(struct resource *parent,
++				     struct resource *res)
++{
++	struct resource *p, **pp;
++	struct resource **firstpp = NULL;
++
++	for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
++		if (p->end < res->start)
++			continue;
++		if (res->end < p->start)
++			break;
++		if (p->start < res->start || p->end > res->end)
++			return -1;	/* not completely contained */
++		if (firstpp == NULL)
++			firstpp = pp;
++	}
++	if (firstpp == NULL)
++		return -1;	/* didn't find any conflicting entries? */
++	res->parent = parent;
++	res->child = *firstpp;
++	res->sibling = *pp;
++	*firstpp = res;
++	*pp = NULL;
++	for (p = res->child; p != NULL; p = p->sibling) {
++		p->parent = res;
++		DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
++		    p->name,
++		    (unsigned long long)p->start,
++		    (unsigned long long)p->end, res->name);
++	}
++	return 0;
++}
++
++/*
++ *  Handle resources of PCI devices.  If the world were perfect, we could
++ *  just allocate all the resource regions and do nothing more.  It isn't.
++ *  On the other hand, we cannot just re-allocate all devices, as it would
++ *  require us to know lots of host bridge internals.  So we attempt to
++ *  keep as much of the original configuration as possible, but tweak it
++ *  when it's found to be wrong.
++ *
++ *  Known BIOS problems we have to work around:
++ *	- I/O or memory regions not configured
++ *	- regions configured, but not enabled in the command register
++ *	- bogus I/O addresses above 64K used
++ *	- expansion ROMs left enabled (this may sound harmless, but given
++ *	  the fact the PCI specs explicitly allow address decoders to be
++ *	  shared between expansion ROMs and other resource regions, it's
++ *	  at least dangerous)
++ *
++ *  Our solution:
++ *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
++ *	    This gives us fixed barriers on where we can allocate.
++ *	(2) Allocate resources for all enabled devices.  If there is
++ *	    a collision, just mark the resource as unallocated. Also
++ *	    disable expansion ROMs during this step.
++ *	(3) Try to allocate resources for disabled devices.  If the
++ *	    resources were assigned correctly, everything goes well,
++ *	    if they weren't, they won't disturb allocation of other
++ *	    resources.
++ *	(4) Assign new addresses to resources which were either
++ *	    not configured at all or misconfigured.  If explicitly
++ *	    requested by the user, configure expansion ROM address
++ *	    as well.
++ */
++
++static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
++{
++	struct pci_bus *bus;
++	int i;
++	struct resource *res, *pr;
++
++	/* Depth-First Search on bus tree */
++	list_for_each_entry(bus, bus_list, node) {
++		for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
++			if ((res = bus->resource[i]) == NULL || !res->flags
++			    || res->start > res->end)
++				continue;
++			if (bus->parent == NULL)
++				pr = (res->flags & IORESOURCE_IO) ?
++					&ioport_resource : &iomem_resource;
++			else {
++				/* Don't bother with non-root busses when
++				 * re-assigning all resources. We clear the
++				 * resource flags as if they were colliding
++				 * and as such ensure proper re-allocation
++				 * later.
++				 */
++				if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
++					goto clear_resource;
++				pr = pci_find_parent_resource(bus->self, res);
++				if (pr == res) {
++					/* this happens when the generic PCI
++					 * code (wrongly) decides that this
++					 * bridge is transparent  -- paulus
++					 */
++					continue;
++				}
++			}
++
++			DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
++			    "[0x%x], parent %p (%s)\n",
++			    bus->self ? pci_name(bus->self) : "PHB",
++			    bus->number, i,
++			    (unsigned long long)res->start,
++			    (unsigned long long)res->end,
++			    (unsigned int)res->flags,
++			    pr, (pr && pr->name) ? pr->name : "nil");
++
++			if (pr && !(pr->flags & IORESOURCE_UNSET)) {
++				if (request_resource(pr, res) == 0)
++					continue;
++				/*
++				 * Must be a conflict with an existing entry.
++				 * Move that entry (or entries) under the
++				 * bridge resource and try again.
++				 */
++				if (reparent_resources(pr, res) == 0)
++					continue;
++			}
++			printk(KERN_WARNING
++			       "PCI: Cannot allocate resource region "
++			       "%d of PCI bridge %d, will remap\n",
++			       i, bus->number);
++clear_resource:
++			res->flags = 0;
++		}
++		pcibios_allocate_bus_resources(&bus->children);
++	}
++}
++
++static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
++{
++	struct resource *pr, *r = &dev->resource[idx];
++
++	DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
++	    pci_name(dev), idx,
++	    (unsigned long long)r->start,
++	    (unsigned long long)r->end,
++	    (unsigned int)r->flags);
++
++	pr = pci_find_parent_resource(dev, r);
++	if (!pr || (pr->flags & IORESOURCE_UNSET) ||
++	    request_resource(pr, r) < 0) {
++		printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
++		       " of device %s, will remap\n", idx, pci_name(dev));
++		if (pr)
++			DBG("PCI:  parent is %p: %016llx-%016llx [%x]\n", pr,
++			    (unsigned long long)pr->start,
++			    (unsigned long long)pr->end,
++			    (unsigned int)pr->flags);
++		/* We'll assign a new address later */
++		r->flags |= IORESOURCE_UNSET;
++		r->end -= r->start;
++		r->start = 0;
++	}
++}
++
++static void __init pcibios_allocate_resources(int pass)
++{
++	struct pci_dev *dev = NULL;
++	int idx, disabled;
++	u16 command;
++	struct resource *r;
++
++	for_each_pci_dev(dev) {
++		pci_read_config_word(dev, PCI_COMMAND, &command);
++		for (idx = 0; idx < 6; idx++) {
++			r = &dev->resource[idx];
++			if (r->parent)		/* Already allocated */
++				continue;
++			if (!r->flags || (r->flags & IORESOURCE_UNSET))
++				continue;	/* Not assigned at all */
++			if (r->flags & IORESOURCE_IO)
++				disabled = !(command & PCI_COMMAND_IO);
++			else
++				disabled = !(command & PCI_COMMAND_MEMORY);
++			if (pass == disabled)
++				alloc_resource(dev, idx);
++		}
++		if (pass)
++			continue;
++		r = &dev->resource[PCI_ROM_RESOURCE];
++		if (r->flags & IORESOURCE_ROM_ENABLE) {
++			/* Turn the ROM off, leave the resource region,
++			 * but keep it unregistered.
++			 */
++			u32 reg;
++			DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
++			r->flags &= ~IORESOURCE_ROM_ENABLE;
++			pci_read_config_dword(dev, dev->rom_base_reg, &reg);
++			pci_write_config_dword(dev, dev->rom_base_reg,
++					       reg & ~PCI_ROM_ADDRESS_ENABLE);
++		}
++	}
++}
++
++void __init pcibios_resource_survey(void)
++{
++	/* Allocate and assign resources. If we re-assign everything, then
++	 * we skip the allocate phase
++	 */
++	pcibios_allocate_bus_resources(&pci_root_buses);
++
++	if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
++		pcibios_allocate_resources(0);
++		pcibios_allocate_resources(1);
++	}
++
++	if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
++		DBG("PCI: Assigning unassigned resouces...\n");
++		pci_assign_unassigned_resources();
++	}
++
++	/* Call machine dependent fixup */
++	if (ppc_md.pcibios_fixup)
++		ppc_md.pcibios_fixup();
++}
++
++#ifdef CONFIG_HOTPLUG
++/* This is used by the pSeries hotplug driver to allocate resource
++ * of newly plugged busses. We can try to consolidate with the
++ * rest of the code later, for now, keep it as-is
++ */
++void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
++{
++	struct pci_dev *dev;
++	struct pci_bus *child_bus;
++
++	list_for_each_entry(dev, &bus->devices, bus_list) {
++		int i;
++
++		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
++			struct resource *r = &dev->resource[i];
++
++			if (r->parent || !r->start || !r->flags)
++				continue;
++			pci_claim_resource(dev, i);
++		}
++	}
++
++	list_for_each_entry(child_bus, &bus->children, node)
++		pcibios_claim_one_bus(child_bus);
++}
++EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
++#endif /* CONFIG_HOTPLUG */
++
++int pcibios_enable_device(struct pci_dev *dev, int mask)
++{
++	u16 cmd, old_cmd;
++	int idx;
++	struct resource *r;
++
++	if (ppc_md.pcibios_enable_device_hook)
++		if (ppc_md.pcibios_enable_device_hook(dev))
++			return -EINVAL;
++
++	pci_read_config_word(dev, PCI_COMMAND, &cmd);
++	old_cmd = cmd;
++	for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
++		/* Only set up the requested stuff */
++		if (!(mask & (1 << idx)))
++			continue;
++		r = &dev->resource[idx];
++		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
++			continue;
++		if ((idx == PCI_ROM_RESOURCE) &&
++				(!(r->flags & IORESOURCE_ROM_ENABLE)))
++			continue;
++		if (r->parent == NULL) {
++			printk(KERN_ERR "PCI: Device %s not available because"
++			       " of resource collisions\n", pci_name(dev));
++			return -EINVAL;
++		}
++		if (r->flags & IORESOURCE_IO)
++			cmd |= PCI_COMMAND_IO;
++		if (r->flags & IORESOURCE_MEM)
++			cmd |= PCI_COMMAND_MEMORY;
++	}
++	if (cmd != old_cmd) {
++		printk("PCI: Enabling device %s (%04x -> %04x)\n",
++		       pci_name(dev), old_cmd, cmd);
++		pci_write_config_word(dev, PCI_COMMAND, cmd);
++	}
++	return 0;
++}
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/pci_32.c powerpc.git/arch/powerpc/kernel/pci_32.c
+--- linux-2.6.24/arch/powerpc/kernel/pci_32.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/pci_32.c	2008-01-28 20:25:49.000000000 +0100
+@@ -13,6 +13,7 @@
+ #include <linux/bootmem.h>
+ #include <linux/irq.h>
+ #include <linux/list.h>
++#include <linux/of.h>
+ 
+ #include <asm/processor.h>
+ #include <asm/io.h>
+@@ -32,19 +33,12 @@
+ #endif
+ 
+ unsigned long isa_io_base     = 0;
+-unsigned long isa_mem_base    = 0;
+ unsigned long pci_dram_offset = 0;
+ int pcibios_assign_bus_offset = 1;
+ 
+ void pcibios_make_OF_bus_map(void);
+ 
+-static int pci_relocate_bridge_resource(struct pci_bus *bus, int i);
+-static int probe_resource(struct pci_bus *parent, struct resource *pr,
+-			  struct resource *res, struct resource **conflict);
+-static void update_bridge_base(struct pci_bus *bus, int i);
+-static void pcibios_fixup_resources(struct pci_dev* dev);
+ static void fixup_broken_pcnet32(struct pci_dev* dev);
+-static int reparent_resources(struct resource *parent, struct resource *res);
+ static void fixup_cpc710_pci64(struct pci_dev* dev);
+ #ifdef CONFIG_PPC_OF
+ static u8* pci_to_OF_bus_map;
+@@ -53,7 +47,7 @@
+ /* By default, we don't re-assign bus numbers. We do this only on
+  * some pmacs
+  */
+-int pci_assign_all_buses;
++static int pci_assign_all_buses;
+ 
+ LIST_HEAD(hose_list);
+ 
+@@ -100,505 +94,6 @@
+ }
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CPC710_PCI64,	fixup_cpc710_pci64);
+ 
+-static void
+-pcibios_fixup_resources(struct pci_dev *dev)
+-{
+-	struct pci_controller* hose = (struct pci_controller *)dev->sysdata;
+-	int i;
+-	unsigned long offset;
+-
+-	if (!hose) {
+-		printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev));
+-		return;
+-	}
+-	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+-		struct resource *res = dev->resource + i;
+-		if (!res->flags)
+-			continue;
+-		if (res->end == 0xffffffff) {
+-			DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n",
+-			    pci_name(dev), i, (u64)res->start, (u64)res->end);
+-			res->end -= res->start;
+-			res->start = 0;
+-			res->flags |= IORESOURCE_UNSET;
+-			continue;
+-		}
+-		offset = 0;
+-		if (res->flags & IORESOURCE_MEM) {
+-			offset = hose->pci_mem_offset;
+-		} else if (res->flags & IORESOURCE_IO) {
+-			offset = (unsigned long) hose->io_base_virt
+-				- isa_io_base;
+-		}
+-		if (offset != 0) {
+-			res->start += offset;
+-			res->end += offset;
+-			DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n",
+-			    i, res->flags, pci_name(dev),
+-			    (u64)res->start - offset, (u64)res->start);
+-		}
+-	}
+-
+-	/* Call machine specific resource fixup */
+-	if (ppc_md.pcibios_fixup_resources)
+-		ppc_md.pcibios_fixup_resources(dev);
+-}
+-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID,		PCI_ANY_ID,			pcibios_fixup_resources);
+-
+-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+-			struct resource *res)
+-{
+-	unsigned long offset = 0;
+-	struct pci_controller *hose = dev->sysdata;
+-
+-	if (hose && res->flags & IORESOURCE_IO)
+-		offset = (unsigned long)hose->io_base_virt - isa_io_base;
+-	else if (hose && res->flags & IORESOURCE_MEM)
+-		offset = hose->pci_mem_offset;
+-	region->start = res->start - offset;
+-	region->end = res->end - offset;
+-}
+-EXPORT_SYMBOL(pcibios_resource_to_bus);
+-
+-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+-			     struct pci_bus_region *region)
+-{
+-	unsigned long offset = 0;
+-	struct pci_controller *hose = dev->sysdata;
+-
+-	if (hose && res->flags & IORESOURCE_IO)
+-		offset = (unsigned long)hose->io_base_virt - isa_io_base;
+-	else if (hose && res->flags & IORESOURCE_MEM)
+-		offset = hose->pci_mem_offset;
+-	res->start = region->start + offset;
+-	res->end = region->end + offset;
+-}
+-EXPORT_SYMBOL(pcibios_bus_to_resource);
+-
+-/*
+- * We need to avoid collisions with `mirrored' VGA ports
+- * and other strange ISA hardware, so we always want the
+- * addresses to be allocated in the 0x000-0x0ff region
+- * modulo 0x400.
+- *
+- * Why? Because some silly external IO cards only decode
+- * the low 10 bits of the IO address. The 0x00-0xff region
+- * is reserved for motherboard devices that decode all 16
+- * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+- * but we want to try to avoid allocating at 0x2900-0x2bff
+- * which might have be mirrored at 0x0100-0x03ff..
+- */
+-void pcibios_align_resource(void *data, struct resource *res,
+-				resource_size_t size, resource_size_t align)
+-{
+-	struct pci_dev *dev = data;
+-
+-	if (res->flags & IORESOURCE_IO) {
+-		resource_size_t start = res->start;
+-
+-		if (size > 0x100) {
+-			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+-			       " (%lld bytes)\n", pci_name(dev),
+-			       dev->resource - res, (unsigned long long)size);
+-		}
+-
+-		if (start & 0x300) {
+-			start = (start + 0x3ff) & ~0x3ff;
+-			res->start = start;
+-		}
+-	}
+-}
+-EXPORT_SYMBOL(pcibios_align_resource);
+-
+-/*
+- *  Handle resources of PCI devices.  If the world were perfect, we could
+- *  just allocate all the resource regions and do nothing more.  It isn't.
+- *  On the other hand, we cannot just re-allocate all devices, as it would
+- *  require us to know lots of host bridge internals.  So we attempt to
+- *  keep as much of the original configuration as possible, but tweak it
+- *  when it's found to be wrong.
+- *
+- *  Known BIOS problems we have to work around:
+- *	- I/O or memory regions not configured
+- *	- regions configured, but not enabled in the command register
+- *	- bogus I/O addresses above 64K used
+- *	- expansion ROMs left enabled (this may sound harmless, but given
+- *	  the fact the PCI specs explicitly allow address decoders to be
+- *	  shared between expansion ROMs and other resource regions, it's
+- *	  at least dangerous)
+- *
+- *  Our solution:
+- *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
+- *	    This gives us fixed barriers on where we can allocate.
+- *	(2) Allocate resources for all enabled devices.  If there is
+- *	    a collision, just mark the resource as unallocated. Also
+- *	    disable expansion ROMs during this step.
+- *	(3) Try to allocate resources for disabled devices.  If the
+- *	    resources were assigned correctly, everything goes well,
+- *	    if they weren't, they won't disturb allocation of other
+- *	    resources.
+- *	(4) Assign new addresses to resources which were either
+- *	    not configured at all or misconfigured.  If explicitly
+- *	    requested by the user, configure expansion ROM address
+- *	    as well.
+- */
+-
+-static void __init
+-pcibios_allocate_bus_resources(struct list_head *bus_list)
+-{
+-	struct pci_bus *bus;
+-	int i;
+-	struct resource *res, *pr;
+-
+-	/* Depth-First Search on bus tree */
+-	list_for_each_entry(bus, bus_list, node) {
+-		for (i = 0; i < 4; ++i) {
+-			if ((res = bus->resource[i]) == NULL || !res->flags
+-			    || res->start > res->end)
+-				continue;
+-			if (bus->parent == NULL)
+-				pr = (res->flags & IORESOURCE_IO)?
+-					&ioport_resource: &iomem_resource;
+-			else {
+-				pr = pci_find_parent_resource(bus->self, res);
+-				if (pr == res) {
+-					/* this happens when the generic PCI
+-					 * code (wrongly) decides that this
+-					 * bridge is transparent  -- paulus
+-					 */
+-					continue;
+-				}
+-			}
+-
+-			DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n",
+-			    (u64)res->start, (u64)res->end, res->flags, pr);
+-			if (pr) {
+-				if (request_resource(pr, res) == 0)
+-					continue;
+-				/*
+-				 * Must be a conflict with an existing entry.
+-				 * Move that entry (or entries) under the
+-				 * bridge resource and try again.
+-				 */
+-				if (reparent_resources(pr, res) == 0)
+-					continue;
+-			}
+-			printk(KERN_ERR "PCI: Cannot allocate resource region "
+-			       "%d of PCI bridge %d\n", i, bus->number);
+-			if (pci_relocate_bridge_resource(bus, i))
+-				bus->resource[i] = NULL;
+-		}
+-		pcibios_allocate_bus_resources(&bus->children);
+-	}
+-}
+-
+-/*
+- * Reparent resource children of pr that conflict with res
+- * under res, and make res replace those children.
+- */
+-static int __init
+-reparent_resources(struct resource *parent, struct resource *res)
+-{
+-	struct resource *p, **pp;
+-	struct resource **firstpp = NULL;
+-
+-	for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
+-		if (p->end < res->start)
+-			continue;
+-		if (res->end < p->start)
+-			break;
+-		if (p->start < res->start || p->end > res->end)
+-			return -1;	/* not completely contained */
+-		if (firstpp == NULL)
+-			firstpp = pp;
+-	}
+-	if (firstpp == NULL)
+-		return -1;	/* didn't find any conflicting entries? */
+-	res->parent = parent;
+-	res->child = *firstpp;
+-	res->sibling = *pp;
+-	*firstpp = res;
+-	*pp = NULL;
+-	for (p = res->child; p != NULL; p = p->sibling) {
+-		p->parent = res;
+-		DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
+-		    p->name, (u64)p->start, (u64)p->end, res->name);
+-	}
+-	return 0;
+-}
+-
+-/*
+- * A bridge has been allocated a range which is outside the range
+- * of its parent bridge, so it needs to be moved.
+- */
+-static int __init
+-pci_relocate_bridge_resource(struct pci_bus *bus, int i)
+-{
+-	struct resource *res, *pr, *conflict;
+-	unsigned long try, size;
+-	int j;
+-	struct pci_bus *parent = bus->parent;
+-
+-	if (parent == NULL) {
+-		/* shouldn't ever happen */
+-		printk(KERN_ERR "PCI: can't move host bridge resource\n");
+-		return -1;
+-	}
+-	res = bus->resource[i];
+-	if (res == NULL)
+-		return -1;
+-	pr = NULL;
+-	for (j = 0; j < 4; j++) {
+-		struct resource *r = parent->resource[j];
+-		if (!r)
+-			continue;
+-		if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
+-			continue;
+-		if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) {
+-			pr = r;
+-			break;
+-		}
+-		if (res->flags & IORESOURCE_PREFETCH)
+-			pr = r;
+-	}
+-	if (pr == NULL)
+-		return -1;
+-	size = res->end - res->start;
+-	if (pr->start > pr->end || size > pr->end - pr->start)
+-		return -1;
+-	try = pr->end;
+-	for (;;) {
+-		res->start = try - size;
+-		res->end = try;
+-		if (probe_resource(bus->parent, pr, res, &conflict) == 0)
+-			break;
+-		if (conflict->start <= pr->start + size)
+-			return -1;
+-		try = conflict->start - 1;
+-	}
+-	if (request_resource(pr, res)) {
+-		DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n",
+-		    (u64)res->start, (u64)res->end);
+-		return -1;		/* "can't happen" */
+-	}
+-	update_bridge_base(bus, i);
+-	printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n",
+-	       bus->number, i, (unsigned long long)res->start,
+-	       (unsigned long long)res->end);
+-	return 0;
+-}
+-
+-static int __init
+-probe_resource(struct pci_bus *parent, struct resource *pr,
+-	       struct resource *res, struct resource **conflict)
+-{
+-	struct pci_bus *bus;
+-	struct pci_dev *dev;
+-	struct resource *r;
+-	int i;
+-
+-	for (r = pr->child; r != NULL; r = r->sibling) {
+-		if (r->end >= res->start && res->end >= r->start) {
+-			*conflict = r;
+-			return 1;
+-		}
+-	}
+-	list_for_each_entry(bus, &parent->children, node) {
+-		for (i = 0; i < 4; ++i) {
+-			if ((r = bus->resource[i]) == NULL)
+-				continue;
+-			if (!r->flags || r->start > r->end || r == res)
+-				continue;
+-			if (pci_find_parent_resource(bus->self, r) != pr)
+-				continue;
+-			if (r->end >= res->start && res->end >= r->start) {
+-				*conflict = r;
+-				return 1;
+-			}
+-		}
+-	}
+-	list_for_each_entry(dev, &parent->devices, bus_list) {
+-		for (i = 0; i < 6; ++i) {
+-			r = &dev->resource[i];
+-			if (!r->flags || (r->flags & IORESOURCE_UNSET))
+-				continue;
+-			if (pci_find_parent_resource(dev, r) != pr)
+-				continue;
+-			if (r->end >= res->start && res->end >= r->start) {
+-				*conflict = r;
+-				return 1;
+-			}
+-		}
+-	}
+-	return 0;
+-}
+-
+-void __init
+-update_bridge_resource(struct pci_dev *dev, struct resource *res)
+-{
+-	u8 io_base_lo, io_limit_lo;
+-	u16 mem_base, mem_limit;
+-	u16 cmd;
+-	unsigned long start, end, off;
+-	struct pci_controller *hose = dev->sysdata;
+-
+-	if (!hose) {
+-		printk("update_bridge_base: no hose?\n");
+-		return;
+-	}
+-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+-	pci_write_config_word(dev, PCI_COMMAND,
+-			      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+-	if (res->flags & IORESOURCE_IO) {
+-		off = (unsigned long) hose->io_base_virt - isa_io_base;
+-		start = res->start - off;
+-		end = res->end - off;
+-		io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK;
+-		io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK;
+-		if (end > 0xffff)
+-			io_base_lo |= PCI_IO_RANGE_TYPE_32;
+-		else
+-			io_base_lo |= PCI_IO_RANGE_TYPE_16;
+-		pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
+-				start >> 16);
+-		pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
+-				end >> 16);
+-		pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo);
+-		pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo);
+-
+-	} else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH))
+-		   == IORESOURCE_MEM) {
+-		off = hose->pci_mem_offset;
+-		mem_base = ((res->start - off) >> 16) & PCI_MEMORY_RANGE_MASK;
+-		mem_limit = ((res->end - off) >> 16) & PCI_MEMORY_RANGE_MASK;
+-		pci_write_config_word(dev, PCI_MEMORY_BASE, mem_base);
+-		pci_write_config_word(dev, PCI_MEMORY_LIMIT, mem_limit);
+-
+-	} else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH))
+-		   == (IORESOURCE_MEM | IORESOURCE_PREFETCH)) {
+-		off = hose->pci_mem_offset;
+-		mem_base = ((res->start - off) >> 16) & PCI_PREF_RANGE_MASK;
+-		mem_limit = ((res->end - off) >> 16) & PCI_PREF_RANGE_MASK;
+-		pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, mem_base);
+-		pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, mem_limit);
+-
+-	} else {
+-		DBG(KERN_ERR "PCI: ugh, bridge %s res has flags=%lx\n",
+-		    pci_name(dev), res->flags);
+-	}
+-	pci_write_config_word(dev, PCI_COMMAND, cmd);
+-}
+-
+-static void __init
+-update_bridge_base(struct pci_bus *bus, int i)
+-{
+-	struct resource *res = bus->resource[i];
+-	struct pci_dev *dev = bus->self;
+-	update_bridge_resource(dev, res);
+-}
+-
+-static inline void alloc_resource(struct pci_dev *dev, int idx)
+-{
+-	struct resource *pr, *r = &dev->resource[idx];
+-
+-	DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n",
+-	    pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags);
+-	pr = pci_find_parent_resource(dev, r);
+-	if (!pr || request_resource(pr, r) < 0) {
+-		printk(KERN_ERR "PCI: Cannot allocate resource region %d"
+-		       " of device %s\n", idx, pci_name(dev));
+-		if (pr)
+-			DBG("PCI:  parent is %p: %016llx-%016llx (f=%lx)\n",
+-			    pr, (u64)pr->start, (u64)pr->end, pr->flags);
+-		/* We'll assign a new address later */
+-		r->flags |= IORESOURCE_UNSET;
+-		r->end -= r->start;
+-		r->start = 0;
+-	}
+-}
+-
+-static void __init
+-pcibios_allocate_resources(int pass)
+-{
+-	struct pci_dev *dev = NULL;
+-	int idx, disabled;
+-	u16 command;
+-	struct resource *r;
+-
+-	for_each_pci_dev(dev) {
+-		pci_read_config_word(dev, PCI_COMMAND, &command);
+-		for (idx = 0; idx < 6; idx++) {
+-			r = &dev->resource[idx];
+-			if (r->parent)		/* Already allocated */
+-				continue;
+-			if (!r->flags || (r->flags & IORESOURCE_UNSET))
+-				continue;	/* Not assigned at all */
+-			if (r->flags & IORESOURCE_IO)
+-				disabled = !(command & PCI_COMMAND_IO);
+-			else
+-				disabled = !(command & PCI_COMMAND_MEMORY);
+-			if (pass == disabled)
+-				alloc_resource(dev, idx);
+-		}
+-		if (pass)
+-			continue;
+-		r = &dev->resource[PCI_ROM_RESOURCE];
+-		if (r->flags & IORESOURCE_ROM_ENABLE) {
+-			/* Turn the ROM off, leave the resource region, but keep it unregistered. */
+-			u32 reg;
+-			DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
+-			r->flags &= ~IORESOURCE_ROM_ENABLE;
+-			pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+-			pci_write_config_dword(dev, dev->rom_base_reg,
+-					       reg & ~PCI_ROM_ADDRESS_ENABLE);
+-		}
+-	}
+-}
+-
+-static void __init
+-pcibios_assign_resources(void)
+-{
+-	struct pci_dev *dev = NULL;
+-	int idx;
+-	struct resource *r;
+-
+-	for_each_pci_dev(dev) {
+-		int class = dev->class >> 8;
+-
+-		/* Don't touch classless devices and host bridges */
+-		if (!class || class == PCI_CLASS_BRIDGE_HOST)
+-			continue;
+-
+-		for (idx = 0; idx < 6; idx++) {
+-			r = &dev->resource[idx];
+-
+-			/*
+-			 * We shall assign a new address to this resource,
+-			 * either because the BIOS (sic) forgot to do so
+-			 * or because we have decided the old address was
+-			 * unusable for some reason.
+-			 */
+-			if ((r->flags & IORESOURCE_UNSET) && r->end &&
+-			    (!ppc_md.pcibios_enable_device_hook ||
+-			     !ppc_md.pcibios_enable_device_hook(dev, 1))) {
+-				int rc;
+-
+-				r->flags &= ~IORESOURCE_UNSET;
+-				rc = pci_assign_resource(dev, idx);
+-				BUG_ON(rc);
+-			}
+-		}
+-
+-#if 0 /* don't assign ROMs */
+-		r = &dev->resource[PCI_ROM_RESOURCE];
+-		r->end -= r->start;
+-		r->start = 0;
+-		if (r->end)
+-			pci_assign_resource(dev, PCI_ROM_RESOURCE);
+-#endif
+-	}
+-}
+-
+ #ifdef CONFIG_PPC_OF
+ /*
+  * Functions below are used on OpenFirmware machines.
+@@ -619,7 +114,7 @@
+ 	} else
+ 		pci_to_OF_bus_map[pci_bus] = bus_range[0];
+ 
+-	for (node=node->child; node != 0;node = node->sibling) {
++	for_each_child_of_node(node, node) {
+ 		struct pci_dev* dev;
+ 		const unsigned int *class_code, *reg;
+ 	
+@@ -662,8 +157,8 @@
+ 
+ 	/* For each hose, we begin searching bridges */
+ 	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+-		struct device_node* node;	
+-		node = (struct device_node *)hose->arch_data;
++		struct device_node* node = hose->dn;
++
+ 		if (!node)
+ 			continue;
+ 		make_one_node_map(node, hose->first_busno);
+@@ -688,15 +183,18 @@
+ typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
+ 
+ static struct device_node*
+-scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
++scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void* data)
+ {
++	struct device_node *node;
+ 	struct device_node* sub_node;
+ 
+-	for (; node != 0;node = node->sibling) {
++	for_each_child_of_node(parent, node) {
+ 		const unsigned int *class_code;
+ 	
+-		if (filter(node, data))
++		if (filter(node, data)) {
++			of_node_put(node);
+ 			return node;
++		}
+ 
+ 		/* For PCI<->PCI bridges or CardBus bridges, we go down
+ 		 * Note: some OFs create a parent node "multifunc-device" as
+@@ -708,9 +206,11 @@
+ 			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
+ 			strcmp(node->name, "multifunc-device"))
+ 			continue;
+-		sub_node = scan_OF_pci_childs(node->child, filter, data);
+-		if (sub_node)
++		sub_node = scan_OF_pci_childs(node, filter, data);
++		if (sub_node) {
++			of_node_put(node);
+ 			return sub_node;
++		}
+ 	}
+ 	return NULL;
+ }
+@@ -718,11 +218,11 @@
+ static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
+ 					       unsigned int devfn)
+ {
+-	struct device_node *np = NULL;
++	struct device_node *np;
+ 	const u32 *reg;
+ 	unsigned int psize;
+ 
+-	while ((np = of_get_next_child(parent, np)) != NULL) {
++	for_each_child_of_node(parent, np) {
+ 		reg = of_get_property(np, "reg", &psize);
+ 		if (reg == NULL || psize < 4)
+ 			continue;
+@@ -742,7 +242,7 @@
+ 		struct pci_controller *hose = pci_bus_to_host(bus);
+ 		if (hose == NULL)
+ 			return NULL;
+-		return of_node_get(hose->arch_data);
++		return of_node_get(hose->dn);
+ 	}
+ 
+ 	/* not a root bus, we need to get our parent */
+@@ -812,9 +312,9 @@
+ 		return -ENODEV;
+ 	/* Make sure it's really a PCI device */
+ 	hose = pci_find_hose_for_OF_device(node);
+-	if (!hose || !hose->arch_data)
++	if (!hose || !hose->dn)
+ 		return -ENODEV;
+-	if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
++	if (!scan_OF_pci_childs(hose->dn,
+ 			find_OF_pci_device_filter, (void *)node))
+ 		return -ENODEV;
+ 	reg = of_get_property(node, "reg", NULL);
+@@ -843,120 +343,6 @@
+ }
+ EXPORT_SYMBOL(pci_device_from_OF_node);
+ 
+-void __init
+-pci_process_bridge_OF_ranges(struct pci_controller *hose,
+-			   struct device_node *dev, int primary)
+-{
+-	static unsigned int static_lc_ranges[256] __initdata;
+-	const unsigned int *dt_ranges;
+-	unsigned int *lc_ranges, *ranges, *prev, size;
+-	int rlen = 0, orig_rlen;
+-	int memno = 0;
+-	struct resource *res;
+-	int np, na = of_n_addr_cells(dev);
+-	np = na + 5;
+-
+-	/* First we try to merge ranges to fix a problem with some pmacs
+-	 * that can have more than 3 ranges, fortunately using contiguous
+-	 * addresses -- BenH
+-	 */
+-	dt_ranges = of_get_property(dev, "ranges", &rlen);
+-	if (!dt_ranges)
+-		return;
+-	/* Sanity check, though hopefully that never happens */
+-	if (rlen > sizeof(static_lc_ranges)) {
+-		printk(KERN_WARNING "OF ranges property too large !\n");
+-		rlen = sizeof(static_lc_ranges);
+-	}
+-	lc_ranges = static_lc_ranges;
+-	memcpy(lc_ranges, dt_ranges, rlen);
+-	orig_rlen = rlen;
+-
+-	/* Let's work on a copy of the "ranges" property instead of damaging
+-	 * the device-tree image in memory
+-	 */
+-	ranges = lc_ranges;
+-	prev = NULL;
+-	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+-		if (prev) {
+-			if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
+-				(prev[2] + prev[na+4]) == ranges[2] &&
+-				(prev[na+2] + prev[na+4]) == ranges[na+2]) {
+-				prev[na+4] += ranges[na+4];
+-				ranges[0] = 0;
+-				ranges += np;
+-				continue;
+-			}
+-		}
+-		prev = ranges;
+-		ranges += np;
+-	}
+-
+-	/*
+-	 * The ranges property is laid out as an array of elements,
+-	 * each of which comprises:
+-	 *   cells 0 - 2:	a PCI address
+-	 *   cells 3 or 3+4:	a CPU physical address
+-	 *			(size depending on dev->n_addr_cells)
+-	 *   cells 4+5 or 5+6:	the size of the range
+-	 */
+-	ranges = lc_ranges;
+-	rlen = orig_rlen;
+-	while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
+-		res = NULL;
+-		size = ranges[na+4];
+-		switch ((ranges[0] >> 24) & 0x3) {
+-		case 1:		/* I/O space */
+-			if (ranges[2] != 0)
+-				break;
+-			hose->io_base_phys = ranges[na+2];
+-			/* limit I/O space to 16MB */
+-			if (size > 0x01000000)
+-				size = 0x01000000;
+-			hose->io_base_virt = ioremap(ranges[na+2], size);
+-			if (primary)
+-				isa_io_base = (unsigned long) hose->io_base_virt;
+-			res = &hose->io_resource;
+-			res->flags = IORESOURCE_IO;
+-			res->start = ranges[2];
+-			DBG("PCI: IO 0x%llx -> 0x%llx\n",
+-			    (u64)res->start, (u64)res->start + size - 1);
+-			break;
+-		case 2:		/* memory space */
+-			memno = 0;
+-			if (ranges[1] == 0 && ranges[2] == 0
+-			    && ranges[na+4] <= (16 << 20)) {
+-				/* 1st 16MB, i.e. ISA memory area */
+-				if (primary)
+-					isa_mem_base = ranges[na+2];
+-				memno = 1;
+-			}
+-			while (memno < 3 && hose->mem_resources[memno].flags)
+-				++memno;
+-			if (memno == 0)
+-				hose->pci_mem_offset = ranges[na+2] - ranges[2];
+-			if (memno < 3) {
+-				res = &hose->mem_resources[memno];
+-				res->flags = IORESOURCE_MEM;
+-				if(ranges[0] & 0x40000000)
+-					res->flags |= IORESOURCE_PREFETCH;
+-				res->start = ranges[na+2];
+-				DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
+-				    (u64)res->start, (u64)res->start + size - 1);
+-			}
+-			break;
+-		}
+-		if (res != NULL) {
+-			res->name = dev->full_name;
+-			res->end = res->start + size - 1;
+-			res->parent = NULL;
+-			res->sibling = NULL;
+-			res->child = NULL;
+-		}
+-		ranges += np;
+-	}
+-}
+-
+ /* We create the "pci-OF-bus-map" property now so it appears in the
+  * /proc device tree
+  */
+@@ -986,219 +372,7 @@
+ }
+ #endif /* CONFIG_PPC_OF */
+ 
+-#ifdef CONFIG_PPC_PMAC
+-/*
+- * This set of routines checks for PCI<->PCI bridges that have closed
+- * IO resources and have child devices. It tries to re-open an IO
+- * window on them.
+- *
+- * This is a _temporary_ fix to workaround a problem with Apple's OF
+- * closing IO windows on P2P bridges when the OF drivers of cards
+- * below this bridge don't claim any IO range (typically ATI or
+- * Adaptec).
+- *
+- * A more complete fix would be to use drivers/pci/setup-bus.c, which
+- * involves a working pcibios_fixup_pbus_ranges(), some more care about
+- * ordering when creating the host bus resources, and maybe a few more
+- * minor tweaks
+- */
+-
+-/* Initialize bridges with base/limit values we have collected */
+-static void __init
+-do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
+-{
+-	struct pci_dev *bridge = bus->self;
+-	struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
+-	u32 l;
+-	u16 w;
+-	struct resource res;
+-
+-	if (bus->resource[0] == NULL)
+-		return;
+- 	res = *(bus->resource[0]);
+-
+-	DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));
+-	res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
+-	res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
+-	DBG("  IO window: %016llx-%016llx\n", res.start, res.end);
+-
+-	/* Set up the top and bottom of the PCI I/O segment for this bus. */
+-	pci_read_config_dword(bridge, PCI_IO_BASE, &l);
+-	l &= 0xffff000f;
+-	l |= (res.start >> 8) & 0x00f0;
+-	l |= res.end & 0xf000;
+-	pci_write_config_dword(bridge, PCI_IO_BASE, l);
+-
+-	if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
+-		l = (res.start >> 16) | (res.end & 0xffff0000);
+-		pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
+-	}
+-
+-	pci_read_config_word(bridge, PCI_COMMAND, &w);
+-	w |= PCI_COMMAND_IO;
+-	pci_write_config_word(bridge, PCI_COMMAND, w);
+-
+-#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
+-	if (enable_vga) {
+-		pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
+-		w |= PCI_BRIDGE_CTL_VGA;
+-		pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
+-	}
+-#endif
+-}
+-
+-/* This function is pretty basic and actually quite broken for the
+- * general case, it's enough for us right now though. It's supposed
+- * to tell us if we need to open an IO range at all or not and what
+- * size.
+- */
+-static int __init
+-check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
+-{
+-	struct pci_dev *dev;
+-	int	i;
+-	int	rc = 0;
+-
+-#define push_end(res, mask) do {		\
+-	BUG_ON((mask+1) & mask);		\
+-	res->end = (res->end + mask) | mask;	\
+-} while (0)
+-
+-	list_for_each_entry(dev, &bus->devices, bus_list) {
+-		u16 class = dev->class >> 8;
+-
+-		if (class == PCI_CLASS_DISPLAY_VGA ||
+-		    class == PCI_CLASS_NOT_DEFINED_VGA)
+-			*found_vga = 1;
+-		if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
+-			rc |= check_for_io_childs(dev->subordinate, res, found_vga);
+-		if (class == PCI_CLASS_BRIDGE_CARDBUS)
+-			push_end(res, 0xfff);
+-
+-		for (i=0; i<PCI_NUM_RESOURCES; i++) {
+-			struct resource *r;
+-			unsigned long r_size;
+-
+-			if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
+-			    && i >= PCI_BRIDGE_RESOURCES)
+-				continue;
+-			r = &dev->resource[i];
+-			r_size = r->end - r->start;
+-			if (r_size < 0xfff)
+-				r_size = 0xfff;
+-			if (r->flags & IORESOURCE_IO && (r_size) != 0) {
+-				rc = 1;
+-				push_end(res, r_size);
+-			}
+-		}
+-	}
+-
+-	return rc;
+-}
+-
+-/* Here we scan all P2P bridges of a given level that have a closed
+- * IO window. Note that the test for the presence of a VGA card should
+- * be improved to take into account already configured P2P bridges,
+- * currently, we don't see them and might end up configuring 2 bridges
+- * with VGA pass through enabled
+- */
+-static void __init
+-do_fixup_p2p_level(struct pci_bus *bus)
+-{
+-	struct pci_bus *b;
+-	int i, parent_io;
+-	int has_vga = 0;
+-
+-	for (parent_io=0; parent_io<4; parent_io++)
+-		if (bus->resource[parent_io]
+-		    && bus->resource[parent_io]->flags & IORESOURCE_IO)
+-			break;
+-	if (parent_io >= 4)
+-		return;
+-
+-	list_for_each_entry(b, &bus->children, node) {
+-		struct pci_dev *d = b->self;
+-		struct pci_controller* hose = (struct pci_controller *)d->sysdata;
+-		struct resource *res = b->resource[0];
+-		struct resource tmp_res;
+-		unsigned long max;
+-		int found_vga = 0;
+-
+-		memset(&tmp_res, 0, sizeof(tmp_res));
+-		tmp_res.start = bus->resource[parent_io]->start;
+-
+-		/* We don't let low addresses go through that closed P2P bridge, well,
+-		 * that may not be necessary but I feel safer that way
+-		 */
+-		if (tmp_res.start == 0)
+-			tmp_res.start = 0x1000;
+-	
+-		if (!list_empty(&b->devices) && res && res->flags == 0 &&
+-		    res != bus->resource[parent_io] &&
+-		    (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+-		    check_for_io_childs(b, &tmp_res, &found_vga)) {
+-			u8 io_base_lo;
+-
+-			printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
+-
+-			if (found_vga) {
+-				if (has_vga) {
+-					printk(KERN_WARNING "Skipping VGA, already active"
+-					    " on bus segment\n");
+-					found_vga = 0;
+-				} else
+-					has_vga = 1;
+-			}
+-			pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
+-
+-			if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
+-				max = ((unsigned long) hose->io_base_virt
+-					- isa_io_base) + 0xffffffff;
+-			else
+-				max = ((unsigned long) hose->io_base_virt
+-					- isa_io_base) + 0xffff;
+-
+-			*res = tmp_res;
+-			res->flags = IORESOURCE_IO;
+-			res->name = b->name;
+-		
+-			/* Find a resource in the parent where we can allocate */
+-			for (i = 0 ; i < 4; i++) {
+-				struct resource *r = bus->resource[i];
+-				if (!r)
+-					continue;
+-				if ((r->flags & IORESOURCE_IO) == 0)
+-					continue;
+-				DBG("Trying to allocate from %016llx, size %016llx from parent"
+-				    " res %d: %016llx -> %016llx\n",
+-					res->start, res->end, i, r->start, r->end);
+-			
+-				if (allocate_resource(r, res, res->end + 1, res->start, max,
+-				    res->end + 1, NULL, NULL) < 0) {
+-					DBG("Failed !\n");
+-					continue;
+-				}
+-				do_update_p2p_io_resource(b, found_vga);
+-				break;
+-			}
+-		}
+-		do_fixup_p2p_level(b);
+-	}
+-}
+-
+-static void
+-pcibios_fixup_p2p_bridges(void)
+-{
+-	struct pci_bus *b;
+-
+-	list_for_each_entry(b, &pci_root_buses, node)
+-		do_fixup_p2p_level(b);
+-}
+-
+-#endif /* CONFIG_PPC_PMAC */
+-
+-static int __init
+-pcibios_init(void)
++static int __init pcibios_init(void)
+ {
+ 	struct pci_controller *hose, *tmp;
+ 	struct pci_bus *bus;
+@@ -1206,6 +380,9 @@
+ 
+ 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
+ 
++	if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
++		pci_assign_all_buses = 1;
++
+ 	/* Scan all of the recorded PCI controllers.  */
+ 	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ 		if (pci_assign_all_buses)
+@@ -1213,9 +390,10 @@
+ 		hose->last_busno = 0xff;
+ 		bus = pci_scan_bus_parented(hose->parent, hose->first_busno,
+ 					    hose->ops, hose);
+-		if (bus)
++		if (bus) {
+ 			pci_bus_add_devices(bus);
+-		hose->last_busno = bus->subordinate;
++			hose->last_busno = bus->subordinate;
++		}
+ 		if (pci_assign_all_buses || next_busno <= hose->last_busno)
+ 			next_busno = hose->last_busno + pcibios_assign_bus_offset;
+ 	}
+@@ -1228,18 +406,8 @@
+ 	if (pci_assign_all_buses && have_of)
+ 		pcibios_make_OF_bus_map();
+ 
+-	/* Call machine dependent fixup */
+-	if (ppc_md.pcibios_fixup)
+-		ppc_md.pcibios_fixup();
+-
+-	/* Allocate and assign resources */
+-	pcibios_allocate_bus_resources(&pci_root_buses);
+-	pcibios_allocate_resources(0);
+-	pcibios_allocate_resources(1);
+-#ifdef CONFIG_PPC_PMAC
+-	pcibios_fixup_p2p_bridges();
+-#endif /* CONFIG_PPC_PMAC */
+-	pcibios_assign_resources();
++	/* Call common code to handle resource allocation */
++	pcibios_resource_survey();
+ 
+ 	/* Call machine dependent post-init code */
+ 	if (ppc_md.pcibios_after_init)
+@@ -1250,14 +418,14 @@
+ 
+ subsys_initcall(pcibios_init);
+ 
+-void pcibios_fixup_bus(struct pci_bus *bus)
++void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
+ {
+ 	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+ 	unsigned long io_offset;
+ 	struct resource *res;
+-	struct pci_dev *dev;
+ 	int i;
+ 
++	/* Hookup PHB resources */
+ 	io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+ 	if (bus->parent == NULL) {
+ 		/* This is a host bridge - fill in its resources */
+@@ -1272,8 +440,8 @@
+ 			res->end = IO_SPACE_LIMIT;
+ 			res->flags = IORESOURCE_IO;
+ 		}
+-		res->start += io_offset;
+-		res->end += io_offset;
++		res->start = (res->start + io_offset) & 0xffffffffu;
++		res->end = (res->end + io_offset) & 0xffffffffu;
+ 
+ 		for (i = 0; i < 3; ++i) {
+ 			res = &hose->mem_resources[i];
+@@ -1288,35 +456,6 @@
+ 			}
+ 			bus->resource[i+1] = res;
+ 		}
+-	} else {
+-		/* This is a subordinate bridge */
+-		pci_read_bridge_bases(bus);
+-
+-		for (i = 0; i < 4; ++i) {
+-			if ((res = bus->resource[i]) == NULL)
+-				continue;
+-			if (!res->flags || bus->self->transparent)
+-				continue;
+-			if (io_offset && (res->flags & IORESOURCE_IO)) {
+-				res->start += io_offset;
+-				res->end += io_offset;
+-			} else if (hose->pci_mem_offset
+-				   && (res->flags & IORESOURCE_MEM)) {
+-				res->start += hose->pci_mem_offset;
+-				res->end += hose->pci_mem_offset;
+-			}
+-		}
+-	}
+-
+-	/* Platform specific bus fixups */
+-	if (ppc_md.pcibios_fixup_bus)
+-		ppc_md.pcibios_fixup_bus(bus);
+-
+-	/* Read default IRQs and fixup if necessary */
+-	list_for_each_entry(dev, &bus->devices, bus_list) {
+-		pci_read_irq_line(dev);
+-		if (ppc_md.pci_irq_fixup)
+-			ppc_md.pci_irq_fixup(dev);
+ 	}
+ }
+ 
+@@ -1328,37 +467,6 @@
+ 	/* XXX FIXME - update OF device tree node interrupt property */
+ }
+ 
+-int pcibios_enable_device(struct pci_dev *dev, int mask)
+-{
+-	u16 cmd, old_cmd;
+-	int idx;
+-	struct resource *r;
+-
+-	if (ppc_md.pcibios_enable_device_hook)
+-		if (ppc_md.pcibios_enable_device_hook(dev, 0))
+-			return -EINVAL;
+-		
+-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+-	old_cmd = cmd;
+-	for (idx=0; idx<6; idx++) {
+-		r = &dev->resource[idx];
+-		if (r->flags & IORESOURCE_UNSET) {
+-			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
+-			return -EINVAL;
+-		}
+-		if (r->flags & IORESOURCE_IO)
+-			cmd |= PCI_COMMAND_IO;
+-		if (r->flags & IORESOURCE_MEM)
+-			cmd |= PCI_COMMAND_MEMORY;
+-	}
+-	if (cmd != old_cmd) {
+-		printk("PCI: Enabling device %s (%04x -> %04x)\n",
+-		       pci_name(dev), old_cmd, cmd);
+-		pci_write_config_word(dev, PCI_COMMAND, cmd);
+-	}
+-	return 0;
+-}
+-
+ static struct pci_controller*
+ pci_bus_to_hose(int bus)
+ {
+@@ -1381,17 +489,6 @@
+ 	struct pci_controller* hose;
+ 	long result = -EOPNOTSUPP;
+ 
+-	/* Argh ! Please forgive me for that hack, but that's the
+-	 * simplest way to get existing XFree to not lockup on some
+-	 * G5 machines... So when something asks for bus 0 io base
+-	 * (bus 0 is HT root), we return the AGP one instead.
+-	 */
+-#ifdef CONFIG_PPC_PMAC
+-	if (machine_is(powermac) && machine_is_compatible("MacRISC4"))
+-		if (bus == 0)
+-			bus = 0xf0;
+-#endif /* CONFIG_PPC_PMAC */
+-
+ 	hose = pci_bus_to_hose(bus);
+ 	if (!hose)
+ 		return -ENODEV;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/pci_64.c powerpc.git/arch/powerpc/kernel/pci_64.c
+--- linux-2.6.24/arch/powerpc/kernel/pci_64.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/pci_64.c	2008-01-28 20:25:49.000000000 +0100
+@@ -31,7 +31,6 @@
+ #include <asm/byteorder.h>
+ #include <asm/machdep.h>
+ #include <asm/ppc-pci.h>
+-#include <asm/firmware.h>
+ 
+ #ifdef DEBUG
+ #include <asm/udbg.h>
+@@ -41,10 +40,6 @@
+ #endif
+ 
+ unsigned long pci_probe_only = 1;
+-int pci_assign_all_buses = 0;
+-
+-static void fixup_resource(struct resource *res, struct pci_dev *dev);
+-static void do_bus_setup(struct pci_bus *bus);
+ 
+ /* pci_io_base -- the base address from which io bars are offsets.
+  * This is the lowest I/O base address (so bar values are always positive),
+@@ -70,139 +65,31 @@
+ }
+ EXPORT_SYMBOL(get_pci_dma_ops);
+ 
+-static void fixup_broken_pcnet32(struct pci_dev* dev)
+-{
+-	if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
+-		dev->vendor = PCI_VENDOR_ID_AMD;
+-		pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+-	}
+-}
+-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
+-
+-void  pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+-			      struct resource *res)
+-{
+-	unsigned long offset = 0;
+-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+-
+-	if (!hose)
+-		return;
+-
+-	if (res->flags & IORESOURCE_IO)
+-	        offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+-
+-	if (res->flags & IORESOURCE_MEM)
+-		offset = hose->pci_mem_offset;
+-
+-	region->start = res->start - offset;
+-	region->end = res->end - offset;
+-}
+ 
+-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+-			      struct pci_bus_region *region)
++int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+ {
+-	unsigned long offset = 0;
+-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+-
+-	if (!hose)
+-		return;
+-
+-	if (res->flags & IORESOURCE_IO)
+-	        offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+-
+-	if (res->flags & IORESOURCE_MEM)
+-		offset = hose->pci_mem_offset;
+-
+-	res->start = region->start + offset;
+-	res->end = region->end + offset;
++	return dma_set_mask(&dev->dev, mask);
+ }
+ 
+-#ifdef CONFIG_HOTPLUG
+-EXPORT_SYMBOL(pcibios_resource_to_bus);
+-EXPORT_SYMBOL(pcibios_bus_to_resource);
+-#endif
+-
+-/*
+- * We need to avoid collisions with `mirrored' VGA ports
+- * and other strange ISA hardware, so we always want the
+- * addresses to be allocated in the 0x000-0x0ff region
+- * modulo 0x400.
+- *
+- * Why? Because some silly external IO cards only decode
+- * the low 10 bits of the IO address. The 0x00-0xff region
+- * is reserved for motherboard devices that decode all 16
+- * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+- * but we want to try to avoid allocating at 0x2900-0x2bff
+- * which might have be mirrored at 0x0100-0x03ff..
+- */
+-void pcibios_align_resource(void *data, struct resource *res,
+-			    resource_size_t size, resource_size_t align)
++int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+ {
+-	struct pci_dev *dev = data;
+-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+-	resource_size_t start = res->start;
+-	unsigned long alignto;
+-
+-	if (res->flags & IORESOURCE_IO) {
+-	        unsigned long offset = (unsigned long)hose->io_base_virt -
+-					_IO_BASE;
+-		/* Make sure we start at our min on all hoses */
+-		if (start - offset < PCIBIOS_MIN_IO)
+-			start = PCIBIOS_MIN_IO + offset;
+-
+-		/*
+-		 * Put everything into 0x00-0xff region modulo 0x400
+-		 */
+-		if (start & 0x300)
+-			start = (start + 0x3ff) & ~0x3ff;
++	int rc;
+ 
+-	} else if (res->flags & IORESOURCE_MEM) {
+-		/* Make sure we start at our min on all hoses */
+-		if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM)
+-			start = PCIBIOS_MIN_MEM + hose->pci_mem_offset;
++	rc = dma_set_mask(&dev->dev, mask);
++	dev->dev.coherent_dma_mask = dev->dma_mask;
+ 
+-		/* Align to multiple of size of minimum base.  */
+-		alignto = max(0x1000UL, align);
+-		start = ALIGN(start, alignto);
+-	}
+-
+-	res->start = start;
++	return rc;
+ }
+ 
+-void __devinit pcibios_claim_one_bus(struct pci_bus *b)
++static void fixup_broken_pcnet32(struct pci_dev* dev)
+ {
+-	struct pci_dev *dev;
+-	struct pci_bus *child_bus;
+-
+-	list_for_each_entry(dev, &b->devices, bus_list) {
+-		int i;
+-
+-		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+-			struct resource *r = &dev->resource[i];
+-
+-			if (r->parent || !r->start || !r->flags)
+-				continue;
+-			pci_claim_resource(dev, i);
+-		}
++	if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
++		dev->vendor = PCI_VENDOR_ID_AMD;
++		pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+ 	}
+-
+-	list_for_each_entry(child_bus, &b->children, node)
+-		pcibios_claim_one_bus(child_bus);
+ }
+-#ifdef CONFIG_HOTPLUG
+-EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
+-#endif
+-
+-static void __init pcibios_claim_of_setup(void)
+-{
+-	struct pci_bus *b;
+-
+-	if (firmware_has_feature(FW_FEATURE_ISERIES))
+-		return;
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
+ 
+-	list_for_each_entry(b, &pci_root_buses, node)
+-		pcibios_claim_one_bus(b);
+-}
+ 
+ static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
+ {
+@@ -270,7 +157,6 @@
+ 		res->end = base + size - 1;
+ 		res->flags = flags;
+ 		res->name = pci_name(dev);
+-		fixup_resource(res, dev);
+ 	}
+ }
+ 
+@@ -339,16 +225,17 @@
+ EXPORT_SYMBOL(of_create_pci_dev);
+ 
+ void __devinit of_scan_bus(struct device_node *node,
+-				  struct pci_bus *bus)
++			   struct pci_bus *bus)
+ {
+-	struct device_node *child = NULL;
++	struct device_node *child;
+ 	const u32 *reg;
+ 	int reglen, devfn;
+ 	struct pci_dev *dev;
+ 
+ 	DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
+ 
+-	while ((child = of_get_next_child(node, child)) != NULL) {
++	/* Scan direct children */
++	for_each_child_of_node(node, child) {
+ 		DBG("  * %s\n", child->full_name);
+ 		reg = of_get_property(child, "reg", &reglen);
+ 		if (reg == NULL || reglen < 20)
+@@ -359,19 +246,26 @@
+ 		dev = of_create_pci_dev(child, bus, devfn);
+ 		if (!dev)
+ 			continue;
+-		DBG("dev header type: %x\n", dev->hdr_type);
++		DBG("    dev header type: %x\n", dev->hdr_type);
++	}
+ 
++	/* Ally all fixups */
++	pcibios_fixup_of_probed_bus(bus);
++
++	/* Now scan child busses */
++	list_for_each_entry(dev, &bus->devices, bus_list) {
+ 		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+-		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+-			of_scan_pci_bridge(child, dev);
++		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
++			struct device_node *child = pci_device_to_OF_node(dev);
++			if (dev)
++				of_scan_pci_bridge(child, dev);
++		}
+ 	}
+-
+-	do_bus_setup(bus);
+ }
+ EXPORT_SYMBOL(of_scan_bus);
+ 
+ void __devinit of_scan_pci_bridge(struct device_node *node,
+-			 	struct pci_dev *dev)
++				  struct pci_dev *dev)
+ {
+ 	struct pci_bus *bus;
+ 	const u32 *busrange, *ranges;
+@@ -441,7 +335,6 @@
+ 		res->start = of_read_number(&ranges[1], 2);
+ 		res->end = res->start + size - 1;
+ 		res->flags = flags;
+-		fixup_resource(res, dev);
+ 	}
+ 	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
+ 		bus->number);
+@@ -462,12 +355,12 @@
+ void __devinit scan_phb(struct pci_controller *hose)
+ {
+ 	struct pci_bus *bus;
+-	struct device_node *node = hose->arch_data;
++	struct device_node *node = hose->dn;
+ 	int i, mode;
+-	struct resource *res;
+ 
+-	DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
++	DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
+ 
++	/* Create an empty bus for the toplevel */
+ 	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
+ 	if (bus == NULL) {
+ 		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
+@@ -477,27 +370,27 @@
+ 	bus->secondary = hose->first_busno;
+ 	hose->bus = bus;
+ 
+-	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+-		pcibios_map_io_space(bus);
+-
+-	bus->resource[0] = res = &hose->io_resource;
+-	if (res->flags && request_resource(&ioport_resource, res)) {
+-		printk(KERN_ERR "Failed to request PCI IO region "
+-		       "on PCI domain %04x\n", hose->global_number);
+-		DBG("res->start = 0x%016lx, res->end = 0x%016lx\n",
+-		    res->start, res->end);
+-	}
++	/* Get some IO space for the new PHB */
++	pcibios_map_io_space(bus);
+ 
++	/* Wire up PHB bus resources */
++	DBG("PCI: PHB IO resource    = %016lx-%016lx [%lx]\n",
++	    hose->io_resource.start, hose->io_resource.end,
++	    hose->io_resource.flags);
++	bus->resource[0] = &hose->io_resource;
+ 	for (i = 0; i < 3; ++i) {
+-		res = &hose->mem_resources[i];
+-		bus->resource[i+1] = res;
+-		if (res->flags && request_resource(&iomem_resource, res))
+-			printk(KERN_ERR "Failed to request PCI memory region "
+-			       "on PCI domain %04x\n", hose->global_number);
+-	}
++		DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
++		    hose->mem_resources[i].start,
++		    hose->mem_resources[i].end,
++		    hose->mem_resources[i].flags);
++		bus->resource[i+1] = &hose->mem_resources[i];
++	}
++	DBG("PCI: PHB MEM offset     = %016lx\n", hose->pci_mem_offset);
++	DBG("PCI: PHB IO  offset     = %08lx\n",
++	    (unsigned long)hose->io_base_virt - _IO_BASE);
+ 
++	/* Get probe mode and perform scan */
+ 	mode = PCI_PROBE_NORMAL;
+-
+ 	if (node && ppc_md.pci_probe_mode)
+ 		mode = ppc_md.pci_probe_mode(bus);
+ 	DBG("    probe mode: %d\n", mode);
+@@ -514,15 +407,15 @@
+ {
+ 	struct pci_controller *hose, *tmp;
+ 
++	printk(KERN_INFO "PCI: Probing PCI hardware\n");
++
+ 	/* For now, override phys_mem_access_prot. If we need it,
+ 	 * later, we may move that initialization to each ppc_md
+ 	 */
+ 	ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
+ 
+-	if (firmware_has_feature(FW_FEATURE_ISERIES))
+-		iSeries_pcibios_init();
+-
+-	printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
++	if (pci_probe_only)
++		ppc_pci_flags |= PPC_PCI_PROBE_ONLY;
+ 
+ 	/* Scan all of the recorded PCI controllers.  */
+ 	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+@@ -530,19 +423,8 @@
+ 		pci_bus_add_devices(hose->bus);
+ 	}
+ 
+-	if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
+-		if (pci_probe_only)
+-			pcibios_claim_of_setup();
+-		else
+-			/* FIXME: `else' will be removed when
+-			   pci_assign_unassigned_resources() is able to work
+-			   correctly with [partially] allocated PCI tree. */
+-			pci_assign_unassigned_resources();
+-	}
+-
+-	/* Call machine dependent final fixup */
+-	if (ppc_md.pcibios_fixup)
+-		ppc_md.pcibios_fixup();
++	/* Call common code to handle resource allocation */
++	pcibios_resource_survey();
+ 
+ 	printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
+ 
+@@ -551,141 +433,6 @@
+ 
+ subsys_initcall(pcibios_init);
+ 
+-int pcibios_enable_device(struct pci_dev *dev, int mask)
+-{
+-	u16 cmd, oldcmd;
+-	int i;
+-
+-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+-	oldcmd = cmd;
+-
+-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+-		struct resource *res = &dev->resource[i];
+-
+-		/* Only set up the requested stuff */
+-		if (!(mask & (1<<i)))
+-			continue;
+-
+-		if (res->flags & IORESOURCE_IO)
+-			cmd |= PCI_COMMAND_IO;
+-		if (res->flags & IORESOURCE_MEM)
+-			cmd |= PCI_COMMAND_MEMORY;
+-	}
+-
+-	if (cmd != oldcmd) {
+-		printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n",
+-		       pci_name(dev), cmd);
+-                /* Enable the appropriate bits in the PCI command register.  */
+-		pci_write_config_word(dev, PCI_COMMAND, cmd);
+-	}
+-	return 0;
+-}
+-
+-/* Decide whether to display the domain number in /proc */
+-int pci_proc_domain(struct pci_bus *bus)
+-{
+-	if (firmware_has_feature(FW_FEATURE_ISERIES))
+-		return 0;
+-	else {
+-		struct pci_controller *hose = pci_bus_to_host(bus);
+-		return hose->buid != 0;
+-	}
+-}
+-
+-void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+-					    struct device_node *dev, int prim)
+-{
+-	const unsigned int *ranges;
+-	unsigned int pci_space;
+-	unsigned long size;
+-	int rlen = 0;
+-	int memno = 0;
+-	struct resource *res;
+-	int np, na = of_n_addr_cells(dev);
+-	unsigned long pci_addr, cpu_phys_addr;
+-
+-	np = na + 5;
+-
+-	/* From "PCI Binding to 1275"
+-	 * The ranges property is laid out as an array of elements,
+-	 * each of which comprises:
+-	 *   cells 0 - 2:	a PCI address
+-	 *   cells 3 or 3+4:	a CPU physical address
+-	 *			(size depending on dev->n_addr_cells)
+-	 *   cells 4+5 or 5+6:	the size of the range
+-	 */
+-	ranges = of_get_property(dev, "ranges", &rlen);
+-	if (ranges == NULL)
+-		return;
+-	hose->io_base_phys = 0;
+-	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+-		res = NULL;
+-		pci_space = ranges[0];
+-		pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
+-		cpu_phys_addr = of_translate_address(dev, &ranges[3]);
+-		size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
+-		ranges += np;
+-		if (size == 0)
+-			continue;
+-
+-		/* Now consume following elements while they are contiguous */
+-		while (rlen >= np * sizeof(unsigned int)) {
+-			unsigned long addr, phys;
+-
+-			if (ranges[0] != pci_space)
+-				break;
+-			addr = ((unsigned long)ranges[1] << 32) | ranges[2];
+-			phys = ranges[3];
+-			if (na >= 2)
+-				phys = (phys << 32) | ranges[4];
+-			if (addr != pci_addr + size ||
+-			    phys != cpu_phys_addr + size)
+-				break;
+-
+-			size += ((unsigned long)ranges[na+3] << 32)
+-				| ranges[na+4];
+-			ranges += np;
+-			rlen -= np * sizeof(unsigned int);
+-		}
+-
+-		switch ((pci_space >> 24) & 0x3) {
+-		case 1:		/* I/O space */
+-			hose->io_base_phys = cpu_phys_addr - pci_addr;
+-			/* handle from 0 to top of I/O window */
+-			hose->pci_io_size = pci_addr + size;
+-
+-			res = &hose->io_resource;
+-			res->flags = IORESOURCE_IO;
+-			res->start = pci_addr;
+-			DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number,
+-				    res->start, res->start + size - 1);
+-			break;
+-		case 2:		/* memory space */
+-			memno = 0;
+-			while (memno < 3 && hose->mem_resources[memno].flags)
+-				++memno;
+-
+-			if (memno == 0)
+-				hose->pci_mem_offset = cpu_phys_addr - pci_addr;
+-			if (memno < 3) {
+-				res = &hose->mem_resources[memno];
+-				res->flags = IORESOURCE_MEM;
+-				res->start = cpu_phys_addr;
+-				DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number,
+-					    res->start, res->start + size - 1);
+-			}
+-			break;
+-		}
+-		if (res != NULL) {
+-			res->name = dev->full_name;
+-			res->end = res->start + size - 1;
+-			res->parent = NULL;
+-			res->sibling = NULL;
+-			res->child = NULL;
+-		}
+-	}
+-}
+-
+ #ifdef CONFIG_HOTPLUG
+ 
+ int pcibios_unmap_io_space(struct pci_bus *bus)
+@@ -719,8 +466,7 @@
+ 	if (hose->io_base_alloc == 0)
+ 		return 0;
+ 
+-	DBG("IO unmapping for PHB %s\n",
+-	    ((struct device_node *)hose->arch_data)->full_name);
++	DBG("IO unmapping for PHB %s\n", hose->dn->full_name);
+ 	DBG("  alloc=0x%p\n", hose->io_base_alloc);
+ 
+ 	/* This is a PHB, we fully unmap the IO area */
+@@ -779,8 +525,7 @@
+ 	hose->io_base_virt = (void __iomem *)(area->addr +
+ 					      hose->io_base_phys - phys_page);
+ 
+-	DBG("IO mapping for PHB %s\n",
+-	    ((struct device_node *)hose->arch_data)->full_name);
++	DBG("IO mapping for PHB %s\n", hose->dn->full_name);
+ 	DBG("  phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
+ 	    hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
+ 	DBG("  size=0x%016lx (alloc=0x%016lx)\n",
+@@ -803,51 +548,13 @@
+ }
+ EXPORT_SYMBOL_GPL(pcibios_map_io_space);
+ 
+-static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
+-{
+-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+-	unsigned long offset;
+-
+-	if (res->flags & IORESOURCE_IO) {
+-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+-		res->start += offset;
+-		res->end += offset;
+-	} else if (res->flags & IORESOURCE_MEM) {
+-		res->start += hose->pci_mem_offset;
+-		res->end += hose->pci_mem_offset;
+-	}
+-}
+-
+-void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
+-					      struct pci_bus *bus)
+-{
+-	/* Update device resources.  */
+-	int i;
+-
+-	DBG("%s: Fixup resources:\n", pci_name(dev));
+-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+-		struct resource *res = &dev->resource[i];
+-		if (!res->flags)
+-			continue;
+-
+-		DBG("  0x%02x < %08lx:0x%016lx...0x%016lx\n",
+-		    i, res->flags, res->start, res->end);
+-
+-		fixup_resource(res, dev);
+-
+-		DBG("       > %08lx:0x%016lx...0x%016lx\n",
+-		    res->flags, res->start, res->end);
+-	}
+-}
+-EXPORT_SYMBOL(pcibios_fixup_device_resources);
+-
+ void __devinit pcibios_setup_new_device(struct pci_dev *dev)
+ {
+ 	struct dev_archdata *sd = &dev->dev.archdata;
+ 
+ 	sd->of_node = pci_device_to_OF_node(dev);
+ 
+-	DBG("PCI device %s OF node: %s\n", pci_name(dev),
++	DBG("PCI: device %s OF node: %s\n", pci_name(dev),
+ 	    sd->of_node ? sd->of_node->full_name : "<none>");
+ 
+ 	sd->dma_ops = pci_dma_ops;
+@@ -861,7 +568,7 @@
+ }
+ EXPORT_SYMBOL(pcibios_setup_new_device);
+ 
+-static void __devinit do_bus_setup(struct pci_bus *bus)
++void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
+ {
+ 	struct pci_dev *dev;
+ 
+@@ -870,42 +577,7 @@
+ 
+ 	list_for_each_entry(dev, &bus->devices, bus_list)
+ 		pcibios_setup_new_device(dev);
+-
+-	/* Read default IRQs and fixup if necessary */
+-	list_for_each_entry(dev, &bus->devices, bus_list) {
+-		pci_read_irq_line(dev);
+-		if (ppc_md.pci_irq_fixup)
+-			ppc_md.pci_irq_fixup(dev);
+-	}
+-}
+-
+-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+-{
+-	struct pci_dev *dev = bus->self;
+-	struct device_node *np;
+-
+-	np = pci_bus_to_OF_node(bus);
+-
+-	DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>");
+-
+-	if (dev && pci_probe_only &&
+-	    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+-		/* This is a subordinate bridge */
+-
+-		pci_read_bridge_bases(bus);
+-		pcibios_fixup_device_resources(dev, bus);
+-	}
+-
+-	do_bus_setup(bus);
+-
+-	if (!pci_probe_only)
+-		return;
+-
+-	list_for_each_entry(dev, &bus->devices, bus_list)
+-		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+-			pcibios_fixup_device_resources(dev, bus);
+ }
+-EXPORT_SYMBOL(pcibios_fixup_bus);
+ 
+ unsigned long pci_address_to_pio(phys_addr_t address)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/pci_dn.c powerpc.git/arch/powerpc/kernel/pci_dn.c
+--- linux-2.6.24/arch/powerpc/kernel/pci_dn.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/pci_dn.c	2008-01-28 20:25:49.000000000 +0100
+@@ -56,11 +56,6 @@
+ 		pdn->busno = (regs[0] >> 16) & 0xff;
+ 		pdn->devfn = (regs[0] >> 8) & 0xff;
+ 	}
+-	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+-		const u32 *busp = of_get_property(dn, "linux,subbus", NULL);
+-		if (busp)
+-			pdn->bussubno = *busp;
+-	}
+ 
+ 	pdn->pci_ext_config_space = (type && *type == 1);
+ 	return NULL;
+@@ -133,7 +128,7 @@
+  */
+ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
+ {
+-	struct device_node * dn = (struct device_node *) phb->arch_data;
++	struct device_node *dn = phb->dn;
+ 	struct pci_dn *pdn;
+ 
+ 	/* PHB nodes themselves must not match */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/ppc_ksyms.c powerpc.git/arch/powerpc/kernel/ppc_ksyms.c
+--- linux-2.6.24/arch/powerpc/kernel/ppc_ksyms.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/ppc_ksyms.c	2008-01-28 20:25:49.000000000 +0100
+@@ -59,6 +59,7 @@
+ extern int sys_sigreturn(struct pt_regs *regs);
+ 
+ EXPORT_SYMBOL(clear_pages);
++EXPORT_SYMBOL(copy_page);
+ EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
+ EXPORT_SYMBOL(DMA_MODE_READ);
+ EXPORT_SYMBOL(DMA_MODE_WRITE);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/prom.c powerpc.git/arch/powerpc/kernel/prom.c
+--- linux-2.6.24/arch/powerpc/kernel/prom.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/prom.c	2008-01-28 20:25:49.000000000 +0100
+@@ -583,6 +583,20 @@
+ 		      ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
+ }
+ 
++#ifdef CONFIG_PPC64
++static void __init check_cpu_slb_size(unsigned long node)
++{
++	u32 *slb_size_ptr;
++
++	slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL);
++	if (slb_size_ptr != NULL) {
++		mmu_slb_size = *slb_size_ptr;
++	}
++}
++#else
++#define check_cpu_slb_size(node) do { } while(0)
++#endif
++
+ static struct feature_property {
+ 	const char *name;
+ 	u32 min_value;
+@@ -600,6 +614,29 @@
+ #endif /* CONFIG_PPC64 */
+ };
+ 
++#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU)
++static inline void identical_pvr_fixup(unsigned long node)
++{
++	unsigned int pvr;
++	char *model = of_get_flat_dt_prop(node, "model", NULL);
++
++	/*
++	 * Since 440GR(x)/440EP(x) processors have the same pvr,
++	 * we check the node path and set bit 28 in the cur_cpu_spec
++	 * pvr for EP(x) processor version. This bit is always 0 in
++	 * the "real" pvr. Then we call identify_cpu again with
++	 * the new logical pvr to enable FPU support.
++	 */
++	if (model && strstr(model, "440EP")) {
++		pvr = cur_cpu_spec->pvr_value | 0x8;
++		identify_cpu(0, pvr);
++		DBG("Using logical pvr %x for %s\n", pvr, model);
++	}
++}
++#else
++#define identical_pvr_fixup(node) do { } while(0)
++#endif
++
+ static void __init check_cpu_feature_properties(unsigned long node)
+ {
+ 	unsigned long i;
+@@ -697,22 +734,13 @@
+ 		prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
+ 		if (prop && (*prop & 0xff000000) == 0x0f000000)
+ 			identify_cpu(0, *prop);
+-#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU)
+-		/*
+-		 * Since 440GR(x)/440EP(x) processors have the same pvr,
+-		 * we check the node path and set bit 28 in the cur_cpu_spec
+-		 * pvr for EP(x) processor version. This bit is always 0 in
+-		 * the "real" pvr. Then we call identify_cpu again with
+-		 * the new logical pvr to enable FPU support.
+-		 */
+-		if (strstr(uname, "440EP")) {
+-			identify_cpu(0, cur_cpu_spec->pvr_value | 0x8);
+-		}
+-#endif
++
++		identical_pvr_fixup(node);
+ 	}
+ 
+ 	check_cpu_feature_properties(node);
+ 	check_cpu_pa_features(node);
++	check_cpu_slb_size(node);
+ 
+ #ifdef CONFIG_PPC_PSERIES
+ 	if (nthreads > 1)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/prom_parse.c powerpc.git/arch/powerpc/kernel/prom_parse.c
+--- linux-2.6.24/arch/powerpc/kernel/prom_parse.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/prom_parse.c	2008-01-28 20:25:49.000000000 +0100
+@@ -273,7 +273,7 @@
+ #else
+ 			struct pci_controller *host;
+ 			host = pci_bus_to_host(pdev->bus);
+-			ppnode = host ? host->arch_data : NULL;
++			ppnode = host ? host->dn : NULL;
+ #endif
+ 			/* No node for host bridge ? give up */
+ 			if (ppnode == NULL)
+@@ -419,7 +419,7 @@
+ 
+ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+ 			    struct of_bus *pbus, u32 *addr,
+-			    int na, int ns, int pna)
++			    int na, int ns, int pna, const char *rprop)
+ {
+ 	const u32 *ranges;
+ 	unsigned int rlen;
+@@ -438,7 +438,7 @@
+ 	 * to translate addresses that aren't supposed to be translated in
+ 	 * the first place. --BenH.
+ 	 */
+-	ranges = of_get_property(parent, "ranges", &rlen);
++	ranges = of_get_property(parent, rprop, &rlen);
+ 	if (ranges == NULL || rlen == 0) {
+ 		offset = of_read_number(addr, na);
+ 		memset(addr, 0, pna * 4);
+@@ -481,7 +481,8 @@
+  * that can be mapped to a cpu physical address). This is not really specified
+  * that way, but this is traditionally the way IBM at least do things
+  */
+-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
++u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
++			   const char *rprop)
+ {
+ 	struct device_node *parent = NULL;
+ 	struct of_bus *bus, *pbus;
+@@ -540,7 +541,7 @@
+ 		    pbus->name, pna, pns, parent->full_name);
+ 
+ 		/* Apply bus translation */
+-		if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
++		if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+ 			break;
+ 
+ 		/* Complete the move up one level */
+@@ -556,8 +557,19 @@
+ 
+ 	return result;
+ }
++
++u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
++{
++	return __of_translate_address(dev, in_addr, "ranges");
++}
+ EXPORT_SYMBOL(of_translate_address);
+ 
++u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
++{
++	return __of_translate_address(dev, in_addr, "dma-ranges");
++}
++EXPORT_SYMBOL(of_translate_dma_address);
++
+ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+ 		    unsigned int *flags)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/rio.c powerpc.git/arch/powerpc/kernel/rio.c
+--- linux-2.6.24/arch/powerpc/kernel/rio.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/rio.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,52 @@
++/*
++ * RapidIO PPC32 support
++ *
++ * Copyright 2005 MontaVista Software, Inc.
++ * Matt Porter <mporter@kernel.crashing.org>
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/rio.h>
++
++#include <asm/rio.h>
++
++/**
++ * platform_rio_init - Do platform specific RIO init
++ *
++ * Any platform specific initialization of RapdIO
++ * hardware is done here as well as registration
++ * of any active master ports in the system.
++ */
++void __attribute__ ((weak))
++    platform_rio_init(void)
++{
++	printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
++}
++
++/**
++ * ppc_rio_init - Do PPC32 RIO init
++ *
++ * Calls platform-specific RIO init code and then calls
++ * rio_init_mports() to initialize any master ports that
++ * have been registered with the RIO subsystem.
++ */
++static int __init ppc_rio_init(void)
++{
++	printk(KERN_INFO "RIO: RapidIO init\n");
++
++	/* Platform specific initialization */
++	platform_rio_init();
++
++	/* Enumerate all registered ports */
++	rio_init_mports();
++
++	return 0;
++}
++
++subsys_initcall(ppc_rio_init);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/rtas_pci.c powerpc.git/arch/powerpc/kernel/rtas_pci.c
+--- linux-2.6.24/arch/powerpc/kernel/rtas_pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/rtas_pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -260,7 +260,7 @@
+ 
+ int __devinit rtas_setup_phb(struct pci_controller *phb)
+ {
+-	struct device_node *dev = phb->arch_data;
++	struct device_node *dev = phb->dn;
+ 
+ 	if (is_python(dev))
+ 		python_countermeasures(dev);
+@@ -280,10 +280,7 @@
+ 	struct pci_controller *phb;
+ 	struct device_node *root = of_find_node_by_path("/");
+ 
+-	for (node = of_get_next_child(root, NULL);
+-	     node != NULL;
+-	     node = of_get_next_child(root, node)) {
+-
++	for_each_child_of_node(root, node) {
+ 		if (node->type == NULL || (strcmp(node->type, "pci") != 0 &&
+ 					   strcmp(node->type, "pciex") != 0))
+ 			continue;
+@@ -311,10 +308,12 @@
+ 		if (prop)
+ 			pci_probe_only = *prop;
+ 
++#ifdef CONFIG_PPC32 /* Will be made generic soon */
+ 		prop = of_get_property(of_chosen,
+ 				"linux,pci-assign-all-buses", NULL);
+-		if (prop)
+-			pci_assign_all_buses = *prop;
++		if (prop && *prop)
++			ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
++#endif /* CONFIG_PPC32 */
+ 	}
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/setup-common.c powerpc.git/arch/powerpc/kernel/setup-common.c
+--- linux-2.6.24/arch/powerpc/kernel/setup-common.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/setup-common.c	2008-01-28 20:25:49.000000000 +0100
+@@ -33,6 +33,7 @@
+ #include <linux/serial.h>
+ #include <linux/serial_8250.h>
+ #include <linux/debugfs.h>
++#include <linux/percpu.h>
+ #include <asm/io.h>
+ #include <asm/prom.h>
+ #include <asm/processor.h>
+@@ -57,6 +58,7 @@
+ #include <asm/mmu.h>
+ #include <asm/lmb.h>
+ #include <asm/xmon.h>
++#include <asm/cputhreads.h>
+ 
+ #include "setup.h"
+ 
+@@ -327,6 +329,31 @@
+ 
+ #ifdef CONFIG_SMP
+ 
++int threads_per_core, threads_shift;
++cpumask_t threads_core_mask;
++
++static void __init cpu_init_thread_core_maps(int tpc)
++{
++	int i;
++
++	threads_per_core = tpc;
++	threads_core_mask = CPU_MASK_NONE;
++
++	/* This implementation only supports power of 2 number of threads
++	 * for simplicity and performance
++	 */
++	threads_shift = ilog2(tpc);
++	BUG_ON(tpc != (1 << threads_shift));
++
++	for (i = 0; i < tpc; i++)
++		cpu_set(i, threads_core_mask);
++
++	printk(KERN_INFO "CPU maps initialized for %d thread%s per core\n",
++	       tpc, tpc > 1 ? "s" : "");
++	printk(KERN_DEBUG " (thread shift is %d)\n", threads_shift);
++}
++
++
+ /**
+  * setup_cpu_maps - initialize the following cpu maps:
+  *                  cpu_possible_map
+@@ -350,22 +377,32 @@
+ {
+ 	struct device_node *dn = NULL;
+ 	int cpu = 0;
++	int nthreads = 1;
++
++	DBG("smp_setup_cpu_maps()\n");
+ 
+ 	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
+ 		const int *intserv;
+-		int j, len = sizeof(u32), nthreads = 1;
++		int j, len;
++
++		DBG("  * %s...\n", dn->full_name);
+ 
+ 		intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s",
+ 				&len);
+-		if (intserv)
++		if (intserv) {
+ 			nthreads = len / sizeof(int);
+-		else {
++			DBG("    ibm,ppc-interrupt-server#s -> %d threads\n",
++			    nthreads);
++		} else {
++			DBG("    no ibm,ppc-interrupt-server#s -> 1 thread\n");
+ 			intserv = of_get_property(dn, "reg", NULL);
+ 			if (!intserv)
+ 				intserv = &cpu;	/* assume logical == phys */
+ 		}
+ 
+ 		for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
++			DBG("    thread %d -> cpu %d (hard id %d)\n",
++			    j, cpu, intserv[j]);
+ 			cpu_set(cpu, cpu_present_map);
+ 			set_hard_smp_processor_id(cpu, intserv[j]);
+ 			cpu_set(cpu, cpu_possible_map);
+@@ -373,6 +410,12 @@
+ 		}
+ 	}
+ 
++	/* If no SMT supported, nthreads is forced to 1 */
++	if (!cpu_has_feature(CPU_FTR_SMT)) {
++		DBG("  SMT disabled ! nthreads forced to 1\n");
++		nthreads = 1;
++	}
++
+ #ifdef CONFIG_PPC64
+ 	/*
+ 	 * On pSeries LPAR, we need to know how many cpus
+@@ -395,7 +438,7 @@
+ 
+ 		/* Double maxcpus for processors which have SMT capability */
+ 		if (cpu_has_feature(CPU_FTR_SMT))
+-			maxcpus *= 2;
++			maxcpus *= nthreads;
+ 
+ 		if (maxcpus > NR_CPUS) {
+ 			printk(KERN_WARNING
+@@ -412,9 +455,16 @@
+ 	out:
+ 		of_node_put(dn);
+ 	}
+-
+ 	vdso_data->processorCount = num_present_cpus();
+ #endif /* CONFIG_PPC64 */
++
++        /* Initialize CPU <=> thread mapping/
++	 *
++	 * WARNING: We assume that the number of threads is the same for
++	 * every CPU in the system. If that is not the case, then some code
++	 * here will have to be reworked
++	 */
++	cpu_init_thread_core_maps(nthreads);
+ }
+ 
+ /*
+@@ -424,17 +474,19 @@
+  */
+ void __init smp_setup_cpu_sibling_map(void)
+ {
+-#if defined(CONFIG_PPC64)
+-	int cpu;
++#ifdef CONFIG_PPC64
++	int i, cpu, base;
+ 
+-	/*
+-	 * Do the sibling map; assume only two threads per processor.
+-	 */
+ 	for_each_possible_cpu(cpu) {
+-		cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
+-		if (cpu_has_feature(CPU_FTR_SMT))
+-			cpu_set(cpu ^ 0x1, per_cpu(cpu_sibling_map, cpu));
++		DBG("Sibling map for CPU %d:", cpu);
++		base = cpu_first_thread_in_core(cpu);
++		for (i = 0; i < threads_per_core; i++) {
++			cpu_set(base + i, per_cpu(cpu_sibling_map, cpu));
++			DBG(" %d", base + i);
++		}
++		DBG("\n");
+ 	}
++
+ #endif /* CONFIG_PPC64 */
+ }
+ #endif /* CONFIG_SMP */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/signal_32.c powerpc.git/arch/powerpc/kernel/signal_32.c
+--- linux-2.6.24/arch/powerpc/kernel/signal_32.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/signal_32.c	2008-01-28 20:25:49.000000000 +0100
+@@ -24,13 +24,12 @@
+ #include <linux/signal.h>
+ #include <linux/errno.h>
+ #include <linux/elf.h>
++#include <linux/ptrace.h>
+ #ifdef CONFIG_PPC64
+ #include <linux/syscalls.h>
+ #include <linux/compat.h>
+-#include <linux/ptrace.h>
+ #else
+ #include <linux/wait.h>
+-#include <linux/ptrace.h>
+ #include <linux/unistd.h>
+ #include <linux/stddef.h>
+ #include <linux/tty.h>
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/smp.c powerpc.git/arch/powerpc/kernel/smp.c
+--- linux-2.6.24/arch/powerpc/kernel/smp.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/smp.c	2008-01-28 20:25:49.000000000 +0100
+@@ -76,6 +76,8 @@
+ 
+ int smt_enabled_at_boot = 1;
+ 
++static int ipi_fail_ok;
++
+ static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
+ 
+ #ifdef CONFIG_PPC64
+@@ -181,12 +183,13 @@
+  * <wait> If true, wait (atomically) until function has completed on other CPUs.
+  * [RETURNS] 0 on success, else a negative status code. Does not return until
+  * remote CPUs are nearly ready to execute <<func>> or are or have executed.
++ * <map> is a cpu map of the cpus to send IPI to.
+  *
+  * You must not call this function with disabled interrupts or from a
+  * hardware interrupt handler or from a bottom half handler.
+  */
+-int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
+-			int wait, cpumask_t map)
++static int __smp_call_function_map(void (*func) (void *info), void *info,
++				   int nonatomic, int wait, cpumask_t map)
+ {
+ 	struct call_data_struct data;
+ 	int ret = -1, num_cpus;
+@@ -203,8 +206,6 @@
+ 	if (wait)
+ 		atomic_set(&data.finished, 0);
+ 
+-	spin_lock(&call_lock);
+-
+ 	/* remove 'self' from the map */
+ 	if (cpu_isset(smp_processor_id(), map))
+ 		cpu_clear(smp_processor_id(), map);
+@@ -231,7 +232,8 @@
+ 			printk("smp_call_function on cpu %d: other cpus not "
+ 				"responding (%d)\n", smp_processor_id(),
+ 				atomic_read(&data.started));
+-			debugger(NULL);
++			if (!ipi_fail_ok)
++				debugger(NULL);
+ 			goto out;
+ 		}
+ 	}
+@@ -258,14 +260,18 @@
+  out:
+ 	call_data = NULL;
+ 	HMT_medium();
+-	spin_unlock(&call_lock);
+ 	return ret;
+ }
+ 
+ static int __smp_call_function(void (*func)(void *info), void *info,
+ 			       int nonatomic, int wait)
+ {
+-	return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map);
++	int ret;
++	spin_lock(&call_lock);
++	ret =__smp_call_function_map(func, info, nonatomic, wait,
++				       cpu_online_map);
++	spin_unlock(&call_lock);
++	return ret;
+ }
+ 
+ int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
+@@ -278,8 +284,8 @@
+ }
+ EXPORT_SYMBOL(smp_call_function);
+ 
+-int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic,
+-			int wait)
++int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
++			     int nonatomic, int wait)
+ {
+ 	cpumask_t map = CPU_MASK_NONE;
+ 	int ret = 0;
+@@ -291,9 +297,11 @@
+ 		return -EINVAL;
+ 
+ 	cpu_set(cpu, map);
+-	if (cpu != get_cpu())
+-		ret = smp_call_function_map(func,info,nonatomic,wait,map);
+-	else {
++	if (cpu != get_cpu()) {
++		spin_lock(&call_lock);
++		ret = __smp_call_function_map(func, info, nonatomic, wait, map);
++		spin_unlock(&call_lock);
++	} else {
+ 		local_irq_disable();
+ 		func(info);
+ 		local_irq_enable();
+@@ -305,7 +313,22 @@
+ 
+ void smp_send_stop(void)
+ {
+-	__smp_call_function(stop_this_cpu, NULL, 1, 0);
++	int nolock;
++
++	/* It's OK to fail sending the IPI, since the alternative is to
++	 * be stuck forever waiting on the other CPU to take the interrupt.
++	 *
++	 * It's better to at least continue and go through reboot, since this
++	 * function is usually called at panic or reboot time in the first
++	 * place.
++	 */
++	ipi_fail_ok = 1;
++
++	/* Don't deadlock in case we got called through panic */
++	nolock = !spin_trylock(&call_lock);
++	__smp_call_function_map(stop_this_cpu, NULL, 1, 0, cpu_online_map);
++	if (!nolock)
++		spin_unlock(&call_lock);
+ }
+ 
+ void smp_call_function_interrupt(void)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/systbl_chk.c powerpc.git/arch/powerpc/kernel/systbl_chk.c
+--- linux-2.6.24/arch/powerpc/kernel/systbl_chk.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/systbl_chk.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,58 @@
++/*
++ * This file, when run through CPP produces a list of syscall numbers
++ * in the order of systbl.h.  That way we can check for gaps and syscalls
++ * that are out of order.
++ *
++ * Unfortunately, we cannot check for the correct ordering of entries
++ * using SYSX().
++ *
++ * Copyright © IBM Corporation
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <asm/unistd.h>
++
++#define SYSCALL(func)		__NR_##func
++#define COMPAT_SYS(func)	__NR_##func
++#define PPC_SYS(func)		__NR_##func
++#ifdef CONFIG_PPC64
++#define OLDSYS(func)		-1
++#define SYS32ONLY(func)		-1
++#else
++#define OLDSYS(func)		__NR_old##func
++#define SYS32ONLY(func)		__NR_##func
++#endif
++#define SYSX(f, f3264, f32)	-1
++
++#define SYSCALL_SPU(func)	SYSCALL(func)
++#define COMPAT_SYS_SPU(func)	COMPAT_SYS(func)
++#define PPC_SYS_SPU(func)	PPC_SYS(func)
++#define SYSX_SPU(f, f3264, f32)	SYSX(f, f3264, f32)
++
++/* Just insert a marker for ni_syscalls */
++#define	__NR_ni_syscall		-1
++
++/*
++ * These are the known exceptions.
++ * Hopefully, there will be no more.
++ */
++#define	__NR_llseek		__NR__llseek
++#undef	__NR_umount
++#define	__NR_umount		__NR_umount2
++#define	__NR_old_getrlimit	__NR_getrlimit
++#define	__NR_newstat		__NR_stat
++#define	__NR_newlstat		__NR_lstat
++#define	__NR_newfstat		__NR_fstat
++#define	__NR_newuname		__NR_uname
++#define	__NR_sysctl		__NR__sysctl
++#define __NR_olddebug_setcontext	__NR_sys_debug_setcontext
++
++/* We call sys_ugetrlimit for syscall number __NR_getrlimit */
++#define getrlimit		ugetrlimit
++
++START_TABLE
++#include <asm/systbl.h>
++END_TABLE __NR_syscalls
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/systbl_chk.sh powerpc.git/arch/powerpc/kernel/systbl_chk.sh
+--- linux-2.6.24/arch/powerpc/kernel/systbl_chk.sh	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/systbl_chk.sh	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,33 @@
++#!/bin/sh
++#
++# Just process the CPP output from systbl_chk.c and complain
++# if anything is out of order.
++#
++# Copyright © 2008 IBM Corporation
++#
++# 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.
++
++awk	'BEGIN { num = -1; }	# Ignore the beginning of the file
++	/^#/ { next; }
++	/^[ \t]*$/ { next; }
++	/^START_TABLE/ { num = 0; next; }
++	/^END_TABLE/ {
++		if (num != $2) {
++			printf "__NR_syscalls (%s) is not one more than the last syscall (%s)\n",
++				$2, num - 1;
++			exit(1);
++		}
++		num = -1;	# Ignore the rest of the file
++	}
++	{
++		if (num == -1) next;
++		if (($1 != -1) && ($1 != num)) {
++			printf "Syscall %s out of order (expected %s)\n",
++				$1, num;
++			exit(1);
++		};
++		num++;
++	}' "$1"
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/time.c powerpc.git/arch/powerpc/kernel/time.c
+--- linux-2.6.24/arch/powerpc/kernel/time.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/time.c	2008-01-28 20:25:49.000000000 +0100
+@@ -116,9 +116,12 @@
+        .features       = CLOCK_EVT_FEAT_ONESHOT,
+ };
+ 
+-static DEFINE_PER_CPU(struct clock_event_device, decrementers);
+-void init_decrementer_clockevent(void);
+-static DEFINE_PER_CPU(u64, decrementer_next_tb);
++struct decrementer_clock {
++	struct clock_event_device event;
++	u64 next_tb;
++};
++
++static DEFINE_PER_CPU(struct decrementer_clock, decrementers);
+ 
+ #ifdef CONFIG_PPC_ISERIES
+ static unsigned long __initdata iSeries_recal_titan;
+@@ -216,7 +219,11 @@
+  */
+ static u64 read_spurr(u64 purr)
+ {
+-	if (cpu_has_feature(CPU_FTR_SPURR))
++	/*
++	 * cpus without PURR won't have a SPURR
++	 * We already know the former when we use this, so tell gcc
++	 */
++	if (cpu_has_feature(CPU_FTR_PURR) && cpu_has_feature(CPU_FTR_SPURR))
+ 		return mfspr(SPRN_SPURR);
+ 	return purr;
+ }
+@@ -227,29 +234,30 @@
+  */
+ void account_system_vtime(struct task_struct *tsk)
+ {
+-	u64 now, nowscaled, delta, deltascaled;
++	u64 now, nowscaled, delta, deltascaled, sys_time;
+ 	unsigned long flags;
+ 
+ 	local_irq_save(flags);
+ 	now = read_purr();
+-	delta = now - get_paca()->startpurr;
+-	get_paca()->startpurr = now;
+ 	nowscaled = read_spurr(now);
++	delta = now - get_paca()->startpurr;
+ 	deltascaled = nowscaled - get_paca()->startspurr;
++	get_paca()->startpurr = now;
+ 	get_paca()->startspurr = nowscaled;
+ 	if (!in_interrupt()) {
+ 		/* deltascaled includes both user and system time.
+ 		 * Hence scale it based on the purr ratio to estimate
+ 		 * the system time */
++		sys_time = get_paca()->system_time;
+ 		if (get_paca()->user_time)
+-			deltascaled = deltascaled * get_paca()->system_time /
+-			     (get_paca()->system_time + get_paca()->user_time);
+-		delta += get_paca()->system_time;
++			deltascaled = deltascaled * sys_time /
++			     (sys_time + get_paca()->user_time);
++		delta += sys_time;
+ 		get_paca()->system_time = 0;
+ 	}
+ 	account_system_time(tsk, 0, delta);
+-	get_paca()->purrdelta = delta;
+ 	account_system_time_scaled(tsk, deltascaled);
++	get_paca()->purrdelta = delta;
+ 	get_paca()->spurrdelta = deltascaled;
+ 	local_irq_restore(flags);
+ }
+@@ -326,11 +334,9 @@
+ 	s64 stolen;
+ 	struct cpu_purr_data *pme;
+ 
+-	if (!cpu_has_feature(CPU_FTR_PURR))
+-		return;
+-	pme = &per_cpu(cpu_purr_data, smp_processor_id());
++	pme = &__get_cpu_var(cpu_purr_data);
+ 	if (!pme->initialized)
+-		return;		/* this can happen in early boot */
++		return;		/* !CPU_FTR_PURR or early in early boot */
+ 	tb = mftb();
+ 	purr = mfspr(SPRN_PURR);
+ 	stolen = (tb - pme->tb) - (purr - pme->purr);
+@@ -353,7 +359,7 @@
+ 	if (!cpu_has_feature(CPU_FTR_PURR))
+ 		return;
+ 	local_irq_save(flags);
+-	pme = &per_cpu(cpu_purr_data, smp_processor_id());
++	pme = &__get_cpu_var(cpu_purr_data);
+ 	pme->tb = mftb();
+ 	pme->purr = mfspr(SPRN_PURR);
+ 	pme->initialized = 1;
+@@ -556,8 +562,8 @@
+ void timer_interrupt(struct pt_regs * regs)
+ {
+ 	struct pt_regs *old_regs;
+-	int cpu = smp_processor_id();
+-	struct clock_event_device *evt = &per_cpu(decrementers, cpu);
++	struct decrementer_clock *decrementer =  &__get_cpu_var(decrementers);
++	struct clock_event_device *evt = &decrementer->event;
+ 	u64 now;
+ 
+ 	/* Ensure a positive value is written to the decrementer, or else
+@@ -570,9 +576,9 @@
+ #endif
+ 
+ 	now = get_tb_or_rtc();
+-	if (now < per_cpu(decrementer_next_tb, cpu)) {
++	if (now < decrementer->next_tb) {
+ 		/* not time for this event yet */
+-		now = per_cpu(decrementer_next_tb, cpu) - now;
++		now = decrementer->next_tb - now;
+ 		if (now <= DECREMENTER_MAX)
+ 			set_dec((int)now);
+ 		return;
+@@ -623,6 +629,45 @@
+ 	set_dec(ticks);
+ }
+ 
++#ifdef CONFIG_SUSPEND
++void generic_suspend_disable_irqs(void)
++{
++	preempt_disable();
++
++	/* Disable the decrementer, so that it doesn't interfere
++	 * with suspending.
++	 */
++
++	set_dec(0x7fffffff);
++	local_irq_disable();
++	set_dec(0x7fffffff);
++}
++
++void generic_suspend_enable_irqs(void)
++{
++	wakeup_decrementer();
++
++	local_irq_enable();
++	preempt_enable();
++}
++
++/* Overrides the weak version in kernel/power/main.c */
++void arch_suspend_disable_irqs(void)
++{
++	if (ppc_md.suspend_disable_irqs)
++		ppc_md.suspend_disable_irqs();
++	generic_suspend_disable_irqs();
++}
++
++/* Overrides the weak version in kernel/power/main.c */
++void arch_suspend_enable_irqs(void)
++{
++	generic_suspend_enable_irqs();
++	if (ppc_md.suspend_enable_irqs)
++		ppc_md.suspend_enable_irqs();
++}
++#endif
++
+ #ifdef CONFIG_SMP
+ void __init smp_space_timers(unsigned int max_cpus)
+ {
+@@ -811,7 +856,7 @@
+ static int decrementer_set_next_event(unsigned long evt,
+ 				      struct clock_event_device *dev)
+ {
+-	__get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt;
++	__get_cpu_var(decrementers).next_tb = get_tb_or_rtc() + evt;
+ 	set_dec(evt);
+ 	return 0;
+ }
+@@ -825,7 +870,7 @@
+ 
+ static void register_decrementer_clockevent(int cpu)
+ {
+-	struct clock_event_device *dec = &per_cpu(decrementers, cpu);
++	struct clock_event_device *dec = &per_cpu(decrementers, cpu).event;
+ 
+ 	*dec = decrementer_clockevent;
+ 	dec->cpumask = cpumask_of_cpu(cpu);
+@@ -836,7 +881,7 @@
+ 	clockevents_register_device(dec);
+ }
+ 
+-void init_decrementer_clockevent(void)
++static void __init init_decrementer_clockevent(void)
+ {
+ 	int cpu = smp_processor_id();
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/traps.c powerpc.git/arch/powerpc/kernel/traps.c
+--- linux-2.6.24/arch/powerpc/kernel/traps.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/traps.c	2008-01-28 20:25:49.000000000 +0100
+@@ -334,18 +334,25 @@
+ #define clear_single_step(regs)	((regs)->msr &= ~MSR_SE)
+ #endif
+ 
+-static int generic_machine_check_exception(struct pt_regs *regs)
++#if defined(CONFIG_4xx)
++int machine_check_4xx(struct pt_regs *regs)
+ {
+ 	unsigned long reason = get_mc_reason(regs);
+ 
+-#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
+ 	if (reason & ESR_IMCP) {
+ 		printk("Instruction");
+ 		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+ 	} else
+ 		printk("Data");
+ 	printk(" machine check in kernel mode.\n");
+-#elif defined(CONFIG_440A)
++
++	return 0;
++}
++
++int machine_check_440A(struct pt_regs *regs)
++{
++	unsigned long reason = get_mc_reason(regs);
++
+ 	printk("Machine check in kernel mode.\n");
+ 	if (reason & ESR_IMCP){
+ 		printk("Instruction Synchronous Machine Check exception\n");
+@@ -375,7 +382,13 @@
+ 		/* Clear MCSR */
+ 		mtspr(SPRN_MCSR, mcsr);
+ 	}
+-#elif defined (CONFIG_E500)
++	return 0;
++}
++#elif defined(CONFIG_E500)
++int machine_check_e500(struct pt_regs *regs)
++{
++	unsigned long reason = get_mc_reason(regs);
++
+ 	printk("Machine check in kernel mode.\n");
+ 	printk("Caused by (from MCSR=%lx): ", reason);
+ 
+@@ -403,7 +416,14 @@
+ 		printk("Bus - Instruction Parity Error\n");
+ 	if (reason & MCSR_BUS_RPERR)
+ 		printk("Bus - Read Parity Error\n");
+-#elif defined (CONFIG_E200)
++
++	return 0;
++}
++#elif defined(CONFIG_E200)
++int machine_check_e200(struct pt_regs *regs)
++{
++	unsigned long reason = get_mc_reason(regs);
++
+ 	printk("Machine check in kernel mode.\n");
+ 	printk("Caused by (from MCSR=%lx): ", reason);
+ 
+@@ -421,7 +441,14 @@
+ 		printk("Bus - Read Bus Error on data load\n");
+ 	if (reason & MCSR_BUS_WRERR)
+ 		printk("Bus - Write Bus Error on buffered store or cache line push\n");
+-#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
++
++	return 0;
++}
++#else
++int machine_check_generic(struct pt_regs *regs)
++{
++	unsigned long reason = get_mc_reason(regs);
++
+ 	printk("Machine check in kernel mode.\n");
+ 	printk("Caused by (from SRR1=%lx): ", reason);
+ 	switch (reason & 0x601F0000) {
+@@ -451,22 +478,26 @@
+ 	default:
+ 		printk("Unknown values in msr\n");
+ 	}
+-#endif /* CONFIG_4xx */
+-
+ 	return 0;
+ }
++#endif /* everything else */
+ 
+ void machine_check_exception(struct pt_regs *regs)
+ {
+ 	int recover = 0;
+ 
+-	/* See if any machine dependent calls */
++	/* See if any machine dependent calls. In theory, we would want
++	 * to call the CPU first, and call the ppc_md. one if the CPU
++	 * one returns a positive number. However there is existing code
++	 * that assumes the board gets a first chance, so let's keep it
++	 * that way for now and fix things later. --BenH.
++	 */
+ 	if (ppc_md.machine_check_exception)
+ 		recover = ppc_md.machine_check_exception(regs);
+-	else
+-		recover = generic_machine_check_exception(regs);
++	else if (cur_cpu_spec->machine_check)
++		recover = cur_cpu_spec->machine_check(regs);
+ 
+-	if (recover)
++	if (recover > 0)
+ 		return;
+ 
+ 	if (user_mode(regs)) {
+@@ -476,7 +507,12 @@
+ 	}
+ 
+ #if defined(CONFIG_8xx) && defined(CONFIG_PCI)
+-	/* the qspan pci read routines can cause machine checks -- Cort */
++	/* the qspan pci read routines can cause machine checks -- Cort
++	 *
++	 * yuck !!! that totally needs to go away ! There are better ways
++	 * to deal with that than having a wart in the mcheck handler.
++	 * -- BenH
++	 */
+ 	bad_page_fault(regs, regs->dar, SIGBUS);
+ 	return;
+ #endif
+@@ -622,6 +658,9 @@
+ #define INST_POPCNTB		0x7c0000f4
+ #define INST_POPCNTB_MASK	0xfc0007fe
+ 
++#define INST_ISEL		0x7c00001e
++#define INST_ISEL_MASK		0xfc00003e
++
+ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
+ {
+ 	u8 rT = (instword >> 21) & 0x1f;
+@@ -707,6 +746,23 @@
+ 	return 0;
+ }
+ 
++static int emulate_isel(struct pt_regs *regs, u32 instword)
++{
++	u8 rT = (instword >> 21) & 0x1f;
++	u8 rA = (instword >> 16) & 0x1f;
++	u8 rB = (instword >> 11) & 0x1f;
++	u8 BC = (instword >> 6) & 0x1f;
++	u8 bit;
++	unsigned long tmp;
++
++	tmp = (rA == 0) ? 0 : regs->gpr[rA];
++	bit = (regs->ccr >> (31 - BC)) & 0x1;
++
++	regs->gpr[rT] = bit ? tmp : regs->gpr[rB];
++
++	return 0;
++}
++
+ static int emulate_instruction(struct pt_regs *regs)
+ {
+ 	u32 instword;
+@@ -749,6 +805,11 @@
+ 		return emulate_popcntb_inst(regs, instword);
+ 	}
+ 
++	/* Emulate isel (Integer Select) instruction */
++	if ((instword & INST_ISEL_MASK) == INST_ISEL) {
++		return emulate_isel(regs, instword);
++	}
++
+ 	return -EINVAL;
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/udbg.c powerpc.git/arch/powerpc/kernel/udbg.c
+--- linux-2.6.24/arch/powerpc/kernel/udbg.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/udbg.c	2008-01-28 20:25:49.000000000 +0100
+@@ -54,9 +54,16 @@
+ #elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
+ 	/* PPC44x debug */
+ 	udbg_init_44x_as1();
++#elif defined(CONFIG_PPC_EARLY_DEBUG_40x)
++	/* PPC40x debug */
++	udbg_init_40x_realmode();
+ #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
+ 	udbg_init_cpm();
+ #endif
++
++#ifdef CONFIG_PPC_EARLY_DEBUG
++	console_loglevel = 10;
++#endif
+ }
+ 
+ /* udbg library, used by xmon et al */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/kernel/udbg_16550.c powerpc.git/arch/powerpc/kernel/udbg_16550.c
+--- linux-2.6.24/arch/powerpc/kernel/udbg_16550.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/kernel/udbg_16550.c	2008-01-28 20:25:49.000000000 +0100
+@@ -46,7 +46,7 @@
+ 
+ #define LCR_DLAB 0x80
+ 
+-static volatile struct NS16550 __iomem *udbg_comport;
++static struct NS16550 __iomem *udbg_comport;
+ 
+ static void udbg_550_putc(char c)
+ {
+@@ -117,7 +117,7 @@
+ {
+ 	unsigned int dll, dlm, divisor, prescaler, speed;
+ 	u8 old_lcr;
+-	volatile struct NS16550 __iomem *port = comport;
++	struct NS16550 __iomem *port = comport;
+ 
+ 	old_lcr = in_8(&port->lcr);
+ 
+@@ -162,7 +162,7 @@
+ 
+ void __init udbg_init_maple_realmode(void)
+ {
+-	udbg_comport = (volatile struct NS16550 __iomem *)0xf40003f8;
++	udbg_comport = (struct NS16550 __iomem *)0xf40003f8;
+ 
+ 	udbg_putc = udbg_maple_real_putc;
+ 	udbg_getc = NULL;
+@@ -184,7 +184,7 @@
+ 
+ void udbg_init_pas_realmode(void)
+ {
+-	udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8UL;
++	udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL;
+ 
+ 	udbg_putc = udbg_pas_real_putc;
+ 	udbg_getc = NULL;
+@@ -219,9 +219,42 @@
+ void __init udbg_init_44x_as1(void)
+ {
+ 	udbg_comport =
+-		(volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
++		(struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
+ 
+ 	udbg_putc = udbg_44x_as1_putc;
+ 	udbg_getc = udbg_44x_as1_getc;
+ }
+ #endif /* CONFIG_PPC_EARLY_DEBUG_44x */
++
++#ifdef CONFIG_PPC_EARLY_DEBUG_40x
++static void udbg_40x_real_putc(char c)
++{
++	if (udbg_comport) {
++		while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
++			/* wait for idle */;
++		real_writeb(c, &udbg_comport->thr); eieio();
++		if (c == '\n')
++			udbg_40x_real_putc('\r');
++	}
++}
++
++static int udbg_40x_real_getc(void)
++{
++	if (udbg_comport) {
++		while ((real_readb(&udbg_comport->lsr) & LSR_DR) == 0)
++			; /* wait for char */
++		return real_readb(&udbg_comport->rbr);
++	}
++	return -1;
++}
++
++void __init udbg_init_40x_realmode(void)
++{
++	udbg_comport = (struct NS16550 __iomem *)
++		CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR;
++
++	udbg_putc = udbg_40x_real_putc;
++	udbg_getc = udbg_40x_real_getc;
++	udbg_getc_poll = NULL;
++}
++#endif /* CONFIG_PPC_EARLY_DEBUG_40x */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/math-emu/op-4.h powerpc.git/arch/powerpc/math-emu/op-4.h
+--- linux-2.6.24/arch/powerpc/math-emu/op-4.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/math-emu/op-4.h	2008-01-28 20:25:49.000000000 +0100
+@@ -194,19 +194,39 @@
+   (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
+ 
+ #ifndef __FP_FRAC_ADD_4
+-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+-  (r0 = x0 + y0,							\
+-   r1 = x1 + y1 + (r0 < x0),						\
+-   r2 = x2 + y2 + (r1 < x1),						\
+-   r3 = x3 + y3 + (r2 < x2))
++#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)	\
++  do {								\
++    int _c1, _c2, _c3;						\
++    r0 = x0 + y0;						\
++    _c1 = r0 < x0;						\
++    r1 = x1 + y1;						\
++    _c2 = r1 < x1;						\
++    r1 += _c1;							\
++    _c2 |= r1 < _c1;						\
++    r2 = x2 + y2;						\
++    _c3 = r2 < x2;						\
++    r2 += _c2;							\
++    _c3 |= r2 < _c2;						\
++    r3 = x3 + y3 + _c3;						\
++  } while (0)
+ #endif
+ 
+ #ifndef __FP_FRAC_SUB_4
+-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+-  (r0 = x0 - y0,                                                        \
+-   r1 = x1 - y1 - (r0 > x0),                                            \
+-   r2 = x2 - y2 - (r1 > x1),                                            \
+-   r3 = x3 - y3 - (r2 > x2))
++#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)	\
++  do {								\
++    int _c1, _c2, _c3;						\
++    r0 = x0 - y0;						\
++    _c1 = r0 > x0;						\
++    r1 = x1 - y1;						\
++    _c2 = r1 > x1;						\
++    r1 -= _c1;							\
++    _c2 |= r1 > _c1;						\
++    r2 = x2 - y2;						\
++    _c3 = r2 > x2;						\
++    r2 -= _c2;							\
++    _c3 |= r2 > _c2;						\
++    r3 = x3 - y3 - _c3;						\
++  } while (0)
+ #endif
+ 
+ #ifndef __FP_FRAC_ADDI_4
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/mm/fault.c powerpc.git/arch/powerpc/mm/fault.c
+--- linux-2.6.24/arch/powerpc/mm/fault.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/mm/fault.c	2008-01-28 20:25:49.000000000 +0100
+@@ -167,10 +167,8 @@
+ 	if (notify_page_fault(regs))
+ 		return 0;
+ 
+-	if (trap == 0x300) {
+-		if (debugger_fault_handler(regs))
+-			return 0;
+-	}
++	if (unlikely(debugger_fault_handler(regs)))
++		return 0;
+ 
+ 	/* On a kernel SLB miss we can only check for a valid exception entry */
+ 	if (!user_mode(regs) && (address >= TASK_SIZE))
+@@ -189,7 +187,7 @@
+ 			return SIGSEGV;
+ 		/* in_atomic() in user mode is really bad,
+ 		   as is current->mm == NULL. */
+-		printk(KERN_EMERG "Page fault in user mode with"
++		printk(KERN_EMERG "Page fault in user mode with "
+ 		       "in_atomic() = %d mm = %p\n", in_atomic(), mm);
+ 		printk(KERN_EMERG "NIP = %lx  MSR = %lx\n",
+ 		       regs->nip, regs->msr);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/mm/fsl_booke_mmu.c powerpc.git/arch/powerpc/mm/fsl_booke_mmu.c
+--- linux-2.6.24/arch/powerpc/mm/fsl_booke_mmu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/mm/fsl_booke_mmu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -165,15 +165,15 @@
+ void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1,
+ 		unsigned long cam2)
+ {
+-	settlbcam(0, KERNELBASE, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0);
++	settlbcam(0, PAGE_OFFSET, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0);
+ 	tlbcam_index++;
+ 	if (cam1) {
+ 		tlbcam_index++;
+-		settlbcam(1, KERNELBASE+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0);
++		settlbcam(1, PAGE_OFFSET+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0);
+ 	}
+ 	if (cam2) {
+ 		tlbcam_index++;
+-		settlbcam(2, KERNELBASE+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0);
++		settlbcam(2, PAGE_OFFSET+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0);
+ 	}
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/mm/hash_utils_64.c powerpc.git/arch/powerpc/mm/hash_utils_64.c
+--- linux-2.6.24/arch/powerpc/mm/hash_utils_64.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/mm/hash_utils_64.c	2008-01-28 21:37:04.000000000 +0100
+@@ -96,6 +96,7 @@
+ int mmu_io_psize = MMU_PAGE_4K;
+ int mmu_kernel_ssize = MMU_SEGSIZE_256M;
+ int mmu_highuser_ssize = MMU_SEGSIZE_256M;
++u16 mmu_slb_size = 64;
+ #ifdef CONFIG_HUGETLB_PAGE
+ int mmu_huge_psize = MMU_PAGE_16M;
+ unsigned int HPAGE_SHIFT;
+@@ -368,18 +369,11 @@
+ 	 * on what is available
+ 	 */
+ 	if (mmu_psize_defs[MMU_PAGE_16M].shift)
+-		mmu_huge_psize = MMU_PAGE_16M;
++		set_huge_psize(MMU_PAGE_16M);
+ 	/* With 4k/4level pagetables, we can't (for now) cope with a
+ 	 * huge page size < PMD_SIZE */
+ 	else if (mmu_psize_defs[MMU_PAGE_1M].shift)
+-		mmu_huge_psize = MMU_PAGE_1M;
+-
+-	/* Calculate HPAGE_SHIFT and sanity check it */
+-	if (mmu_psize_defs[mmu_huge_psize].shift > MIN_HUGEPTE_SHIFT &&
+-	    mmu_psize_defs[mmu_huge_psize].shift < SID_SHIFT)
+-		HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift;
+-	else
+-		HPAGE_SHIFT = 0; /* No huge pages dude ! */
++		set_huge_psize(MMU_PAGE_1M);
+ #endif /* CONFIG_HUGETLB_PAGE */
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/mm/hugetlbpage.c powerpc.git/arch/powerpc/mm/hugetlbpage.c
+--- linux-2.6.24/arch/powerpc/mm/hugetlbpage.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/mm/hugetlbpage.c	2008-01-28 20:25:49.000000000 +0100
+@@ -24,18 +24,17 @@
+ #include <asm/cputable.h>
+ #include <asm/spu.h>
+ 
++#define HPAGE_SHIFT_64K	16
++#define HPAGE_SHIFT_16M	24
++
+ #define NUM_LOW_AREAS	(0x100000000UL >> SID_SHIFT)
+ #define NUM_HIGH_AREAS	(PGTABLE_RANGE >> HTLB_AREA_SHIFT)
+ 
+-#ifdef CONFIG_PPC_64K_PAGES
+-#define HUGEPTE_INDEX_SIZE	(PMD_SHIFT-HPAGE_SHIFT)
+-#else
+-#define HUGEPTE_INDEX_SIZE	(PUD_SHIFT-HPAGE_SHIFT)
+-#endif
+-#define PTRS_PER_HUGEPTE	(1 << HUGEPTE_INDEX_SIZE)
+-#define HUGEPTE_TABLE_SIZE	(sizeof(pte_t) << HUGEPTE_INDEX_SIZE)
++unsigned int hugepte_shift;
++#define PTRS_PER_HUGEPTE	(1 << hugepte_shift)
++#define HUGEPTE_TABLE_SIZE	(sizeof(pte_t) << hugepte_shift)
+ 
+-#define HUGEPD_SHIFT		(HPAGE_SHIFT + HUGEPTE_INDEX_SIZE)
++#define HUGEPD_SHIFT		(HPAGE_SHIFT + hugepte_shift)
+ #define HUGEPD_SIZE		(1UL << HUGEPD_SHIFT)
+ #define HUGEPD_MASK		(~(HUGEPD_SIZE-1))
+ 
+@@ -82,11 +81,35 @@
+ 	return 0;
+ }
+ 
++/* Base page size affects how we walk hugetlb page tables */
++#ifdef CONFIG_PPC_64K_PAGES
++#define hpmd_offset(pud, addr)		pmd_offset(pud, addr)
++#define hpmd_alloc(mm, pud, addr)	pmd_alloc(mm, pud, addr)
++#else
++static inline
++pmd_t *hpmd_offset(pud_t *pud, unsigned long addr)
++{
++	if (HPAGE_SHIFT == HPAGE_SHIFT_64K)
++		return pmd_offset(pud, addr);
++	else
++		return (pmd_t *) pud;
++}
++static inline
++pmd_t *hpmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr)
++{
++	if (HPAGE_SHIFT == HPAGE_SHIFT_64K)
++		return pmd_alloc(mm, pud, addr);
++	else
++		return (pmd_t *) pud;
++}
++#endif
++
+ /* Modelled after find_linux_pte() */
+ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+ {
+ 	pgd_t *pg;
+ 	pud_t *pu;
++	pmd_t *pm;
+ 
+ 	BUG_ON(get_slice_psize(mm, addr) != mmu_huge_psize);
+ 
+@@ -96,14 +119,9 @@
+ 	if (!pgd_none(*pg)) {
+ 		pu = pud_offset(pg, addr);
+ 		if (!pud_none(*pu)) {
+-#ifdef CONFIG_PPC_64K_PAGES
+-			pmd_t *pm;
+-			pm = pmd_offset(pu, addr);
++			pm = hpmd_offset(pu, addr);
+ 			if (!pmd_none(*pm))
+ 				return hugepte_offset((hugepd_t *)pm, addr);
+-#else
+-			return hugepte_offset((hugepd_t *)pu, addr);
+-#endif
+ 		}
+ 	}
+ 
+@@ -114,6 +132,7 @@
+ {
+ 	pgd_t *pg;
+ 	pud_t *pu;
++	pmd_t *pm;
+ 	hugepd_t *hpdp = NULL;
+ 
+ 	BUG_ON(get_slice_psize(mm, addr) != mmu_huge_psize);
+@@ -124,14 +143,9 @@
+ 	pu = pud_alloc(mm, pg, addr);
+ 
+ 	if (pu) {
+-#ifdef CONFIG_PPC_64K_PAGES
+-		pmd_t *pm;
+-		pm = pmd_alloc(mm, pu, addr);
++		pm = hpmd_alloc(mm, pu, addr);
+ 		if (pm)
+ 			hpdp = (hugepd_t *)pm;
+-#else
+-		hpdp = (hugepd_t *)pu;
+-#endif
+ 	}
+ 
+ 	if (! hpdp)
+@@ -158,7 +172,6 @@
+ 						 PGF_CACHENUM_MASK));
+ }
+ 
+-#ifdef CONFIG_PPC_64K_PAGES
+ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
+ 				   unsigned long addr, unsigned long end,
+ 				   unsigned long floor, unsigned long ceiling)
+@@ -191,7 +204,6 @@
+ 	pud_clear(pud);
+ 	pmd_free_tlb(tlb, pmd);
+ }
+-#endif
+ 
+ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
+ 				   unsigned long addr, unsigned long end,
+@@ -210,9 +222,15 @@
+ 			continue;
+ 		hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling);
+ #else
+-		if (pud_none(*pud))
+-			continue;
+-		free_hugepte_range(tlb, (hugepd_t *)pud);
++		if (HPAGE_SHIFT == HPAGE_SHIFT_64K) {
++			if (pud_none_or_clear_bad(pud))
++				continue;
++			hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling);
++		} else {
++			if (pud_none(*pud))
++				continue;
++			free_hugepte_range(tlb, (hugepd_t *)pud);
++		}
+ #endif
+ 	} while (pud++, addr = next, addr != end);
+ 
+@@ -526,6 +544,57 @@
+ 	return err;
+ }
+ 
++void set_huge_psize(int psize)
++{
++	/* Check that it is a page size supported by the hardware and
++	 * that it fits within pagetable limits. */
++	if (mmu_psize_defs[psize].shift && mmu_psize_defs[psize].shift < SID_SHIFT &&
++		(mmu_psize_defs[psize].shift > MIN_HUGEPTE_SHIFT ||
++			mmu_psize_defs[psize].shift == HPAGE_SHIFT_64K)) {
++		HPAGE_SHIFT = mmu_psize_defs[psize].shift;
++		mmu_huge_psize = psize;
++#ifdef CONFIG_PPC_64K_PAGES
++		hugepte_shift = (PMD_SHIFT-HPAGE_SHIFT);
++#else
++		if (HPAGE_SHIFT == HPAGE_SHIFT_64K)
++			hugepte_shift = (PMD_SHIFT-HPAGE_SHIFT);
++		else
++			hugepte_shift = (PUD_SHIFT-HPAGE_SHIFT);
++#endif
++
++	} else
++		HPAGE_SHIFT = 0;
++}
++
++static int __init hugepage_setup_sz(char *str)
++{
++	unsigned long long size;
++	int mmu_psize = -1;
++	int shift;
++
++	size = memparse(str, &str);
++
++	shift = __ffs(size);
++	switch (shift) {
++#ifndef CONFIG_PPC_64K_PAGES
++	case HPAGE_SHIFT_64K:
++		mmu_psize = MMU_PAGE_64K;
++		break;
++#endif
++	case HPAGE_SHIFT_16M:
++		mmu_psize = MMU_PAGE_16M;
++		break;
++	}
++
++	if (mmu_psize >=0 && mmu_psize_defs[mmu_psize].shift)
++		set_huge_psize(mmu_psize);
++	else
++		printk(KERN_WARNING "Invalid huge page size specified(%llu)\n", size);
++
++	return 1;
++}
++__setup("hugepagesz=", hugepage_setup_sz);
++
+ static void zero_ctor(struct kmem_cache *cache, void *addr)
+ {
+ 	memset(addr, 0, kmem_cache_size(cache));
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/mm/lmb.c powerpc.git/arch/powerpc/mm/lmb.c
+--- linux-2.6.24/arch/powerpc/mm/lmb.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/mm/lmb.c	2008-01-28 20:25:49.000000000 +0100
+@@ -342,3 +342,16 @@
+ 		}
+ 	}
+ }
++
++int __init lmb_is_reserved(unsigned long addr)
++{
++	int i;
++
++	for (i = 0; i < lmb.reserved.cnt; i++) {
++		unsigned long upper = lmb.reserved.region[i].base +
++				      lmb.reserved.region[i].size - 1;
++		if ((addr >= lmb.reserved.region[i].base) && (addr <= upper))
++			return 1;
++	}
++	return 0;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/mm/mem.c powerpc.git/arch/powerpc/mm/mem.c
+--- linux-2.6.24/arch/powerpc/mm/mem.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/mm/mem.c	2008-01-28 20:25:49.000000000 +0100
+@@ -213,15 +213,30 @@
+ 	 */
+ #ifdef CONFIG_HIGHMEM
+ 	free_bootmem_with_active_regions(0, total_lowmem >> PAGE_SHIFT);
++
++	/* reserve the sections we're already using */
++	for (i = 0; i < lmb.reserved.cnt; i++) {
++		unsigned long addr = lmb.reserved.region[i].base +
++				     lmb_size_bytes(&lmb.reserved, i) - 1;
++		if (addr < total_lowmem)
++			reserve_bootmem(lmb.reserved.region[i].base,
++					lmb_size_bytes(&lmb.reserved, i));
++		else if (lmb.reserved.region[i].base < total_lowmem) {
++			unsigned long adjusted_size = total_lowmem -
++				      lmb.reserved.region[i].base;
++			reserve_bootmem(lmb.reserved.region[i].base,
++					adjusted_size);
++		}
++	}
+ #else
+ 	free_bootmem_with_active_regions(0, max_pfn);
+-#endif
+ 
+ 	/* reserve the sections we're already using */
+ 	for (i = 0; i < lmb.reserved.cnt; i++)
+ 		reserve_bootmem(lmb.reserved.region[i].base,
+ 				lmb_size_bytes(&lmb.reserved, i));
+ 
++#endif
+ 	/* XXX need to clip this if using highmem? */
+ 	sparse_memory_present_with_active_regions(0);
+ 
+@@ -334,11 +349,13 @@
+ 		highmem_mapnr = total_lowmem >> PAGE_SHIFT;
+ 		for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
+ 			struct page *page = pfn_to_page(pfn);
+-
++			if (lmb_is_reserved(pfn << PAGE_SHIFT))
++				continue;
+ 			ClearPageReserved(page);
+ 			init_page_count(page);
+ 			__free_page(page);
+ 			totalhigh_pages++;
++			reservedpages--;
+ 		}
+ 		totalram_pages += totalhigh_pages;
+ 		printk(KERN_DEBUG "High memory: %luk\n",
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/mm/slb.c powerpc.git/arch/powerpc/mm/slb.c
+--- linux-2.6.24/arch/powerpc/mm/slb.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/mm/slb.c	2008-01-28 20:25:49.000000000 +0100
+@@ -256,6 +256,7 @@
+ 	static int slb_encoding_inited;
+ 	extern unsigned int *slb_miss_kernel_load_linear;
+ 	extern unsigned int *slb_miss_kernel_load_io;
++	extern unsigned int *slb_compare_rr_to_size;
+ 
+ 	/* Prepare our SLB miss handler based on our page size */
+ 	linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
+@@ -269,6 +270,8 @@
+ 				   SLB_VSID_KERNEL | linear_llp);
+ 		patch_slb_encoding(slb_miss_kernel_load_io,
+ 				   SLB_VSID_KERNEL | io_llp);
++		patch_slb_encoding(slb_compare_rr_to_size,
++				   mmu_slb_size);
+ 
+ 		DBG("SLB: linear  LLP = %04x\n", linear_llp);
+ 		DBG("SLB: io      LLP = %04x\n", io_llp);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/mm/slb_low.S powerpc.git/arch/powerpc/mm/slb_low.S
+--- linux-2.6.24/arch/powerpc/mm/slb_low.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/mm/slb_low.S	2008-01-28 20:25:49.000000000 +0100
+@@ -227,8 +227,9 @@
+ 
+ 7:	ld	r10,PACASTABRR(r13)
+ 	addi	r10,r10,1
+-	/* use a cpu feature mask if we ever change our slb size */
+-	cmpldi	r10,SLB_NUM_ENTRIES
++	/* This gets soft patched on boot. */
++_GLOBAL(slb_compare_rr_to_size)
++	cmpldi	r10,0
+ 
+ 	blt+	4f
+ 	li	r10,SLB_NUM_BOLTED
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/oprofile/op_model_cell.c powerpc.git/arch/powerpc/oprofile/op_model_cell.c
+--- linux-2.6.24/arch/powerpc/oprofile/op_model_cell.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/oprofile/op_model_cell.c	2008-01-28 20:25:49.000000000 +0100
+@@ -61,7 +61,7 @@
+ #define NUM_THREADS 2         /* number of physical threads in
+ 			       * physical processor
+ 			       */
+-#define NUM_TRACE_BUS_WORDS 4
++#define NUM_DEBUG_BUS_WORDS 4
+ #define NUM_INPUT_BUS_WORDS 2
+ 
+ #define MAX_SPU_COUNT 0xFFFFFF	/* maximum 24 bit LFSR value */
+@@ -169,7 +169,6 @@
+ 
+ static u32 ctr_enabled;
+ 
+-static unsigned char trace_bus[NUM_TRACE_BUS_WORDS];
+ static unsigned char input_bus[NUM_INPUT_BUS_WORDS];
+ 
+ /*
+@@ -298,7 +297,7 @@
+ 
+ 	p->signal_group = event / 100;
+ 	p->bus_word = bus_word;
+-	p->sub_unit = (unit_mask & 0x0000f000) >> 12;
++	p->sub_unit = GET_SUB_UNIT(unit_mask);
+ 
+ 	pm_regs.pm07_cntrl[ctr] = 0;
+ 	pm_regs.pm07_cntrl[ctr] |= PM07_CTR_COUNT_CYCLES(count_cycles);
+@@ -334,16 +333,16 @@
+ 		p->bit = signal_bit;
+ 	}
+ 
+-	for (i = 0; i < NUM_TRACE_BUS_WORDS; i++) {
++	for (i = 0; i < NUM_DEBUG_BUS_WORDS; i++) {
+ 		if (bus_word & (1 << i)) {
+ 			pm_regs.debug_bus_control |=
+-			    (bus_type << (31 - (2 * i) + 1));
++			    (bus_type << (30 - (2 * i)));
+ 
+ 			for (j = 0; j < NUM_INPUT_BUS_WORDS; j++) {
+ 				if (input_bus[j] == 0xff) {
+ 					input_bus[j] = i;
+ 					pm_regs.group_control |=
+-					    (i << (31 - i));
++					    (i << (30 - (2 * j)));
+ 
+ 					break;
+ 				}
+@@ -450,6 +449,12 @@
+ 	hdw_thread = 1 ^ hdw_thread;
+ 	next_hdw_thread = hdw_thread;
+ 
++	pm_regs.group_control = 0;
++	pm_regs.debug_bus_control = 0;
++
++	for (i = 0; i < NUM_INPUT_BUS_WORDS; i++)
++		input_bus[i] = 0xff;
++
+ 	/*
+ 	 * There are some per thread events.  Must do the
+ 	 * set event, for the thread that is being started
+@@ -619,9 +624,6 @@
+ 		pmc_cntrl[1][i].vcntr = i;
+ 	}
+ 
+-	for (i = 0; i < NUM_TRACE_BUS_WORDS; i++)
+-		trace_bus[i] = 0xff;
+-
+ 	for (i = 0; i < NUM_INPUT_BUS_WORDS; i++)
+ 		input_bus[i] = 0xff;
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/40x/Kconfig powerpc.git/arch/powerpc/platforms/40x/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/40x/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/40x/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -14,28 +14,34 @@
+ #	help
+ #	  This option enables support for the CPCI405 board.
+ 
+-#config EP405
+-#	bool "EP405/EP405PC"
+-#	depends on 40x
+-#	default n
+-#	select 405GP
+-#	help
+-#	  This option enables support for the EP405/EP405PC boards.
+-
+-#config EP405PC
+-#	bool "EP405PC Support"
+-#	depends on EP405
+-#	default y
+-#	help
+-#	  This option enables support for the extra features of the EP405PC board.
++config EP405
++	bool "EP405/EP405PC"
++	depends on 40x
++	default n
++	select 405GP
++	select PCI
++	help
++	  This option enables support for the EP405/EP405PC boards.
+ 
+ config KILAUEA
+ 	bool "Kilauea"
+ 	depends on 40x
+ 	default n
++	select 405EX
++	select PPC4xx_PCI_EXPRESS
+ 	help
+ 	  This option enables support for the AMCC PPC405EX evaluation board.
+ 
++config MAKALU
++	bool "Makalu"
++	depends on 40x
++	default n
++	select 405EX
++	select PCI
++	select PPC4xx_PCI_EXPRESS
++	help
++	  This option enables support for the AMCC PPC405EX board.
++
+ #config REDWOOD_5
+ #	bool "Redwood-5"
+ #	depends on 40x
+@@ -65,6 +71,7 @@
+ 	depends on 40x
+ 	default y
+ 	select 405GP
++	select PCI
+ 	help
+ 	  This option enables support for the IBM PPC405GP evaluation board.
+ 
+@@ -105,6 +112,11 @@
+ config 405EP
+ 	bool
+ 
++config 405EX
++	bool
++	select IBM_NEW_EMAC_EMAC4
++	select IBM_NEW_EMAC_RGMII
++
+ config 405GPR
+ 	bool
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/40x/Makefile powerpc.git/arch/powerpc/platforms/40x/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/40x/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/40x/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -1,3 +1,5 @@
+ obj-$(CONFIG_KILAUEA)				+= kilauea.o
++obj-$(CONFIG_MAKALU)				+= makalu.o
+ obj-$(CONFIG_WALNUT)				+= walnut.o
+ obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD)	+= virtex.o
++obj-$(CONFIG_EP405)				+= ep405.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/40x/ep405.c powerpc.git/arch/powerpc/platforms/40x/ep405.c
+--- linux-2.6.24/arch/powerpc/platforms/40x/ep405.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/40x/ep405.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,123 @@
++/*
++ * Architecture- / platform-specific boot-time initialization code for
++ * IBM PowerPC 4xx based boards. Adapted from original
++ * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
++ * <dan@net4x.com>.
++ *
++ * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
++ *
++ * Rewritten and ported to the merged powerpc tree:
++ * Copyright 2007 IBM Corporation
++ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
++ *
++ * Adapted to EP405 by Ben. Herrenschmidt <benh@kernel.crashing.org>
++ *
++ * TODO: Wire up the PCI IRQ mux and the southbridge interrupts
++ *
++ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
++ * the terms of the GNU General Public License version 2.  This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ */
++
++#include <linux/init.h>
++#include <linux/of_platform.h>
++
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++#include <asm/time.h>
++#include <asm/uic.h>
++#include <asm/pci-bridge.h>
++
++static struct device_node *bcsr_node;
++static void __iomem *bcsr_regs;
++
++/* BCSR registers  */
++#define BCSR_ID			0
++#define BCSR_PCI_CTRL	       	1
++#define BCSR_FLASH_NV_POR_CTRL	2
++#define BCSR_FENET_UART_CTRL	3
++#define BCSR_PCI_IRQ		4
++#define BCSR_XIRQ_SELECT	5
++#define BCSR_XIRQ_ROUTING	6
++#define BCSR_XIRQ_STATUS	7
++#define BCSR_XIRQ_STATUS2	8
++#define BCSR_SW_STAT_LED_CTRL	9
++#define BCSR_GPIO_IRQ_PAR_CTRL	10
++/* there's more, can't be bothered typing them tho */
++
++
++static __initdata struct of_device_id ep405_of_bus[] = {
++	{ .compatible = "ibm,plb3", },
++	{ .compatible = "ibm,opb", },
++	{ .compatible = "ibm,ebc", },
++	{},
++};
++
++static int __init ep405_device_probe(void)
++{
++	of_platform_bus_probe(NULL, ep405_of_bus, NULL);
++
++	return 0;
++}
++machine_device_initcall(ep405, ep405_device_probe);
++
++static void __init ep405_init_bcsr(void)
++{
++	const u8 *irq_routing;
++	int i;
++
++	/* Find the bloody thing & map it */
++	bcsr_node = of_find_compatible_node(NULL, NULL, "ep405-bcsr");
++	if (bcsr_node == NULL) {
++		printk(KERN_ERR "EP405 BCSR not found !\n");
++		return;
++	}
++	bcsr_regs = of_iomap(bcsr_node, 0);
++	if (bcsr_regs == NULL) {
++		printk(KERN_ERR "EP405 BCSR failed to map !\n");
++		return;
++	}
++
++	/* Get the irq-routing property and apply the routing to the CPLD */
++	irq_routing = of_get_property(bcsr_node, "irq-routing", NULL);
++	if (irq_routing == NULL)
++		return;
++	for (i = 0; i < 16; i++) {
++		u8 irq = irq_routing[i];
++		out_8(bcsr_regs + BCSR_XIRQ_SELECT, i);
++		out_8(bcsr_regs + BCSR_XIRQ_ROUTING, irq);
++	}
++	in_8(bcsr_regs + BCSR_XIRQ_SELECT);
++	mb();
++	out_8(bcsr_regs + BCSR_GPIO_IRQ_PAR_CTRL, 0xfe);
++}
++
++static void __init ep405_setup_arch(void)
++{
++	/* Find & init the BCSR CPLD */
++	ep405_init_bcsr();
++
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++}
++
++static int __init ep405_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++
++	if (!of_flat_dt_is_compatible(root, "ep405"))
++		return 0;
++
++	return 1;
++}
++
++define_machine(ep405) {
++	.name			= "EP405",
++	.probe			= ep405_probe,
++	.setup_arch		= ep405_setup_arch,
++	.progress		= udbg_progress,
++	.init_IRQ		= uic_init_tree,
++	.get_irq		= uic_get_irq,
++	.calibrate_decr		= generic_calibrate_decr,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/40x/kilauea.c powerpc.git/arch/powerpc/platforms/40x/kilauea.c
+--- linux-2.6.24/arch/powerpc/platforms/40x/kilauea.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/40x/kilauea.c	2008-01-28 20:25:49.000000000 +0100
+@@ -19,8 +19,9 @@
+ #include <asm/udbg.h>
+ #include <asm/time.h>
+ #include <asm/uic.h>
++#include <asm/pci-bridge.h>
+ 
+-static struct of_device_id kilauea_of_bus[] = {
++static __initdata struct of_device_id kilauea_of_bus[] = {
+ 	{ .compatible = "ibm,plb4", },
+ 	{ .compatible = "ibm,opb", },
+ 	{ .compatible = "ibm,ebc", },
+@@ -29,14 +30,11 @@
+ 
+ static int __init kilauea_device_probe(void)
+ {
+-	if (!machine_is(kilauea))
+-		return 0;
+-
+ 	of_platform_bus_probe(NULL, kilauea_of_bus, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(kilauea_device_probe);
++machine_device_initcall(kilauea, kilauea_device_probe);
+ 
+ static int __init kilauea_probe(void)
+ {
+@@ -45,6 +43,8 @@
+ 	if (!of_flat_dt_is_compatible(root, "amcc,kilauea"))
+ 		return 0;
+ 
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
+ 	return 1;
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/40x/makalu.c powerpc.git/arch/powerpc/platforms/40x/makalu.c
+--- linux-2.6.24/arch/powerpc/platforms/40x/makalu.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/40x/makalu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,58 @@
++/*
++ * Makalu board specific routines
++ *
++ * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
++ *
++ * Based on the Walnut code by
++ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
++ * Copyright 2007 IBM Corporation
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++#include <asm/time.h>
++#include <asm/uic.h>
++#include <asm/pci-bridge.h>
++
++static __initdata struct of_device_id makalu_of_bus[] = {
++	{ .compatible = "ibm,plb4", },
++	{ .compatible = "ibm,opb", },
++	{ .compatible = "ibm,ebc", },
++	{},
++};
++
++static int __init makalu_device_probe(void)
++{
++	of_platform_bus_probe(NULL, makalu_of_bus, NULL);
++
++	return 0;
++}
++machine_device_initcall(makalu, makalu_device_probe);
++
++static int __init makalu_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++
++	if (!of_flat_dt_is_compatible(root, "amcc,makalu"))
++		return 0;
++
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
++	return 1;
++}
++
++define_machine(makalu) {
++	.name 				= "Makalu",
++	.probe 				= makalu_probe,
++	.progress 			= udbg_progress,
++	.init_IRQ 			= uic_init_tree,
++	.get_irq 			= uic_get_irq,
++	.calibrate_decr			= generic_calibrate_decr,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/40x/virtex.c powerpc.git/arch/powerpc/platforms/40x/virtex.c
+--- linux-2.6.24/arch/powerpc/platforms/40x/virtex.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/40x/virtex.c	2008-01-28 20:25:49.000000000 +0100
+@@ -15,16 +15,23 @@
+ #include <asm/time.h>
+ #include <asm/xilinx_intc.h>
+ 
++static struct of_device_id xilinx_of_bus_ids[] __initdata = {
++	{ .compatible = "xlnx,plb-v46-1.00.a", },
++	{ .compatible = "xlnx,plb-v34-1.01.a", },
++	{ .compatible = "xlnx,plb-v34-1.02.a", },
++	{ .compatible = "xlnx,opb-v20-1.10.c", },
++	{ .compatible = "xlnx,dcr-v29-1.00.a", },
++	{ .compatible = "xlnx,compound", },
++	{}
++};
++
+ static int __init virtex_device_probe(void)
+ {
+-	if (!machine_is(virtex))
+-		return 0;
+-
+-	of_platform_bus_probe(NULL, NULL, NULL);
++	of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(virtex_device_probe);
++machine_device_initcall(virtex, virtex_device_probe);
+ 
+ static int __init virtex_probe(void)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/40x/walnut.c powerpc.git/arch/powerpc/platforms/40x/walnut.c
+--- linux-2.6.24/arch/powerpc/platforms/40x/walnut.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/40x/walnut.c	2008-01-28 20:25:49.000000000 +0100
+@@ -24,8 +24,9 @@
+ #include <asm/udbg.h>
+ #include <asm/time.h>
+ #include <asm/uic.h>
++#include <asm/pci-bridge.h>
+ 
+-static struct of_device_id walnut_of_bus[] = {
++static __initdata struct of_device_id walnut_of_bus[] = {
+ 	{ .compatible = "ibm,plb3", },
+ 	{ .compatible = "ibm,opb", },
+ 	{ .compatible = "ibm,ebc", },
+@@ -34,15 +35,12 @@
+ 
+ static int __init walnut_device_probe(void)
+ {
+-	if (!machine_is(walnut))
+-		return 0;
+-
+-	/* FIXME: do bus probe here */
+ 	of_platform_bus_probe(NULL, walnut_of_bus, NULL);
++	of_instantiate_rtc();
+ 
+ 	return 0;
+ }
+-device_initcall(walnut_device_probe);
++machine_device_initcall(walnut, walnut_device_probe);
+ 
+ static int __init walnut_probe(void)
+ {
+@@ -51,6 +49,8 @@
+ 	if (!of_flat_dt_is_compatible(root, "ibm,walnut"))
+ 		return 0;
+ 
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
+ 	return 1;
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/Kconfig powerpc.git/arch/powerpc/platforms/44x/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/44x/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -3,6 +3,7 @@
+ 	depends on 44x
+ 	default n
+ 	select 440EP
++	select PCI
+ 	help
+ 	  This option enables support for the IBM PPC440EP evaluation board.
+ 
+@@ -11,6 +12,8 @@
+ 	depends on 44x
+ 	default y
+ 	select 440GP
++	select PCI
++	select OF_RTC
+ 	help
+ 	  This option enables support for the IBM PPC440GP evaluation board.
+ 
+@@ -22,6 +25,48 @@
+ 	help
+ 	  This option enables support for the AMCC PPC440EPX evaluation board.
+ 
++config TAISHAN
++	bool "Taishan"
++	depends on 44x
++	default n
++	select 440GX
++	select PCI
++	help
++	  This option enables support for the AMCC PPC440GX "Taishan"
++	  evaluation board.
++
++config KATMAI
++	bool "Katmai"
++	depends on 44x
++	default n
++	select 440SPe
++	select PCI
++	select PPC4xx_PCI_EXPRESS
++	help
++	  This option enables support for the AMCC PPC440SPe evaluation board.
++
++config RAINIER
++	bool "Rainier"
++	depends on 44x
++	default n
++	select 440GRX
++	select PCI
++	help
++	  This option enables support for the AMCC PPC440GRX evaluation board.
++
++config WARP
++	bool "PIKA Warp"
++	depends on 44x
++	default n
++	select 440EP
++	help
++	  This option enables support for the PIKA Warp(tm) Appliance. The Warp
++          is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP
++	  stations and trunks.
++
++	  See http://www.pikatechnologies.com/ and follow the "PIKA for Computer
++	  Telephony Developers" link for more information.
++
+ #config LUAN
+ #	bool "Luan"
+ #	depends on 44x
+@@ -44,6 +89,7 @@
+ 	select PPC_FPU
+ 	select IBM440EP_ERR42
+ 	select IBM_NEW_EMAC_ZMII
++	select USB_ARCH_HAS_OHCI
+ 
+ config 440EPX
+ 	bool
+@@ -52,20 +98,29 @@
+ 	select IBM_NEW_EMAC_RGMII
+ 	select IBM_NEW_EMAC_ZMII
+ 
++config 440GRX
++	bool
++	select IBM_NEW_EMAC_EMAC4
++	select IBM_NEW_EMAC_RGMII
++	select IBM_NEW_EMAC_ZMII
++
+ config 440GP
+ 	bool
+ 	select IBM_NEW_EMAC_ZMII
+ 
+ config 440GX
+ 	bool
++        select IBM_NEW_EMAC_EMAC4
++	select IBM_NEW_EMAC_RGMII
++        select IBM_NEW_EMAC_ZMII #test only
++        select IBM_NEW_EMAC_TAH  #test only
+ 
+ config 440SP
+ 	bool
+ 
+-config 440A
++config 440SPe
++        select IBM_NEW_EMAC_EMAC4
+ 	bool
+-	depends on 440GX || 440EPX
+-	default y
+ 
+ # 44x errata/workaround config symbols, selected by the CPU models above
+ config IBM440EP_ERR42
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/Makefile powerpc.git/arch/powerpc/platforms/44x/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/44x/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -1,4 +1,9 @@
+ obj-$(CONFIG_44x)	:= misc_44x.o
+ obj-$(CONFIG_EBONY)	+= ebony.o
+-obj-$(CONFIG_BAMBOO) += bamboo.o
++obj-$(CONFIG_TAISHAN)	+= taishan.o
++obj-$(CONFIG_BAMBOO)	+= bamboo.o
+ obj-$(CONFIG_SEQUOIA)	+= sequoia.o
++obj-$(CONFIG_KATMAI)	+= katmai.o
++obj-$(CONFIG_RAINIER)	+= rainier.o
++obj-$(CONFIG_WARP)	+= warp.o
++obj-$(CONFIG_WARP)	+= warp-nand.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/bamboo.c powerpc.git/arch/powerpc/platforms/44x/bamboo.c
+--- linux-2.6.24/arch/powerpc/platforms/44x/bamboo.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/bamboo.c	2008-01-28 20:25:49.000000000 +0100
+@@ -21,9 +21,11 @@
+ #include <asm/udbg.h>
+ #include <asm/time.h>
+ #include <asm/uic.h>
++#include <asm/pci-bridge.h>
++
+ #include "44x.h"
+ 
+-static struct of_device_id bamboo_of_bus[] = {
++static __initdata struct of_device_id bamboo_of_bus[] = {
+ 	{ .compatible = "ibm,plb4", },
+ 	{ .compatible = "ibm,opb", },
+ 	{ .compatible = "ibm,ebc", },
+@@ -32,14 +34,11 @@
+ 
+ static int __init bamboo_device_probe(void)
+ {
+-	if (!machine_is(bamboo))
+-		return 0;
+-
+ 	of_platform_bus_probe(NULL, bamboo_of_bus, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(bamboo_device_probe);
++machine_device_initcall(bamboo, bamboo_device_probe);
+ 
+ static int __init bamboo_probe(void)
+ {
+@@ -48,6 +47,8 @@
+ 	if (!of_flat_dt_is_compatible(root, "amcc,bamboo"))
+ 		return 0;
+ 
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
+ 	return 1;
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/ebony.c powerpc.git/arch/powerpc/platforms/44x/ebony.c
+--- linux-2.6.24/arch/powerpc/platforms/44x/ebony.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/ebony.c	2008-01-28 20:25:49.000000000 +0100
+@@ -18,16 +18,18 @@
+ 
+ #include <linux/init.h>
+ #include <linux/of_platform.h>
++#include <linux/rtc.h>
+ 
+ #include <asm/machdep.h>
+ #include <asm/prom.h>
+ #include <asm/udbg.h>
+ #include <asm/time.h>
+ #include <asm/uic.h>
++#include <asm/pci-bridge.h>
+ 
+ #include "44x.h"
+ 
+-static struct of_device_id ebony_of_bus[] = {
++static __initdata struct of_device_id ebony_of_bus[] = {
+ 	{ .compatible = "ibm,plb4", },
+ 	{ .compatible = "ibm,opb", },
+ 	{ .compatible = "ibm,ebc", },
+@@ -36,14 +38,12 @@
+ 
+ static int __init ebony_device_probe(void)
+ {
+-	if (!machine_is(ebony))
+-		return 0;
+-
+ 	of_platform_bus_probe(NULL, ebony_of_bus, NULL);
++	of_instantiate_rtc();
+ 
+ 	return 0;
+ }
+-device_initcall(ebony_device_probe);
++machine_device_initcall(ebony, ebony_device_probe);
+ 
+ /*
+  * Called very early, MMU is off, device-tree isn't unflattened
+@@ -55,6 +55,8 @@
+ 	if (!of_flat_dt_is_compatible(root, "ibm,ebony"))
+ 		return 0;
+ 
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
+ 	return 1;
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/katmai.c powerpc.git/arch/powerpc/platforms/44x/katmai.c
+--- linux-2.6.24/arch/powerpc/platforms/44x/katmai.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/katmai.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,63 @@
++/*
++ * Katmai board specific routines
++ *
++ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
++ * Copyright 2007 IBM Corp.
++ *
++ * Based on the Bamboo code by
++ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
++ * Copyright 2007 IBM Corporation
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++#include <linux/init.h>
++#include <linux/of_platform.h>
++
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++#include <asm/time.h>
++#include <asm/uic.h>
++#include <asm/pci-bridge.h>
++
++#include "44x.h"
++
++static __initdata struct of_device_id katmai_of_bus[] = {
++	{ .compatible = "ibm,plb4", },
++	{ .compatible = "ibm,opb", },
++	{ .compatible = "ibm,ebc", },
++	{},
++};
++
++static int __init katmai_device_probe(void)
++{
++	of_platform_bus_probe(NULL, katmai_of_bus, NULL);
++
++	return 0;
++}
++machine_device_initcall(katmai, katmai_device_probe);
++
++static int __init katmai_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++
++	if (!of_flat_dt_is_compatible(root, "amcc,katmai"))
++		return 0;
++
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
++	return 1;
++}
++
++define_machine(katmai) {
++	.name 				= "Katmai",
++	.probe 				= katmai_probe,
++	.progress 			= udbg_progress,
++	.init_IRQ 			= uic_init_tree,
++	.get_irq 			= uic_get_irq,
++	.restart			= ppc44x_reset_system,
++	.calibrate_decr			= generic_calibrate_decr,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/rainier.c powerpc.git/arch/powerpc/platforms/44x/rainier.c
+--- linux-2.6.24/arch/powerpc/platforms/44x/rainier.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/rainier.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,62 @@
++/*
++ * Rainier board specific routines
++ *
++ * Valentine Barshak <vbarshak@ru.mvista.com>
++ * Copyright 2007 MontaVista Software Inc.
++ *
++ * Based on the Bamboo code by
++ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
++ * Copyright 2007 IBM Corporation
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++#include <linux/init.h>
++#include <linux/of_platform.h>
++
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++#include <asm/time.h>
++#include <asm/uic.h>
++#include <asm/pci-bridge.h>
++#include "44x.h"
++
++static __initdata struct of_device_id rainier_of_bus[] = {
++	{ .compatible = "ibm,plb4", },
++	{ .compatible = "ibm,opb", },
++	{ .compatible = "ibm,ebc", },
++	{},
++};
++
++static int __init rainier_device_probe(void)
++{
++	of_platform_bus_probe(NULL, rainier_of_bus, NULL);
++
++	return 0;
++}
++machine_device_initcall(rainier, rainier_device_probe);
++
++static int __init rainier_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++
++	if (!of_flat_dt_is_compatible(root, "amcc,rainier"))
++		return 0;
++
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
++	return 1;
++}
++
++define_machine(rainier) {
++	.name 				= "Rainier",
++	.probe 				= rainier_probe,
++	.progress 			= udbg_progress,
++	.init_IRQ 			= uic_init_tree,
++	.get_irq 			= uic_get_irq,
++	.restart			= ppc44x_reset_system,
++	.calibrate_decr			= generic_calibrate_decr,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/sequoia.c powerpc.git/arch/powerpc/platforms/44x/sequoia.c
+--- linux-2.6.24/arch/powerpc/platforms/44x/sequoia.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/sequoia.c	2008-01-28 20:25:49.000000000 +0100
+@@ -21,9 +21,11 @@
+ #include <asm/udbg.h>
+ #include <asm/time.h>
+ #include <asm/uic.h>
++#include <asm/pci-bridge.h>
++
+ #include "44x.h"
+ 
+-static struct of_device_id sequoia_of_bus[] = {
++static __initdata struct of_device_id sequoia_of_bus[] = {
+ 	{ .compatible = "ibm,plb4", },
+ 	{ .compatible = "ibm,opb", },
+ 	{ .compatible = "ibm,ebc", },
+@@ -32,14 +34,11 @@
+ 
+ static int __init sequoia_device_probe(void)
+ {
+-	if (!machine_is(sequoia))
+-		return 0;
+-
+ 	of_platform_bus_probe(NULL, sequoia_of_bus, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(sequoia_device_probe);
++machine_device_initcall(sequoia, sequoia_device_probe);
+ 
+ static int __init sequoia_probe(void)
+ {
+@@ -48,6 +47,8 @@
+ 	if (!of_flat_dt_is_compatible(root, "amcc,sequoia"))
+ 		return 0;
+ 
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
+ 	return 1;
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/taishan.c powerpc.git/arch/powerpc/platforms/44x/taishan.c
+--- linux-2.6.24/arch/powerpc/platforms/44x/taishan.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/taishan.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,73 @@
++/*
++ * Taishan board specific routines based off ebony.c code
++ * original copyrights below
++ *
++ * Matt Porter <mporter@kernel.crashing.org>
++ * Copyright 2002-2005 MontaVista Software Inc.
++ *
++ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
++ * Copyright (c) 2003-2005 Zultys Technologies
++ *
++ * Rewritten and ported to the merged powerpc tree:
++ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
++ *
++ * Modified from ebony.c for taishan:
++ * Copyright 2007 Hugh Blemings <hugh@au.ibm.com>, IBM Corporation.
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/init.h>
++#include <linux/of_platform.h>
++
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++#include <asm/time.h>
++#include <asm/uic.h>
++#include <asm/pci-bridge.h>
++
++#include "44x.h"
++
++static __initdata struct of_device_id taishan_of_bus[] = {
++	{ .compatible = "ibm,plb4", },
++	{ .compatible = "ibm,opb", },
++	{ .compatible = "ibm,ebc", },
++	{},
++};
++
++static int __init taishan_device_probe(void)
++{
++	of_platform_bus_probe(NULL, taishan_of_bus, NULL);
++
++	return 0;
++}
++machine_device_initcall(taishan, taishan_device_probe);
++
++/*
++ * Called very early, MMU is off, device-tree isn't unflattened
++ */
++static int __init taishan_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++
++	if (!of_flat_dt_is_compatible(root, "amcc,taishan"))
++		return 0;
++
++	ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
++
++	return 1;
++}
++
++define_machine(taishan) {
++	.name			= "Taishan",
++	.probe			= taishan_probe,
++	.progress		= udbg_progress,
++	.init_IRQ		= uic_init_tree,
++	.get_irq		= uic_get_irq,
++	.restart		= ppc44x_reset_system,
++	.calibrate_decr		= generic_calibrate_decr,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/warp-nand.c powerpc.git/arch/powerpc/platforms/44x/warp-nand.c
+--- linux-2.6.24/arch/powerpc/platforms/44x/warp-nand.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/warp-nand.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,105 @@
++/*
++ * PIKA Warp(tm) NAND flash specific routines
++ *
++ * Copyright (c) 2008 PIKA Technologies
++ *   Sean MacLennan <smaclennan@pikatech.com>
++ */
++
++#include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/ndfc.h>
++
++#ifdef CONFIG_MTD_NAND_NDFC
++
++#define CS_NAND_0	1	/* use chip select 1 for NAND device 0 */
++
++#define WARP_NAND_FLASH_REG_ADDR	0xD0000000UL
++#define WARP_NAND_FLASH_REG_SIZE	0x2000
++
++static struct resource warp_ndfc = {
++	.start = WARP_NAND_FLASH_REG_ADDR,
++	.end   = WARP_NAND_FLASH_REG_ADDR + WARP_NAND_FLASH_REG_SIZE,
++	.flags = IORESOURCE_MEM,
++};
++
++static struct mtd_partition nand_parts[] = {
++	{
++		.name   = "kernel",
++		.offset = 0,
++		.size   = 0x0200000
++	},
++	{
++		.name   = "root",
++		.offset = 0x0200000,
++		.size   = 0x3400000
++	},
++	{
++		.name   = "user",
++		.offset = 0x3600000,
++		.size   = 0x0A00000
++	},
++};
++
++struct ndfc_controller_settings warp_ndfc_settings = {
++	.ccr_settings = (NDFC_CCR_BS(CS_NAND_0) | NDFC_CCR_ARAC1),
++	.ndfc_erpn = 0,
++};
++
++static struct ndfc_chip_settings warp_chip0_settings = {
++	.bank_settings = 0x80002222,
++};
++
++struct platform_nand_ctrl warp_nand_ctrl = {
++	.priv = &warp_ndfc_settings,
++};
++
++static struct platform_device warp_ndfc_device = {
++	.name = "ndfc-nand",
++	.id = 0,
++	.dev = {
++		.platform_data = &warp_nand_ctrl,
++	},
++	.num_resources = 1,
++	.resource = &warp_ndfc,
++};
++
++static struct nand_ecclayout nand_oob_16 = {
++	.eccbytes = 3,
++	.eccpos = { 0, 1, 2, 3, 6, 7 },
++	.oobfree = { {.offset = 8, .length = 16} }
++};
++
++static struct platform_nand_chip warp_nand_chip0 = {
++	.nr_chips = 1,
++	.chip_offset = CS_NAND_0,
++	.nr_partitions = ARRAY_SIZE(nand_parts),
++	.partitions = nand_parts,
++	.chip_delay = 50,
++	.ecclayout = &nand_oob_16,
++	.priv = &warp_chip0_settings,
++};
++
++static struct platform_device warp_nand_device = {
++	.name = "ndfc-chip",
++	.id = 0,
++	.num_resources = 1,
++	.resource = &warp_ndfc,
++	.dev = {
++		.platform_data = &warp_nand_chip0,
++		.parent = &warp_ndfc_device.dev,
++	}
++};
++
++static int warp_setup_nand_flash(void)
++{
++	platform_device_register(&warp_ndfc_device);
++	platform_device_register(&warp_nand_device);
++
++	return 0;
++}
++device_initcall(warp_setup_nand_flash);
++
++#endif
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/44x/warp.c powerpc.git/arch/powerpc/platforms/44x/warp.c
+--- linux-2.6.24/arch/powerpc/platforms/44x/warp.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/44x/warp.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,153 @@
++/*
++ * PIKA Warp(tm) board specific routines
++ *
++ * Copyright (c) 2008 PIKA Technologies
++ *   Sean MacLennan <smaclennan@pikatech.com>
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++#include <linux/init.h>
++#include <linux/of_platform.h>
++#include <linux/kthread.h>
++
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++#include <asm/time.h>
++#include <asm/uic.h>
++
++#include "44x.h"
++
++
++static __initdata struct of_device_id warp_of_bus[] = {
++	{ .compatible = "ibm,plb4", },
++	{ .compatible = "ibm,opb", },
++	{ .compatible = "ibm,ebc", },
++	{},
++};
++
++static int __init warp_device_probe(void)
++{
++	of_platform_bus_probe(NULL, warp_of_bus, NULL);
++	return 0;
++}
++machine_device_initcall(warp, warp_device_probe);
++
++static int __init warp_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++
++	return of_flat_dt_is_compatible(root, "pika,warp");
++}
++
++define_machine(warp) {
++	.name		= "Warp",
++	.probe 		= warp_probe,
++	.progress 	= udbg_progress,
++	.init_IRQ 	= uic_init_tree,
++	.get_irq 	= uic_get_irq,
++	.restart	= ppc44x_reset_system,
++	.calibrate_decr = generic_calibrate_decr,
++};
++
++
++#define LED_GREEN (0x80000000 >> 0)
++#define LED_RED   (0x80000000 >> 1)
++
++
++/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */
++void warp_set_power_leds(int green, int red)
++{
++	static void __iomem *gpio_base = NULL;
++	unsigned leds;
++
++	if (gpio_base == NULL) {
++		struct device_node *np;
++
++		/* Power LEDS are on the second GPIO controller */
++		np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
++		if (np)
++			np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
++		if (np == NULL) {
++			printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
++			return;
++		}
++
++		gpio_base = of_iomap(np, 0);
++		of_node_put(np);
++		if (gpio_base == NULL) {
++			printk(KERN_ERR __FILE__ ": Unable to map gpio");
++			return;
++		}
++	}
++
++	leds = in_be32(gpio_base);
++
++	switch (green) {
++	case 0: leds &= ~LED_GREEN; break;
++	case 1: leds |=  LED_GREEN; break;
++	}
++	switch (red) {
++	case 0: leds &= ~LED_RED; break;
++	case 1: leds |=  LED_RED; break;
++	}
++
++	out_be32(gpio_base, leds);
++}
++EXPORT_SYMBOL(warp_set_power_leds);
++
++
++#ifdef CONFIG_SENSORS_AD7414
++static int pika_dtm_thread(void __iomem *fpga)
++{
++	extern int ad7414_get_temp(int index);
++
++	while (!kthread_should_stop()) {
++		int temp = ad7414_get_temp(0);
++
++		out_be32(fpga, temp);
++
++		set_current_state(TASK_INTERRUPTIBLE);
++		schedule_timeout(HZ);
++	}
++
++	return 0;
++}
++
++static int __init pika_dtm_start(void)
++{
++	struct task_struct *dtm_thread;
++	struct device_node *np;
++	struct resource res;
++	void __iomem *fpga;
++
++	np = of_find_compatible_node(NULL, NULL, "pika,fpga");
++	if (np == NULL)
++		return -ENOENT;
++
++	/* We do not call of_iomap here since it would map in the entire
++	 * fpga space, which is over 8k.
++	 */
++	if (of_address_to_resource(np, 0, &res)) {
++		of_node_put(np);
++		return -ENOENT;
++	}
++	of_node_put(np);
++
++	fpga = ioremap(res.start + 0x20, 4);
++	if (fpga == NULL)
++		return -ENOENT;
++
++	dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm");
++	if (IS_ERR(dtm_thread)) {
++		iounmap(fpga);
++		return PTR_ERR(dtm_thread);
++	}
++
++	return 0;
++}
++device_initcall(pika_dtm_start);
++#endif
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/Kconfig powerpc.git/arch/powerpc/platforms/52xx/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/52xx/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -19,6 +19,28 @@
+ 
+ 	  It is safe to say 'Y' here
+ 
++config PPC_MPC5200_SIMPLE
++	bool "Generic support for simple MPC5200 based boards"
++	depends on PPC_MULTIPLATFORM && PPC32
++	select PPC_MPC5200
++	select DEFAULT_UIMAGE
++	select WANT_DEVICE_TREE
++	default n
++	help
++	  This option enables support for a simple MPC52xx based boards which
++	  do not need a custom platform specific setup. Such boards are
++	  supported assuming the following:
++
++	  - GPIO pins are configured by the firmware,
++	  - CDM configuration (clocking) is setup correctly by firmware,
++	  - if the 'fsl,has-wdt' property is present in one of the
++	    gpt nodes, then it is safe to use such gpt to reset the board,
++	  - PCI is supported if enabled in the kernel configuration
++	    and if there is a PCI bus node defined in the device tree.
++
++	  Boards that are compatible with this generic platform support
++	  are: 'tqc,tqm5200', 'promess,motionpro', 'schindler,cm5200'.
++
+ config PPC_EFIKA
+ 	bool "bPlan Efika 5k2. MPC5200B based computer"
+ 	depends on PPC_MULTIPLATFORM && PPC32
+@@ -31,8 +53,7 @@
+ config PPC_LITE5200
+ 	bool "Freescale Lite5200 Eval Board"
+ 	depends on PPC_MULTIPLATFORM && PPC32
+-	select WANT_DEVICE_TREE
+ 	select PPC_MPC5200
++	select DEFAULT_UIMAGE
++	select WANT_DEVICE_TREE
+ 	default n
+-
+-
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/Makefile powerpc.git/arch/powerpc/platforms/52xx/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/52xx/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -6,6 +6,7 @@
+ obj-$(CONFIG_PCI)		+= mpc52xx_pci.o
+ endif
+ 
++obj-$(CONFIG_PPC_MPC5200_SIMPLE) += mpc5200_simple.o
+ obj-$(CONFIG_PPC_EFIKA)		+= efika.o
+ obj-$(CONFIG_PPC_LITE5200)	+= lite5200.o
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/lite5200.c powerpc.git/arch/powerpc/platforms/52xx/lite5200.c
+--- linux-2.6.24/arch/powerpc/platforms/52xx/lite5200.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/lite5200.c	2008-01-28 20:25:49.000000000 +0100
+@@ -42,10 +42,13 @@
+ static void __init
+ lite5200_fix_clock_config(void)
+ {
++	struct device_node *np;
+ 	struct mpc52xx_cdm  __iomem *cdm;
+ 
+ 	/* Map zones */
+-	cdm = mpc52xx_find_and_map("mpc5200-cdm");
++	np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm");
++	cdm = of_iomap(np, 0);
++	of_node_put(np);
+ 	if (!cdm) {
+ 		printk(KERN_ERR "%s() failed; expect abnormal behaviour\n",
+ 		       __FUNCTION__);
+@@ -74,10 +77,13 @@
+ static void __init
+ lite5200_fix_port_config(void)
+ {
++	struct device_node *np;
+ 	struct mpc52xx_gpio __iomem *gpio;
+ 	u32 port_config;
+ 
+-	gpio = mpc52xx_find_and_map("mpc5200-gpio");
++	np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio");
++	gpio = of_iomap(np, 0);
++	of_node_put(np);
+ 	if (!gpio) {
+ 		printk(KERN_ERR "%s() failed. expect abnormal behavior\n",
+ 		       __FUNCTION__);
+@@ -131,10 +137,6 @@
+ 
+ static void __init lite5200_setup_arch(void)
+ {
+-#ifdef CONFIG_PCI
+-	struct device_node *np;
+-#endif
+-
+ 	if (ppc_md.progress)
+ 		ppc_md.progress("lite5200_setup_arch()", 0);
+ 
+@@ -154,13 +156,7 @@
+ 	lite5200_pm_init();
+ #endif
+ 
+-#ifdef CONFIG_PCI
+-	np = of_find_node_by_type(NULL, "pci");
+-	if (np) {
+-		mpc52xx_add_bridge(np);
+-		of_node_put(np);
+-	}
+-#endif
++	mpc52xx_setup_pci();
+ }
+ 
+ /*
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/lite5200_pm.c powerpc.git/arch/powerpc/platforms/52xx/lite5200_pm.c
+--- linux-2.6.24/arch/powerpc/platforms/52xx/lite5200_pm.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/lite5200_pm.c	2008-01-28 20:25:49.000000000 +0100
+@@ -42,6 +42,8 @@
+ 
+ static int lite5200_pm_prepare(void)
+ {
++	struct device_node *np;
++
+ 	/* deep sleep? let mpc52xx code handle that */
+ 	if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
+ 		return mpc52xx_pm_prepare();
+@@ -50,7 +52,9 @@
+ 		return -EINVAL;
+ 
+ 	/* map registers */
+-	mbar = mpc52xx_find_and_map("mpc5200");
++	np = of_find_compatible_node(NULL, NULL, "mpc5200");
++	mbar = of_iomap(np, 0);
++	of_node_put(np);
+ 	if (!mbar) {
+ 		printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__);
+ 		return -ENOSYS;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/mpc5200_simple.c powerpc.git/arch/powerpc/platforms/52xx/mpc5200_simple.c
+--- linux-2.6.24/arch/powerpc/platforms/52xx/mpc5200_simple.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/mpc5200_simple.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,85 @@
++/*
++ * Support for 'mpc5200-simple-platform' compatible boards.
++ *
++ * Written by Marian Balakowicz <m8@semihalf.com>
++ * Copyright (C) 2007 Semihalf
++ *
++ * 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.
++ *
++ * Description:
++ * This code implements support for a simple MPC52xx based boards which
++ * do not need a custom platform specific setup. Such boards are
++ * supported assuming the following:
++ *
++ * - GPIO pins are configured by the firmware,
++ * - CDM configuration (clocking) is setup correctly by firmware,
++ * - if the 'fsl,has-wdt' property is present in one of the
++ *   gpt nodes, then it is safe to use such gpt to reset the board,
++ * - PCI is supported if enabled in the kernel configuration
++ *   and if there is a PCI bus node defined in the device tree.
++ *
++ * Boards that are compatible with this generic platform support
++ * are listed in a 'board' table.
++ */
++
++#undef DEBUG
++#include <asm/time.h>
++#include <asm/prom.h>
++#include <asm/machdep.h>
++#include <asm/mpc52xx.h>
++
++/*
++ * Setup the architecture
++ */
++static void __init mpc5200_simple_setup_arch(void)
++{
++	if (ppc_md.progress)
++		ppc_md.progress("mpc5200_simple_setup_arch()", 0);
++
++	/* Some mpc5200 & mpc5200b related configuration */
++	mpc5200_setup_xlb_arbiter();
++
++	/* Map wdt for mpc52xx_restart() */
++	mpc52xx_map_wdt();
++
++	mpc52xx_setup_pci();
++}
++
++/* list of the supported boards */
++static char *board[] __initdata = {
++	"promess,motionpro",
++	"schindler,cm5200",
++	"tqc,tqm5200",
++	NULL
++};
++
++/*
++ * Called very early, MMU is off, device-tree isn't unflattened
++ */
++static int __init mpc5200_simple_probe(void)
++{
++	unsigned long node = of_get_flat_dt_root();
++	int i = 0;
++
++	while (board[i]) {
++		if (of_flat_dt_is_compatible(node, board[i]))
++			break;
++		i++;
++	}
++	
++	return (board[i] != NULL);
++}
++
++define_machine(mpc5200_simple_platform) {
++	.name		= "mpc5200-simple-platform",
++	.probe		= mpc5200_simple_probe,
++	.setup_arch	= mpc5200_simple_setup_arch,
++	.init		= mpc52xx_declare_of_platform_devices,
++	.init_IRQ	= mpc52xx_init_irq,
++	.get_irq	= mpc52xx_get_irq,
++	.restart	= mpc52xx_restart,
++	.calibrate_decr	= generic_calibrate_decr,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/mpc52xx_common.c powerpc.git/arch/powerpc/platforms/52xx/mpc52xx_common.c
+--- linux-2.6.24/arch/powerpc/platforms/52xx/mpc52xx_common.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/mpc52xx_common.c	2008-01-28 20:25:49.000000000 +0100
+@@ -26,45 +26,6 @@
+  */
+ static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL;
+ 
+-static void __iomem *
+-mpc52xx_map_node(struct device_node *ofn)
+-{
+-	const u32 *regaddr_p;
+-	u64 regaddr64, size64;
+-
+-	if (!ofn)
+-		return NULL;
+-
+-	regaddr_p = of_get_address(ofn, 0, &size64, NULL);
+-	if (!regaddr_p) {
+-		of_node_put(ofn);
+-		return NULL;
+-	}
+-
+-	regaddr64 = of_translate_address(ofn, regaddr_p);
+-
+-	of_node_put(ofn);
+-
+-	return ioremap((u32)regaddr64, (u32)size64);
+-}
+-
+-void __iomem *
+-mpc52xx_find_and_map(const char *compatible)
+-{
+-	return mpc52xx_map_node(
+-		of_find_compatible_node(NULL, NULL, compatible));
+-}
+-
+-EXPORT_SYMBOL(mpc52xx_find_and_map);
+-
+-void __iomem *
+-mpc52xx_find_and_map_path(const char *path)
+-{
+-	return mpc52xx_map_node(of_find_node_by_path(path));
+-}
+-
+-EXPORT_SYMBOL(mpc52xx_find_and_map_path);
+-
+ /**
+  * 	mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
+  * 	@node:	device node
+@@ -101,9 +62,12 @@
+ void __init
+ mpc5200_setup_xlb_arbiter(void)
+ {
++	struct device_node *np;
+ 	struct mpc52xx_xlb  __iomem *xlb;
+ 
+-	xlb = mpc52xx_find_and_map("mpc5200-xlb");
++	np = of_find_compatible_node(NULL, NULL, "mpc5200-xlb");
++	xlb = of_iomap(np, 0);
++	of_node_put(np);
+ 	if (!xlb) {
+ 		printk(KERN_ERR __FILE__ ": "
+ 			"Error mapping XLB in mpc52xx_setup_cpu().  "
+@@ -124,11 +88,21 @@
+ 	iounmap(xlb);
+ }
+ 
++static struct of_device_id mpc52xx_bus_ids[] __initdata= {
++	{ .compatible = "fsl,mpc5200-immr", },
++	{ .compatible = "fsl,lpb", },
++
++	/* depreciated matches; shouldn't be used in new device trees */
++	{ .type = "builtin", .compatible = "mpc5200", }, /* efika */
++	{ .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
++	{},
++};
++
+ void __init
+ mpc52xx_declare_of_platform_devices(void)
+ {
+ 	/* Find every child of the SOC node and add it to of_platform */
+-	if (of_platform_bus_probe(NULL, NULL, NULL))
++	if (of_platform_bus_probe(NULL, mpc52xx_bus_ids, NULL))
+ 		printk(KERN_ERR __FILE__ ": "
+ 			"Error while probing of_platform bus\n");
+ }
+@@ -146,16 +120,19 @@
+ 	for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") {
+ 		has_wdt = of_get_property(np, "fsl,has-wdt", NULL);
+ 		if (has_wdt) {
+-			mpc52xx_wdt = mpc52xx_map_node(np);
++			mpc52xx_wdt = of_iomap(np, 0);
++			of_node_put(np);
+ 			return;
+ 		}
+ 	}
+ 	for_each_compatible_node(np, NULL, "mpc5200-gpt") {
+ 		has_wdt = of_get_property(np, "has-wdt", NULL);
+ 		if (has_wdt) {
+-			mpc52xx_wdt = mpc52xx_map_node(np);
++			mpc52xx_wdt = of_iomap(np, 0);
++			of_node_put(np);
+ 			return;
+ 		}
++
+ 	}
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/mpc52xx_pci.c powerpc.git/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+--- linux-2.6.24/arch/powerpc/platforms/52xx/mpc52xx_pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/mpc52xx_pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -363,7 +363,7 @@
+ 
+ 	pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
+ 
+-	pci_assign_all_buses = 1;
++	ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+ 
+ 	if (of_address_to_resource(node, 0, &rsrc) != 0) {
+ 		printk(KERN_ERR "Can't get %s resources\n", node->full_name);
+@@ -406,3 +406,17 @@
+ 
+ 	return 0;
+ }
++
++void __init mpc52xx_setup_pci(void)
++{
++	struct device_node *pci;
++
++	pci = of_find_compatible_node(NULL, NULL, "fsl,mpc5200-pci");
++	if (!pci)
++		pci = of_find_compatible_node(NULL, NULL, "mpc5200-pci");
++	if (!pci)
++		return;
++
++	mpc52xx_add_bridge(pci);
++	of_node_put(pci);
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/mpc52xx_pic.c powerpc.git/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+--- linux-2.6.24/arch/powerpc/platforms/52xx/mpc52xx_pic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/mpc52xx_pic.c	2008-01-28 20:25:49.000000000 +0100
+@@ -364,16 +364,18 @@
+ {
+ 	u32 intr_ctrl;
+ 	struct device_node *picnode;
++	struct device_node *np;
+ 
+ 	/* Remap the necessary zones */
+ 	picnode = of_find_compatible_node(NULL, NULL, "mpc5200-pic");
+-
+-	intr = mpc52xx_find_and_map("mpc5200-pic");
++	intr = of_iomap(picnode, 0);
+ 	if (!intr)
+ 		panic(__FILE__	": find_and_map failed on 'mpc5200-pic'. "
+ 				"Check node !");
+ 
+-	sdma = mpc52xx_find_and_map("mpc5200-bestcomm");
++	np = of_find_compatible_node(NULL, NULL, "mpc5200-bestcomm");
++	sdma = of_iomap(np, 0);
++	of_node_put(np);
+ 	if (!sdma)
+ 		panic(__FILE__	": find_and_map failed on 'mpc5200-bestcomm'. "
+ 				"Check node !");
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/52xx/mpc52xx_pm.c powerpc.git/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+--- linux-2.6.24/arch/powerpc/platforms/52xx/mpc52xx_pm.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/52xx/mpc52xx_pm.c	2008-01-28 20:25:49.000000000 +0100
+@@ -59,10 +59,14 @@
+ 
+ int mpc52xx_pm_prepare(void)
+ {
++	struct device_node *np;
++
+ 	/* map the whole register space */
+-	mbar = mpc52xx_find_and_map("mpc5200");
++	np = of_find_compatible_node(NULL, NULL, "mpc5200");
++	mbar = of_iomap(np, 0);
++	of_node_put(np);
+ 	if (!mbar) {
+-		printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__);
++		pr_err("mpc52xx_pm_prepare(): could not map registers\n");
+ 		return -ENOSYS;
+ 	}
+ 	/* these offsets are from mpc5200 users manual */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/82xx/Kconfig powerpc.git/arch/powerpc/platforms/82xx/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/82xx/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/82xx/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -26,6 +26,19 @@
+ 	help
+ 	  This option enables support for the PQ2FADS board
+ 
++config EP8248E
++	bool "Embedded Planet EP8248E (a.k.a. CWH-PPC-8248N-VE)"
++	select 8272
++	select 8260
++	select FSL_SOC
++	select PPC_CPM_NEW_BINDING
++	select MDIO_BITBANG
++	help
++	  This enables support for the Embedded Planet EP8248E board.
++
++	  This board is also resold by Freescale as the QUICCStart
++	  MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE.
++
+ endchoice
+ 
+ config PQ2ADS
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/82xx/Makefile powerpc.git/arch/powerpc/platforms/82xx/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/82xx/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/82xx/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -5,3 +5,4 @@
+ obj-$(CONFIG_CPM2) += pq2.o
+ obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o
+ obj-$(CONFIG_PQ2FADS) += pq2fads.o
++obj-$(CONFIG_EP8248E) += ep8248e.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/82xx/ep8248e.c powerpc.git/arch/powerpc/platforms/82xx/ep8248e.c
+--- linux-2.6.24/arch/powerpc/platforms/82xx/ep8248e.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/82xx/ep8248e.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,324 @@
++/*
++ * Embedded Planet EP8248E support
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc.
++ * Author: Scott Wood <scottwood@freescale.com>
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/fsl_devices.h>
++#include <linux/mdio-bitbang.h>
++#include <linux/of_platform.h>
++
++#include <asm/io.h>
++#include <asm/cpm2.h>
++#include <asm/udbg.h>
++#include <asm/machdep.h>
++#include <asm/time.h>
++#include <asm/mpc8260.h>
++#include <asm/prom.h>
++
++#include <sysdev/fsl_soc.h>
++#include <sysdev/cpm2_pic.h>
++
++#include "pq2.h"
++
++static u8 __iomem *ep8248e_bcsr;
++static struct device_node *ep8248e_bcsr_node;
++
++#define BCSR7_SCC2_ENABLE 0x10
++
++#define BCSR8_PHY1_ENABLE 0x80
++#define BCSR8_PHY1_POWER  0x40
++#define BCSR8_PHY2_ENABLE 0x20
++#define BCSR8_PHY2_POWER  0x10
++#define BCSR8_MDIO_READ   0x04
++#define BCSR8_MDIO_CLOCK  0x02
++#define BCSR8_MDIO_DATA   0x01
++
++#define BCSR9_USB_ENABLE  0x80
++#define BCSR9_USB_POWER   0x40
++#define BCSR9_USB_HOST    0x20
++#define BCSR9_USB_FULL_SPEED_TARGET 0x10
++
++static void __init ep8248e_pic_init(void)
++{
++	struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,pq2-pic");
++	if (!np) {
++		printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
++		return;
++	}
++
++	cpm2_pic_init(np);
++	of_node_put(np);
++}
++
++static void ep8248e_set_mdc(struct mdiobb_ctrl *ctrl, int level)
++{
++	if (level)
++		setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_CLOCK);
++	else
++		clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_CLOCK);
++
++	/* Read back to flush the write. */
++	in_8(&ep8248e_bcsr[8]);
++}
++
++static void ep8248e_set_mdio_dir(struct mdiobb_ctrl *ctrl, int output)
++{
++	if (output)
++		clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_READ);
++	else
++		setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_READ);
++
++	/* Read back to flush the write. */
++	in_8(&ep8248e_bcsr[8]);
++}
++
++static void ep8248e_set_mdio_data(struct mdiobb_ctrl *ctrl, int data)
++{
++	if (data)
++		setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_DATA);
++	else
++		clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_DATA);
++
++	/* Read back to flush the write. */
++	in_8(&ep8248e_bcsr[8]);
++}
++
++static int ep8248e_get_mdio_data(struct mdiobb_ctrl *ctrl)
++{
++	return in_8(&ep8248e_bcsr[8]) & BCSR8_MDIO_DATA;
++}
++
++static const struct mdiobb_ops ep8248e_mdio_ops = {
++	.set_mdc = ep8248e_set_mdc,
++	.set_mdio_dir = ep8248e_set_mdio_dir,
++	.set_mdio_data = ep8248e_set_mdio_data,
++	.get_mdio_data = ep8248e_get_mdio_data,
++	.owner = THIS_MODULE,
++};
++
++static struct mdiobb_ctrl ep8248e_mdio_ctrl = {
++	.ops = &ep8248e_mdio_ops,
++};
++
++static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
++                                        const struct of_device_id *match)
++{
++	struct mii_bus *bus;
++	struct resource res;
++	struct device_node *node;
++	int ret, i;
++
++	node = of_get_parent(ofdev->node);
++	of_node_put(node);
++	if (node != ep8248e_bcsr_node)
++		return -ENODEV;
++
++	ret = of_address_to_resource(ofdev->node, 0, &res);
++	if (ret)
++		return ret;
++
++	bus = alloc_mdio_bitbang(&ep8248e_mdio_ctrl);
++	if (!bus)
++		return -ENOMEM;
++
++	bus->phy_mask = 0;
++	bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
++
++	for (i = 0; i < PHY_MAX_ADDR; i++)
++		bus->irq[i] = -1;
++
++	bus->name = "ep8248e-mdio-bitbang";
++	bus->dev = &ofdev->dev;
++	bus->id = res.start;
++
++	return mdiobus_register(bus);
++}
++
++static int ep8248e_mdio_remove(struct of_device *ofdev)
++{
++	BUG();
++	return 0;
++}
++
++static const struct of_device_id ep8248e_mdio_match[] = {
++	{
++		.compatible = "fsl,ep8248e-mdio-bitbang",
++	},
++	{},
++};
++
++static struct of_platform_driver ep8248e_mdio_driver = {
++	.driver = {
++		.name = "ep8248e-mdio-bitbang",
++	},
++	.match_table = ep8248e_mdio_match,
++	.probe = ep8248e_mdio_probe,
++	.remove = ep8248e_mdio_remove,
++};
++
++struct cpm_pin {
++	int port, pin, flags;
++};
++
++static __initdata struct cpm_pin ep8248e_pins[] = {
++	/* SMC1 */
++	{2, 4, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{2, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++
++	/* SCC1 */
++	{2, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{2, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++
++	/* FCC1 */
++	{0, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{0, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{0, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{0, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{0, 18, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{0, 19, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{0, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{0, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{0, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
++	{0, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
++	{0, 28, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{0, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{0, 30, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
++	{0, 31, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
++	{2, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{2, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++
++	/* FCC2 */
++	{1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++
++	/* I2C */
++	{4, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
++	{4, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
++
++	/* USB */
++	{2, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{2, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{2, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{2, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++	{3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
++	{3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
++};
++
++static void __init init_ioports(void)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(ep8248e_pins); i++) {
++		const struct cpm_pin *pin = &ep8248e_pins[i];
++		cpm2_set_pin(pin->port, pin->pin, pin->flags);
++	}
++
++	cpm2_smc_clk_setup(CPM_CLK_SMC1, CPM_BRG7);
++	cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
++	cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
++	cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK8, CPM_CLK_TX); /* USB */
++	cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK11, CPM_CLK_RX);
++	cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_TX);
++	cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX);
++	cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
++}
++
++static void __init ep8248e_setup_arch(void)
++{
++	if (ppc_md.progress)
++		ppc_md.progress("ep8248e_setup_arch()", 0);
++
++	cpm2_reset();
++
++	/* When this is set, snooping CPM DMA from RAM causes
++	 * machine checks.  See erratum SIU18.
++	 */
++	clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
++
++	ep8248e_bcsr_node =
++		of_find_compatible_node(NULL, NULL, "fsl,ep8248e-bcsr");
++	if (!ep8248e_bcsr_node) {
++		printk(KERN_ERR "No bcsr in device tree\n");
++		return;
++	}
++
++	ep8248e_bcsr = of_iomap(ep8248e_bcsr_node, 0);
++	if (!ep8248e_bcsr) {
++		printk(KERN_ERR "Cannot map BCSR registers\n");
++		of_node_put(ep8248e_bcsr_node);
++		ep8248e_bcsr_node = NULL;
++		return;
++	}
++
++	setbits8(&ep8248e_bcsr[7], BCSR7_SCC2_ENABLE);
++	setbits8(&ep8248e_bcsr[8], BCSR8_PHY1_ENABLE | BCSR8_PHY1_POWER |
++	                           BCSR8_PHY2_ENABLE | BCSR8_PHY2_POWER);
++
++	init_ioports();
++
++	if (ppc_md.progress)
++		ppc_md.progress("ep8248e_setup_arch(), finish", 0);
++}
++
++static  __initdata struct of_device_id of_bus_ids[] = {
++	{ .compatible = "simple-bus", },
++	{ .compatible = "fsl,ep8248e-bcsr", },
++	{},
++};
++
++static int __init declare_of_platform_devices(void)
++{
++	of_platform_bus_probe(NULL, of_bus_ids, NULL);
++	of_register_platform_driver(&ep8248e_mdio_driver);
++
++	return 0;
++}
++machine_device_initcall(ep8248e, declare_of_platform_devices);
++
++/*
++ * Called very early, device-tree isn't unflattened
++ */
++static int __init ep8248e_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++	return of_flat_dt_is_compatible(root, "fsl,ep8248e");
++}
++
++define_machine(ep8248e)
++{
++	.name = "Embedded Planet EP8248E",
++	.probe = ep8248e_probe,
++	.setup_arch = ep8248e_setup_arch,
++	.init_IRQ = ep8248e_pic_init,
++	.get_irq = cpm2_get_irq,
++	.calibrate_decr = generic_calibrate_decr,
++	.restart = pq2_restart,
++	.progress = udbg_progress,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/82xx/pq2.c powerpc.git/arch/powerpc/platforms/82xx/pq2.c
+--- linux-2.6.24/arch/powerpc/platforms/82xx/pq2.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/82xx/pq2.c	2008-01-28 20:25:49.000000000 +0100
+@@ -53,13 +53,13 @@
+ 	if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
+ 		goto err;
+ 
+-	pci_assign_all_buses = 1;
++	ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+ 
+ 	hose = pcibios_alloc_controller(np);
+ 	if (!hose)
+ 		return;
+ 
+-	hose->arch_data = np;
++	hose->dn = np;
+ 
+ 	setup_indirect_pci(hose, r.start + 0x100, r.start + 0x104, 0);
+ 	pci_process_bridge_OF_ranges(hose, np, 1);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/82xx/pq2fads.c powerpc.git/arch/powerpc/platforms/82xx/pq2fads.c
+--- linux-2.6.24/arch/powerpc/platforms/82xx/pq2fads.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/82xx/pq2fads.c	2008-01-28 20:25:49.000000000 +0100
+@@ -15,12 +15,12 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/fsl_devices.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/io.h>
+ #include <asm/cpm2.h>
+ #include <asm/udbg.h>
+ #include <asm/machdep.h>
+-#include <asm/of_platform.h>
+ #include <asm/time.h>
+ 
+ #include <sysdev/fsl_soc.h>
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/Kconfig powerpc.git/arch/powerpc/platforms/83xx/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/83xx/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -50,6 +50,11 @@
+ 	help
+ 	  This option enables support for the MPC836x MDS Processor Board.
+ 
++config MPC837x_MDS
++	bool "Freescale MPC837x MDS"
++	select DEFAULT_UIMAGE
++	help
++	  This option enables support for the MPC837x MDS Processor Board.
+ endchoice
+ 
+ config PPC_MPC831x
+@@ -75,3 +80,9 @@
+ 	select PPC_UDBG_16550
+ 	select PPC_INDIRECT_PCI
+ 	default y if MPC836x_MDS
++
++config PPC_MPC837x
++	bool
++	select PPC_UDBG_16550
++	select PPC_INDIRECT_PCI
++	default y if MPC837x_MDS
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/Makefile powerpc.git/arch/powerpc/platforms/83xx/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/83xx/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -9,3 +9,4 @@
+ obj-$(CONFIG_MPC834x_ITX)	+= mpc834x_itx.o
+ obj-$(CONFIG_MPC836x_MDS)	+= mpc836x_mds.o
+ obj-$(CONFIG_MPC832x_MDS)	+= mpc832x_mds.o
++obj-$(CONFIG_MPC837x_MDS)	+= mpc837x_mds.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/mpc8313_rdb.c powerpc.git/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/mpc8313_rdb.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/mpc8313_rdb.c	2008-01-28 20:25:49.000000000 +0100
+@@ -14,6 +14,7 @@
+  */
+ 
+ #include <linux/pci.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/time.h>
+ #include <asm/ipic.h>
+@@ -70,11 +71,23 @@
+  */
+ static int __init mpc8313_rdb_probe(void)
+ {
+-        unsigned long root = of_get_flat_dt_root();
++	unsigned long root = of_get_flat_dt_root();
+ 
+-        return of_flat_dt_is_compatible(root, "MPC8313ERDB");
++	return of_flat_dt_is_compatible(root, "MPC8313ERDB");
+ }
+ 
++static struct of_device_id __initdata of_bus_ids[] = {
++	{ .compatible = "simple-bus" },
++	{},
++};
++
++static int __init declare_of_platform_devices(void)
++{
++	of_platform_bus_probe(NULL, of_bus_ids, NULL);
++	return 0;
++}
++machine_device_initcall(mpc8313_rdb, declare_of_platform_devices);
++
+ define_machine(mpc8313_rdb) {
+ 	.name			= "MPC8313 RDB",
+ 	.probe			= mpc8313_rdb_probe,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/mpc832x_mds.c powerpc.git/arch/powerpc/platforms/83xx/mpc832x_mds.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/mpc832x_mds.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/mpc832x_mds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -23,9 +23,9 @@
+ #include <linux/seq_file.h>
+ #include <linux/root_dev.h>
+ #include <linux/initrd.h>
++#include <linux/of_platform.h>
++#include <linux/of_device.h>
+ 
+-#include <asm/of_device.h>
+-#include <asm/of_platform.h>
+ #include <asm/system.h>
+ #include <asm/atomic.h>
+ #include <asm/time.h>
+@@ -110,15 +110,12 @@
+ 
+ static int __init mpc832x_declare_of_platform_devices(void)
+ {
+-	if (!machine_is(mpc832x_mds))
+-		return 0;
+-
+ 	/* Publish the QE devices */
+ 	of_platform_bus_probe(NULL, mpc832x_ids, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(mpc832x_declare_of_platform_devices);
++machine_device_initcall(mpc832x_mds, mpc832x_declare_of_platform_devices);
+ 
+ static void __init mpc832x_sys_init_IRQ(void)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/mpc832x_rdb.c powerpc.git/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/mpc832x_rdb.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/mpc832x_rdb.c	2008-01-28 20:25:49.000000000 +0100
+@@ -19,8 +19,8 @@
+ #include <linux/spi/spi.h>
+ #include <linux/spi/mmc_spi.h>
+ #include <linux/mmc/host.h>
++#include <linux/of_platform.h>
+ 
+-#include <asm/of_platform.h>
+ #include <asm/time.h>
+ #include <asm/ipic.h>
+ #include <asm/udbg.h>
+@@ -63,9 +63,6 @@
+ 
+ static int __init mpc832x_spi_init(void)
+ {
+-	if (!machine_is(mpc832x_rdb))
+-		return 0;
+-
+ 	par_io_config_pin(3,  0, 3, 0, 1, 0); /* SPI1 MOSI, I/O */
+ 	par_io_config_pin(3,  1, 3, 0, 1, 0); /* SPI1 MISO, I/O */
+ 	par_io_config_pin(3,  2, 3, 0, 1, 0); /* SPI1 CLK,  I/O */
+@@ -80,7 +77,7 @@
+ 			    mpc83xx_spi_deactivate_cs);
+ }
+ 
+-device_initcall(mpc832x_spi_init);
++machine_device_initcall(mpc832x_rdb, mpc832x_spi_init);
+ 
+ /* ************************************************************************
+  *
+@@ -123,15 +120,12 @@
+ 
+ static int __init mpc832x_declare_of_platform_devices(void)
+ {
+-	if (!machine_is(mpc832x_rdb))
+-		return 0;
+-
+ 	/* Publish the QE devices */
+ 	of_platform_bus_probe(NULL, mpc832x_ids, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(mpc832x_declare_of_platform_devices);
++machine_device_initcall(mpc832x_rdb, mpc832x_declare_of_platform_devices);
+ 
+ void __init mpc832x_rdb_init_IRQ(void)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/mpc834x_itx.c powerpc.git/arch/powerpc/platforms/83xx/mpc834x_itx.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/mpc834x_itx.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/mpc834x_itx.c	2008-01-28 20:25:49.000000000 +0100
+@@ -23,6 +23,7 @@
+ #include <linux/delay.h>
+ #include <linux/seq_file.h>
+ #include <linux/root_dev.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/system.h>
+ #include <asm/atomic.h>
+@@ -37,6 +38,17 @@
+ 
+ #include "mpc83xx.h"
+ 
++static struct of_device_id __initdata mpc834x_itx_ids[] = {
++	{ .compatible = "fsl,pq2pro-localbus", },
++	{},
++};
++
++static int __init mpc834x_itx_declare_of_platform_devices(void)
++{
++	return of_platform_bus_probe(NULL, mpc834x_itx_ids, NULL);
++}
++machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices);
++
+ /* ************************************************************************
+  *
+  * Setup the architecture
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/mpc834x_mds.c powerpc.git/arch/powerpc/platforms/83xx/mpc834x_mds.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/mpc834x_mds.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/mpc834x_mds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -23,6 +23,7 @@
+ #include <linux/delay.h>
+ #include <linux/seq_file.h>
+ #include <linux/root_dev.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/system.h>
+ #include <asm/atomic.h>
+@@ -106,14 +107,27 @@
+ 	ipic_set_default_priority();
+ }
+ 
++static struct of_device_id mpc834x_ids[] = {
++	{ .type = "soc", },
++	{ .compatible = "soc", },
++	{},
++};
++
++static int __init mpc834x_declare_of_platform_devices(void)
++{
++	of_platform_bus_probe(NULL, mpc834x_ids, NULL);
++	return 0;
++}
++machine_device_initcall(mpc834x_mds, mpc834x_declare_of_platform_devices);
++
+ /*
+  * Called very early, MMU is off, device-tree isn't unflattened
+  */
+ static int __init mpc834x_mds_probe(void)
+ {
+-        unsigned long root = of_get_flat_dt_root();
++	unsigned long root = of_get_flat_dt_root();
+ 
+-        return of_flat_dt_is_compatible(root, "MPC834xMDS");
++	return of_flat_dt_is_compatible(root, "MPC834xMDS");
+ }
+ 
+ define_machine(mpc834x_mds) {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/mpc836x_mds.c powerpc.git/arch/powerpc/platforms/83xx/mpc836x_mds.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/mpc836x_mds.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/mpc836x_mds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -29,9 +29,9 @@
+ #include <linux/seq_file.h>
+ #include <linux/root_dev.h>
+ #include <linux/initrd.h>
++#include <linux/of_platform.h>
++#include <linux/of_device.h>
+ 
+-#include <asm/of_device.h>
+-#include <asm/of_platform.h>
+ #include <asm/system.h>
+ #include <asm/atomic.h>
+ #include <asm/time.h>
+@@ -141,15 +141,12 @@
+ 
+ static int __init mpc836x_declare_of_platform_devices(void)
+ {
+-	if (!machine_is(mpc836x_mds))
+-		return 0;
+-
+ 	/* Publish the QE devices */
+ 	of_platform_bus_probe(NULL, mpc836x_ids, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(mpc836x_declare_of_platform_devices);
++machine_device_initcall(mpc836x_mds, mpc836x_declare_of_platform_devices);
+ 
+ static void __init mpc836x_mds_init_IRQ(void)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/mpc837x_mds.c powerpc.git/arch/powerpc/platforms/83xx/mpc837x_mds.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/mpc837x_mds.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/mpc837x_mds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,147 @@
++/*
++ * arch/powerpc/platforms/83xx/mpc837x_mds.c
++ *
++ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
++ *
++ * MPC837x MDS board specific routines
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation;  either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/pci.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
++
++#include <asm/time.h>
++#include <asm/ipic.h>
++#include <asm/udbg.h>
++#include <asm/prom.h>
++
++#include "mpc83xx.h"
++
++#define BCSR12_USB_SER_MASK	0x8a
++#define BCSR12_USB_SER_PIN	0x80
++#define BCSR12_USB_SER_DEVICE	0x02
++extern int mpc837x_usb_cfg(void);
++
++static int mpc837xmds_usb_cfg(void)
++{
++	struct device_node *np;
++	const void *phy_type, *mode;
++	void __iomem *bcsr_regs = NULL;
++	u8 bcsr12;
++	int ret;
++
++	ret = mpc837x_usb_cfg();
++	if (ret)
++		return ret;
++	/* Map BCSR area */
++	np = of_find_node_by_name(NULL, "bcsr");
++	if (np) {
++		struct resource res;
++
++		of_address_to_resource(np, 0, &res);
++		bcsr_regs = ioremap(res.start, res.end - res.start + 1);
++		of_node_put(np);
++	}
++	if (!bcsr_regs)
++		return -1;
++
++	np = of_find_node_by_name(NULL, "usb");
++	if (!np)
++		return -ENODEV;
++	phy_type = of_get_property(np, "phy_type", NULL);
++	if (phy_type && !strcmp(phy_type, "ulpi")) {
++		clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN);
++	} else if (phy_type && !strcmp(phy_type, "serial")) {
++		mode = of_get_property(np, "dr_mode", NULL);
++		bcsr12 = in_8(bcsr_regs + 12) & ~BCSR12_USB_SER_MASK;
++		bcsr12 |= BCSR12_USB_SER_PIN;
++		if (mode && !strcmp(mode, "peripheral"))
++			bcsr12 |= BCSR12_USB_SER_DEVICE;
++		out_8(bcsr_regs + 12, bcsr12);
++	} else {
++		printk(KERN_ERR "USB DR: unsupported PHY\n");
++	}
++
++	of_node_put(np);
++	iounmap(bcsr_regs);
++	return 0;
++}
++
++/* ************************************************************************
++ *
++ * Setup the architecture
++ *
++ */
++static void __init mpc837x_mds_setup_arch(void)
++{
++#ifdef CONFIG_PCI
++	struct device_node *np;
++#endif
++
++	if (ppc_md.progress)
++		ppc_md.progress("mpc837x_mds_setup_arch()", 0);
++
++#ifdef CONFIG_PCI
++	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
++		mpc83xx_add_bridge(np);
++#endif
++	mpc837xmds_usb_cfg();
++}
++
++static struct of_device_id mpc837x_ids[] = {
++	{ .type = "soc", },
++	{ .compatible = "soc", },
++	{},
++};
++
++static int __init mpc837x_declare_of_platform_devices(void)
++{
++	/* Publish of_device */
++	of_platform_bus_probe(NULL, mpc837x_ids, NULL);
++
++	return 0;
++}
++machine_device_initcall(mpc837x_mds, mpc837x_declare_of_platform_devices);
++
++static void __init mpc837x_mds_init_IRQ(void)
++{
++	struct device_node *np;
++
++	np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
++	if (!np)
++		return;
++
++	ipic_init(np, 0);
++
++	/* Initialize the default interrupt mapping priorities,
++	 * in case the boot rom changed something on us.
++	 */
++	ipic_set_default_priority();
++}
++
++/*
++ * Called very early, MMU is off, device-tree isn't unflattened
++ */
++static int __init mpc837x_mds_probe(void)
++{
++        unsigned long root = of_get_flat_dt_root();
++
++        return of_flat_dt_is_compatible(root, "fsl,mpc837xmds");
++}
++
++define_machine(mpc837x_mds) {
++	.name			= "MPC837x MDS",
++	.probe			= mpc837x_mds_probe,
++	.setup_arch		= mpc837x_mds_setup_arch,
++	.init_IRQ		= mpc837x_mds_init_IRQ,
++	.get_irq		= ipic_get_irq,
++	.restart		= mpc83xx_restart,
++	.time_init		= mpc83xx_time_init,
++	.calibrate_decr		= generic_calibrate_decr,
++	.progress		= udbg_progress,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/mpc83xx.h powerpc.git/arch/powerpc/platforms/83xx/mpc83xx.h
+--- linux-2.6.24/arch/powerpc/platforms/83xx/mpc83xx.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/mpc83xx.h	2008-01-28 20:25:49.000000000 +0100
+@@ -14,6 +14,7 @@
+ #define MPC83XX_SCCR_USB_DRCM_11   0x00300000
+ #define MPC83XX_SCCR_USB_DRCM_01   0x00100000
+ #define MPC83XX_SCCR_USB_DRCM_10   0x00200000
++#define MPC837X_SCCR_USB_DRCM_11   0x00c00000
+ 
+ /* system i/o configuration register low */
+ #define MPC83XX_SICRL_OFFS         0x114
+@@ -22,6 +23,8 @@
+ #define MPC834X_SICRL_USB1         0x20000000
+ #define MPC831X_SICRL_USB_MASK     0x00000c00
+ #define MPC831X_SICRL_USB_ULPI     0x00000800
++#define MPC837X_SICRL_USB_MASK     0xf0000000
++#define MPC837X_SICRL_USB_ULPI     0x50000000
+ 
+ /* system i/o configuration register high */
+ #define MPC83XX_SICRH_OFFS         0x118
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/pci.c powerpc.git/arch/powerpc/platforms/83xx/pci.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -54,7 +54,7 @@
+ 		       " bus 0\n", dev->full_name);
+ 	}
+ 
+-	pci_assign_all_buses = 1;
++	ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+ 	hose = pcibios_alloc_controller(dev);
+ 	if (!hose)
+ 		return -ENOMEM;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/83xx/usb.c powerpc.git/arch/powerpc/platforms/83xx/usb.c
+--- linux-2.6.24/arch/powerpc/platforms/83xx/usb.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/83xx/usb.c	2008-01-28 20:25:49.000000000 +0100
+@@ -41,7 +41,7 @@
+ 	sicrl = in_be32(immap + MPC83XX_SICRL_OFFS) & ~MPC834X_SICRL_USB_MASK;
+ 	sicrh = in_be32(immap + MPC83XX_SICRH_OFFS) & ~MPC834X_SICRH_USB_UTMI;
+ 
+-	np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr");
++	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
+ 	if (np) {
+ 		sccr |= MPC83XX_SCCR_USB_DRCM_11;  /* 1:3 */
+ 
+@@ -67,7 +67,7 @@
+ 		port0_is_dr = 1;
+ 		of_node_put(np);
+ 	}
+-	np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph");
++	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-mph");
+ 	if (np) {
+ 		sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
+ 
+@@ -111,7 +111,7 @@
+ 	const void *dr_mode;
+ #endif
+ 
+-	np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr");
++	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
+ 	if (!np)
+ 		return -ENODEV;
+ 	prop = of_get_property(np, "phy_type", NULL);
+@@ -179,3 +179,43 @@
+ 	return ret;
+ }
+ #endif /* CONFIG_PPC_MPC831x */
++
++#ifdef CONFIG_PPC_MPC837x
++int mpc837x_usb_cfg(void)
++{
++	void __iomem *immap;
++	struct device_node *np = NULL;
++	const void *prop;
++	int ret = 0;
++
++	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
++	if (!np)
++		return -ENODEV;
++	prop = of_get_property(np, "phy_type", NULL);
++
++	if (!prop || (strcmp(prop, "ulpi") && strcmp(prop, "serial"))) {
++		printk(KERN_WARNING "837x USB PHY type not supported\n");
++		of_node_put(np);
++		return -EINVAL;
++	}
++
++	/* Map IMMR space for pin and clock settings */
++	immap = ioremap(get_immrbase(), 0x1000);
++	if (!immap) {
++		of_node_put(np);
++		return -ENOMEM;
++	}
++
++	/* Configure clock */
++	clrsetbits_be32(immap + MPC83XX_SCCR_OFFS, MPC837X_SCCR_USB_DRCM_11,
++			MPC837X_SCCR_USB_DRCM_11);
++
++	/* Configure pin mux for ULPI/serial */
++	clrsetbits_be32(immap + MPC83XX_SICRL_OFFS, MPC837X_SICRL_USB_MASK,
++			MPC837X_SICRL_USB_ULPI);
++
++	iounmap(immap);
++	of_node_put(np);
++	return ret;
++}
++#endif /* CONFIG_PPC_MPC837x */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/85xx/mpc85xx_ads.c powerpc.git/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+--- linux-2.6.24/arch/powerpc/platforms/85xx/mpc85xx_ads.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/85xx/mpc85xx_ads.c	2008-01-28 20:25:49.000000000 +0100
+@@ -52,9 +52,9 @@
+ {
+ 	int cascade_irq;
+ 
+-	while ((cascade_irq = cpm2_get_irq()) >= 0) {
++	while ((cascade_irq = cpm2_get_irq()) >= 0)
+ 		generic_handle_irq(cascade_irq);
+-	}
++
+ 	desc->chip->eoi(irq);
+ }
+ 
+@@ -70,13 +70,12 @@
+ #endif
+ 
+ 	np = of_find_node_by_type(np, "open-pic");
+-
+-	if (np == NULL) {
++	if (!np) {
+ 		printk(KERN_ERR "Could not find open-pic node\n");
+ 		return;
+ 	}
+ 
+-	if(of_address_to_resource(np, 0, &r)) {
++	if (of_address_to_resource(np, 0, &r)) {
+ 		printk(KERN_ERR "Could not map mpic register space\n");
+ 		of_node_put(np);
+ 		return;
+@@ -100,6 +99,7 @@
+ 	irq = irq_of_parse_and_map(np, 0);
+ 
+ 	cpm2_pic_init(np);
++	of_node_put(np);
+ 	set_irq_chained_handler(irq, cpm2_cascade);
+ #endif
+ }
+@@ -112,7 +112,7 @@
+ 	int port, pin, flags;
+ };
+ 
+-static struct cpm_pin mpc8560_ads_pins[] = {
++static const struct cpm_pin mpc8560_ads_pins[] = {
+ 	/* SCC1 */
+ 	{3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+ 	{3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
+@@ -233,13 +233,11 @@
+ 
+ static int __init declare_of_platform_devices(void)
+ {
+-	if (!machine_is(mpc85xx_ads))
+-		return 0;
+-
+ 	of_platform_bus_probe(NULL, of_bus_ids, NULL);
++
+ 	return 0;
+ }
+-device_initcall(declare_of_platform_devices);
++machine_device_initcall(mpc85xx_ads, declare_of_platform_devices);
+ 
+ /*
+  * Called very early, device-tree isn't unflattened
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/85xx/mpc85xx_cds.c powerpc.git/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+--- linux-2.6.24/arch/powerpc/platforms/85xx/mpc85xx_cds.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/85xx/mpc85xx_cds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -222,9 +222,6 @@
+ 	struct device_node *cascade_node = NULL;
+ 	int cascade_irq;
+ 
+-	if (!machine_is(mpc85xx_cds))
+-		return 0;
+-
+ 	/* Initialize the i8259 controller */
+ 	for_each_node_by_type(np, "interrupt-controller")
+ 		if (of_device_is_compatible(np, "chrp,iic")) {
+@@ -262,8 +259,7 @@
+ 
+ 	return 0;
+ }
+-
+-device_initcall(mpc85xx_cds_8259_attach);
++machine_device_initcall(mpc85xx_cds, mpc85xx_cds_8259_attach);
+ 
+ #endif /* CONFIG_PPC_I8259 */
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/85xx/mpc85xx_ds.c powerpc.git/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+--- linux-2.6.24/arch/powerpc/platforms/85xx/mpc85xx_ds.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/85xx/mpc85xx_ds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -123,7 +123,7 @@
+ 	struct device_node* node;
+ 	struct resource rsrc;
+ 
+-	node = (struct device_node *)hose->arch_data;
++	node = hose->dn;
+ 	of_address_to_resource(node, 0, &rsrc);
+ 
+ 	if ((rsrc.start & 0xfffff) == primary_phb_addr) {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/85xx/mpc85xx_mds.c powerpc.git/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+--- linux-2.6.24/arch/powerpc/platforms/85xx/mpc85xx_mds.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/85xx/mpc85xx_mds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -30,9 +30,9 @@
+ #include <linux/initrd.h>
+ #include <linux/module.h>
+ #include <linux/fsl_devices.h>
++#include <linux/of_platform.h>
++#include <linux/of_device.h>
+ 
+-#include <asm/of_device.h>
+-#include <asm/of_platform.h>
+ #include <asm/system.h>
+ #include <asm/atomic.h>
+ #include <asm/time.h>
+@@ -144,15 +144,12 @@
+ 
+ static int __init mpc85xx_publish_devices(void)
+ {
+-	if (!machine_is(mpc85xx_mds))
+-		return 0;
+-
+ 	/* Publish the QE devices */
+-	of_platform_bus_probe(NULL,mpc85xx_ids,NULL);
++	of_platform_bus_probe(NULL, mpc85xx_ids, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(mpc85xx_publish_devices);
++machine_device_initcall(mpc85xx_mds, mpc85xx_publish_devices);
+ 
+ static void __init mpc85xx_mds_pic_init(void)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/86xx/mpc8610_hpcd.c powerpc.git/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+--- linux-2.6.24/arch/powerpc/platforms/86xx/mpc8610_hpcd.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/86xx/mpc8610_hpcd.c	2008-01-28 20:25:49.000000000 +0100
+@@ -34,9 +34,24 @@
+ 
+ #include <asm/mpic.h>
+ 
++#include <linux/of_platform.h>
+ #include <sysdev/fsl_pci.h>
+ #include <sysdev/fsl_soc.h>
+ 
++static struct of_device_id __initdata mpc8610_ids[] = {
++	{ .compatible = "fsl,mpc8610-immr", },
++	{}
++};
++
++static int __init mpc8610_declare_of_platform_devices(void)
++{
++	/* Without this call, the SSI device driver won't get probed. */
++	of_platform_bus_probe(NULL, mpc8610_ids, NULL);
++
++	return 0;
++}
++machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
++
+ void __init
+ mpc86xx_hpcd_init_irq(void)
+ {
+@@ -124,7 +139,7 @@
+ static void __devinit final_uli5288(struct pci_dev *dev)
+ {
+ 	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+-	struct device_node *hosenode = hose ? hose->arch_data : NULL;
++	struct device_node *hosenode = hose ? hose->dn : NULL;
+ 	struct of_irq oirq;
+ 	int virq, pin = 2;
+ 	u32 laddr[3];
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c powerpc.git/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+--- linux-2.6.24/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c	2008-01-28 20:25:49.000000000 +0100
+@@ -18,6 +18,7 @@
+ #include <linux/kdev_t.h>
+ #include <linux/delay.h>
+ #include <linux/seq_file.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/system.h>
+ #include <asm/time.h>
+@@ -116,7 +117,7 @@
+ 	struct device_node* node;	
+ 	struct resource rsrc;
+ 
+-	node = (struct device_node *)hose->arch_data;
++	node = hose->dn;
+ 	of_address_to_resource(node, 0, &rsrc);
+ 
+ 	if ((rsrc.start & 0xfffff) == 0x8000) {
+@@ -212,6 +213,19 @@
+ 	return 0;
+ }
+ 
++static __initdata struct of_device_id of_bus_ids[] = {
++	{ .compatible = "simple-bus", },
++	{},
++};
++
++static int __init declare_of_platform_devices(void)
++{
++	of_platform_bus_probe(NULL, of_bus_ids, NULL);
++
++	return 0;
++}
++machine_device_initcall(mpc86xx_hpcn, declare_of_platform_devices);
++
+ define_machine(mpc86xx_hpcn) {
+ 	.name			= "MPC86xx HPCN",
+ 	.probe			= mpc86xx_hpcn_probe,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/8xx/Kconfig powerpc.git/arch/powerpc/platforms/8xx/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/8xx/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/8xx/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -18,6 +18,7 @@
+ config MPC86XADS
+ 	bool "MPC86XADS"
+ 	select CPM1
++	select PPC_CPM_NEW_BINDING
+ 	help
+ 	  MPC86x Application Development System by Freescale Semiconductor.
+ 	  The MPC86xADS is meant to serve as a platform for s/w and h/w
+@@ -43,6 +44,15 @@
+ 	  This board is also resold by Freescale as the QUICCStart
+ 	  MPC885 Evaluation System and/or the CWH-PPC-885XN-VE.
+ 
++config PPC_ADDER875
++	bool "Analogue & Micro Adder 875"
++	select CPM1
++	select PPC_CPM_NEW_BINDING
++	select REDBOOT
++	help
++	  This enables support for the Analogue & Micro Adder 875
++	  board.
++
+ endchoice
+ 
+ menu "Freescale Ethernet driver platform-specific options"
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/8xx/Makefile powerpc.git/arch/powerpc/platforms/8xx/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/8xx/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/8xx/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -5,3 +5,4 @@
+ obj-$(CONFIG_MPC885ADS)   += mpc885ads_setup.o
+ obj-$(CONFIG_MPC86XADS)   += mpc86xads_setup.o
+ obj-$(CONFIG_PPC_EP88XC)  += ep88xc.o
++obj-$(CONFIG_PPC_ADDER875) += adder875.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/8xx/adder875.c powerpc.git/arch/powerpc/platforms/8xx/adder875.c
+--- linux-2.6.24/arch/powerpc/platforms/8xx/adder875.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/8xx/adder875.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,118 @@
++/* Analogue & Micro Adder MPC875 board support
++ *
++ * Author: Scott Wood <scottwood@freescale.com>
++ *
++ * Copyright (c) 2007 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, version 2, as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/init.h>
++#include <linux/fs_enet_pd.h>
++#include <linux/of_platform.h>
++
++#include <asm/time.h>
++#include <asm/machdep.h>
++#include <asm/commproc.h>
++#include <asm/fs_pd.h>
++#include <asm/udbg.h>
++#include <asm/prom.h>
++
++#include <sysdev/commproc.h>
++
++struct cpm_pin {
++	int port, pin, flags;
++};
++
++static __initdata struct cpm_pin adder875_pins[] = {
++	/* SMC1 */
++	{CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
++	{CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
++
++	/* MII1 */
++	{CPM_PORTA, 0, CPM_PIN_INPUT},
++	{CPM_PORTA, 1, CPM_PIN_INPUT},
++	{CPM_PORTA, 2, CPM_PIN_INPUT},
++	{CPM_PORTA, 3, CPM_PIN_INPUT},
++	{CPM_PORTA, 4, CPM_PIN_OUTPUT},
++	{CPM_PORTA, 10, CPM_PIN_OUTPUT},
++	{CPM_PORTA, 11, CPM_PIN_OUTPUT},
++	{CPM_PORTB, 19, CPM_PIN_INPUT},
++	{CPM_PORTB, 31, CPM_PIN_INPUT},
++	{CPM_PORTC, 12, CPM_PIN_INPUT},
++	{CPM_PORTC, 13, CPM_PIN_INPUT},
++	{CPM_PORTE, 30, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 31, CPM_PIN_OUTPUT},
++
++	/* MII2 */
++	{CPM_PORTE, 14, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{CPM_PORTE, 15, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{CPM_PORTE, 16, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 17, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{CPM_PORTE, 18, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{CPM_PORTE, 19, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{CPM_PORTE, 20, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
++	{CPM_PORTE, 21, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 22, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 23, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 24, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 25, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 26, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 27, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 28, CPM_PIN_OUTPUT},
++	{CPM_PORTE, 29, CPM_PIN_OUTPUT},
++};
++
++static void __init init_ioports(void)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(adder875_pins); i++) {
++		const struct cpm_pin *pin = &adder875_pins[i];
++		cpm1_set_pin(pin->port, pin->pin, pin->flags);
++	}
++
++	cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
++
++	/* Set FEC1 and FEC2 to MII mode */
++	clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
++}
++
++static void __init adder875_setup(void)
++{
++	cpm_reset();
++	init_ioports();
++}
++
++static int __init adder875_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++	return of_flat_dt_is_compatible(root, "analogue-and-micro,adder875");
++}
++
++static __initdata struct of_device_id of_bus_ids[] = {
++	{ .compatible = "simple-bus", },
++	{},
++};
++
++static int __init declare_of_platform_devices(void)
++{
++	of_platform_bus_probe(NULL, of_bus_ids, NULL);
++	return 0;
++}
++machine_device_initcall(adder875, declare_of_platform_devices);
++
++define_machine(adder875) {
++	.name = "Adder MPC875",
++	.probe = adder875_probe,
++	.setup_arch = adder875_setup,
++	.init_IRQ = m8xx_pic_init,
++	.get_irq = mpc8xx_get_irq,
++	.restart = mpc8xx_restart,
++	.calibrate_decr = generic_calibrate_decr,
++	.set_rtc_time = mpc8xx_set_rtc_time,
++	.get_rtc_time = mpc8xx_get_rtc_time,
++	.progress = udbg_progress,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/8xx/ep88xc.c powerpc.git/arch/powerpc/platforms/8xx/ep88xc.c
+--- linux-2.6.24/arch/powerpc/platforms/8xx/ep88xc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/8xx/ep88xc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -155,12 +155,11 @@
+ static int __init declare_of_platform_devices(void)
+ {
+ 	/* Publish the QE devices */
+-	if (machine_is(ep88xc))
+-		of_platform_bus_probe(NULL, of_bus_ids, NULL);
++	of_platform_bus_probe(NULL, of_bus_ids, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(declare_of_platform_devices);
++machine_device_initcall(ep88xc, declare_of_platform_devices);
+ 
+ define_machine(ep88xc) {
+ 	.name = "Embedded Planet EP88xC",
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/8xx/m8xx_setup.c powerpc.git/arch/powerpc/platforms/8xx/m8xx_setup.c
+--- linux-2.6.24/arch/powerpc/platforms/8xx/m8xx_setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/8xx/m8xx_setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -120,7 +120,7 @@
+ 	ppc_tb_freq /= 16;
+ 	ppc_proc_freq = 50000000;
+ 	if (!get_freq("clock-frequency", &ppc_proc_freq))
+-		printk(KERN_ERR "WARNING: Estimating processor frequency"
++		printk(KERN_ERR "WARNING: Estimating processor frequency "
+ 		                "(not found)\n");
+ 
+ 	printk("Decrementer Frequency = 0x%lx\n", ppc_tb_freq);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/8xx/mpc86xads.h powerpc.git/arch/powerpc/platforms/8xx/mpc86xads.h
+--- linux-2.6.24/arch/powerpc/platforms/8xx/mpc86xads.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/8xx/mpc86xads.h	2008-01-28 20:25:49.000000000 +0100
+@@ -15,27 +15,6 @@
+ #ifndef __ASM_MPC86XADS_H__
+ #define __ASM_MPC86XADS_H__
+ 
+-#include <sysdev/fsl_soc.h>
+-
+-/* U-Boot maps BCSR to 0xff080000 */
+-#define BCSR_ADDR		((uint)0xff080000)
+-#define BCSR_SIZE		((uint)32)
+-#define BCSR0			((uint)(BCSR_ADDR + 0x00))
+-#define BCSR1			((uint)(BCSR_ADDR + 0x04))
+-#define BCSR2			((uint)(BCSR_ADDR + 0x08))
+-#define BCSR3			((uint)(BCSR_ADDR + 0x0c))
+-#define BCSR4			((uint)(BCSR_ADDR + 0x10))
+-
+-#define CFG_PHYDEV_ADDR		((uint)0xff0a0000)
+-#define BCSR5			((uint)(CFG_PHYDEV_ADDR + 0x300))
+-
+-#define MPC8xx_CPM_OFFSET	(0x9c0)
+-#define CPM_MAP_ADDR		(get_immrbase() + MPC8xx_CPM_OFFSET)
+-#define CPM_IRQ_OFFSET		16     // for compability with cpm_uart driver
+-
+-#define PCMCIA_MEM_ADDR		((uint)0xff020000)
+-#define PCMCIA_MEM_SIZE		((uint)(64 * 1024))
+-
+ /* Bits of interest in the BCSRs.
+  */
+ #define BCSR1_ETHEN		((uint)0x20000000)
+@@ -64,28 +43,5 @@
+ #define BCSR5_MII1_EN		0x02
+ #define BCSR5_MII1_RST		0x01
+ 
+-/* Interrupt level assignments */
+-#define PHY_INTERRUPT	SIU_IRQ7	/* PHY link change interrupt */
+-#define SIU_INT_FEC1	SIU_LEVEL1	/* FEC1 interrupt */
+-#define FEC_INTERRUPT	SIU_INT_FEC1	/* FEC interrupt */
+-
+-/* We don't use the 8259 */
+-#define NR_8259_INTS	0
+-
+-/* CPM Ethernet through SCC1 */
+-#define PA_ENET_RXD     ((ushort)0x0001)
+-#define PA_ENET_TXD     ((ushort)0x0002)
+-#define PA_ENET_TCLK    ((ushort)0x0100)
+-#define PA_ENET_RCLK    ((ushort)0x0200)
+-#define PB_ENET_TENA    ((uint)0x00001000)
+-#define PC_ENET_CLSN    ((ushort)0x0010)
+-#define PC_ENET_RENA    ((ushort)0x0020)
+-
+-/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to
+- * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+- */
+-#define SICR_ENET_MASK  ((uint)0x000000ff)
+-#define SICR_ENET_CLKRT ((uint)0x0000002c)
+-
+ #endif /* __ASM_MPC86XADS_H__ */
+ #endif /* __KERNEL__ */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/8xx/mpc86xads_setup.c powerpc.git/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+--- linux-2.6.24/arch/powerpc/platforms/8xx/mpc86xads_setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/8xx/mpc86xads_setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -6,264 +6,133 @@
+  *
+  * Copyright 2005 MontaVista Software Inc.
+  *
++ * Heavily modified by Scott Wood <scottwood@freescale.com>
++ * Copyright 2007 Freescale Semiconductor, Inc.
++ *
+  * This file is licensed under the terms of the GNU General Public License
+  * version 2. This program is licensed "as is" without any warranty of any
+  * kind, whether express or implied.
+  */
+ 
+ #include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/param.h>
+-#include <linux/string.h>
+-#include <linux/ioport.h>
+-#include <linux/device.h>
+-#include <linux/delay.h>
+-#include <linux/root_dev.h>
+-
+-#include <linux/fs_enet_pd.h>
+-#include <linux/fs_uart_pd.h>
+-#include <linux/mii.h>
++#include <linux/of_platform.h>
+ 
+-#include <asm/delay.h>
+ #include <asm/io.h>
+ #include <asm/machdep.h>
+-#include <asm/page.h>
+-#include <asm/processor.h>
+ #include <asm/system.h>
+ #include <asm/time.h>
+ #include <asm/mpc8xx.h>
+ #include <asm/8xx_immap.h>
+ #include <asm/commproc.h>
+ #include <asm/fs_pd.h>
+-#include <asm/prom.h>
++#include <asm/udbg.h>
+ 
+ #include <sysdev/commproc.h>
+ 
+-static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
+-static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
+-static void init_scc1_ioports(struct fs_platform_info* ptr);
+-
+-void __init mpc86xads_board_setup(void)
+-{
+-	cpm8xx_t *cp;
+- 	unsigned int *bcsr_io;
+-	u8 tmpval8;
+-
+-	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+-	cp = (cpm8xx_t *)immr_map(im_cpm);
++#include "mpc86xads.h"
+ 
+-	if (bcsr_io == NULL) {
+-		printk(KERN_CRIT "Could not remap BCSR\n");
+-		return;
+-	}
+-#ifdef CONFIG_SERIAL_CPM_SMC1
+-	clrbits32(bcsr_io, BCSR1_RS232EN_1);
+-	clrbits32(&cp->cp_simode, 0xe0000000 >> 17);	/* brg1 */
+-	tmpval8 = in_8(&(cp->cp_smc[0].smc_smcm)) | (SMCM_RX | SMCM_TX);
+-	out_8(&(cp->cp_smc[0].smc_smcm), tmpval8);
+-	clrbits16(&cp->cp_smc[0].smc_smcmr, SMCMR_REN | SMCMR_TEN);
+-#else
+-	setbits32(bcsr_io,BCSR1_RS232EN_1);
+-	out_be16(&cp->cp_smc[0].smc_smcmr, 0);
+-	out_8(&cp->cp_smc[0].smc_smce, 0);
+-#endif
+-
+-#ifdef CONFIG_SERIAL_CPM_SMC2
+-	clrbits32(bcsr_io,BCSR1_RS232EN_2);
+-	clrbits32(&cp->cp_simode, 0xe0000000 >> 1);
+-	setbits32(&cp->cp_simode, 0x20000000 >> 1);	/* brg2 */
+-	tmpval8 = in_8(&(cp->cp_smc[1].smc_smcm)) | (SMCM_RX | SMCM_TX);
+-	out_8(&(cp->cp_smc[1].smc_smcm), tmpval8);
+-	clrbits16(&cp->cp_smc[1].smc_smcmr, SMCMR_REN | SMCMR_TEN);
+-
+-	init_smc2_uart_ioports(0);
+-#else
+-	setbits32(bcsr_io,BCSR1_RS232EN_2);
+-	out_be16(&cp->cp_smc[1].smc_smcmr, 0);
+-	out_8(&cp->cp_smc[1].smc_smce, 0);
+-#endif
+-	immr_unmap(cp);
+-	iounmap(bcsr_io);
+-}
++struct cpm_pin {
++	int port, pin, flags;
++};
+ 
++static struct cpm_pin mpc866ads_pins[] = {
++	/* SMC1 */
++	{CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
++	{CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
++
++	/* SMC2 */
++	{CPM_PORTB, 21, CPM_PIN_INPUT}, /* RX */
++	{CPM_PORTB, 20, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
++
++	/* SCC1 */
++	{CPM_PORTA, 6, CPM_PIN_INPUT}, /* CLK1 */
++	{CPM_PORTA, 7, CPM_PIN_INPUT}, /* CLK2 */
++	{CPM_PORTA, 14, CPM_PIN_INPUT}, /* TX */
++	{CPM_PORTA, 15, CPM_PIN_INPUT}, /* RX */
++	{CPM_PORTB, 19, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */
++	{CPM_PORTC, 10, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* RENA */
++	{CPM_PORTC, 11, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* CLSN */
++
++	/* MII */
++	{CPM_PORTD, 3, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 4, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 5, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 6, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 7, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 8, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 9, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 10, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 11, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 12, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 13, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 14, CPM_PIN_OUTPUT},
++	{CPM_PORTD, 15, CPM_PIN_OUTPUT},
++};
+ 
+-static void init_fec1_ioports(struct fs_platform_info* ptr)
++static void __init init_ioports(void)
+ {
+-	iop8xx_t *io_port = (iop8xx_t *)immr_map(im_ioport);
++	int i;
+ 
+-	/* configure FEC1 pins  */
++	for (i = 0; i < ARRAY_SIZE(mpc866ads_pins); i++) {
++		struct cpm_pin *pin = &mpc866ads_pins[i];
++		cpm1_set_pin(pin->port, pin->pin, pin->flags);
++	}
+ 
+-	setbits16(&io_port->iop_pdpar, 0x1fff);
+-	setbits16(&io_port->iop_pddir, 0x1fff);
++	cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
++	cpm1_clk_setup(CPM_CLK_SMC2, CPM_BRG2, CPM_CLK_RTX);
++	cpm1_clk_setup(CPM_CLK_SCC1, CPM_CLK1, CPM_CLK_TX);
++	cpm1_clk_setup(CPM_CLK_SCC1, CPM_CLK2, CPM_CLK_RX);
+ 
+-	immr_unmap(io_port);
++	/* Set FEC1 and FEC2 to MII mode */
++	clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
+ }
+ 
+-void init_fec_ioports(struct fs_platform_info *fpi)
++static void __init mpc86xads_setup_arch(void)
+ {
+-	int fec_no = fs_get_fec_index(fpi->fs_no);
++	struct device_node *np;
++	u32 __iomem *bcsr_io;
++
++	cpm_reset();
++	init_ioports();
+ 
+-	switch (fec_no) {
+-	case 0:
+-		init_fec1_ioports(fpi);
+-		break;
+-	default:
+-		printk(KERN_ERR "init_fec_ioports: invalid FEC number\n");
++	np = of_find_compatible_node(NULL, NULL, "fsl,mpc866ads-bcsr");
++	if (!np) {
++		printk(KERN_CRIT "Could not find fsl,mpc866ads-bcsr node\n");
+ 		return;
+ 	}
+-}
+ 
+-static void init_scc1_ioports(struct fs_platform_info* fpi)
+-{
+-	unsigned *bcsr_io;
+-	iop8xx_t *io_port;
+-	cpm8xx_t *cp;
+-
+-	bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE);
+-	io_port = (iop8xx_t *)immr_map(im_ioport);
+-	cp = (cpm8xx_t *)immr_map(im_cpm);
++	bcsr_io = of_iomap(np, 0);
++	of_node_put(np);
+ 
+ 	if (bcsr_io == NULL) {
+ 		printk(KERN_CRIT "Could not remap BCSR\n");
+ 		return;
+ 	}
+ 
+-	/* Configure port A pins for Txd and Rxd.
+-	 */
+-	setbits16(&io_port->iop_papar, PA_ENET_RXD | PA_ENET_TXD);
+-	clrbits16(&io_port->iop_padir, PA_ENET_RXD | PA_ENET_TXD);
+-	clrbits16(&io_port->iop_paodr, PA_ENET_TXD);
+-
+-	/* Configure port C pins to enable CLSN and RENA.
+-	 */
+-	clrbits16(&io_port->iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
+-	clrbits16(&io_port->iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
+-	setbits16(&io_port->iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
+-
+-	/* Configure port A for TCLK and RCLK.
+-	 */
+-	setbits16(&io_port->iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
+-        clrbits16(&io_port->iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
+-        clrbits32(&cp->cp_pbpar, PB_ENET_TENA);
+-        clrbits32(&cp->cp_pbdir, PB_ENET_TENA);
+-
+-	/* Configure Serial Interface clock routing.
+-	 * First, clear all SCC bits to zero, then set the ones we want.
+-	 */
+-	clrbits32(&cp->cp_sicr, SICR_ENET_MASK);
+-	setbits32(&cp->cp_sicr, SICR_ENET_CLKRT);
+-
+-	/* In the original SCC enet driver the following code is placed at
+-	   the end of the initialization */
+-        setbits32(&cp->cp_pbpar, PB_ENET_TENA);
+-        setbits32(&cp->cp_pbdir, PB_ENET_TENA);
+-
+-	clrbits32(bcsr_io+1, BCSR1_ETHEN);
++	clrbits32(bcsr_io, BCSR1_RS232EN_1 | BCSR1_RS232EN_2 | BCSR1_ETHEN);
+ 	iounmap(bcsr_io);
+-	immr_unmap(cp);
+-	immr_unmap(io_port);
+-}
+-
+-void init_scc_ioports(struct fs_platform_info *fpi)
+-{
+-	int scc_no = fs_get_scc_index(fpi->fs_no);
+-
+-	switch (scc_no) {
+-	case 0:
+-		init_scc1_ioports(fpi);
+-		break;
+-	default:
+-		printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
+-		return;
+-	}
+ }
+ 
+-
+-
+-static void init_smc1_uart_ioports(struct fs_uart_platform_info* ptr)
++static int __init mpc86xads_probe(void)
+ {
+-        unsigned *bcsr_io;
+-	cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm);
+-
+-	setbits32(&cp->cp_pbpar, 0x000000c0);
+-	clrbits32(&cp->cp_pbdir, 0x000000c0);
+-	clrbits16(&cp->cp_pbodr, 0x00c0);
+-	immr_unmap(cp);
+-
+-        bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+-
+-        if (bcsr_io == NULL) {
+-                printk(KERN_CRIT "Could not remap BCSR1\n");
+-                return;
+-        }
+-        clrbits32(bcsr_io,BCSR1_RS232EN_1);
+-        iounmap(bcsr_io);
++	unsigned long root = of_get_flat_dt_root();
++	return of_flat_dt_is_compatible(root, "fsl,mpc866ads");
+ }
+ 
+-static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi)
+-{
+-        unsigned *bcsr_io;
+-	cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm);
+-
+-	setbits32(&cp->cp_pbpar, 0x00000c00);
+-	clrbits32(&cp->cp_pbdir, 0x00000c00);
+-	clrbits16(&cp->cp_pbodr, 0x0c00);
+-	immr_unmap(cp);
+-
+-        bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+-
+-        if (bcsr_io == NULL) {
+-                printk(KERN_CRIT "Could not remap BCSR1\n");
+-                return;
+-        }
+-        clrbits32(bcsr_io,BCSR1_RS232EN_2);
+-        iounmap(bcsr_io);
+-}
++static struct of_device_id __initdata of_bus_ids[] = {
++	{ .name = "soc", },
++	{ .name = "cpm", },
++	{ .name = "localbus", },
++	{},
++};
+ 
+-void init_smc_ioports(struct fs_uart_platform_info *data)
++static int __init declare_of_platform_devices(void)
+ {
+-	int smc_no = fs_uart_id_fsid2smc(data->fs_no);
+-
+-	switch (smc_no) {
+-	case 0:
+-		init_smc1_uart_ioports(data);
+-		data->brg = data->clk_rx;
+-		break;
+-	case 1:
+-		init_smc2_uart_ioports(data);
+-		data->brg = data->clk_rx;
+-		break;
+-	default:
+-		printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
+-		return;
+-	}
+-}
++	of_platform_bus_probe(NULL, of_bus_ids, NULL);
+ 
+-int platform_device_skip(const char *model, int id)
+-{
+ 	return 0;
+ }
+-
+-static void __init mpc86xads_setup_arch(void)
+-{
+-	cpm_reset();
+-
+-	mpc86xads_board_setup();
+-
+-	ROOT_DEV = Root_NFS;
+-}
+-
+-static int __init mpc86xads_probe(void)
+-{
+-	char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
+-					  "model", NULL);
+-	if (model == NULL)
+-		return 0;
+-	if (strcmp(model, "MPC866ADS"))
+-		return 0;
+-
+-	return 1;
+-}
++machine_device_initcall(mpc86x_ads, declare_of_platform_devices);
+ 
+ define_machine(mpc86x_ads) {
+ 	.name			= "MPC86x ADS",
+@@ -275,4 +144,5 @@
+ 	.calibrate_decr		= mpc8xx_calibrate_decr,
+ 	.set_rtc_time		= mpc8xx_set_rtc_time,
+ 	.get_rtc_time		= mpc8xx_get_rtc_time,
++	.progress		= udbg_progress,
+ };
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/8xx/mpc885ads_setup.c powerpc.git/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+--- linux-2.6.24/arch/powerpc/platforms/8xx/mpc885ads_setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/8xx/mpc885ads_setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -264,12 +264,11 @@
+ static int __init declare_of_platform_devices(void)
+ {
+ 	/* Publish the QE devices */
+-	if (machine_is(mpc885_ads))
+-		of_platform_bus_probe(NULL, of_bus_ids, NULL);
++	of_platform_bus_probe(NULL, of_bus_ids, NULL);
+ 
+ 	return 0;
+ }
+-device_initcall(declare_of_platform_devices);
++machine_device_initcall(mpc885_ads, declare_of_platform_devices);
+ 
+ define_machine(mpc885_ads) {
+ 	.name			= "Freescale MPC885 ADS",
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/Kconfig powerpc.git/arch/powerpc/platforms/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -22,6 +22,7 @@
+ 	depends on 6xx
+ 	select FSL_SOC
+ 	select 83xx
++	select IPIC
+ 	select WANT_DEVICE_TREE
+ 
+ config PPC_86xx
+@@ -80,6 +81,10 @@
+ 	bool
+ 	default y
+ 
++config IPIC
++	bool
++	default n
++
+ config MPIC
+ 	bool
+ 	default n
+@@ -265,6 +270,7 @@
+ config QUICC_ENGINE
+ 	bool
+ 	select PPC_LIB_RHEAP
++	select CRC32
+ 	help
+ 	  The QUICC Engine (QE) is a new generation of communications
+ 	  coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
+@@ -315,6 +321,12 @@
+ config CPM
+ 	bool
+ 
++config OF_RTC
++	bool
++	help
++	  Uses information from the OF or flattened device tree to instatiate
++	  platform devices for direct mapped RTC chips like the DS1742 or DS1743.
++
+ source "arch/powerpc/sysdev/bestcomm/Kconfig"
+ 
+ endmenu
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/Kconfig.cputype powerpc.git/arch/powerpc/platforms/Kconfig.cputype
+--- linux-2.6.24/arch/powerpc/platforms/Kconfig.cputype	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/Kconfig.cputype	2008-01-28 20:25:49.000000000 +0100
+@@ -43,6 +43,7 @@
+ 	bool "AMCC 40x"
+ 	select PPC_DCR_NATIVE
+ 	select WANT_DEVICE_TREE
++	select PPC_UDBG_16550
+ 
+ config 44x
+ 	bool "AMCC 44x"
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/Makefile powerpc.git/arch/powerpc/platforms/cell/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/cell/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -20,7 +20,7 @@
+ 
+ obj-$(CONFIG_SPU_BASE)			+= spu_callbacks.o spu_base.o \
+ 					   spu_notify.o \
+-					   spu_syscalls.o \
++					   spu_syscalls.o spu_fault.o \
+ 					   $(spu-priv1-y) \
+ 					   $(spu-manage-y) \
+ 					   spufs/
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/cbe_cpufreq.c powerpc.git/arch/powerpc/platforms/cell/cbe_cpufreq.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/cbe_cpufreq.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/cbe_cpufreq.c	2008-01-28 20:25:49.000000000 +0100
+@@ -21,8 +21,9 @@
+  */
+ 
+ #include <linux/cpufreq.h>
++#include <linux/of_platform.h>
++
+ #include <asm/machdep.h>
+-#include <asm/of_platform.h>
+ #include <asm/prom.h>
+ #include <asm/cell-regs.h>
+ #include "cbe_cpufreq.h"
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c powerpc.git/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c	2008-01-28 20:25:49.000000000 +0100
+@@ -23,7 +23,8 @@
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/timer.h>
+-#include <asm/of_platform.h>
++#include <linux/of_platform.h>
++
+ #include <asm/processor.h>
+ #include <asm/prom.h>
+ #include <asm/pmi.h>
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/cbe_regs.c powerpc.git/arch/powerpc/platforms/cell/cbe_regs.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/cbe_regs.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/cbe_regs.c	2008-01-28 20:25:49.000000000 +0100
+@@ -9,13 +9,13 @@
+ #include <linux/percpu.h>
+ #include <linux/types.h>
+ #include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/io.h>
+ #include <asm/pgtable.h>
+ #include <asm/prom.h>
+ #include <asm/ptrace.h>
+-#include <asm/of_device.h>
+-#include <asm/of_platform.h>
+ #include <asm/cell-regs.h>
+ 
+ /*
+@@ -256,6 +256,7 @@
+ 			printk(KERN_ERR "cbe_regs: More BE chips than supported"
+ 			       "!\n");
+ 			cbe_regs_map_count--;
++			of_node_put(cpu);
+ 			return;
+ 		}
+ 		map->cpu_node = cpu;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/io-workarounds.c powerpc.git/arch/powerpc/platforms/cell/io-workarounds.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/io-workarounds.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/io-workarounds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -238,7 +238,7 @@
+ static void __init spider_pci_add_one(struct pci_controller *phb)
+ {
+ 	struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count];
+-	struct device_node *np = phb->arch_data;
++	struct device_node *np = phb->dn;
+ 	struct resource rsrc;
+ 	void __iomem *regs;
+ 
+@@ -309,15 +309,12 @@
+ {
+ 	struct pci_controller *phb;
+ 
+-	if (!machine_is(cell))
+-		return 0;
+-
+ 	/* Find spider bridges. We assume they have been all probed
+ 	 * in setup_arch(). If that was to change, we would need to
+ 	 * update this code to cope with dynamically added busses
+ 	 */
+ 	list_for_each_entry(phb, &hose_list, list_node) {
+-		struct device_node *np = phb->arch_data;
++		struct device_node *np = phb->dn;
+ 		const char *model = of_get_property(np, "model", NULL);
+ 
+ 		/* If no model property or name isn't exactly "pci", skip */
+@@ -343,4 +340,4 @@
+ 
+ 	return 0;
+ }
+-arch_initcall(spider_pci_workaround_init);
++machine_arch_initcall(cell, spider_pci_workaround_init);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/iommu.c powerpc.git/arch/powerpc/platforms/cell/iommu.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/iommu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/iommu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -26,14 +26,15 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/notifier.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/prom.h>
+ #include <asm/iommu.h>
+ #include <asm/machdep.h>
+ #include <asm/pci-bridge.h>
+ #include <asm/udbg.h>
+-#include <asm/of_platform.h>
+ #include <asm/lmb.h>
++#include <asm/firmware.h>
+ #include <asm/cell-regs.h>
+ 
+ #include "interrupt.h"
+@@ -309,8 +310,8 @@
+ {
+ 	struct page *page;
+ 	int ret, i;
+-	unsigned long reg, segments, pages_per_segment, ptab_size, n_pte_pages;
+-	unsigned long xlate_base;
++	unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
++		      n_pte_pages, xlate_base;
+ 	unsigned int virq;
+ 
+ 	if (cell_iommu_find_ioc(iommu->nid, &xlate_base))
+@@ -327,7 +328,8 @@
+ 			__FUNCTION__, iommu->nid, segments, pages_per_segment);
+ 
+ 	/* set up the segment table */
+-	page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
++	stab_size = segments * sizeof(unsigned long);
++	page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
+ 	BUG_ON(!page);
+ 	iommu->stab = page_address(page);
+ 	clear_page(iommu->stab);
+@@ -489,15 +491,18 @@
+ 	return NULL;
+ }
+ 
++static unsigned long cell_dma_direct_offset;
++
+ static void cell_dma_dev_setup(struct device *dev)
+ {
+ 	struct iommu_window *window;
+ 	struct cbe_iommu *iommu;
+ 	struct dev_archdata *archdata = &dev->archdata;
+ 
+-	/* If we run without iommu, no need to do anything */
+-	if (get_pci_dma_ops() == &dma_direct_ops)
++	if (get_pci_dma_ops() == &dma_direct_ops) {
++		archdata->dma_data = (void *)cell_dma_direct_offset;
+ 		return;
++	}
+ 
+ 	/* Current implementation uses the first window available in that
+ 	 * node's iommu. We -might- do something smarter later though it may
+@@ -653,7 +658,7 @@
+ 
+ 	/* If we have no Axon, we set up the spider DMA magic offset */
+ 	if (of_find_node_by_name(NULL, "axon") == NULL)
+-		dma_direct_offset = SPIDER_DMA_OFFSET;
++		cell_dma_direct_offset = SPIDER_DMA_OFFSET;
+ 
+ 	/* Now we need to check to see where the memory is mapped
+ 	 * in PCI space. We assume that all busses use the same dma
+@@ -687,10 +692,13 @@
+ 		return -ENODEV;
+ 	}
+ 
+-	dma_direct_offset += base;
++	cell_dma_direct_offset += base;
++
++	if (cell_dma_direct_offset != 0)
++		ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
+ 
+ 	printk("iommu: disabled, direct DMA offset is 0x%lx\n",
+-	       dma_direct_offset);
++	       cell_dma_direct_offset);
+ 
+ 	return 0;
+ }
+@@ -699,9 +707,6 @@
+ {
+ 	struct device_node *np;
+ 
+-	if (!machine_is(cell))
+-		return -ENODEV;
+-
+ 	/* If IOMMU is disabled or we have little enough RAM to not need
+ 	 * to enable it, we setup a direct mapping.
+ 	 *
+@@ -744,5 +749,6 @@
+ 
+ 	return 0;
+ }
+-arch_initcall(cell_iommu_init);
++machine_arch_initcall(cell, cell_iommu_init);
++machine_arch_initcall(celleb_native, cell_iommu_init);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/pmu.c powerpc.git/arch/powerpc/platforms/cell/pmu.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/pmu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/pmu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -213,7 +213,7 @@
+ 		break;
+ 
+ 	case pm_interval:
+-		READ_SHADOW_REG(val, pm_interval);
++		READ_MMIO_UPPER32(val, pm_interval);
+ 		break;
+ 
+ 	case pm_start_stop:
+@@ -381,9 +381,6 @@
+ 	unsigned int irq;
+ 	int rc, node;
+ 
+-	if (!machine_is(cell))
+-		return 0;
+-
+ 	for_each_node(node) {
+ 		irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI |
+ 					       (node << IIC_IRQ_NODE_SHIFT));
+@@ -404,7 +401,7 @@
+ 
+ 	return 0;
+ }
+-arch_initcall(cbe_init_pm_irq);
++machine_arch_initcall(cell, cbe_init_pm_irq);
+ 
+ void cbe_sync_irq(int node)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/setup.c powerpc.git/arch/powerpc/platforms/cell/setup.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -30,6 +30,7 @@
+ #include <linux/console.h>
+ #include <linux/mutex.h>
+ #include <linux/memory_hotplug.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/mmu.h>
+ #include <asm/processor.h>
+@@ -51,7 +52,6 @@
+ #include <asm/spu_priv1.h>
+ #include <asm/udbg.h>
+ #include <asm/mpic.h>
+-#include <asm/of_platform.h>
+ #include <asm/cell-regs.h>
+ 
+ #include "interrupt.h"
+@@ -85,9 +85,6 @@
+ {
+ 	int node;
+ 
+-	if (!machine_is(cell))
+-		return 0;
+-
+ 	/* Publish OF platform devices for southbridge IOs */
+ 	of_platform_bus_probe(NULL, NULL, NULL);
+ 
+@@ -101,7 +98,7 @@
+ 	}
+ 	return 0;
+ }
+-device_initcall(cell_publish_devices);
++machine_device_initcall(cell, cell_publish_devices);
+ 
+ static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/smp.c powerpc.git/arch/powerpc/platforms/cell/smp.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/smp.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/smp.c	2008-01-28 20:25:49.000000000 +0100
+@@ -42,6 +42,7 @@
+ #include <asm/firmware.h>
+ #include <asm/system.h>
+ #include <asm/rtas.h>
++#include <asm/cputhreads.h>
+ 
+ #include "interrupt.h"
+ #include <asm/udbg.h>
+@@ -182,7 +183,7 @@
+ 	 */
+ 	if (system_state < SYSTEM_RUNNING &&
+ 	    cpu_has_feature(CPU_FTR_SMT) &&
+-	    !smt_enabled_at_boot && nr % 2 != 0)
++	    !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
+ 		return 0;
+ 
+ 	return 1;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spu_base.c powerpc.git/arch/powerpc/platforms/cell/spu_base.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spu_base.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spu_base.c	2008-01-28 20:25:49.000000000 +0100
+@@ -34,6 +34,7 @@
+ #include <linux/linux_logo.h>
+ #include <asm/spu.h>
+ #include <asm/spu_priv1.h>
++#include <asm/spu_csa.h>
+ #include <asm/xmon.h>
+ #include <asm/prom.h>
+ 
+@@ -47,6 +48,13 @@
+ EXPORT_SYMBOL_GPL(cbe_spu_info);
+ 
+ /*
++ * The spufs fault-handling code needs to call force_sig_info to raise signals
++ * on DMA errors. Export it here to avoid general kernel-wide access to this
++ * function
++ */
++EXPORT_SYMBOL_GPL(force_sig_info);
++
++/*
+  * Protects cbe_spu_info and spu->number.
+  */
+ static DEFINE_SPINLOCK(spu_lock);
+@@ -66,6 +74,10 @@
+ static DEFINE_SPINLOCK(spu_full_list_lock);
+ static DEFINE_MUTEX(spu_full_list_mutex);
+ 
++struct spu_slb {
++	u64 esid, vsid;
++};
++
+ void spu_invalidate_slbs(struct spu *spu)
+ {
+ 	struct spu_priv2 __iomem *priv2 = spu->priv2;
+@@ -114,40 +126,36 @@
+ }
+ EXPORT_SYMBOL_GPL(spu_associate_mm);
+ 
+-static int __spu_trap_invalid_dma(struct spu *spu)
++int spu_64k_pages_available(void)
+ {
+-	pr_debug("%s\n", __FUNCTION__);
+-	spu->dma_callback(spu, SPE_EVENT_INVALID_DMA);
+-	return 0;
++	return mmu_psize_defs[MMU_PAGE_64K].shift != 0;
+ }
++EXPORT_SYMBOL_GPL(spu_64k_pages_available);
+ 
+-static int __spu_trap_dma_align(struct spu *spu)
++static void spu_restart_dma(struct spu *spu)
+ {
+-	pr_debug("%s\n", __FUNCTION__);
+-	spu->dma_callback(spu, SPE_EVENT_DMA_ALIGNMENT);
+-	return 0;
+-}
++	struct spu_priv2 __iomem *priv2 = spu->priv2;
+ 
+-static int __spu_trap_error(struct spu *spu)
+-{
+-	pr_debug("%s\n", __FUNCTION__);
+-	spu->dma_callback(spu, SPE_EVENT_SPE_ERROR);
+-	return 0;
++	if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
++		out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
+ }
+ 
+-static void spu_restart_dma(struct spu *spu)
++static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
+ {
+ 	struct spu_priv2 __iomem *priv2 = spu->priv2;
+ 
+-	if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
+-		out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
++	pr_debug("%s: adding SLB[%d] 0x%016lx 0x%016lx\n",
++			__func__, slbe, slb->vsid, slb->esid);
++
++	out_be64(&priv2->slb_index_W, slbe);
++	out_be64(&priv2->slb_vsid_RW, slb->vsid);
++	out_be64(&priv2->slb_esid_RW, slb->esid);
+ }
+ 
+ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
+ {
+-	struct spu_priv2 __iomem *priv2 = spu->priv2;
+ 	struct mm_struct *mm = spu->mm;
+-	u64 esid, vsid, llp;
++	struct spu_slb slb;
+ 	int psize;
+ 
+ 	pr_debug("%s\n", __FUNCTION__);
+@@ -159,7 +167,7 @@
+ 		printk("%s: invalid access during switch!\n", __func__);
+ 		return 1;
+ 	}
+-	esid = (ea & ESID_MASK) | SLB_ESID_V;
++	slb.esid = (ea & ESID_MASK) | SLB_ESID_V;
+ 
+ 	switch(REGION_ID(ea)) {
+ 	case USER_REGION_ID:
+@@ -168,21 +176,21 @@
+ #else
+ 		psize = mm->context.user_psize;
+ #endif
+-		vsid = (get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) |
+-				SLB_VSID_USER;
++		slb.vsid = (get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M)
++				<< SLB_VSID_SHIFT) | SLB_VSID_USER;
+ 		break;
+ 	case VMALLOC_REGION_ID:
+ 		if (ea < VMALLOC_END)
+ 			psize = mmu_vmalloc_psize;
+ 		else
+ 			psize = mmu_io_psize;
+-		vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) |
+-			SLB_VSID_KERNEL;
++		slb.vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M)
++				<< SLB_VSID_SHIFT) | SLB_VSID_KERNEL;
+ 		break;
+ 	case KERNEL_REGION_ID:
+ 		psize = mmu_linear_psize;
+-		vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) |
+-			SLB_VSID_KERNEL;
++		slb.vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M)
++				<< SLB_VSID_SHIFT) | SLB_VSID_KERNEL;
+ 		break;
+ 	default:
+ 		/* Future: support kernel segments so that drivers
+@@ -191,11 +199,9 @@
+ 		pr_debug("invalid region access at %016lx\n", ea);
+ 		return 1;
+ 	}
+-	llp = mmu_psize_defs[psize].sllp;
++	slb.vsid |= mmu_psize_defs[psize].sllp;
+ 
+-	out_be64(&priv2->slb_index_W, spu->slb_replace);
+-	out_be64(&priv2->slb_vsid_RW, vsid | llp);
+-	out_be64(&priv2->slb_esid_RW, esid);
++	spu_load_slb(spu, spu->slb_replace, &slb);
+ 
+ 	spu->slb_replace++;
+ 	if (spu->slb_replace >= 8)
+@@ -225,13 +231,83 @@
+ 		return 1;
+ 	}
+ 
++	spu->class_0_pending = 0;
+ 	spu->dar = ea;
+ 	spu->dsisr = dsisr;
+-	mb();
++
+ 	spu->stop_callback(spu);
++
+ 	return 0;
+ }
+ 
++static void __spu_kernel_slb(void *addr, struct spu_slb *slb)
++{
++	unsigned long ea = (unsigned long)addr;
++	u64 llp;
++
++	if (REGION_ID(ea) == KERNEL_REGION_ID)
++		llp = mmu_psize_defs[mmu_linear_psize].sllp;
++	else
++		llp = mmu_psize_defs[mmu_virtual_psize].sllp;
++
++	slb->vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) |
++		SLB_VSID_KERNEL | llp;
++	slb->esid = (ea & ESID_MASK) | SLB_ESID_V;
++}
++
++/**
++ * Given an array of @nr_slbs SLB entries, @slbs, return non-zero if the
++ * address @new_addr is present.
++ */
++static inline int __slb_present(struct spu_slb *slbs, int nr_slbs,
++		void *new_addr)
++{
++	unsigned long ea = (unsigned long)new_addr;
++	int i;
++
++	for (i = 0; i < nr_slbs; i++)
++		if (!((slbs[i].esid ^ ea) & ESID_MASK))
++			return 1;
++
++	return 0;
++}
++
++/**
++ * Setup the SPU kernel SLBs, in preparation for a context save/restore. We
++ * need to map both the context save area, and the save/restore code.
++ *
++ * Because the lscsa and code may cross segment boundaires, we check to see
++ * if mappings are required for the start and end of each range. We currently
++ * assume that the mappings are smaller that one segment - if not, something
++ * is seriously wrong.
++ */
++void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
++		void *code, int code_size)
++{
++	struct spu_slb slbs[4];
++	int i, nr_slbs = 0;
++	/* start and end addresses of both mappings */
++	void *addrs[] = {
++		lscsa, (void *)lscsa + sizeof(*lscsa) - 1,
++		code, code + code_size - 1
++	};
++
++	/* check the set of addresses, and create a new entry in the slbs array
++	 * if there isn't already a SLB for that address */
++	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
++		if (__slb_present(slbs, nr_slbs, addrs[i]))
++			continue;
++
++		__spu_kernel_slb(addrs[i], &slbs[nr_slbs]);
++		nr_slbs++;
++	}
++
++	/* Add the set of SLBs */
++	for (i = 0; i < nr_slbs; i++)
++		spu_load_slb(spu, i, &slbs[i]);
++}
++EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
++
+ static irqreturn_t
+ spu_irq_class_0(int irq, void *data)
+ {
+@@ -240,12 +316,13 @@
+ 
+ 	spu = data;
+ 
++	spin_lock(&spu->register_lock);
+ 	mask = spu_int_mask_get(spu, 0);
+-	stat = spu_int_stat_get(spu, 0);
+-	stat &= mask;
++	stat = spu_int_stat_get(spu, 0) & mask;
+ 
+-	spin_lock(&spu->register_lock);
+ 	spu->class_0_pending |= stat;
++	spu->dsisr = spu_mfc_dsisr_get(spu);
++	spu->dar = spu_mfc_dar_get(spu);
+ 	spin_unlock(&spu->register_lock);
+ 
+ 	spu->stop_callback(spu);
+@@ -255,31 +332,6 @@
+ 	return IRQ_HANDLED;
+ }
+ 
+-int
+-spu_irq_class_0_bottom(struct spu *spu)
+-{
+-	unsigned long flags;
+-	unsigned long stat;
+-
+-	spin_lock_irqsave(&spu->register_lock, flags);
+-	stat = spu->class_0_pending;
+-	spu->class_0_pending = 0;
+-
+-	if (stat & 1) /* invalid DMA alignment */
+-		__spu_trap_dma_align(spu);
+-
+-	if (stat & 2) /* invalid MFC DMA */
+-		__spu_trap_invalid_dma(spu);
+-
+-	if (stat & 4) /* error on SPU */
+-		__spu_trap_error(spu);
+-
+-	spin_unlock_irqrestore(&spu->register_lock, flags);
+-
+-	return (stat & 0x7) ? -EIO : 0;
+-}
+-EXPORT_SYMBOL_GPL(spu_irq_class_0_bottom);
+-
+ static irqreturn_t
+ spu_irq_class_1(int irq, void *data)
+ {
+@@ -294,24 +346,23 @@
+ 	stat  = spu_int_stat_get(spu, 1) & mask;
+ 	dar   = spu_mfc_dar_get(spu);
+ 	dsisr = spu_mfc_dsisr_get(spu);
+-	if (stat & 2) /* mapping fault */
++	if (stat & CLASS1_STORAGE_FAULT_INTR)
+ 		spu_mfc_dsisr_set(spu, 0ul);
+ 	spu_int_stat_clear(spu, 1, stat);
+ 	spin_unlock(&spu->register_lock);
+ 	pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
+ 			dar, dsisr);
+ 
+-	if (stat & 1) /* segment fault */
++	if (stat & CLASS1_SEGMENT_FAULT_INTR)
+ 		__spu_trap_data_seg(spu, dar);
+ 
+-	if (stat & 2) { /* mapping fault */
++	if (stat & CLASS1_STORAGE_FAULT_INTR)
+ 		__spu_trap_data_map(spu, dar, dsisr);
+-	}
+ 
+-	if (stat & 4) /* ls compare & suspend on get */
++	if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_GET_INTR)
+ 		;
+ 
+-	if (stat & 8) /* ls compare & suspend on put */
++	if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR)
+ 		;
+ 
+ 	return stat ? IRQ_HANDLED : IRQ_NONE;
+@@ -323,6 +374,8 @@
+ 	struct spu *spu;
+ 	unsigned long stat;
+ 	unsigned long mask;
++	const int mailbox_intrs =
++		CLASS2_MAILBOX_THRESHOLD_INTR | CLASS2_MAILBOX_INTR;
+ 
+ 	spu = data;
+ 	spin_lock(&spu->register_lock);
+@@ -330,31 +383,30 @@
+ 	mask = spu_int_mask_get(spu, 2);
+ 	/* ignore interrupts we're not waiting for */
+ 	stat &= mask;
+-	/*
+-	 * mailbox interrupts (0x1 and 0x10) are level triggered.
+-	 * mask them now before acknowledging.
+-	 */
+-	if (stat & 0x11)
+-		spu_int_mask_and(spu, 2, ~(stat & 0x11));
++
++	/* mailbox interrupts are level triggered. mask them now before
++	 * acknowledging */
++	if (stat & mailbox_intrs)
++		spu_int_mask_and(spu, 2, ~(stat & mailbox_intrs));
+ 	/* acknowledge all interrupts before the callbacks */
+ 	spu_int_stat_clear(spu, 2, stat);
+ 	spin_unlock(&spu->register_lock);
+ 
+ 	pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask);
+ 
+-	if (stat & 1)  /* PPC core mailbox */
++	if (stat & CLASS2_MAILBOX_INTR)
+ 		spu->ibox_callback(spu);
+ 
+-	if (stat & 2) /* SPU stop-and-signal */
++	if (stat & CLASS2_SPU_STOP_INTR)
+ 		spu->stop_callback(spu);
+ 
+-	if (stat & 4) /* SPU halted */
++	if (stat & CLASS2_SPU_HALT_INTR)
+ 		spu->stop_callback(spu);
+ 
+-	if (stat & 8) /* DMA tag group complete */
++	if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR)
+ 		spu->mfc_callback(spu);
+ 
+-	if (stat & 0x10) /* SPU mailbox threshold */
++	if (stat & CLASS2_MAILBOX_THRESHOLD_INTR)
+ 		spu->wbox_callback(spu);
+ 
+ 	spu->stats.class2_intr++;
+@@ -479,13 +531,27 @@
+ int spu_add_sysdev_attr_group(struct attribute_group *attrs)
+ {
+ 	struct spu *spu;
++	int rc = 0;
+ 
+ 	mutex_lock(&spu_full_list_mutex);
+-	list_for_each_entry(spu, &spu_full_list, full_list)
+-		sysfs_create_group(&spu->sysdev.kobj, attrs);
++	list_for_each_entry(spu, &spu_full_list, full_list) {
++		rc = sysfs_create_group(&spu->sysdev.kobj, attrs);
++
++		/* we're in trouble here, but try unwinding anyway */
++		if (rc) {
++			printk(KERN_ERR "%s: can't create sysfs group '%s'\n",
++					__func__, attrs->name);
++
++			list_for_each_entry_continue_reverse(spu,
++					&spu_full_list, full_list)
++				sysfs_remove_group(&spu->sysdev.kobj, attrs);
++			break;
++		}
++	}
++
+ 	mutex_unlock(&spu_full_list_mutex);
+ 
+-	return 0;
++	return rc;
+ }
+ EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spu_fault.c powerpc.git/arch/powerpc/platforms/cell/spu_fault.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spu_fault.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spu_fault.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,98 @@
++/*
++ * SPU mm fault handler
++ *
++ * (C) Copyright IBM Deutschland Entwicklung GmbH 2007
++ *
++ * Author: Arnd Bergmann <arndb@de.ibm.com>
++ * Author: Jeremy Kerr <jk@ozlabs.org>
++ *
++ * 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, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++
++#include <asm/spu.h>
++#include <asm/spu_csa.h>
++
++/*
++ * This ought to be kept in sync with the powerpc specific do_page_fault
++ * function. Currently, there are a few corner cases that we haven't had
++ * to handle fortunately.
++ */
++int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
++		unsigned long dsisr, unsigned *flt)
++{
++	struct vm_area_struct *vma;
++	unsigned long is_write;
++	int ret;
++
++#if 0
++	if (!IS_VALID_EA(ea)) {
++		return -EFAULT;
++	}
++#endif /* XXX */
++	if (mm == NULL) {
++		return -EFAULT;
++	}
++	if (mm->pgd == NULL) {
++		return -EFAULT;
++	}
++
++	down_read(&mm->mmap_sem);
++	vma = find_vma(mm, ea);
++	if (!vma)
++		goto bad_area;
++	if (vma->vm_start <= ea)
++		goto good_area;
++	if (!(vma->vm_flags & VM_GROWSDOWN))
++		goto bad_area;
++	if (expand_stack(vma, ea))
++		goto bad_area;
++good_area:
++	is_write = dsisr & MFC_DSISR_ACCESS_PUT;
++	if (is_write) {
++		if (!(vma->vm_flags & VM_WRITE))
++			goto bad_area;
++	} else {
++		if (dsisr & MFC_DSISR_ACCESS_DENIED)
++			goto bad_area;
++		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
++			goto bad_area;
++	}
++	ret = 0;
++	*flt = handle_mm_fault(mm, vma, ea, is_write);
++	if (unlikely(*flt & VM_FAULT_ERROR)) {
++		if (*flt & VM_FAULT_OOM) {
++			ret = -ENOMEM;
++			goto bad_area;
++		} else if (*flt & VM_FAULT_SIGBUS) {
++			ret = -EFAULT;
++			goto bad_area;
++		}
++		BUG();
++	}
++	if (*flt & VM_FAULT_MAJOR)
++		current->maj_flt++;
++	else
++		current->min_flt++;
++	up_read(&mm->mmap_sem);
++	return ret;
++
++bad_area:
++	up_read(&mm->mmap_sem);
++	return -EFAULT;
++}
++EXPORT_SYMBOL_GPL(spu_handle_mm_fault);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spu_manage.c powerpc.git/arch/powerpc/platforms/cell/spu_manage.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spu_manage.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spu_manage.c	2008-01-28 20:25:49.000000000 +0100
+@@ -35,6 +35,7 @@
+ #include <asm/firmware.h>
+ #include <asm/prom.h>
+ 
++#include "spufs/spufs.h"
+ #include "interrupt.h"
+ 
+ struct device_node *spu_devnode(struct spu *spu)
+@@ -345,7 +346,7 @@
+ 		}
+ 		ret = spu_map_interrupts_old(spu, spe);
+ 		if (ret) {
+-			printk(KERN_ERR "%s: could not map interrupts",
++			printk(KERN_ERR "%s: could not map interrupts\n",
+ 				spu->name);
+ 			goto out_unmap;
+ 		}
+@@ -369,6 +370,16 @@
+ 	return 0;
+ }
+ 
++static void enable_spu_by_master_run(struct spu_context *ctx)
++{
++	ctx->ops->master_start(ctx);
++}
++
++static void disable_spu_by_master_run(struct spu_context *ctx)
++{
++	ctx->ops->master_stop(ctx);
++}
++
+ /* Hardcoded affinity idxs for qs20 */
+ #define QS20_SPES_PER_BE 8
+ static int qs20_reg_idxs[QS20_SPES_PER_BE] =   { 0, 2, 4, 6, 7, 5, 3, 1 };
+@@ -411,10 +422,15 @@
+ 
+ static int of_has_vicinity(void)
+ {
+-	struct spu* spu;
++	struct device_node *dn;
+ 
+-	spu = list_first_entry(&cbe_spu_info[0].spus, struct spu, cbe_list);
+-	return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL;
++	for_each_node_by_type(dn, "spe") {
++		if (of_find_property(dn, "vicinity", NULL))  {
++			of_node_put(dn);
++			return 1;
++		}
++	}
++	return 0;
+ }
+ 
+ static struct spu *devnode_spu(int cbe, struct device_node *dn)
+@@ -525,7 +541,7 @@
+ 		if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
+ 			init_affinity_qs20_harcoded();
+ 		else
+-			printk("No affinity configuration found");
++			printk("No affinity configuration found\n");
+ 	}
+ 
+ 	return 0;
+@@ -535,5 +551,7 @@
+ 	.enumerate_spus = of_enumerate_spus,
+ 	.create_spu = of_create_spu,
+ 	.destroy_spu = of_destroy_spu,
++	.enable_spu = enable_spu_by_master_run,
++	.disable_spu = disable_spu_by_master_run,
+ 	.init_affinity = init_affinity,
+ };
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/Makefile powerpc.git/arch/powerpc/platforms/cell/spufs/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -1,8 +1,8 @@
+-obj-y += switch.o fault.o lscsa_alloc.o
+ 
+ obj-$(CONFIG_SPU_FS) += spufs.o
+ spufs-y += inode.o file.o context.o syscalls.o coredump.o
+ spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
++spufs-y += switch.o fault.o lscsa_alloc.o
+ 
+ # Rules to build switch.o with the help of SPU tool chain
+ SPU_CROSS	:= spu-
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/backing_ops.c powerpc.git/arch/powerpc/platforms/cell/spufs/backing_ops.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/backing_ops.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/backing_ops.c	2008-01-28 20:25:49.000000000 +0100
+@@ -106,16 +106,20 @@
+ 		if (stat & 0xff0000)
+ 			ret |= POLLIN | POLLRDNORM;
+ 		else {
+-			ctx->csa.priv1.int_stat_class0_RW &= ~0x1;
+-			ctx->csa.priv1.int_mask_class2_RW |= 0x1;
++			ctx->csa.priv1.int_stat_class2_RW &=
++				~CLASS2_MAILBOX_INTR;
++			ctx->csa.priv1.int_mask_class2_RW |=
++				CLASS2_ENABLE_MAILBOX_INTR;
+ 		}
+ 	}
+ 	if (events & (POLLOUT | POLLWRNORM)) {
+ 		if (stat & 0x00ff00)
+ 			ret = POLLOUT | POLLWRNORM;
+ 		else {
+-			ctx->csa.priv1.int_stat_class0_RW &= ~0x10;
+-			ctx->csa.priv1.int_mask_class2_RW |= 0x10;
++			ctx->csa.priv1.int_stat_class2_RW &=
++				~CLASS2_MAILBOX_THRESHOLD_INTR;
++			ctx->csa.priv1.int_mask_class2_RW |=
++				CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR;
+ 		}
+ 	}
+ 	spin_unlock_irq(&ctx->csa.register_lock);
+@@ -139,7 +143,7 @@
+ 		ret = 4;
+ 	} else {
+ 		/* make sure we get woken up by the interrupt */
+-		ctx->csa.priv1.int_mask_class2_RW |= 0x1UL;
++		ctx->csa.priv1.int_mask_class2_RW |= CLASS2_ENABLE_MAILBOX_INTR;
+ 		ret = 0;
+ 	}
+ 	spin_unlock(&ctx->csa.register_lock);
+@@ -169,7 +173,8 @@
+ 	} else {
+ 		/* make sure we get woken up by the interrupt when space
+ 		   becomes available */
+-		ctx->csa.priv1.int_mask_class2_RW |= 0x10;
++		ctx->csa.priv1.int_mask_class2_RW |=
++			CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR;
+ 		ret = 0;
+ 	}
+ 	spin_unlock(&ctx->csa.register_lock);
+@@ -268,6 +273,11 @@
+ 	return ctx->csa.lscsa->ls;
+ }
+ 
++static void spu_backing_privcntl_write(struct spu_context *ctx, u64 val)
++{
++	ctx->csa.priv2.spu_privcntl_RW = val;
++}
++
+ static u32 spu_backing_runcntl_read(struct spu_context *ctx)
+ {
+ 	return ctx->csa.prob.spu_runcntl_RW;
+@@ -285,6 +295,11 @@
+ 	spin_unlock(&ctx->csa.register_lock);
+ }
+ 
++static void spu_backing_runcntl_stop(struct spu_context *ctx)
++{
++	spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
++}
++
+ static void spu_backing_master_start(struct spu_context *ctx)
+ {
+ 	struct spu_state *csa = &ctx->csa;
+@@ -358,7 +373,7 @@
+ 
+ static void spu_backing_restart_dma(struct spu_context *ctx)
+ {
+-	/* nothing to do here */
++	ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND;
+ }
+ 
+ struct spu_context_ops spu_backing_ops = {
+@@ -379,8 +394,10 @@
+ 	.npc_write = spu_backing_npc_write,
+ 	.status_read = spu_backing_status_read,
+ 	.get_ls = spu_backing_get_ls,
++	.privcntl_write = spu_backing_privcntl_write,
+ 	.runcntl_read = spu_backing_runcntl_read,
+ 	.runcntl_write = spu_backing_runcntl_write,
++	.runcntl_stop = spu_backing_runcntl_stop,
+ 	.master_start = spu_backing_master_start,
+ 	.master_stop = spu_backing_master_stop,
+ 	.set_mfc_query = spu_backing_set_mfc_query,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/context.c powerpc.git/arch/powerpc/platforms/cell/spufs/context.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/context.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/context.c	2008-01-28 20:25:49.000000000 +0100
+@@ -52,6 +52,7 @@
+ 	init_waitqueue_head(&ctx->wbox_wq);
+ 	init_waitqueue_head(&ctx->stop_wq);
+ 	init_waitqueue_head(&ctx->mfc_wq);
++	init_waitqueue_head(&ctx->run_wq);
+ 	ctx->state = SPU_STATE_SAVED;
+ 	ctx->ops = &spu_backing_ops;
+ 	ctx->owner = get_task_mm(current);
+@@ -105,7 +106,17 @@
+ void spu_forget(struct spu_context *ctx)
+ {
+ 	struct mm_struct *mm;
+-	spu_acquire_saved(ctx);
++
++	/*
++	 * This is basically an open-coded spu_acquire_saved, except that
++	 * we don't acquire the state mutex interruptible.
++	 */
++	mutex_lock(&ctx->state_mutex);
++	if (ctx->state != SPU_STATE_SAVED) {
++		set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
++		spu_deactivate(ctx);
++	}
++
+ 	mm = ctx->owner;
+ 	ctx->owner = NULL;
+ 	mmput(mm);
+@@ -133,47 +144,23 @@
+ }
+ 
+ /**
+- * spu_acquire_runnable - lock spu contex and make sure it is in runnable state
++ * spu_acquire_saved - lock spu contex and make sure it is in saved state
+  * @ctx:	spu contex to lock
+- *
+- * Note:
+- *	Returns 0 and with the context locked on success
+- *	Returns negative error and with the context _unlocked_ on failure.
+  */
+-int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags)
++int spu_acquire_saved(struct spu_context *ctx)
+ {
+-	int ret = -EINVAL;
++	int ret;
+ 
+-	spu_acquire(ctx);
+-	if (ctx->state == SPU_STATE_SAVED) {
+-		/*
+-		 * Context is about to be freed, so we can't acquire it anymore.
+-		 */
+-		if (!ctx->owner)
+-			goto out_unlock;
+-		ret = spu_activate(ctx, flags);
+-		if (ret)
+-			goto out_unlock;
+-	}
+-
+-	return 0;
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 
+- out_unlock:
+-	spu_release(ctx);
+-	return ret;
+-}
+-
+-/**
+- * spu_acquire_saved - lock spu contex and make sure it is in saved state
+- * @ctx:	spu contex to lock
+- */
+-void spu_acquire_saved(struct spu_context *ctx)
+-{
+-	spu_acquire(ctx);
+ 	if (ctx->state != SPU_STATE_SAVED) {
+ 		set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
+ 		spu_deactivate(ctx);
+ 	}
++
++	return 0;
+ }
+ 
+ /**
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/coredump.c powerpc.git/arch/powerpc/platforms/cell/spufs/coredump.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/coredump.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/coredump.c	2008-01-28 20:25:49.000000000 +0100
+@@ -148,7 +148,9 @@
+ 
+ 	fd = 0;
+ 	while ((ctx = coredump_next_context(&fd)) != NULL) {
+-		spu_acquire_saved(ctx);
++		rc = spu_acquire_saved(ctx);
++		if (rc)
++			break;
+ 		rc = spufs_ctx_note_size(ctx, fd);
+ 		spu_release_saved(ctx);
+ 		if (rc < 0)
+@@ -224,7 +226,9 @@
+ 
+ 	fd = 0;
+ 	while ((ctx = coredump_next_context(&fd)) != NULL) {
+-		spu_acquire_saved(ctx);
++		rc = spu_acquire_saved(ctx);
++		if (rc)
++			return rc;
+ 
+ 		for (j = 0; spufs_coredump_read[j].name != NULL; j++) {
+ 			rc = spufs_arch_write_note(ctx, j, file, fd, foffset);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/fault.c powerpc.git/arch/powerpc/platforms/cell/spufs/fault.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/fault.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/fault.c	2008-01-28 20:25:49.000000000 +0100
+@@ -28,117 +28,71 @@
+ 
+ #include "spufs.h"
+ 
+-/*
+- * This ought to be kept in sync with the powerpc specific do_page_fault
+- * function. Currently, there are a few corner cases that we haven't had
+- * to handle fortunately.
++/**
++ * Handle an SPE event, depending on context SPU_CREATE_EVENTS_ENABLED flag.
++ *
++ * If the context was created with events, we just set the return event.
++ * Otherwise, send an appropriate signal to the process.
+  */
+-static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
+-		unsigned long dsisr, unsigned *flt)
+-{
+-	struct vm_area_struct *vma;
+-	unsigned long is_write;
+-	int ret;
+-
+-#if 0
+-	if (!IS_VALID_EA(ea)) {
+-		return -EFAULT;
+-	}
+-#endif /* XXX */
+-	if (mm == NULL) {
+-		return -EFAULT;
+-	}
+-	if (mm->pgd == NULL) {
+-		return -EFAULT;
+-	}
+-
+-	down_read(&mm->mmap_sem);
+-	vma = find_vma(mm, ea);
+-	if (!vma)
+-		goto bad_area;
+-	if (vma->vm_start <= ea)
+-		goto good_area;
+-	if (!(vma->vm_flags & VM_GROWSDOWN))
+-		goto bad_area;
+-	if (expand_stack(vma, ea))
+-		goto bad_area;
+-good_area:
+-	is_write = dsisr & MFC_DSISR_ACCESS_PUT;
+-	if (is_write) {
+-		if (!(vma->vm_flags & VM_WRITE))
+-			goto bad_area;
+-	} else {
+-		if (dsisr & MFC_DSISR_ACCESS_DENIED)
+-			goto bad_area;
+-		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+-			goto bad_area;
+-	}
+-	ret = 0;
+-	*flt = handle_mm_fault(mm, vma, ea, is_write);
+-	if (unlikely(*flt & VM_FAULT_ERROR)) {
+-		if (*flt & VM_FAULT_OOM) {
+-			ret = -ENOMEM;
+-			goto bad_area;
+-		} else if (*flt & VM_FAULT_SIGBUS) {
+-			ret = -EFAULT;
+-			goto bad_area;
+-		}
+-		BUG();
+-	}
+-	if (*flt & VM_FAULT_MAJOR)
+-		current->maj_flt++;
+-	else
+-		current->min_flt++;
+-	up_read(&mm->mmap_sem);
+-	return ret;
+-
+-bad_area:
+-	up_read(&mm->mmap_sem);
+-	return -EFAULT;
+-}
+-
+-static void spufs_handle_dma_error(struct spu_context *ctx,
++static void spufs_handle_event(struct spu_context *ctx,
+ 				unsigned long ea, int type)
+ {
++	siginfo_t info;
++
+ 	if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) {
+ 		ctx->event_return |= type;
+ 		wake_up_all(&ctx->stop_wq);
+-	} else {
+-		siginfo_t info;
+-		memset(&info, 0, sizeof(info));
+-
+-		switch (type) {
+-		case SPE_EVENT_INVALID_DMA:
+-			info.si_signo = SIGBUS;
+-			info.si_code = BUS_OBJERR;
+-			break;
+-		case SPE_EVENT_SPE_DATA_STORAGE:
+-			info.si_signo = SIGBUS;
+-			info.si_addr = (void __user *)ea;
+-			info.si_code = BUS_ADRERR;
+-			break;
+-		case SPE_EVENT_DMA_ALIGNMENT:
+-			info.si_signo = SIGBUS;
+-			/* DAR isn't set for an alignment fault :( */
+-			info.si_code = BUS_ADRALN;
+-			break;
+-		case SPE_EVENT_SPE_ERROR:
+-			info.si_signo = SIGILL;
+-			info.si_addr = (void __user *)(unsigned long)
+-				ctx->ops->npc_read(ctx) - 4;
+-			info.si_code = ILL_ILLOPC;
+-			break;
+-		}
+-		if (info.si_signo)
+-			force_sig_info(info.si_signo, &info, current);
++		return;
+ 	}
++
++	memset(&info, 0, sizeof(info));
++
++	switch (type) {
++	case SPE_EVENT_INVALID_DMA:
++		info.si_signo = SIGBUS;
++		info.si_code = BUS_OBJERR;
++		break;
++	case SPE_EVENT_SPE_DATA_STORAGE:
++		info.si_signo = SIGSEGV;
++		info.si_addr = (void __user *)ea;
++		info.si_code = SEGV_ACCERR;
++		ctx->ops->restart_dma(ctx);
++		break;
++	case SPE_EVENT_DMA_ALIGNMENT:
++		info.si_signo = SIGBUS;
++		/* DAR isn't set for an alignment fault :( */
++		info.si_code = BUS_ADRALN;
++		break;
++	case SPE_EVENT_SPE_ERROR:
++		info.si_signo = SIGILL;
++		info.si_addr = (void __user *)(unsigned long)
++			ctx->ops->npc_read(ctx) - 4;
++		info.si_code = ILL_ILLOPC;
++		break;
++	}
++
++	if (info.si_signo)
++		force_sig_info(info.si_signo, &info, current);
+ }
+ 
+-void spufs_dma_callback(struct spu *spu, int type)
++int spufs_handle_class0(struct spu_context *ctx)
+ {
+-	spufs_handle_dma_error(spu->ctx, spu->dar, type);
++	unsigned long stat = ctx->csa.class_0_pending & CLASS0_INTR_MASK;
++
++	if (likely(!stat))
++		return 0;
++
++	if (stat & CLASS0_DMA_ALIGNMENT_INTR)
++		spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_DMA_ALIGNMENT);
++
++	if (stat & CLASS0_INVALID_DMA_COMMAND_INTR)
++		spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_INVALID_DMA);
++
++	if (stat & CLASS0_SPU_ERROR_INTR)
++		spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_SPE_ERROR);
++
++	return -EIO;
+ }
+-EXPORT_SYMBOL_GPL(spufs_dma_callback);
+ 
+ /*
+  * bottom half handler for page faults, we can't do this from
+@@ -154,7 +108,7 @@
+ 	u64 ea, dsisr, access;
+ 	unsigned long flags;
+ 	unsigned flt = 0;
+-	int ret;
++	int ret, ret2;
+ 
+ 	/*
+ 	 * dar and dsisr get passed from the registers
+@@ -165,16 +119,8 @@
+ 	 * in time, we can still expect to get the same fault
+ 	 * the immediately after the context restore.
+ 	 */
+-	if (ctx->state == SPU_STATE_RUNNABLE) {
+-		ea = ctx->spu->dar;
+-		dsisr = ctx->spu->dsisr;
+-		ctx->spu->dar= ctx->spu->dsisr = 0;
+-	} else {
+-		ea = ctx->csa.priv1.mfc_dar_RW;
+-		dsisr = ctx->csa.priv1.mfc_dsisr_RW;
+-		ctx->csa.priv1.mfc_dar_RW = 0;
+-		ctx->csa.priv1.mfc_dsisr_RW = 0;
+-	}
++	ea = ctx->csa.dar;
++	dsisr = ctx->csa.dsisr;
+ 
+ 	if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)))
+ 		return 0;
+@@ -201,7 +147,22 @@
+ 	if (ret)
+ 		ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt);
+ 
+-	spu_acquire(ctx);
++	/*
++	 * If spu_acquire fails due to a pending signal we just want to return
++	 * EINTR to userspace even if that means missing the dma restart or
++	 * updating the page fault statistics.
++	 */
++	ret2 = spu_acquire(ctx);
++	if (ret2)
++		goto out;
++
++	/*
++	 * Clear dsisr under ctxt lock after handling the fault, so that
++	 * time slicing will not preempt the context while the page fault
++	 * handler is running. Context switch code removes mappings.
++	 */
++	ctx->csa.dar = ctx->csa.dsisr = 0;
++
+ 	/*
+ 	 * If we handled the fault successfully and are in runnable
+ 	 * state, restart the DMA.
+@@ -222,9 +183,9 @@
+ 		if (ctx->spu)
+ 			ctx->ops->restart_dma(ctx);
+ 	} else
+-		spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);
++		spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);
+ 
++ out:
+ 	spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
+ 	return ret;
+ }
+-EXPORT_SYMBOL_GPL(spufs_handle_class1);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/file.c powerpc.git/arch/powerpc/platforms/cell/spufs/file.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/file.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/file.c	2008-01-28 20:25:49.000000000 +0100
+@@ -40,6 +40,120 @@
+ 
+ #define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
+ 
++/* Simple attribute files */
++struct spufs_attr {
++	int (*get)(void *, u64 *);
++	int (*set)(void *, u64);
++	char get_buf[24];       /* enough to store a u64 and "\n\0" */
++	char set_buf[24];
++	void *data;
++	const char *fmt;        /* format for read operation */
++	struct mutex mutex;     /* protects access to these buffers */
++};
++
++static int spufs_attr_open(struct inode *inode, struct file *file,
++		int (*get)(void *, u64 *), int (*set)(void *, u64),
++		const char *fmt)
++{
++	struct spufs_attr *attr;
++
++	attr = kmalloc(sizeof(*attr), GFP_KERNEL);
++	if (!attr)
++		return -ENOMEM;
++
++	attr->get = get;
++	attr->set = set;
++	attr->data = inode->i_private;
++	attr->fmt = fmt;
++	mutex_init(&attr->mutex);
++	file->private_data = attr;
++
++	return nonseekable_open(inode, file);
++}
++
++static int spufs_attr_release(struct inode *inode, struct file *file)
++{
++       kfree(file->private_data);
++	return 0;
++}
++
++static ssize_t spufs_attr_read(struct file *file, char __user *buf,
++		size_t len, loff_t *ppos)
++{
++	struct spufs_attr *attr;
++	size_t size;
++	ssize_t ret;
++
++	attr = file->private_data;
++	if (!attr->get)
++		return -EACCES;
++
++	ret = mutex_lock_interruptible(&attr->mutex);
++	if (ret)
++		return ret;
++
++	if (*ppos) {		/* continued read */
++		size = strlen(attr->get_buf);
++	} else {		/* first read */
++		u64 val;
++		ret = attr->get(attr->data, &val);
++		if (ret)
++			goto out;
++
++		size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
++				 attr->fmt, (unsigned long long)val);
++	}
++
++	ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
++out:
++	mutex_unlock(&attr->mutex);
++	return ret;
++}
++
++static ssize_t spufs_attr_write(struct file *file, const char __user *buf,
++		size_t len, loff_t *ppos)
++{
++	struct spufs_attr *attr;
++	u64 val;
++	size_t size;
++	ssize_t ret;
++
++	attr = file->private_data;
++	if (!attr->set)
++		return -EACCES;
++
++	ret = mutex_lock_interruptible(&attr->mutex);
++	if (ret)
++		return ret;
++
++	ret = -EFAULT;
++	size = min(sizeof(attr->set_buf) - 1, len);
++	if (copy_from_user(attr->set_buf, buf, size))
++		goto out;
++
++	ret = len; /* claim we got the whole input */
++	attr->set_buf[size] = '\0';
++	val = simple_strtol(attr->set_buf, NULL, 0);
++	attr->set(attr->data, val);
++out:
++	mutex_unlock(&attr->mutex);
++	return ret;
++}
++
++#define DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)	\
++static int __fops ## _open(struct inode *inode, struct file *file)	\
++{									\
++	__simple_attr_check_format(__fmt, 0ull);			\
++	return spufs_attr_open(inode, file, __get, __set, __fmt);	\
++}									\
++static struct file_operations __fops = {				\
++	.owner	 = THIS_MODULE,						\
++	.open	 = __fops ## _open,					\
++	.release = spufs_attr_release,					\
++	.read	 = spufs_attr_read,					\
++	.write	 = spufs_attr_write,					\
++};
++
+ 
+ static int
+ spufs_mem_open(struct inode *inode, struct file *file)
+@@ -84,9 +198,12 @@
+ 	struct spu_context *ctx = file->private_data;
+ 	ssize_t ret;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	ret = __spufs_mem_read(ctx, buffer, size, pos);
+ 	spu_release(ctx);
++
+ 	return ret;
+ }
+ 
+@@ -106,7 +223,10 @@
+ 	if (size > LS_SIZE - pos)
+ 		size = LS_SIZE - pos;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
++
+ 	local_store = ctx->ops->get_ls(ctx);
+ 	ret = copy_from_user(local_store + pos, buffer, size);
+ 	spu_release(ctx);
+@@ -146,7 +266,8 @@
+ 	pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n",
+ 		 addr0, address, offset);
+ 
+-	spu_acquire(ctx);
++	if (spu_acquire(ctx))
++		return NOPFN_REFAULT;
+ 
+ 	if (ctx->state == SPU_STATE_SAVED) {
+ 		vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
+@@ -236,23 +357,32 @@
+ {
+ 	struct spu_context *ctx = vma->vm_file->private_data;
+ 	unsigned long area, offset = address - vma->vm_start;
+-	int ret;
+ 
+ 	offset += vma->vm_pgoff << PAGE_SHIFT;
+ 	if (offset >= ps_size)
+ 		return NOPFN_SIGBUS;
+ 
+-	/* error here usually means a signal.. we might want to test
+-	 * the error code more precisely though
++	/*
++	 * We have to wait for context to be loaded before we have
++	 * pages to hand out to the user, but we don't want to wait
++	 * with the mmap_sem held.
++	 * It is possible to drop the mmap_sem here, but then we need
++	 * to return NOPFN_REFAULT because the mappings may have
++	 * hanged.
+ 	 */
+-	ret = spu_acquire_runnable(ctx, 0);
+-	if (ret)
++	if (spu_acquire(ctx))
+ 		return NOPFN_REFAULT;
+ 
+-	area = ctx->spu->problem_phys + ps_offs;
+-	vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
+-	spu_release(ctx);
++	if (ctx->state == SPU_STATE_SAVED) {
++		up_read(&current->mm->mmap_sem);
++		spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
++		down_read(&current->mm->mmap_sem);
++	} else {
++		area = ctx->spu->problem_phys + ps_offs;
++		vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
++	}
+ 
++	spu_release(ctx);
+ 	return NOPFN_REFAULT;
+ }
+ 
+@@ -286,25 +416,32 @@
+ #define spufs_cntl_mmap NULL
+ #endif /* !SPUFS_MMAP_4K */
+ 
+-static u64 spufs_cntl_get(void *data)
++static int spufs_cntl_get(void *data, u64 *val)
+ {
+ 	struct spu_context *ctx = data;
+-	u64 val;
++	int ret;
+ 
+-	spu_acquire(ctx);
+-	val = ctx->ops->status_read(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
++	*val = ctx->ops->status_read(ctx);
+ 	spu_release(ctx);
+ 
+-	return val;
++	return 0;
+ }
+ 
+-static void spufs_cntl_set(void *data, u64 val)
++static int spufs_cntl_set(void *data, u64 val)
+ {
+ 	struct spu_context *ctx = data;
++	int ret;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	ctx->ops->runcntl_write(ctx, val);
+ 	spu_release(ctx);
++
++	return 0;
+ }
+ 
+ static int spufs_cntl_open(struct inode *inode, struct file *file)
+@@ -317,7 +454,7 @@
+ 	if (!i->i_openers++)
+ 		ctx->cntl = inode->i_mapping;
+ 	mutex_unlock(&ctx->mapping_lock);
+-	return simple_attr_open(inode, file, spufs_cntl_get,
++	return spufs_attr_open(inode, file, spufs_cntl_get,
+ 					spufs_cntl_set, "0x%08lx");
+ }
+ 
+@@ -327,7 +464,7 @@
+ 	struct spufs_inode_info *i = SPUFS_I(inode);
+ 	struct spu_context *ctx = i->i_ctx;
+ 
+-	simple_attr_close(inode, file);
++	spufs_attr_release(inode, file);
+ 
+ 	mutex_lock(&ctx->mapping_lock);
+ 	if (!--i->i_openers)
+@@ -339,8 +476,8 @@
+ static const struct file_operations spufs_cntl_fops = {
+ 	.open = spufs_cntl_open,
+ 	.release = spufs_cntl_release,
+-	.read = simple_attr_read,
+-	.write = simple_attr_write,
++	.read = spufs_attr_read,
++	.write = spufs_attr_write,
+ 	.mmap = spufs_cntl_mmap,
+ };
+ 
+@@ -368,7 +505,9 @@
+ 	int ret;
+ 	struct spu_context *ctx = file->private_data;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	ret = __spufs_regs_read(ctx, buffer, size, pos);
+ 	spu_release_saved(ctx);
+ 	return ret;
+@@ -387,7 +526,9 @@
+ 		return -EFBIG;
+ 	*pos += size;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 
+ 	ret = copy_from_user(lscsa->gprs + *pos - size,
+ 			     buffer, size) ? -EFAULT : size;
+@@ -419,7 +560,9 @@
+ 	int ret;
+ 	struct spu_context *ctx = file->private_data;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	ret = __spufs_fpcr_read(ctx, buffer, size, pos);
+ 	spu_release_saved(ctx);
+ 	return ret;
+@@ -436,10 +579,12 @@
+ 	size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
+ 	if (size <= 0)
+ 		return -EFBIG;
+-	*pos += size;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 
++	*pos += size;
+ 	ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
+ 			     buffer, size) ? -EFAULT : size;
+ 
+@@ -486,7 +631,10 @@
+ 
+ 	udata = (void __user *)buf;
+ 
+-	spu_acquire(ctx);
++	count = spu_acquire(ctx);
++	if (count)
++		return count;
++
+ 	for (count = 0; (count + 4) <= len; count += 4, udata++) {
+ 		int ret;
+ 		ret = ctx->ops->mbox_read(ctx, &mbox_data);
+@@ -522,12 +670,15 @@
+ 			size_t len, loff_t *pos)
+ {
+ 	struct spu_context *ctx = file->private_data;
++	ssize_t ret;
+ 	u32 mbox_stat;
+ 
+ 	if (len < 4)
+ 		return -EINVAL;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 
+ 	mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;
+ 
+@@ -562,6 +713,9 @@
+ {
+ 	struct spu_context *ctx = spu->ctx;
+ 
++	if (!ctx)
++		return;
++
+ 	wake_up_all(&ctx->ibox_wq);
+ 	kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN);
+ }
+@@ -593,7 +747,9 @@
+ 
+ 	udata = (void __user *)buf;
+ 
+-	spu_acquire(ctx);
++	count = spu_acquire(ctx);
++	if (count)
++		return count;
+ 
+ 	/* wait only for the first element */
+ 	count = 0;
+@@ -639,7 +795,11 @@
+ 
+ 	poll_wait(file, &ctx->ibox_wq, wait);
+ 
+-	spu_acquire(ctx);
++	/*
++	 * For now keep this uninterruptible and also ignore the rule
++	 * that poll should not sleep.  Will be fixed later.
++	 */
++	mutex_lock(&ctx->state_mutex);
+ 	mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
+ 	spu_release(ctx);
+ 
+@@ -657,12 +817,15 @@
+ 			size_t len, loff_t *pos)
+ {
+ 	struct spu_context *ctx = file->private_data;
++	ssize_t ret;
+ 	u32 ibox_stat;
+ 
+ 	if (len < 4)
+ 		return -EINVAL;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
+ 	spu_release(ctx);
+ 
+@@ -698,6 +861,9 @@
+ {
+ 	struct spu_context *ctx = spu->ctx;
+ 
++	if (!ctx)
++		return;
++
+ 	wake_up_all(&ctx->wbox_wq);
+ 	kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT);
+ }
+@@ -731,7 +897,9 @@
+ 	if (__get_user(wbox_data, udata))
+ 		return -EFAULT;
+ 
+-	spu_acquire(ctx);
++	count = spu_acquire(ctx);
++	if (count)
++		return count;
+ 
+ 	/*
+ 	 * make sure we can at least write one element, by waiting
+@@ -772,7 +940,11 @@
+ 
+ 	poll_wait(file, &ctx->wbox_wq, wait);
+ 
+-	spu_acquire(ctx);
++	/*
++	 * For now keep this uninterruptible and also ignore the rule
++	 * that poll should not sleep.  Will be fixed later.
++	 */
++	mutex_lock(&ctx->state_mutex);
+ 	mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
+ 	spu_release(ctx);
+ 
+@@ -790,12 +962,15 @@
+ 			size_t len, loff_t *pos)
+ {
+ 	struct spu_context *ctx = file->private_data;
++	ssize_t ret;
+ 	u32 wbox_stat;
+ 
+ 	if (len < 4)
+ 		return -EINVAL;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
+ 	spu_release(ctx);
+ 
+@@ -866,7 +1041,9 @@
+ 	int ret;
+ 	struct spu_context *ctx = file->private_data;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	ret = __spufs_signal1_read(ctx, buf, len, pos);
+ 	spu_release_saved(ctx);
+ 
+@@ -877,6 +1054,7 @@
+ 			size_t len, loff_t *pos)
+ {
+ 	struct spu_context *ctx;
++	ssize_t ret;
+ 	u32 data;
+ 
+ 	ctx = file->private_data;
+@@ -887,7 +1065,9 @@
+ 	if (copy_from_user(&data, buf, 4))
+ 		return -EFAULT;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	ctx->ops->signal1_write(ctx, data);
+ 	spu_release(ctx);
+ 
+@@ -997,7 +1177,9 @@
+ 	struct spu_context *ctx = file->private_data;
+ 	int ret;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	ret = __spufs_signal2_read(ctx, buf, len, pos);
+ 	spu_release_saved(ctx);
+ 
+@@ -1008,6 +1190,7 @@
+ 			size_t len, loff_t *pos)
+ {
+ 	struct spu_context *ctx;
++	ssize_t ret;
+ 	u32 data;
+ 
+ 	ctx = file->private_data;
+@@ -1018,7 +1201,9 @@
+ 	if (copy_from_user(&data, buf, 4))
+ 		return -EFAULT;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	ctx->ops->signal2_write(ctx, data);
+ 	spu_release(ctx);
+ 
+@@ -1086,33 +1271,42 @@
+ #define SPU_ATTR_ACQUIRE_SAVED	2
+ 
+ #define DEFINE_SPUFS_ATTRIBUTE(__name, __get, __set, __fmt, __acquire)	\
+-static u64 __##__get(void *data)					\
++static int __##__get(void *data, u64 *val)				\
+ {									\
+ 	struct spu_context *ctx = data;					\
+-	u64 ret;							\
++	int ret = 0;							\
+ 									\
+ 	if (__acquire == SPU_ATTR_ACQUIRE) {				\
+-		spu_acquire(ctx);					\
+-		ret = __get(ctx);					\
++		ret = spu_acquire(ctx);					\
++		if (ret)						\
++			return ret;					\
++		*val = __get(ctx);					\
+ 		spu_release(ctx);					\
+ 	} else if (__acquire == SPU_ATTR_ACQUIRE_SAVED)	{		\
+-		spu_acquire_saved(ctx);					\
+-		ret = __get(ctx);					\
++		ret = spu_acquire_saved(ctx);				\
++		if (ret)						\
++			return ret;					\
++		*val = __get(ctx);					\
+ 		spu_release_saved(ctx);					\
+ 	} else								\
+-		ret = __get(ctx);					\
++		*val = __get(ctx);					\
+ 									\
+-	return ret;							\
++	return 0;							\
+ }									\
+-DEFINE_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt);
++DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt);
+ 
+-static void spufs_signal1_type_set(void *data, u64 val)
++static int spufs_signal1_type_set(void *data, u64 val)
+ {
+ 	struct spu_context *ctx = data;
++	int ret;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	ctx->ops->signal1_type_set(ctx, val);
+ 	spu_release(ctx);
++
++	return 0;
+ }
+ 
+ static u64 spufs_signal1_type_get(struct spu_context *ctx)
+@@ -1123,13 +1317,18 @@
+ 		       spufs_signal1_type_set, "%llu", SPU_ATTR_ACQUIRE);
+ 
+ 
+-static void spufs_signal2_type_set(void *data, u64 val)
++static int spufs_signal2_type_set(void *data, u64 val)
+ {
+ 	struct spu_context *ctx = data;
++	int ret;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	ctx->ops->signal2_type_set(ctx, val);
+ 	spu_release(ctx);
++
++	return 0;
+ }
+ 
+ static u64 spufs_signal2_type_get(struct spu_context *ctx)
+@@ -1329,6 +1528,9 @@
+ {
+ 	struct spu_context *ctx = spu->ctx;
+ 
++	if (!ctx)
++		return;
++
+ 	wake_up_all(&ctx->mfc_wq);
+ 
+ 	pr_debug("%s %s\n", __FUNCTION__, spu->name);
+@@ -1375,12 +1577,17 @@
+ 	if (size != 4)
+ 		goto out;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
++
++	ret = -EINVAL;
+ 	if (file->f_flags & O_NONBLOCK) {
+ 		status = ctx->ops->read_mfc_tagstatus(ctx);
+ 		if (!(status & ctx->tagwait))
+ 			ret = -EAGAIN;
+ 		else
++			/* XXX(hch): shouldn't we clear ret here? */
+ 			ctx->tagwait &= ~status;
+ 	} else {
+ 		ret = spufs_wait(ctx->mfc_wq,
+@@ -1505,7 +1712,11 @@
+ 	if (ret)
+ 		goto out;
+ 
+-	ret = spu_acquire_runnable(ctx, 0);
++	ret = spu_acquire(ctx);
++	if (ret)
++		goto out;
++
++	ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
+ 	if (ret)
+ 		goto out;
+ 
+@@ -1539,7 +1750,11 @@
+ 
+ 	poll_wait(file, &ctx->mfc_wq, wait);
+ 
+-	spu_acquire(ctx);
++	/*
++	 * For now keep this uninterruptible and also ignore the rule
++	 * that poll should not sleep.  Will be fixed later.
++	 */
++	mutex_lock(&ctx->state_mutex);
+ 	ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
+ 	free_elements = ctx->ops->get_mfc_free_elements(ctx);
+ 	tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
+@@ -1562,7 +1777,9 @@
+ 	struct spu_context *ctx = file->private_data;
+ 	int ret;
+ 
+-	spu_acquire(ctx);
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ #if 0
+ /* this currently hangs */
+ 	ret = spufs_wait(ctx->mfc_wq,
+@@ -1605,12 +1822,18 @@
+ 	.mmap	 = spufs_mfc_mmap,
+ };
+ 
+-static void spufs_npc_set(void *data, u64 val)
++static int spufs_npc_set(void *data, u64 val)
+ {
+ 	struct spu_context *ctx = data;
+-	spu_acquire(ctx);
++	int ret;
++
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 	ctx->ops->npc_write(ctx, val);
+ 	spu_release(ctx);
++
++	return 0;
+ }
+ 
+ static u64 spufs_npc_get(struct spu_context *ctx)
+@@ -1620,13 +1843,19 @@
+ DEFINE_SPUFS_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set,
+ 		       "0x%llx\n", SPU_ATTR_ACQUIRE);
+ 
+-static void spufs_decr_set(void *data, u64 val)
++static int spufs_decr_set(void *data, u64 val)
+ {
+ 	struct spu_context *ctx = data;
+ 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
+-	spu_acquire_saved(ctx);
++	int ret;
++
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	lscsa->decr.slot[0] = (u32) val;
+ 	spu_release_saved(ctx);
++
++	return 0;
+ }
+ 
+ static u64 spufs_decr_get(struct spu_context *ctx)
+@@ -1637,15 +1866,21 @@
+ DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
+ 		       "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED);
+ 
+-static void spufs_decr_status_set(void *data, u64 val)
++static int spufs_decr_status_set(void *data, u64 val)
+ {
+ 	struct spu_context *ctx = data;
+-	spu_acquire_saved(ctx);
++	int ret;
++
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	if (val)
+ 		ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING;
+ 	else
+ 		ctx->csa.priv2.mfc_control_RW &= ~MFC_CNTL_DECREMENTER_RUNNING;
+ 	spu_release_saved(ctx);
++
++	return 0;
+ }
+ 
+ static u64 spufs_decr_status_get(struct spu_context *ctx)
+@@ -1659,13 +1894,19 @@
+ 		       spufs_decr_status_set, "0x%llx\n",
+ 		       SPU_ATTR_ACQUIRE_SAVED);
+ 
+-static void spufs_event_mask_set(void *data, u64 val)
++static int spufs_event_mask_set(void *data, u64 val)
+ {
+ 	struct spu_context *ctx = data;
+ 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
+-	spu_acquire_saved(ctx);
++	int ret;
++
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	lscsa->event_mask.slot[0] = (u32) val;
+ 	spu_release_saved(ctx);
++
++	return 0;
+ }
+ 
+ static u64 spufs_event_mask_get(struct spu_context *ctx)
+@@ -1690,13 +1931,19 @@
+ DEFINE_SPUFS_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get,
+ 		       NULL, "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED)
+ 
+-static void spufs_srr0_set(void *data, u64 val)
++static int spufs_srr0_set(void *data, u64 val)
+ {
+ 	struct spu_context *ctx = data;
+ 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
+-	spu_acquire_saved(ctx);
++	int ret;
++
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	lscsa->srr0.slot[0] = (u32) val;
+ 	spu_release_saved(ctx);
++
++	return 0;
+ }
+ 
+ static u64 spufs_srr0_get(struct spu_context *ctx)
+@@ -1727,10 +1974,12 @@
+ 	return ctx->object_id;
+ }
+ 
+-static void spufs_object_id_set(void *data, u64 id)
++static int spufs_object_id_set(void *data, u64 id)
+ {
+ 	struct spu_context *ctx = data;
+ 	ctx->object_id = id;
++
++	return 0;
+ }
+ 
+ DEFINE_SPUFS_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
+@@ -1777,13 +2026,13 @@
+ static ssize_t __spufs_mbox_info_read(struct spu_context *ctx,
+ 			char __user *buf, size_t len, loff_t *pos)
+ {
+-	u32 mbox_stat;
+ 	u32 data;
+ 
+-	mbox_stat = ctx->csa.prob.mb_stat_R;
+-	if (mbox_stat & 0x0000ff) {
+-		data = ctx->csa.prob.pu_mb_R;
+-	}
++	/* EOF if there's no entry in the mbox */
++	if (!(ctx->csa.prob.mb_stat_R & 0x0000ff))
++		return 0;
++
++	data = ctx->csa.prob.pu_mb_R;
+ 
+ 	return simple_read_from_buffer(buf, len, pos, &data, sizeof data);
+ }
+@@ -1797,7 +2046,9 @@
+ 	if (!access_ok(VERIFY_WRITE, buf, len))
+ 		return -EFAULT;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	spin_lock(&ctx->csa.register_lock);
+ 	ret = __spufs_mbox_info_read(ctx, buf, len, pos);
+ 	spin_unlock(&ctx->csa.register_lock);
+@@ -1815,13 +2066,13 @@
+ static ssize_t __spufs_ibox_info_read(struct spu_context *ctx,
+ 				char __user *buf, size_t len, loff_t *pos)
+ {
+-	u32 ibox_stat;
+ 	u32 data;
+ 
+-	ibox_stat = ctx->csa.prob.mb_stat_R;
+-	if (ibox_stat & 0xff0000) {
+-		data = ctx->csa.priv2.puint_mb_R;
+-	}
++	/* EOF if there's no entry in the ibox */
++	if (!(ctx->csa.prob.mb_stat_R & 0xff0000))
++		return 0;
++
++	data = ctx->csa.priv2.puint_mb_R;
+ 
+ 	return simple_read_from_buffer(buf, len, pos, &data, sizeof data);
+ }
+@@ -1835,7 +2086,9 @@
+ 	if (!access_ok(VERIFY_WRITE, buf, len))
+ 		return -EFAULT;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	spin_lock(&ctx->csa.register_lock);
+ 	ret = __spufs_ibox_info_read(ctx, buf, len, pos);
+ 	spin_unlock(&ctx->csa.register_lock);
+@@ -1876,7 +2129,9 @@
+ 	if (!access_ok(VERIFY_WRITE, buf, len))
+ 		return -EFAULT;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	spin_lock(&ctx->csa.register_lock);
+ 	ret = __spufs_wbox_info_read(ctx, buf, len, pos);
+ 	spin_unlock(&ctx->csa.register_lock);
+@@ -1926,7 +2181,9 @@
+ 	if (!access_ok(VERIFY_WRITE, buf, len))
+ 		return -EFAULT;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	spin_lock(&ctx->csa.register_lock);
+ 	ret = __spufs_dma_info_read(ctx, buf, len, pos);
+ 	spin_unlock(&ctx->csa.register_lock);
+@@ -1977,7 +2234,9 @@
+ 	struct spu_context *ctx = file->private_data;
+ 	int ret;
+ 
+-	spu_acquire_saved(ctx);
++	ret = spu_acquire_saved(ctx);
++	if (ret)
++		return ret;
+ 	spin_lock(&ctx->csa.register_lock);
+ 	ret = __spufs_proxydma_info_read(ctx, buf, len, pos);
+ 	spin_unlock(&ctx->csa.register_lock);
+@@ -2066,8 +2325,12 @@
+ static int spufs_show_stat(struct seq_file *s, void *private)
+ {
+ 	struct spu_context *ctx = s->private;
++	int ret;
++
++	ret = spu_acquire(ctx);
++	if (ret)
++		return ret;
+ 
+-	spu_acquire(ctx);
+ 	seq_printf(s, "%s %llu %llu %llu %llu "
+ 		      "%llu %llu %llu %llu %llu %llu %llu %llu\n",
+ 		ctx_state_names[ctx->stats.util_state],
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/hw_ops.c powerpc.git/arch/powerpc/platforms/cell/spufs/hw_ops.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/hw_ops.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/hw_ops.c	2008-01-28 20:25:49.000000000 +0100
+@@ -76,16 +76,18 @@
+ 		if (stat & 0xff0000)
+ 			ret |= POLLIN | POLLRDNORM;
+ 		else {
+-			spu_int_stat_clear(spu, 2, 0x1);
+-			spu_int_mask_or(spu, 2, 0x1);
++			spu_int_stat_clear(spu, 2, CLASS2_MAILBOX_INTR);
++			spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR);
+ 		}
+ 	}
+ 	if (events & (POLLOUT | POLLWRNORM)) {
+ 		if (stat & 0x00ff00)
+ 			ret = POLLOUT | POLLWRNORM;
+ 		else {
+-			spu_int_stat_clear(spu, 2, 0x10);
+-			spu_int_mask_or(spu, 2, 0x10);
++			spu_int_stat_clear(spu, 2,
++					CLASS2_MAILBOX_THRESHOLD_INTR);
++			spu_int_mask_or(spu, 2,
++					CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR);
+ 		}
+ 	}
+ 	spin_unlock_irq(&spu->register_lock);
+@@ -106,7 +108,7 @@
+ 		ret = 4;
+ 	} else {
+ 		/* make sure we get woken up by the interrupt */
+-		spu_int_mask_or(spu, 2, 0x1);
++		spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR);
+ 		ret = 0;
+ 	}
+ 	spin_unlock_irq(&spu->register_lock);
+@@ -127,7 +129,7 @@
+ 	} else {
+ 		/* make sure we get woken up by the interrupt when space
+ 		   becomes available */
+-		spu_int_mask_or(spu, 2, 0x10);
++		spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR);
+ 		ret = 0;
+ 	}
+ 	spin_unlock_irq(&spu->register_lock);
+@@ -206,6 +208,11 @@
+ 	return ctx->spu->local_store;
+ }
+ 
++static void spu_hw_privcntl_write(struct spu_context *ctx, u64 val)
++{
++	out_be64(&ctx->spu->priv2->spu_privcntl_RW, val);
++}
++
+ static u32 spu_hw_runcntl_read(struct spu_context *ctx)
+ {
+ 	return in_be32(&ctx->spu->problem->spu_runcntl_RW);
+@@ -215,11 +222,21 @@
+ {
+ 	spin_lock_irq(&ctx->spu->register_lock);
+ 	if (val & SPU_RUNCNTL_ISOLATE)
+-		out_be64(&ctx->spu->priv2->spu_privcntl_RW, 4LL);
++		spu_hw_privcntl_write(ctx,
++			SPU_PRIVCNT_LOAD_REQUEST_ENABLE_MASK);
+ 	out_be32(&ctx->spu->problem->spu_runcntl_RW, val);
+ 	spin_unlock_irq(&ctx->spu->register_lock);
+ }
+ 
++static void spu_hw_runcntl_stop(struct spu_context *ctx)
++{
++	spin_lock_irq(&ctx->spu->register_lock);
++	out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
++	while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
++		cpu_relax();
++	spin_unlock_irq(&ctx->spu->register_lock);
++}
++
+ static void spu_hw_master_start(struct spu_context *ctx)
+ {
+ 	struct spu *spu = ctx->spu;
+@@ -319,8 +336,10 @@
+ 	.npc_write = spu_hw_npc_write,
+ 	.status_read = spu_hw_status_read,
+ 	.get_ls = spu_hw_get_ls,
++	.privcntl_write = spu_hw_privcntl_write,
+ 	.runcntl_read = spu_hw_runcntl_read,
+ 	.runcntl_write = spu_hw_runcntl_write,
++	.runcntl_stop = spu_hw_runcntl_stop,
+ 	.master_start = spu_hw_master_start,
+ 	.master_stop = spu_hw_master_stop,
+ 	.set_mfc_query = spu_hw_set_mfc_query,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c powerpc.git/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -28,6 +28,8 @@
+ #include <asm/spu_csa.h>
+ #include <asm/mmu.h>
+ 
++#include "spufs.h"
++
+ static int spu_alloc_lscsa_std(struct spu_state *csa)
+ {
+ 	struct spu_lscsa *lscsa;
+@@ -73,7 +75,7 @@
+ 	int		i, j, n_4k;
+ 
+ 	/* Check availability of 64K pages */
+-	if (mmu_psize_defs[MMU_PAGE_64K].shift == 0)
++	if (!spu_64k_pages_available())
+ 		goto fail;
+ 
+ 	csa->use_big_pages = 1;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/run.c powerpc.git/arch/powerpc/platforms/cell/spufs/run.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/run.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/run.c	2008-01-28 20:25:49.000000000 +0100
+@@ -15,24 +15,55 @@
+ {
+ 	struct spu_context *ctx = spu->ctx;
+ 
+-	wake_up_all(&ctx->stop_wq);
++	/*
++	 * It should be impossible to preempt a context while an exception
++	 * is being processed, since the context switch code is specially
++	 * coded to deal with interrupts ... But, just in case, sanity check
++	 * the context pointer.  It is OK to return doing nothing since
++	 * the exception will be regenerated when the context is resumed.
++	 */
++	if (ctx) {
++		/* Copy exception arguments into module specific structure */
++		ctx->csa.class_0_pending = spu->class_0_pending;
++		ctx->csa.dsisr = spu->dsisr;
++		ctx->csa.dar = spu->dar;
++
++		/* ensure that the exception status has hit memory before a
++		 * thread waiting on the context's stop queue is woken */
++		smp_wmb();
++
++		wake_up_all(&ctx->stop_wq);
++	}
++
++	/* Clear callback arguments from spu structure */
++	spu->class_0_pending = 0;
++	spu->dsisr = 0;
++	spu->dar = 0;
+ }
+ 
+-static inline int spu_stopped(struct spu_context *ctx, u32 *stat)
++int spu_stopped(struct spu_context *ctx, u32 *stat)
+ {
+-	struct spu *spu;
+-	u64 pte_fault;
++	u64 dsisr;
++	u32 stopped;
+ 
+ 	*stat = ctx->ops->status_read(ctx);
+ 
+-	spu = ctx->spu;
+-	if (ctx->state != SPU_STATE_RUNNABLE ||
+-	    test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags))
++	if (test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags))
++		return 1;
++
++	stopped = SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP |
++		SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP;
++	if (*stat & stopped)
++		return 1;
++
++	dsisr = ctx->csa.dsisr;
++	if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
+ 		return 1;
+-	pte_fault = spu->dsisr &
+-	    (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED);
+-	return (!(*stat & SPU_STATUS_RUNNING) || pte_fault || spu->class_0_pending) ?
+-		1 : 0;
++
++	if (ctx->csa.class_0_pending)
++		return 1;
++
++	return 0;
+ }
+ 
+ static int spu_setup_isolated(struct spu_context *ctx)
+@@ -128,34 +159,66 @@
+ 
+ static int spu_run_init(struct spu_context *ctx, u32 *npc)
+ {
++	unsigned long runcntl = SPU_RUNCNTL_RUNNABLE;
++	int ret;
++
+ 	spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
+ 
+-	if (ctx->flags & SPU_CREATE_ISOLATE) {
+-		unsigned long runcntl;
++	/*
++	 * NOSCHED is synchronous scheduling with respect to the caller.
++	 * The caller waits for the context to be loaded.
++	 */
++	if (ctx->flags & SPU_CREATE_NOSCHED) {
++		if (ctx->state == SPU_STATE_SAVED) {
++			ret = spu_activate(ctx, 0);
++			if (ret)
++				return ret;
++		}
++	}
+ 
++	/*
++	 * Apply special setup as required.
++	 */
++	if (ctx->flags & SPU_CREATE_ISOLATE) {
+ 		if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) {
+-			int ret = spu_setup_isolated(ctx);
++			ret = spu_setup_isolated(ctx);
+ 			if (ret)
+ 				return ret;
+ 		}
+ 
+-		/* if userspace has set the runcntrl register (eg, to issue an
+-		 * isolated exit), we need to re-set it here */
++		/*
++		 * If userspace has set the runcntrl register (eg, to
++		 * issue an isolated exit), we need to re-set it here
++		 */
+ 		runcntl = ctx->ops->runcntl_read(ctx) &
+ 			(SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE);
+ 		if (runcntl == 0)
+ 			runcntl = SPU_RUNCNTL_RUNNABLE;
++	}
++
++	if (ctx->flags & SPU_CREATE_NOSCHED) {
++		spuctx_switch_state(ctx, SPU_UTIL_USER);
+ 		ctx->ops->runcntl_write(ctx, runcntl);
+ 	} else {
+-		unsigned long mode = SPU_PRIVCNTL_MODE_NORMAL;
+-		ctx->ops->npc_write(ctx, *npc);
++		unsigned long privcntl;
++
+ 		if (test_thread_flag(TIF_SINGLESTEP))
+-			mode = SPU_PRIVCNTL_MODE_SINGLE_STEP;
+-		out_be64(&ctx->spu->priv2->spu_privcntl_RW, mode);
+-		ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
+-	}
++			privcntl = SPU_PRIVCNTL_MODE_SINGLE_STEP;
++		else
++			privcntl = SPU_PRIVCNTL_MODE_NORMAL;
+ 
+-	spuctx_switch_state(ctx, SPU_UTIL_USER);
++		ctx->ops->npc_write(ctx, *npc);
++		ctx->ops->privcntl_write(ctx, privcntl);
++		ctx->ops->runcntl_write(ctx, runcntl);
++
++		if (ctx->state == SPU_STATE_SAVED) {
++			ret = spu_activate(ctx, 0);
++			if (ret)
++				return ret;
++		} else {
++			spuctx_switch_state(ctx, SPU_UTIL_USER);
++		}
++	}
+ 
+ 	return 0;
+ }
+@@ -165,6 +228,8 @@
+ {
+ 	int ret = 0;
+ 
++	spu_del_from_rq(ctx);
++
+ 	*status = ctx->ops->status_read(ctx);
+ 	*npc = ctx->ops->npc_read(ctx);
+ 
+@@ -177,26 +242,6 @@
+ 	return ret;
+ }
+ 
+-static int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc,
+-				         u32 *status)
+-{
+-	int ret;
+-
+-	ret = spu_run_fini(ctx, npc, status);
+-	if (ret)
+-		return ret;
+-
+-	if (*status & (SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_STOPPED_BY_HALT))
+-		return *status;
+-
+-	ret = spu_acquire_runnable(ctx, 0);
+-	if (ret)
+-		return ret;
+-
+-	spuctx_switch_state(ctx, SPU_UTIL_USER);
+-	return 0;
+-}
+-
+ /*
+  * SPU syscall restarting is tricky because we violate the basic
+  * assumption that the signal handler is running on the interrupted
+@@ -247,7 +292,7 @@
+ 	u32 ls_pointer, npc;
+ 	void __iomem *ls;
+ 	long spu_ret;
+-	int ret;
++	int ret, ret2;
+ 
+ 	/* get syscall block from local store */
+ 	npc = ctx->ops->npc_read(ctx) & ~3;
+@@ -269,9 +314,11 @@
+ 		if (spu_ret <= -ERESTARTSYS) {
+ 			ret = spu_handle_restartsys(ctx, &spu_ret, &npc);
+ 		}
+-		spu_acquire(ctx);
++		ret2 = spu_acquire(ctx);
+ 		if (ret == -ERESTARTSYS)
+ 			return ret;
++		if (ret2)
++			return -EINTR;
+ 	}
+ 
+ 	/* write result, jump over indirect pointer */
+@@ -281,18 +328,6 @@
+ 	return ret;
+ }
+ 
+-static inline int spu_process_events(struct spu_context *ctx)
+-{
+-	struct spu *spu = ctx->spu;
+-	int ret = 0;
+-
+-	if (spu->class_0_pending)
+-		ret = spu_irq_class_0_bottom(spu);
+-	if (!ret && signal_pending(current))
+-		ret = -ERESTARTSYS;
+-	return ret;
+-}
+-
+ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
+ {
+ 	int ret;
+@@ -302,29 +337,14 @@
+ 	if (mutex_lock_interruptible(&ctx->run_mutex))
+ 		return -ERESTARTSYS;
+ 
+-	ctx->ops->master_start(ctx);
++	spu_enable_spu(ctx);
+ 	ctx->event_return = 0;
+ 
+-	spu_acquire(ctx);
+-	if (ctx->state == SPU_STATE_SAVED) {
+-		__spu_update_sched_info(ctx);
+-		spu_set_timeslice(ctx);
+-
+-		ret = spu_activate(ctx, 0);
+-		if (ret) {
+-			spu_release(ctx);
+-			goto out;
+-		}
+-	} else {
+-		/*
+-		 * We have to update the scheduling priority under active_mutex
+-		 * to protect against find_victim().
+-		 *
+-		 * No need to update the timeslice ASAP, it will get updated
+-		 * once the current one has expired.
+-		 */
+-		spu_update_sched_info(ctx);
+-	}
++	ret = spu_acquire(ctx);
++	if (ret)
++		goto out_unlock;
++
++	spu_update_sched_info(ctx);
+ 
+ 	ret = spu_run_init(ctx, npc);
+ 	if (ret) {
+@@ -358,14 +378,12 @@
+ 		if (ret)
+ 			break;
+ 
+-		if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
+-			ret = spu_reacquire_runnable(ctx, npc, &status);
+-			if (ret)
+-				goto out2;
+-			continue;
+-		}
+-		ret = spu_process_events(ctx);
++		ret = spufs_handle_class0(ctx);
++		if (ret)
++			break;
+ 
++		if (signal_pending(current))
++			ret = -ERESTARTSYS;
+ 	} while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP |
+ 				      SPU_STATUS_STOPPED_BY_HALT |
+ 				       SPU_STATUS_SINGLE_STEP)));
+@@ -376,11 +394,10 @@
+ 		ctx->stats.libassist++;
+ 
+ 
+-	ctx->ops->master_stop(ctx);
++	spu_disable_spu(ctx);
+ 	ret = spu_run_fini(ctx, npc, &status);
+ 	spu_yield(ctx);
+ 
+-out2:
+ 	if ((ret == 0) ||
+ 	    ((ret == -ERESTARTSYS) &&
+ 	     ((status & SPU_STATUS_STOPPED_BY_HALT) ||
+@@ -401,6 +418,7 @@
+ 
+ out:
+ 	*event = ctx->event_return;
++out_unlock:
+ 	mutex_unlock(&ctx->run_mutex);
+ 	return ret;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/sched.c powerpc.git/arch/powerpc/platforms/cell/spufs/sched.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/sched.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/sched.c	2008-01-28 20:25:49.000000000 +0100
+@@ -58,6 +58,7 @@
+ static struct spu_prio_array *spu_prio;
+ static struct task_struct *spusched_task;
+ static struct timer_list spusched_timer;
++static struct timer_list spuloadavg_timer;
+ 
+ /*
+  * Priority of a normal, non-rt, non-niced'd process (aka nice level 0).
+@@ -105,15 +106,21 @@
+ void __spu_update_sched_info(struct spu_context *ctx)
+ {
+ 	/*
+-	 * 32-Bit assignment are atomic on powerpc, and we don't care about
+-	 * memory ordering here because retriving the controlling thread is
+-	 * per defintion racy.
++	 * assert that the context is not on the runqueue, so it is safe
++	 * to change its scheduling parameters.
++	 */
++	BUG_ON(!list_empty(&ctx->rq));
++
++	/*
++	 * 32-Bit assignments are atomic on powerpc, and we don't care about
++	 * memory ordering here because retrieving the controlling thread is
++	 * per definition racy.
+ 	 */
+ 	ctx->tid = current->pid;
+ 
+ 	/*
+ 	 * We do our own priority calculations, so we normally want
+-	 * ->static_prio to start with. Unfortunately thies field
++	 * ->static_prio to start with. Unfortunately this field
+ 	 * contains junk for threads with a realtime scheduling
+ 	 * policy so we have to look at ->prio in this case.
+ 	 */
+@@ -124,23 +131,32 @@
+ 	ctx->policy = current->policy;
+ 
+ 	/*
+-	 * A lot of places that don't hold list_mutex poke into
+-	 * cpus_allowed, including grab_runnable_context which
+-	 * already holds the runq_lock.  So abuse runq_lock
+-	 * to protect this field aswell.
++	 * TO DO: the context may be loaded, so we may need to activate
++	 * it again on a different node. But it shouldn't hurt anything
++	 * to update its parameters, because we know that the scheduler
++	 * is not actively looking at this field, since it is not on the
++	 * runqueue. The context will be rescheduled on the proper node
++	 * if it is timesliced or preempted.
+ 	 */
+-	spin_lock(&spu_prio->runq_lock);
+ 	ctx->cpus_allowed = current->cpus_allowed;
+-	spin_unlock(&spu_prio->runq_lock);
+ }
+ 
+ void spu_update_sched_info(struct spu_context *ctx)
+ {
+-	int node = ctx->spu->node;
++	int node;
+ 
+-	mutex_lock(&cbe_spu_info[node].list_mutex);
+-	__spu_update_sched_info(ctx);
+-	mutex_unlock(&cbe_spu_info[node].list_mutex);
++	if (ctx->state == SPU_STATE_RUNNABLE) {
++		node = ctx->spu->node;
++
++		/*
++		 * Take list_mutex to sync with find_victim().
++		 */
++		mutex_lock(&cbe_spu_info[node].list_mutex);
++		__spu_update_sched_info(ctx);
++		mutex_unlock(&cbe_spu_info[node].list_mutex);
++	} else {
++		__spu_update_sched_info(ctx);
++	}
+ }
+ 
+ static int __node_allowed(struct spu_context *ctx, int node)
+@@ -174,7 +190,7 @@
+ 	 * Wake up the active spu_contexts.
+ 	 *
+ 	 * When the awakened processes see their "notify_active" flag is set,
+-	 * they will call spu_switch_notify();
++	 * they will call spu_switch_notify().
+ 	 */
+ 	for_each_online_node(node) {
+ 		struct spu *spu;
+@@ -221,7 +237,6 @@
+ 	spu->wbox_callback = spufs_wbox_callback;
+ 	spu->stop_callback = spufs_stop_callback;
+ 	spu->mfc_callback = spufs_mfc_callback;
+-	spu->dma_callback = spufs_dma_callback;
+ 	mb();
+ 	spu_unmap_mappings(ctx);
+ 	spu_restore(&ctx->csa, spu);
+@@ -409,7 +424,6 @@
+ 	spu->wbox_callback = NULL;
+ 	spu->stop_callback = NULL;
+ 	spu->mfc_callback = NULL;
+-	spu->dma_callback = NULL;
+ 	spu_associate_mm(spu, NULL);
+ 	spu->pid = 0;
+ 	spu->tgid = 0;
+@@ -454,6 +468,13 @@
+ 	}
+ }
+ 
++static void spu_add_to_rq(struct spu_context *ctx)
++{
++	spin_lock(&spu_prio->runq_lock);
++	__spu_add_to_rq(ctx);
++	spin_unlock(&spu_prio->runq_lock);
++}
++
+ static void __spu_del_from_rq(struct spu_context *ctx)
+ {
+ 	int prio = ctx->prio;
+@@ -468,10 +489,24 @@
+ 	}
+ }
+ 
++void spu_del_from_rq(struct spu_context *ctx)
++{
++	spin_lock(&spu_prio->runq_lock);
++	__spu_del_from_rq(ctx);
++	spin_unlock(&spu_prio->runq_lock);
++}
++
+ static void spu_prio_wait(struct spu_context *ctx)
+ {
+ 	DEFINE_WAIT(wait);
+ 
++	/*
++	 * The caller must explicitly wait for a context to be loaded
++	 * if the nosched flag is set.  If NOSCHED is not set, the caller
++	 * queues the context and waits for an spu event or error.
++	 */
++	BUG_ON(!(ctx->flags & SPU_CREATE_NOSCHED));
++
+ 	spin_lock(&spu_prio->runq_lock);
+ 	prepare_to_wait_exclusive(&ctx->stop_wq, &wait, TASK_INTERRUPTIBLE);
+ 	if (!signal_pending(current)) {
+@@ -555,7 +590,7 @@
+ 	/*
+ 	 * Look for a possible preemption candidate on the local node first.
+ 	 * If there is no candidate look at the other nodes.  This isn't
+-	 * exactly fair, but so far the whole spu schedule tries to keep
++	 * exactly fair, but so far the whole spu scheduler tries to keep
+ 	 * a strong node affinity.  We might want to fine-tune this in
+ 	 * the future.
+ 	 */
+@@ -571,6 +606,7 @@
+ 			struct spu_context *tmp = spu->ctx;
+ 
+ 			if (tmp && tmp->prio > ctx->prio &&
++			    !(tmp->flags & SPU_CREATE_NOSCHED) &&
+ 			    (!victim || tmp->prio > victim->prio))
+ 				victim = spu->ctx;
+ 		}
+@@ -582,6 +618,10 @@
+ 			 * higher priority contexts before lower priority
+ 			 * ones, so this is safe until we introduce
+ 			 * priority inheritance schemes.
++			 *
++			 * XXX if the highest priority context is locked,
++			 * this can loop a long time.  Might be better to
++			 * look at another context or give up after X retries.
+ 			 */
+ 			if (!mutex_trylock(&victim->state_mutex)) {
+ 				victim = NULL;
+@@ -589,10 +629,10 @@
+ 			}
+ 
+ 			spu = victim->spu;
+-			if (!spu) {
++			if (!spu || victim->prio <= ctx->prio) {
+ 				/*
+ 				 * This race can happen because we've dropped
+-				 * the active list mutex.  No a problem, just
++				 * the active list mutex.  Not a problem, just
+ 				 * restart the search.
+ 				 */
+ 				mutex_unlock(&victim->state_mutex);
+@@ -607,13 +647,10 @@
+ 
+ 			victim->stats.invol_ctx_switch++;
+ 			spu->stats.invol_ctx_switch++;
++			spu_add_to_rq(victim);
++
+ 			mutex_unlock(&victim->state_mutex);
+-			/*
+-			 * We need to break out of the wait loop in spu_run
+-			 * manually to ensure this context gets put on the
+-			 * runqueue again ASAP.
+-			 */
+-			wake_up(&victim->stop_wq);
++
+ 			return spu;
+ 		}
+ 	}
+@@ -621,6 +658,50 @@
+ 	return NULL;
+ }
+ 
++static void __spu_schedule(struct spu *spu, struct spu_context *ctx)
++{
++	int node = spu->node;
++	int success = 0;
++
++	spu_set_timeslice(ctx);
++
++	mutex_lock(&cbe_spu_info[node].list_mutex);
++	if (spu->ctx == NULL) {
++		spu_bind_context(spu, ctx);
++		cbe_spu_info[node].nr_active++;
++		spu->alloc_state = SPU_USED;
++		success = 1;
++	}
++	mutex_unlock(&cbe_spu_info[node].list_mutex);
++
++	if (success)
++		wake_up_all(&ctx->run_wq);
++	else
++		spu_add_to_rq(ctx);
++}
++
++static void spu_schedule(struct spu *spu, struct spu_context *ctx)
++{
++	/* not a candidate for interruptible because it's called either
++	   from the scheduler thread or from spu_deactivate */
++	mutex_lock(&ctx->state_mutex);
++	__spu_schedule(spu, ctx);
++	spu_release(ctx);
++}
++
++static void spu_unschedule(struct spu *spu, struct spu_context *ctx)
++{
++	int node = spu->node;
++
++	mutex_lock(&cbe_spu_info[node].list_mutex);
++	cbe_spu_info[node].nr_active--;
++	spu->alloc_state = SPU_FREE;
++	spu_unbind_context(spu, ctx);
++	ctx->stats.invol_ctx_switch++;
++	spu->stats.invol_ctx_switch++;
++	mutex_unlock(&cbe_spu_info[node].list_mutex);
++}
++
+ /**
+  * spu_activate - find a free spu for a context and execute it
+  * @ctx:	spu context to schedule
+@@ -632,39 +713,47 @@
+  */
+ int spu_activate(struct spu_context *ctx, unsigned long flags)
+ {
+-	do {
+-		struct spu *spu;
++	struct spu *spu;
+ 
+-		/*
+-		 * If there are multiple threads waiting for a single context
+-		 * only one actually binds the context while the others will
+-		 * only be able to acquire the state_mutex once the context
+-		 * already is in runnable state.
+-		 */
+-		if (ctx->spu)
+-			return 0;
++	/*
++	 * If there are multiple threads waiting for a single context
++	 * only one actually binds the context while the others will
++	 * only be able to acquire the state_mutex once the context
++	 * already is in runnable state.
++	 */
++	if (ctx->spu)
++		return 0;
+ 
+-		spu = spu_get_idle(ctx);
+-		/*
+-		 * If this is a realtime thread we try to get it running by
+-		 * preempting a lower priority thread.
+-		 */
+-		if (!spu && rt_prio(ctx->prio))
+-			spu = find_victim(ctx);
+-		if (spu) {
+-			int node = spu->node;
++spu_activate_top:
++	if (signal_pending(current))
++		return -ERESTARTSYS;
+ 
+-			mutex_lock(&cbe_spu_info[node].list_mutex);
+-			spu_bind_context(spu, ctx);
+-			cbe_spu_info[node].nr_active++;
+-			mutex_unlock(&cbe_spu_info[node].list_mutex);
+-			return 0;
+-		}
++	spu = spu_get_idle(ctx);
++	/*
++	 * If this is a realtime thread we try to get it running by
++	 * preempting a lower priority thread.
++	 */
++	if (!spu && rt_prio(ctx->prio))
++		spu = find_victim(ctx);
++	if (spu) {
++		unsigned long runcntl;
+ 
++		runcntl = ctx->ops->runcntl_read(ctx);
++		__spu_schedule(spu, ctx);
++		if (runcntl & SPU_RUNCNTL_RUNNABLE)
++			spuctx_switch_state(ctx, SPU_UTIL_USER);
++
++		return 0;
++	}
++
++	if (ctx->flags & SPU_CREATE_NOSCHED) {
+ 		spu_prio_wait(ctx);
+-	} while (!signal_pending(current));
++		goto spu_activate_top;
++	}
++
++	spu_add_to_rq(ctx);
+ 
+-	return -ERESTARTSYS;
++	return 0;
+ }
+ 
+ /**
+@@ -706,21 +795,19 @@
+ 	if (spu) {
+ 		new = grab_runnable_context(max_prio, spu->node);
+ 		if (new || force) {
+-			int node = spu->node;
+-
+-			mutex_lock(&cbe_spu_info[node].list_mutex);
+-			spu_unbind_context(spu, ctx);
+-			spu->alloc_state = SPU_FREE;
+-			cbe_spu_info[node].nr_active--;
+-			mutex_unlock(&cbe_spu_info[node].list_mutex);
+-
+-			ctx->stats.vol_ctx_switch++;
+-			spu->stats.vol_ctx_switch++;
+-
+-			if (new)
+-				wake_up(&new->stop_wq);
++			spu_unschedule(spu, ctx);
++			if (new) {
++				if (new->flags & SPU_CREATE_NOSCHED)
++					wake_up(&new->stop_wq);
++				else {
++					spu_release(ctx);
++					spu_schedule(spu, new);
++					/* this one can't easily be made
++					   interruptible */
++					mutex_lock(&ctx->state_mutex);
++				}
++			}
+ 		}
+-
+ 	}
+ 
+ 	return new != NULL;
+@@ -757,43 +844,38 @@
+ 
+ static noinline void spusched_tick(struct spu_context *ctx)
+ {
++	struct spu_context *new = NULL;
++	struct spu *spu = NULL;
++	u32 status;
++
++	if (spu_acquire(ctx))
++		BUG();	/* a kernel thread never has signals pending */
++
++	if (ctx->state != SPU_STATE_RUNNABLE)
++		goto out;
++	if (spu_stopped(ctx, &status))
++		goto out;
+ 	if (ctx->flags & SPU_CREATE_NOSCHED)
+-		return;
++		goto out;
+ 	if (ctx->policy == SCHED_FIFO)
+-		return;
++		goto out;
+ 
+ 	if (--ctx->time_slice)
+-		return;
+-
+-	/*
+-	 * Unfortunately list_mutex ranks outside of state_mutex, so
+-	 * we have to trylock here.  If we fail give the context another
+-	 * tick and try again.
+-	 */
+-	if (mutex_trylock(&ctx->state_mutex)) {
+-		struct spu *spu = ctx->spu;
+-		struct spu_context *new;
++		goto out;
+ 
+-		new = grab_runnable_context(ctx->prio + 1, spu->node);
+-		if (new) {
+-			spu_unbind_context(spu, ctx);
+-			ctx->stats.invol_ctx_switch++;
+-			spu->stats.invol_ctx_switch++;
+-			spu->alloc_state = SPU_FREE;
+-			cbe_spu_info[spu->node].nr_active--;
+-			wake_up(&new->stop_wq);
+-			/*
+-			 * We need to break out of the wait loop in
+-			 * spu_run manually to ensure this context
+-			 * gets put on the runqueue again ASAP.
+-			 */
+-			wake_up(&ctx->stop_wq);
+-		}
+-		spu_set_timeslice(ctx);
+-		mutex_unlock(&ctx->state_mutex);
++	spu = ctx->spu;
++	new = grab_runnable_context(ctx->prio + 1, spu->node);
++	if (new) {
++		spu_unschedule(spu, ctx);
++		spu_add_to_rq(ctx);
+ 	} else {
+ 		ctx->time_slice++;
+ 	}
++out:
++	spu_release(ctx);
++
++	if (new)
++		spu_schedule(spu, new);
+ }
+ 
+ /**
+@@ -817,35 +899,31 @@
+ }
+ 
+ /**
+- * spu_calc_load - given tick count, update the avenrun load estimates.
+- * @tick:	tick count
++ * spu_calc_load - update the avenrun load estimates.
+  *
+  * No locking against reading these values from userspace, as for
+  * the CPU loadavg code.
+  */
+-static void spu_calc_load(unsigned long ticks)
++static void spu_calc_load(void)
+ {
+ 	unsigned long active_tasks; /* fixed-point */
+-	static int count = LOAD_FREQ;
+ 
+-	count -= ticks;
+-
+-	if (unlikely(count < 0)) {
+-		active_tasks = count_active_contexts() * FIXED_1;
+-		do {
+-			CALC_LOAD(spu_avenrun[0], EXP_1, active_tasks);
+-			CALC_LOAD(spu_avenrun[1], EXP_5, active_tasks);
+-			CALC_LOAD(spu_avenrun[2], EXP_15, active_tasks);
+-			count += LOAD_FREQ;
+-		} while (count < 0);
+-	}
++	active_tasks = count_active_contexts() * FIXED_1;
++	CALC_LOAD(spu_avenrun[0], EXP_1, active_tasks);
++	CALC_LOAD(spu_avenrun[1], EXP_5, active_tasks);
++	CALC_LOAD(spu_avenrun[2], EXP_15, active_tasks);
+ }
+ 
+ static void spusched_wake(unsigned long data)
+ {
+ 	mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
+ 	wake_up_process(spusched_task);
+-	spu_calc_load(SPUSCHED_TICK);
++}
++
++static void spuloadavg_wake(unsigned long data)
++{
++	mod_timer(&spuloadavg_timer, jiffies + LOAD_FREQ);
++	spu_calc_load();
+ }
+ 
+ static int spusched_thread(void *unused)
+@@ -857,17 +935,58 @@
+ 		set_current_state(TASK_INTERRUPTIBLE);
+ 		schedule();
+ 		for (node = 0; node < MAX_NUMNODES; node++) {
+-			mutex_lock(&cbe_spu_info[node].list_mutex);
+-			list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list)
+-				if (spu->ctx)
+-					spusched_tick(spu->ctx);
+-			mutex_unlock(&cbe_spu_info[node].list_mutex);
++			struct mutex *mtx = &cbe_spu_info[node].list_mutex;
++
++			mutex_lock(mtx);
++			list_for_each_entry(spu, &cbe_spu_info[node].spus,
++					cbe_list) {
++				struct spu_context *ctx = spu->ctx;
++
++				if (ctx) {
++					mutex_unlock(mtx);
++					spusched_tick(ctx);
++					mutex_lock(mtx);
++				}
++			}
++			mutex_unlock(mtx);
+ 		}
+ 	}
+ 
+ 	return 0;
+ }
+ 
++void spuctx_switch_state(struct spu_context *ctx,
++		enum spu_utilization_state new_state)
++{
++	unsigned long long curtime;
++	signed long long delta;
++	struct timespec ts;
++	struct spu *spu;
++	enum spu_utilization_state old_state;
++
++	ktime_get_ts(&ts);
++	curtime = timespec_to_ns(&ts);
++	delta = curtime - ctx->stats.tstamp;
++
++	WARN_ON(!mutex_is_locked(&ctx->state_mutex));
++	WARN_ON(delta < 0);
++
++	spu = ctx->spu;
++	old_state = ctx->stats.util_state;
++	ctx->stats.util_state = new_state;
++	ctx->stats.tstamp = curtime;
++
++	/*
++	 * Update the physical SPU utilization statistics.
++	 */
++	if (spu) {
++		ctx->stats.times[old_state] += delta;
++		spu->stats.times[old_state] += delta;
++		spu->stats.util_state = new_state;
++		spu->stats.tstamp = curtime;
++	}
++}
++
+ #define LOAD_INT(x) ((x) >> FSHIFT)
+ #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
+ 
+@@ -881,7 +1000,7 @@
+ 
+ 	/*
+ 	 * Note that last_pid doesn't really make much sense for the
+-	 * SPU loadavg (it even seems very odd on the CPU side..),
++	 * SPU loadavg (it even seems very odd on the CPU side...),
+ 	 * but we include it here to have a 100% compatible interface.
+ 	 */
+ 	seq_printf(s, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
+@@ -922,6 +1041,7 @@
+ 	spin_lock_init(&spu_prio->runq_lock);
+ 
+ 	setup_timer(&spusched_timer, spusched_wake, 0);
++	setup_timer(&spuloadavg_timer, spuloadavg_wake, 0);
+ 
+ 	spusched_task = kthread_run(spusched_thread, NULL, "spusched");
+ 	if (IS_ERR(spusched_task)) {
+@@ -929,6 +1049,8 @@
+ 		goto out_free_spu_prio;
+ 	}
+ 
++	mod_timer(&spuloadavg_timer, 0);
++
+ 	entry = create_proc_entry("spu_loadavg", 0, NULL);
+ 	if (!entry)
+ 		goto out_stop_kthread;
+@@ -954,6 +1076,7 @@
+ 	remove_proc_entry("spu_loadavg", NULL);
+ 
+ 	del_timer_sync(&spusched_timer);
++	del_timer_sync(&spuloadavg_timer);
+ 	kthread_stop(spusched_task);
+ 
+ 	for (node = 0; node < MAX_NUMNODES; node++) {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/spufs.h powerpc.git/arch/powerpc/platforms/cell/spufs/spufs.h
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/spufs.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/spufs.h	2008-01-28 20:25:49.000000000 +0100
+@@ -71,6 +71,7 @@
+ 	wait_queue_head_t wbox_wq;
+ 	wait_queue_head_t stop_wq;
+ 	wait_queue_head_t mfc_wq;
++	wait_queue_head_t run_wq;
+ 	struct fasync_struct *ibox_fasync;
+ 	struct fasync_struct *wbox_fasync;
+ 	struct fasync_struct *mfc_fasync;
+@@ -168,8 +169,10 @@
+ 	void (*npc_write) (struct spu_context * ctx, u32 data);
+ 	 u32(*status_read) (struct spu_context * ctx);
+ 	char*(*get_ls) (struct spu_context * ctx);
++	void (*privcntl_write) (struct spu_context *ctx, u64 data);
+ 	 u32 (*runcntl_read) (struct spu_context * ctx);
+ 	void (*runcntl_write) (struct spu_context * ctx, u32 data);
++	void (*runcntl_stop) (struct spu_context * ctx);
+ 	void (*master_start) (struct spu_context * ctx);
+ 	void (*master_stop) (struct spu_context * ctx);
+ 	int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
+@@ -219,15 +222,16 @@
+ 
+ /* fault handling */
+ int spufs_handle_class1(struct spu_context *ctx);
++int spufs_handle_class0(struct spu_context *ctx);
+ 
+ /* affinity */
+ struct spu *affinity_check(struct spu_context *ctx);
+ 
+ /* context management */
+ extern atomic_t nr_spu_contexts;
+-static inline void spu_acquire(struct spu_context *ctx)
++static inline int __must_check spu_acquire(struct spu_context *ctx)
+ {
+-	mutex_lock(&ctx->state_mutex);
++	return mutex_lock_interruptible(&ctx->state_mutex);
+ }
+ 
+ static inline void spu_release(struct spu_context *ctx)
+@@ -242,10 +246,11 @@
+ void spu_unmap_mappings(struct spu_context *ctx);
+ 
+ void spu_forget(struct spu_context *ctx);
+-int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags);
+-void spu_acquire_saved(struct spu_context *ctx);
++int __must_check spu_acquire_saved(struct spu_context *ctx);
+ void spu_release_saved(struct spu_context *ctx);
+ 
++int spu_stopped(struct spu_context *ctx, u32 * stat);
++void spu_del_from_rq(struct spu_context *ctx);
+ int spu_activate(struct spu_context *ctx, unsigned long flags);
+ void spu_deactivate(struct spu_context *ctx);
+ void spu_yield(struct spu_context *ctx);
+@@ -279,7 +284,9 @@
+ 		}							\
+ 		spu_release(ctx);					\
+ 		schedule();						\
+-		spu_acquire(ctx);					\
++		__ret = spu_acquire(ctx);				\
++		if (__ret)						\
++			break;						\
+ 	}								\
+ 	finish_wait(&(wq), &__wait);					\
+ 	__ret;								\
+@@ -306,41 +313,16 @@
+ extern struct spufs_coredump_reader spufs_coredump_read[];
+ extern int spufs_coredump_num_notes;
+ 
+-/*
+- * This function is a little bit too large for an inline, but
+- * as fault.c is built into the kernel we can't move it out of
+- * line.
+- */
+-static inline void spuctx_switch_state(struct spu_context *ctx,
+-		enum spu_utilization_state new_state)
+-{
+-	unsigned long long curtime;
+-	signed long long delta;
+-	struct timespec ts;
+-	struct spu *spu;
+-	enum spu_utilization_state old_state;
+-
+-	ktime_get_ts(&ts);
+-	curtime = timespec_to_ns(&ts);
+-	delta = curtime - ctx->stats.tstamp;
+-
+-	WARN_ON(!mutex_is_locked(&ctx->state_mutex));
+-	WARN_ON(delta < 0);
+-
+-	spu = ctx->spu;
+-	old_state = ctx->stats.util_state;
+-	ctx->stats.util_state = new_state;
+-	ctx->stats.tstamp = curtime;
+-
+-	/*
+-	 * Update the physical SPU utilization statistics.
+-	 */
+-	if (spu) {
+-		ctx->stats.times[old_state] += delta;
+-		spu->stats.times[old_state] += delta;
+-		spu->stats.util_state = new_state;
+-		spu->stats.tstamp = curtime;
+-	}
+-}
++extern int spu_init_csa(struct spu_state *csa);
++extern void spu_fini_csa(struct spu_state *csa);
++extern int spu_save(struct spu_state *prev, struct spu *spu);
++extern int spu_restore(struct spu_state *new, struct spu *spu);
++extern int spu_switch(struct spu_state *prev, struct spu_state *new,
++		      struct spu *spu);
++extern int spu_alloc_lscsa(struct spu_state *csa);
++extern void spu_free_lscsa(struct spu_state *csa);
++
++extern void spuctx_switch_state(struct spu_context *ctx,
++		enum spu_utilization_state new_state);
+ 
+ #endif
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/cell/spufs/switch.c powerpc.git/arch/powerpc/platforms/cell/spufs/switch.c
+--- linux-2.6.24/arch/powerpc/platforms/cell/spufs/switch.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/cell/spufs/switch.c	2008-01-28 20:25:49.000000000 +0100
+@@ -48,6 +48,8 @@
+ #include <asm/spu_csa.h>
+ #include <asm/mmu_context.h>
+ 
++#include "spufs.h"
++
+ #include "spu_save_dump.h"
+ #include "spu_restore_dump.h"
+ 
+@@ -691,35 +693,9 @@
+ 	out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE);
+ }
+ 
+-static inline void get_kernel_slb(u64 ea, u64 slb[2])
++static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu,
++		unsigned int *code, int code_size)
+ {
+-	u64 llp;
+-
+-	if (REGION_ID(ea) == KERNEL_REGION_ID)
+-		llp = mmu_psize_defs[mmu_linear_psize].sllp;
+-	else
+-		llp = mmu_psize_defs[mmu_virtual_psize].sllp;
+-	slb[0] = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) |
+-		SLB_VSID_KERNEL | llp;
+-	slb[1] = (ea & ESID_MASK) | SLB_ESID_V;
+-}
+-
+-static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe)
+-{
+-	struct spu_priv2 __iomem *priv2 = spu->priv2;
+-
+-	out_be64(&priv2->slb_index_W, slbe);
+-	eieio();
+-	out_be64(&priv2->slb_vsid_RW, slb[0]);
+-	out_be64(&priv2->slb_esid_RW, slb[1]);
+-	eieio();
+-}
+-
+-static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu)
+-{
+-	u64 code_slb[2];
+-	u64 lscsa_slb[2];
+-
+ 	/* Save, Step 47:
+ 	 * Restore, Step 30.
+ 	 *     If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All
+@@ -735,11 +711,7 @@
+ 	 *     translation is desired by OS environment).
+ 	 */
+ 	spu_invalidate_slbs(spu);
+-	get_kernel_slb((unsigned long)&spu_save_code[0], code_slb);
+-	get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb);
+-	load_mfc_slb(spu, code_slb, 0);
+-	if ((lscsa_slb[0] != code_slb[0]) || (lscsa_slb[1] != code_slb[1]))
+-		load_mfc_slb(spu, lscsa_slb, 1);
++	spu_setup_kernel_slbs(spu, csa->lscsa, code, code_size);
+ }
+ 
+ static inline void set_switch_active(struct spu_state *csa, struct spu *spu)
+@@ -768,9 +740,9 @@
+ 	 *     (translation) interrupts.
+ 	 */
+ 	spin_lock_irq(&spu->register_lock);
+-	spu_int_stat_clear(spu, 0, ~0ul);
+-	spu_int_stat_clear(spu, 1, ~0ul);
+-	spu_int_stat_clear(spu, 2, ~0ul);
++	spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK);
++	spu_int_stat_clear(spu, 1, CLASS1_INTR_MASK);
++	spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK);
+ 	spu_int_mask_set(spu, 0, 0ul);
+ 	spu_int_mask_set(spu, 1, class1_mask);
+ 	spu_int_mask_set(spu, 2, 0ul);
+@@ -927,8 +899,8 @@
+ 	POLL_WHILE_FALSE(in_be32(&prob->dma_tagstatus_R) & mask);
+ 
+ 	local_irq_save(flags);
+-	spu_int_stat_clear(spu, 0, ~(0ul));
+-	spu_int_stat_clear(spu, 2, ~(0ul));
++	spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK);
++	spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK);
+ 	local_irq_restore(flags);
+ }
+ 
+@@ -946,8 +918,8 @@
+ 	POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING);
+ 
+ 	local_irq_save(flags);
+-	spu_int_stat_clear(spu, 0, ~(0ul));
+-	spu_int_stat_clear(spu, 2, ~(0ul));
++	spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK);
++	spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK);
+ 	local_irq_restore(flags);
+ }
+ 
+@@ -1423,9 +1395,9 @@
+ 	spu_int_mask_set(spu, 0, 0ul);
+ 	spu_int_mask_set(spu, 1, 0ul);
+ 	spu_int_mask_set(spu, 2, 0ul);
+-	spu_int_stat_clear(spu, 0, ~0ul);
+-	spu_int_stat_clear(spu, 1, ~0ul);
+-	spu_int_stat_clear(spu, 2, ~0ul);
++	spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK);
++	spu_int_stat_clear(spu, 1, CLASS1_INTR_MASK);
++	spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK);
+ 	spin_unlock_irq(&spu->register_lock);
+ }
+ 
+@@ -1866,7 +1838,8 @@
+ 	 */
+ 
+ 	resume_mfc_queue(prev, spu);	/* Step 46. */
+-	setup_mfc_slbs(prev, spu);	/* Step 47. */
++	/* Step 47. */
++	setup_mfc_slbs(prev, spu, spu_save_code, sizeof(spu_save_code));
+ 	set_switch_active(prev, spu);	/* Step 48. */
+ 	enable_interrupts(prev, spu);	/* Step 49. */
+ 	save_ls_16kb(prev, spu);	/* Step 50. */
+@@ -1971,7 +1944,8 @@
+ 	setup_spu_status_part1(next, spu);	/* Step 27. */
+ 	setup_spu_status_part2(next, spu);	/* Step 28. */
+ 	restore_mfc_rag(next, spu);	        /* Step 29. */
+-	setup_mfc_slbs(next, spu);	        /* Step 30. */
++	/* Step 30. */
++	setup_mfc_slbs(next, spu, spu_restore_code, sizeof(spu_restore_code));
+ 	set_spu_npc(next, spu);	                /* Step 31. */
+ 	set_signot1(next, spu);	                /* Step 32. */
+ 	set_signot2(next, spu);	                /* Step 33. */
+@@ -2103,10 +2077,6 @@
+ 	int rc;
+ 
+ 	acquire_spu_lock(spu);	        /* Step 1.     */
+-	prev->dar = spu->dar;
+-	prev->dsisr = spu->dsisr;
+-	spu->dar = 0;
+-	spu->dsisr = 0;
+ 	rc = __do_spu_save(prev, spu);	/* Steps 2-53. */
+ 	release_spu_lock(spu);
+ 	if (rc != 0 && rc != 2 && rc != 6) {
+@@ -2133,9 +2103,6 @@
+ 	acquire_spu_lock(spu);
+ 	harvest(NULL, spu);
+ 	spu->slb_replace = 0;
+-	new->dar = 0;
+-	new->dsisr = 0;
+-	spu->class_0_pending = 0;
+ 	rc = __do_spu_restore(new, spu);
+ 	release_spu_lock(spu);
+ 	if (rc) {
+@@ -2215,10 +2182,8 @@
+ 
+ 	return 0;
+ }
+-EXPORT_SYMBOL_GPL(spu_init_csa);
+ 
+ void spu_fini_csa(struct spu_state *csa)
+ {
+ 	spu_free_lscsa(csa);
+ }
+-EXPORT_SYMBOL_GPL(spu_fini_csa);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/celleb/Kconfig powerpc.git/arch/powerpc/platforms/celleb/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/celleb/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/celleb/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -2,6 +2,8 @@
+ 	bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
+ 	depends on PPC_MULTIPLATFORM && PPC64
+ 	select PPC_CELL
++	select PPC_CELL_NATIVE
++	select PPC_RTAS
+ 	select PPC_INDIRECT_IO
+ 	select PPC_OF_PLATFORM_PCI
+ 	select HAS_TXX9_SERIAL
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/celleb/io-workarounds.c powerpc.git/arch/powerpc/platforms/celleb/io-workarounds.c
+--- linux-2.6.24/arch/powerpc/platforms/celleb/io-workarounds.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/celleb/io-workarounds.c	2008-01-28 20:25:49.000000000 +0100
+@@ -22,6 +22,7 @@
+ 
+ #undef DEBUG
+ 
++#include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/irq.h>
+ 
+@@ -222,7 +223,7 @@
+ 			       void (*dummy_read)(struct pci_controller *))
+ {
+ 	struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count];
+-	struct device_node *np = phb->arch_data;
++	struct device_node *np = phb->dn;
+ 
+ 	if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) {
+ 		printk(KERN_ERR "Too many pci bridges, workarounds"
+@@ -256,13 +257,13 @@
+ 
+ 	celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ 	if (!celleb_dummy_page_va) {
+-		printk(KERN_ERR "Celleb: dummy read disabled."
++		printk(KERN_ERR "Celleb: dummy read disabled. "
+ 			"Alloc celleb_dummy_page_va failed\n");
+ 		return 1;
+ 	}
+ 
+ 	list_for_each_entry(phb, &hose_list, list_node) {
+-		node = phb->arch_data;
++		node = phb->dn;
+ 		match = of_match_node(celleb_pci_workaround_match, node);
+ 
+ 		if (match) {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/celleb/iommu.c powerpc.git/arch/powerpc/platforms/celleb/iommu.c
+--- linux-2.6.24/arch/powerpc/platforms/celleb/iommu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/celleb/iommu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -22,8 +22,9 @@
+ #include <linux/init.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/pci.h>
++#include <linux/of_platform.h>
+ 
+-#include <asm/of_platform.h>
++#include <asm/machdep.h>
+ 
+ #include "beat_wrapper.h"
+ 
+@@ -51,6 +52,8 @@
+ 	return 0;
+ }
+ 
++static unsigned long celleb_dma_direct_offset;
++
+ static void __init celleb_init_direct_mapping(void)
+ {
+ 	u64 lpar_addr, io_addr;
+@@ -68,7 +71,18 @@
+ 				     ioid, DMA_FLAGS);
+ 	}
+ 
+-	dma_direct_offset = dma_base;
++	celleb_dma_direct_offset = dma_base;
++}
++
++static void celleb_dma_dev_setup(struct device *dev)
++{
++	dev->archdata.dma_ops = get_pci_dma_ops();
++	dev->archdata.dma_data = (void *)celleb_dma_direct_offset;
++}
++
++static void celleb_pci_dma_dev_setup(struct pci_dev *pdev)
++{
++	celleb_dma_dev_setup(&pdev->dev);
+ }
+ 
+ static int celleb_of_bus_notify(struct notifier_block *nb,
+@@ -80,7 +94,7 @@
+ 	if (action != BUS_NOTIFY_ADD_DEVICE)
+ 		return 0;
+ 
+-	dev->archdata.dma_ops = get_pci_dma_ops();
++	celleb_dma_dev_setup(dev);
+ 
+ 	return 0;
+ }
+@@ -91,14 +105,12 @@
+ 
+ static int __init celleb_init_iommu(void)
+ {
+-	if (!machine_is(celleb))
+-		return -ENODEV;
+-
+ 	celleb_init_direct_mapping();
+ 	set_pci_dma_ops(&dma_direct_ops);
++	ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup;
+ 	bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier);
+ 
+ 	return 0;
+ }
+ 
+-arch_initcall(celleb_init_iommu);
++machine_arch_initcall(celleb_beat, celleb_init_iommu);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/celleb/pci.c powerpc.git/arch/powerpc/platforms/celleb/pci.c
+--- linux-2.6.24/arch/powerpc/platforms/celleb/pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/celleb/pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -31,6 +31,7 @@
+ #include <linux/init.h>
+ #include <linux/bootmem.h>
+ #include <linux/pci_regs.h>
++#include <linux/of.h>
+ #include <linux/of_device.h>
+ 
+ #include <asm/io.h>
+@@ -138,8 +139,6 @@
+ 		*val = celleb_fake_config_readl(p);
+ 		break;
+ 	}
+-
+-	return;
+ }
+ 
+ static void celleb_config_write_fake(unsigned char *config, int where,
+@@ -158,7 +157,6 @@
+ 		celleb_fake_config_writel(val, p);
+ 		break;
+ 	}
+-	return;
+ }
+ 
+ static int celleb_fake_pci_read_config(struct pci_bus *bus,
+@@ -351,6 +349,10 @@
+ 	wi1 = of_get_property(node, "vendor-id", NULL);
+ 	wi2 = of_get_property(node, "class-code", NULL);
+ 	wi3 = of_get_property(node, "revision-id", NULL);
++	if (!wi0 || !wi1 || !wi2 || !wi3) {
++		printk(KERN_ERR "PCI: Missing device tree properties.\n");
++		goto error;
++	}
+ 
+ 	celleb_config_write_fake(*config, PCI_DEVICE_ID, 2, wi0[0] & 0xffff);
+ 	celleb_config_write_fake(*config, PCI_VENDOR_ID, 2, wi1[0] & 0xffff);
+@@ -372,6 +374,10 @@
+ 	celleb_setup_pci_base_addrs(hose, devno, fn, num_base_addr);
+ 
+ 	li = of_get_property(node, "interrupts", &rlen);
++	if (!li) {
++		printk(KERN_ERR "PCI: interrupts not found.\n");
++		goto error;
++	}
+ 	val = li[0];
+ 	celleb_config_write_fake(*config, PCI_INTERRUPT_PIN, 1, 1);
+ 	celleb_config_write_fake(*config, PCI_INTERRUPT_LINE, 1, val);
+@@ -475,7 +481,7 @@
+ 
+ int __init celleb_setup_phb(struct pci_controller *phb)
+ {
+-	struct device_node *dev = phb->arch_data;
++	struct device_node *dev = phb->dn;
+ 	const struct of_device_id *match;
+ 	int (*setup_func)(struct device_node *, struct pci_controller *);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/celleb/scc_epci.c powerpc.git/arch/powerpc/platforms/celleb/scc_epci.c
+--- linux-2.6.24/arch/powerpc/platforms/celleb/scc_epci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/celleb/scc_epci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -95,7 +95,7 @@
+ 	private->dummy_page_da = dma_map_single(hose->parent,
+ 		celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE);
+ 	if (private->dummy_page_da == DMA_ERROR_CODE) {
+-		printk(KERN_ERR "EPCI: dummy read disabled."
++		printk(KERN_ERR "EPCI: dummy read disabled. "
+ 		       "Map dummy page failed.\n");
+ 		return;
+ 	}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/celleb/scc_uhc.c powerpc.git/arch/powerpc/platforms/celleb/scc_uhc.c
+--- linux-2.6.24/arch/powerpc/platforms/celleb/scc_uhc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/celleb/scc_uhc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -47,7 +47,8 @@
+ 	u32 val = 0;
+ 	int i;
+ 
+-	if (!machine_is(celleb))
++	if (!machine_is(celleb_beat) &&
++	    !machine_is(celleb_native))
+ 		return;
+ 
+ 	uhc_base = ioremap(pci_resource_start(dev, 0),
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/celleb/setup.c powerpc.git/arch/powerpc/platforms/celleb/setup.c
+--- linux-2.6.24/arch/powerpc/platforms/celleb/setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/celleb/setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -40,6 +40,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/root_dev.h>
+ #include <linux/console.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/mmu.h>
+ #include <asm/processor.h>
+@@ -52,12 +53,16 @@
+ #include <asm/time.h>
+ #include <asm/spu_priv1.h>
+ #include <asm/firmware.h>
+-#include <asm/of_platform.h>
++#include <asm/rtas.h>
++#include <asm/cell-regs.h>
+ 
+ #include "interrupt.h"
+ #include "beat_wrapper.h"
+ #include "beat.h"
+ #include "pci.h"
++#include "../cell/interrupt.h"
++#include "../cell/pervasive.h"
++#include "../cell/ras.h"
+ 
+ static char celleb_machine_type[128] = "Celleb";
+ 
+@@ -88,61 +93,122 @@
+ 	printk("*** %04x : %s\n", hex, s ? s : "");
+ }
+ 
+-static void __init celleb_setup_arch(void)
++static void __init celleb_setup_arch_common(void)
++{
++	/* init to some ~sane value until calibrate_delay() runs */
++	loops_per_jiffy = 50000000;
++
++#ifdef CONFIG_DUMMY_CONSOLE
++	conswitchp = &dummy_con;
++#endif
++}
++
++static struct of_device_id celleb_bus_ids[] __initdata = {
++	{ .type = "scc", },
++	{ .type = "ioif", },	/* old style */
++	{},
++};
++
++static int __init celleb_publish_devices(void)
++{
++	/* Publish OF platform devices for southbridge IOs */
++	of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
++
++	celleb_pci_workaround_init();
++
++	return 0;
++}
++machine_device_initcall(celleb_beat, celleb_publish_devices);
++machine_device_initcall(celleb_native, celleb_publish_devices);
++
++
++/*
++ * functions for Celleb-Beat
++ */
++static void __init celleb_setup_arch_beat(void)
+ {
+ #ifdef CONFIG_SPU_BASE
+-	spu_priv1_ops = &spu_priv1_beat_ops;
+-	spu_management_ops = &spu_management_of_ops;
++	spu_priv1_ops		= &spu_priv1_beat_ops;
++	spu_management_ops	= &spu_management_of_ops;
+ #endif
+ 
+ #ifdef CONFIG_SMP
+ 	smp_init_celleb();
+ #endif
+ 
+-	/* init to some ~sane value until calibrate_delay() runs */
+-	loops_per_jiffy = 50000000;
+-
+-#ifdef CONFIG_DUMMY_CONSOLE
+-	conswitchp = &dummy_con;
+-#endif
++	celleb_setup_arch_common();
+ }
+ 
+-static int __init celleb_probe(void)
++static int __init celleb_probe_beat(void)
+ {
+ 	unsigned long root = of_get_flat_dt_root();
+ 
+ 	if (!of_flat_dt_is_compatible(root, "Beat"))
+ 		return 0;
+ 
+-	powerpc_firmware_features |= FW_FEATURE_CELLEB_POSSIBLE;
++	powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS
++		| FW_FEATURE_BEAT | FW_FEATURE_LPAR;
+ 	hpte_init_beat_v3();
++
+ 	return 1;
+ }
+ 
+-static struct of_device_id celleb_bus_ids[] __initdata = {
+-	{ .type = "scc", },
+-	{ .type = "ioif", },	/* old style */
+-	{},
+-};
+ 
+-static int __init celleb_publish_devices(void)
++/*
++ * functions for Celleb-native
++ */
++static void __init celleb_init_IRQ_native(void)
+ {
+-	if (!machine_is(celleb))
+-		return 0;
++	iic_init_IRQ();
++	spider_init_IRQ();
++}
+ 
+-	/* Publish OF platform devices for southbridge IOs */
+-	of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
++static void __init celleb_setup_arch_native(void)
++{
++#ifdef CONFIG_SPU_BASE
++	spu_priv1_ops		= &spu_priv1_mmio_ops;
++	spu_management_ops	= &spu_management_of_ops;
++#endif
+ 
+-	celleb_pci_workaround_init();
++	cbe_regs_init();
+ 
+-	return 0;
++#ifdef CONFIG_CBE_RAS
++	cbe_ras_init();
++#endif
++
++#ifdef CONFIG_SMP
++	smp_init_cell();
++#endif
++
++	cbe_pervasive_init();
++
++	/* XXX: nvram initialization should be added */
++
++	celleb_setup_arch_common();
++}
++
++static int __init celleb_probe_native(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++
++	if (of_flat_dt_is_compatible(root, "Beat") ||
++	    !of_flat_dt_is_compatible(root, "TOSHIBA,Celleb"))
++		return 0;
++
++	powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS;
++	hpte_init_native();
++
++	return 1;
+ }
+-device_initcall(celleb_publish_devices);
+ 
+-define_machine(celleb) {
+-	.name			= "Cell Reference Set",
+-	.probe			= celleb_probe,
+-	.setup_arch		= celleb_setup_arch,
++
++/*
++ * machine definitions
++ */
++define_machine(celleb_beat) {
++	.name			= "Cell Reference Set (Beat)",
++	.probe			= celleb_probe_beat,
++	.setup_arch		= celleb_setup_arch_beat,
+ 	.show_cpuinfo		= celleb_show_cpuinfo,
+ 	.restart		= beat_restart,
+ 	.power_off		= beat_power_off,
+@@ -167,3 +233,26 @@
+ 	.machine_crash_shutdown	= default_machine_crash_shutdown,
+ #endif
+ };
++
++define_machine(celleb_native) {
++	.name			= "Cell Reference Set (native)",
++	.probe			= celleb_probe_native,
++	.setup_arch		= celleb_setup_arch_native,
++	.show_cpuinfo		= celleb_show_cpuinfo,
++	.restart		= rtas_restart,
++	.power_off		= rtas_power_off,
++	.halt			= rtas_halt,
++	.get_boot_time		= rtas_get_boot_time,
++	.get_rtc_time		= rtas_get_rtc_time,
++	.set_rtc_time		= rtas_set_rtc_time,
++	.calibrate_decr		= generic_calibrate_decr,
++	.progress		= celleb_progress,
++	.pci_probe_mode 	= celleb_pci_probe_mode,
++	.pci_setup_phb		= celleb_setup_phb,
++	.init_IRQ		= celleb_init_IRQ_native,
++#ifdef CONFIG_KEXEC
++	.machine_kexec		= default_machine_kexec,
++	.machine_kexec_prepare	= default_machine_kexec_prepare,
++	.machine_crash_shutdown	= default_machine_crash_shutdown,
++#endif
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/chrp/pci.c powerpc.git/arch/powerpc/platforms/chrp/pci.c
+--- linux-2.6.24/arch/powerpc/platforms/chrp/pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/chrp/pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -198,7 +198,7 @@
+ 		printk ("RTAS supporting Pegasos OF not found, please upgrade"
+ 			" your firmware\n");
+ 	}
+-	pci_assign_all_buses = 1;
++	ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+ 	/* keep the reference to the root node */
+ }
+ 
+@@ -354,7 +354,7 @@
+  * mode as well. The same fixup must be done to the class-code property in
+  * the IDE node /pci@80000000/ide@C,1
+  */
+-static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
++static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
+ {
+ 	u8 progif;
+ 	struct pci_dev *viaisa;
+@@ -375,4 +375,4 @@
+ 
+ 	pci_dev_put(viaisa);
+ }
+-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/chrp/setup.c powerpc.git/arch/powerpc/platforms/chrp/setup.c
+--- linux-2.6.24/arch/powerpc/platforms/chrp/setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/chrp/setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -115,7 +115,7 @@
+ 	seq_printf(m, "machine\t\t: CHRP %s\n", model);
+ 
+ 	/* longtrail (goldengate) stuff */
+-	if (!strncmp(model, "IBM,LongTrail", 13)) {
++	if (model && !strncmp(model, "IBM,LongTrail", 13)) {
+ 		/* VLSI VAS96011/12 `Golden Gate 2' */
+ 		/* Memory banks */
+ 		sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL)
+@@ -203,15 +203,20 @@
+ static void __init sio_init(void)
+ {
+ 	struct device_node *root;
++	const char *model;
+ 
+-	if ((root = of_find_node_by_path("/")) &&
+-	    !strncmp(of_get_property(root, "model", NULL),
+-			"IBM,LongTrail", 13)) {
++	root = of_find_node_by_path("/");
++	if (!root)
++		return;
++
++	model = of_get_property(root, "model", NULL);
++	if (model && !strncmp(model, "IBM,LongTrail", 13)) {
+ 		/* logical device 0 (KBC/Keyboard) */
+ 		sio_fixup_irq("keyboard", 0, 1, 2);
+ 		/* select logical device 1 (KBC/Mouse) */
+ 		sio_fixup_irq("mouse", 1, 12, 2);
+ 	}
++
+ 	of_node_put(root);
+ }
+ 
+@@ -251,6 +256,57 @@
+ 	for(;;);
+ }
+ 
++/*
++ * Per default, input/output-device points to the keyboard/screen
++ * If no card is installed, the built-in serial port is used as a fallback.
++ * But unfortunately, the firmware does not connect /chosen/{stdin,stdout}
++ * the the built-in serial node. Instead, a /failsafe node is created.
++ */
++static void chrp_init_early(void)
++{
++	struct device_node *node;
++	const char *property;
++
++	if (strstr(cmd_line, "console="))
++		return;
++	/* find the boot console from /chosen/stdout */
++	if (!of_chosen)
++		return;
++	node = of_find_node_by_path("/");
++	if (!node)
++		return;
++	property = of_get_property(node, "model", NULL);
++	if (!property)
++		goto out_put;
++	if (strcmp(property, "Pegasos2"))
++		goto out_put;
++	/* this is a Pegasos2 */
++	property = of_get_property(of_chosen, "linux,stdout-path", NULL);
++	if (!property)
++		goto out_put;
++	of_node_put(node);
++	node = of_find_node_by_path(property);
++	if (!node)
++		return;
++	property = of_get_property(node, "device_type", NULL);
++	if (!property)
++		goto out_put;
++	if (strcmp(property, "serial"))
++		goto out_put;
++	/*
++	 * The 9pin connector is either /failsafe
++	 * or /pci@80000000/isa@C/serial@i2F8
++	 * The optional graphics card has also type 'serial' in VGA mode.
++	 */
++	property = of_get_property(node, "name", NULL);
++	if (!property)
++		goto out_put;
++	if (!strcmp(property, "failsafe") || !strcmp(property, "serial"))
++		add_preferred_console("ttyS", 0, NULL);
++out_put:
++	of_node_put(node);
++}
++
+ void __init chrp_setup_arch(void)
+ {
+ 	struct device_node *root = of_find_node_by_path("/");
+@@ -594,6 +650,7 @@
+ 	.probe			= chrp_probe,
+ 	.setup_arch		= chrp_setup_arch,
+ 	.init			= chrp_init2,
++	.init_early		= chrp_init_early,
+ 	.show_cpuinfo		= chrp_show_cpuinfo,
+ 	.init_IRQ		= chrp_init_IRQ,
+ 	.restart		= rtas_restart,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/embedded6xx/Kconfig powerpc.git/arch/powerpc/platforms/embedded6xx/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/embedded6xx/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/embedded6xx/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -9,6 +9,8 @@
+ 	select FSL_SOC
+ 	select PPC_UDBG_16550 if SERIAL_8250
+ 	select DEFAULT_UIMAGE
++	select MPC10X_OPENPIC
++	select MPC10X_BRIDGE
+ 	help
+ 	  Select LINKSTATION if configuring for one of PPC- (MPC8241)
+ 	  based NAS systems from Buffalo Technology. So far only
+@@ -16,6 +18,19 @@
+ 	  Linkstation-I HD-HLAN and HD-HGLAN versions, and PPC-based
+ 	  Terastation systems should be supported too.
+ 
++config STORCENTER
++	bool "IOMEGA StorCenter"
++	depends on EMBEDDED6xx
++	select MPIC
++	select FSL_SOC
++	select PPC_UDBG_16550 if SERIAL_8250
++	select WANT_DEVICE_TREE
++	select MPC10X_OPENPIC
++	select MPC10X_BRIDGE
++	help
++	  Select STORCENTER if configuring for the iomega StorCenter
++	  with an 8241 CPU in it.
++
+ config MPC7448HPC2
+ 	bool "Freescale MPC7448HPC2(Taiga)"
+ 	depends on EMBEDDED6xx
+@@ -23,6 +38,7 @@
+ 	select DEFAULT_UIMAGE
+ 	select PPC_UDBG_16550
+ 	select WANT_DEVICE_TREE
++	select TSI108_BRIDGE
+ 	help
+ 	  Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
+ 	  platform
+@@ -33,6 +49,7 @@
+ 	select TSI108_BRIDGE
+ 	select PPC_UDBG_16550
+ 	select WANT_DEVICE_TREE
++	select TSI108_BRIDGE
+ 	help
+ 	  Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
+ 	  Board with TSI108/9 bridge (Hickory/Holly)
+@@ -48,17 +65,13 @@
+ 
+ config TSI108_BRIDGE
+ 	bool
+-	depends on MPC7448HPC2 || PPC_HOLLY
+ 	select PCI
+ 	select MPIC
+ 	select MPIC_WEIRD
+-	default y
+ 
+ config MPC10X_BRIDGE
+ 	bool
+-	depends on LINKSTATION
+ 	select PPC_INDIRECT_PCI
+-	default y
+ 
+ config MV64X60
+ 	bool
+@@ -67,8 +80,6 @@
+ 
+ config MPC10X_OPENPIC
+ 	bool
+-	depends on LINKSTATION
+-	default y
+ 
+ config MPC10X_STORE_GATHERING
+ 	bool "Enable MPC10x store gathering"
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/embedded6xx/Makefile powerpc.git/arch/powerpc/platforms/embedded6xx/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/embedded6xx/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/embedded6xx/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -3,5 +3,6 @@
+ #
+ obj-$(CONFIG_MPC7448HPC2)	+= mpc7448_hpc2.o
+ obj-$(CONFIG_LINKSTATION)	+= linkstation.o ls_uart.o
++obj-$(CONFIG_STORCENTER)	+= storcenter.o
+ obj-$(CONFIG_PPC_HOLLY)		+= holly.o
+ obj-$(CONFIG_PPC_PRPMC2800)	+= prpmc2800.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/embedded6xx/holly.c powerpc.git/arch/powerpc/platforms/embedded6xx/holly.c
+--- linux-2.6.24/arch/powerpc/platforms/embedded6xx/holly.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/embedded6xx/holly.c	2008-01-28 20:25:49.000000000 +0100
+@@ -20,12 +20,12 @@
+ #include <linux/console.h>
+ #include <linux/delay.h>
+ #include <linux/irq.h>
+-#include <linux/ide.h>
+ #include <linux/seq_file.h>
+ #include <linux/root_dev.h>
+ #include <linux/serial.h>
+ #include <linux/tty.h>
+ #include <linux/serial_core.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/system.h>
+ #include <asm/time.h>
+@@ -39,7 +39,6 @@
+ #include <asm/tsi108_irq.h>
+ #include <asm/tsi108_pci.h>
+ #include <asm/mpic.h>
+-#include <asm/of_platform.h>
+ 
+ #undef DEBUG
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c powerpc.git/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+--- linux-2.6.24/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c	2008-01-28 20:25:49.000000000 +0100
+@@ -53,8 +53,6 @@
+ 
+ #define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000
+ 
+-extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+-
+ int mpc7448_hpc2_exclude_device(struct pci_controller *hose,
+ 				u_char bus, u_char devfn)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/embedded6xx/storcenter.c powerpc.git/arch/powerpc/platforms/embedded6xx/storcenter.c
+--- linux-2.6.24/arch/powerpc/platforms/embedded6xx/storcenter.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/embedded6xx/storcenter.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,192 @@
++/*
++ * Board setup routines for the storcenter
++ *
++ * Copyright 2007 (C) Oyvind Repvik (nail@nslu2-linux.org)
++ * Copyright 2007 Andy Wilcox, Jon Loeliger
++ *
++ * Based on linkstation.c by G. Liakhovetski
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2.  This program is licensed "as is" without any warranty of
++ * any kind, whether express or implied.
++ */
++
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/initrd.h>
++#include <linux/mtd/physmap.h>
++#include <linux/of_platform.h>
++
++#include <asm/system.h>
++#include <asm/time.h>
++#include <asm/prom.h>
++#include <asm/mpic.h>
++#include <asm/pci-bridge.h>
++
++#include "mpc10x.h"
++
++
++#ifdef CONFIG_MTD_PHYSMAP
++static struct mtd_partition storcenter_physmap_partitions[] = {
++	{
++		.name   = "kernel",
++		.offset = 0x000000,
++		.size   = 0x170000,
++	},
++	{
++		.name   = "rootfs",
++		.offset = 0x170000,
++		.size   = 0x590000,
++	},
++	{
++		.name   = "uboot",
++		.offset = 0x700000,
++		.size   = 0x040000,
++	},
++	{
++		.name   = "config",
++		.offset = 0x740000,
++		.size   = 0x0c0000,
++	},
++};
++#endif
++
++
++static __initdata struct of_device_id storcenter_of_bus[] = {
++	{ .name = "soc", },
++	{},
++};
++
++static int __init storcenter_device_probe(void)
++{
++	of_platform_bus_probe(NULL, storcenter_of_bus, NULL);
++	return 0;
++}
++machine_device_initcall(storcenter, storcenter_device_probe);
++
++
++static int __init storcenter_add_bridge(struct device_node *dev)
++{
++#ifdef CONFIG_PCI
++	int len;
++	struct pci_controller *hose;
++	const int *bus_range;
++
++	printk("Adding PCI host bridge %s\n", dev->full_name);
++
++	hose = pcibios_alloc_controller(dev);
++	if (hose == NULL)
++		return -ENOMEM;
++
++	bus_range = of_get_property(dev, "bus-range", &len);
++	hose->first_busno = bus_range ? bus_range[0] : 0;
++	hose->last_busno = bus_range ? bus_range[1] : 0xff;
++
++	setup_indirect_pci(hose, MPC10X_MAPB_CNFG_ADDR, MPC10X_MAPB_CNFG_DATA, 0);
++
++	/* Interpret the "ranges" property */
++	/* This also maps the I/O region and sets isa_io/mem_base */
++	pci_process_bridge_OF_ranges(hose, dev, 1);
++#endif
++
++	return 0;
++}
++
++static void __init storcenter_setup_arch(void)
++{
++	struct device_node *np;
++
++#ifdef CONFIG_MTD_PHYSMAP
++	physmap_set_partitions(storcenter_physmap_partitions,
++			       ARRAY_SIZE(storcenter_physmap_partitions));
++#endif
++
++	/* Lookup PCI host bridges */
++	for_each_compatible_node(np, "pci", "mpc10x-pci")
++		storcenter_add_bridge(np);
++
++	printk(KERN_INFO "IOMEGA StorCenter\n");
++}
++
++/*
++ * Interrupt setup and service.  Interrrupts on the turbostation come
++ * from the four PCI slots plus onboard 8241 devices: I2C, DUART.
++ */
++static void __init storcenter_init_IRQ(void)
++{
++	struct mpic *mpic;
++	struct device_node *dnp;
++	const void *prop;
++	int size;
++	phys_addr_t paddr;
++
++	dnp = of_find_node_by_type(NULL, "open-pic");
++	if (dnp == NULL)
++		return;
++
++	prop = of_get_property(dnp, "reg", &size);
++	if (prop == NULL) {
++		of_node_put(dnp);
++		return;
++	}
++
++	paddr = (phys_addr_t)of_translate_address(dnp, prop);
++	mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET,
++			4, 32, " EPIC     ");
++
++	of_node_put(dnp);
++
++	BUG_ON(mpic == NULL);
++
++	/* PCI IRQs */
++	/*
++	 * 2.6.12 patch:
++	 *         openpic_set_sources(0, 5, OpenPIC_Addr + 0x10200);
++	 *         openpic_set_sources(5, 2, OpenPIC_Addr + 0x11120);
++	 *         first_irq, num_irqs, __iomem first_ISR
++	 *         o_ss: i, src: 0, fdf50200
++	 *         o_ss: i, src: 1, fdf50220
++	 *         o_ss: i, src: 2, fdf50240
++	 *         o_ss: i, src: 3, fdf50260
++	 *         o_ss: i, src: 4, fdf50280
++	 *         o_ss: i, src: 5, fdf51120
++	 *         o_ss: i, src: 6, fdf51140
++	 */
++	mpic_assign_isu(mpic, 0, paddr + 0x10200);
++	mpic_assign_isu(mpic, 1, paddr + 0x10220);
++	mpic_assign_isu(mpic, 2, paddr + 0x10240);
++	mpic_assign_isu(mpic, 3, paddr + 0x10260);
++	mpic_assign_isu(mpic, 4, paddr + 0x10280);
++	mpic_assign_isu(mpic, 5, paddr + 0x11120);
++	mpic_assign_isu(mpic, 6, paddr + 0x11140);
++
++	mpic_init(mpic);
++}
++
++static void storcenter_restart(char *cmd)
++{
++	local_irq_disable();
++
++	/* Set exception prefix high - to the firmware */
++	_nmask_and_or_msr(0, MSR_IP);
++
++	/* Wait for reset to happen */
++	for (;;) ;
++}
++
++static int __init storcenter_probe(void)
++{
++	unsigned long root = of_get_flat_dt_root();
++
++	return of_flat_dt_is_compatible(root, "storcenter");
++}
++
++define_machine(storcenter){
++	.name 			= "IOMEGA StorCenter",
++	.probe 			= storcenter_probe,
++	.setup_arch 		= storcenter_setup_arch,
++	.init_IRQ 		= storcenter_init_IRQ,
++	.get_irq 		= mpic_get_irq,
++	.restart 		= storcenter_restart,
++	.calibrate_decr 	= generic_calibrate_decr,
++};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/iseries/Makefile powerpc.git/arch/powerpc/platforms/iseries/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/iseries/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/iseries/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -5,7 +5,7 @@
+ obj-y += exception.o
+ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
+ 	hvcall.o proc.o htab.o iommu.o misc.o irq.o
+-obj-$(CONFIG_PCI) += pci.o vpdinfo.o
++obj-$(CONFIG_PCI) += pci.o
+ obj-$(CONFIG_SMP) += smp.o
+ obj-$(CONFIG_VIOPATH) += viopath.o vio.o
+ obj-$(CONFIG_MODULES) += ksyms.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/iseries/iommu.c powerpc.git/arch/powerpc/platforms/iseries/iommu.c
+--- linux-2.6.24/arch/powerpc/platforms/iseries/iommu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/iseries/iommu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -163,8 +163,10 @@
+ 		    (it->it_type == TCE_PCI) &&
+ 		    (it->it_offset == tbl->it_offset) &&
+ 		    (it->it_index == tbl->it_index) &&
+-		    (it->it_size == tbl->it_size))
++		    (it->it_size == tbl->it_size)) {
++			of_node_put(node);
+ 			return it;
++		}
+ 	}
+ 	return NULL;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/iseries/lpevents.c powerpc.git/arch/powerpc/platforms/iseries/lpevents.c
+--- linux-2.6.24/arch/powerpc/platforms/iseries/lpevents.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/iseries/lpevents.c	2008-01-28 20:25:49.000000000 +0100
+@@ -239,7 +239,7 @@
+ 			 * other CPUs, and that the deleted handler isn't
+ 			 * still running on another CPU when we return.
+ 			 */
+-			synchronize_rcu();
++			synchronize_sched();
+ 			return 0;
+ 		}
+ 	}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/iseries/pci.c powerpc.git/arch/powerpc/platforms/iseries/pci.c
+--- linux-2.6.24/arch/powerpc/platforms/iseries/pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/iseries/pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -1,5 +1,6 @@
+ /*
+  * Copyright (C) 2001 Allan Trautman, IBM Corporation
++ * Copyright (C) 2005,2007  Stephen Rothwell, IBM Corp
+  *
+  * iSeries specific routines for PCI.
+  *
+@@ -19,13 +20,18 @@
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+  */
++
++#undef DEBUG
++
+ #include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/string.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
++#include <linux/of.h>
+ 
++#include <asm/types.h>
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/prom.h>
+@@ -35,6 +41,7 @@
+ #include <asm/abs_addr.h>
+ #include <asm/firmware.h>
+ 
++#include <asm/iseries/hv_types.h>
+ #include <asm/iseries/hv_call_xm.h>
+ #include <asm/iseries/mf.h>
+ #include <asm/iseries/iommu.h>
+@@ -45,15 +52,8 @@
+ #include "pci.h"
+ #include "call_pci.h"
+ 
+-/*
+- * Forward declares of prototypes.
+- */
+-static struct device_node *find_Device_Node(int bus, int devfn);
+-
+-static int Pci_Retry_Max = 3;	/* Only retry 3 times  */
+-static int Pci_Error_Flag = 1;	/* Set Retry Error on. */
+-
+-static struct pci_ops iSeries_pci_ops;
++#define PCI_RETRY_MAX	3
++static int limit_pci_retries = 1;	/* Set Retry Error on. */
+ 
+ /*
+  * Table defines
+@@ -62,6 +62,7 @@
+ #define IOMM_TABLE_MAX_ENTRIES	1024
+ #define IOMM_TABLE_ENTRY_SIZE	0x0000000000400000UL
+ #define BASE_IO_MEMORY		0xE000000000000000UL
++#define END_IO_MEMORY		0xEFFFFFFFFFFFFFFFUL
+ 
+ static unsigned long max_io_memory = BASE_IO_MEMORY;
+ static long current_iomm_table_entry;
+@@ -70,12 +71,237 @@
+  * Lookup Tables.
+  */
+ static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES];
+-static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES];
++static u64 ds_addr_table[IOMM_TABLE_MAX_ENTRIES];
+ 
+-static const char pci_io_text[] = "iSeries PCI I/O";
+ static DEFINE_SPINLOCK(iomm_table_lock);
+ 
+ /*
++ * Generate a Direct Select Address for the Hypervisor
++ */
++static inline u64 iseries_ds_addr(struct device_node *node)
++{
++	struct pci_dn *pdn = PCI_DN(node);
++	const u32 *sbp = of_get_property(node, "linux,subbus", NULL);
++
++	return ((u64)pdn->busno << 48) + ((u64)(sbp ? *sbp : 0) << 40)
++			+ ((u64)0x10 << 32);
++}
++
++/*
++ * Size of Bus VPD data
++ */
++#define BUS_VPDSIZE      1024
++
++/*
++ * Bus Vpd Tags
++ */
++#define VPD_END_OF_AREA		0x79
++#define VPD_ID_STRING		0x82
++#define VPD_VENDOR_AREA		0x84
++
++/*
++ * Mfg Area Tags
++ */
++#define VPD_FRU_FRAME_ID	0x4649	/* "FI" */
++#define VPD_SLOT_MAP_FORMAT	0x4D46	/* "MF" */
++#define VPD_SLOT_MAP		0x534D	/* "SM" */
++
++/*
++ * Structures of the areas
++ */
++struct mfg_vpd_area {
++	u16	tag;
++	u8	length;
++	u8	data1;
++	u8	data2;
++};
++#define MFG_ENTRY_SIZE   3
++
++struct slot_map {
++	u8	agent;
++	u8	secondary_agent;
++	u8	phb;
++	char	card_location[3];
++	char	parms[8];
++	char	reserved[2];
++};
++#define SLOT_ENTRY_SIZE   16
++
++/*
++ * Parse the Slot Area
++ */
++static void __init iseries_parse_slot_area(struct slot_map *map, int len,
++		HvAgentId agent, u8 *phb, char card[4])
++{
++	/*
++	 * Parse Slot label until we find the one requested
++	 */
++	while (len > 0) {
++		if (map->agent == agent) {
++			/*
++			 * If Phb wasn't found, grab the entry first one found.
++			 */
++			if (*phb == 0xff)
++				*phb = map->phb;
++			/* Found it, extract the data. */
++			if (map->phb == *phb) {
++				memcpy(card, &map->card_location, 3);
++				card[3]  = 0;
++				break;
++			}
++		}
++		/* Point to the next Slot */
++		map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);
++		len -= SLOT_ENTRY_SIZE;
++	}
++}
++
++/*
++ * Parse the Mfg Area
++ */
++static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,
++		HvAgentId agent, u8 *phb, u8 *frame, char card[4])
++{
++	u16 slot_map_fmt = 0;
++
++	/* Parse Mfg Data */
++	while (len > 0) {
++		int mfg_tag_len = area->length;
++		/* Frame ID         (FI 4649020310 ) */
++		if (area->tag == VPD_FRU_FRAME_ID)
++			*frame = area->data1;
++		/* Slot Map Format  (MF 4D46020004 ) */
++		else if (area->tag == VPD_SLOT_MAP_FORMAT)
++			slot_map_fmt = (area->data1 * 256)
++				+ area->data2;
++		/* Slot Map         (SM 534D90 */
++		else if (area->tag == VPD_SLOT_MAP) {
++			struct slot_map *slot_map;
++
++			if (slot_map_fmt == 0x1004)
++				slot_map = (struct slot_map *)((char *)area
++						+ MFG_ENTRY_SIZE + 1);
++			else
++				slot_map = (struct slot_map *)((char *)area
++						+ MFG_ENTRY_SIZE);
++			iseries_parse_slot_area(slot_map, mfg_tag_len,
++					agent, phb, card);
++		}
++		/*
++		 * Point to the next Mfg Area
++		 * Use defined size, sizeof give wrong answer
++		 */
++		area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len
++				+ MFG_ENTRY_SIZE);
++		len -= (mfg_tag_len + MFG_ENTRY_SIZE);
++	}
++}
++
++/*
++ * Look for "BUS".. Data is not Null terminated.
++ * PHBID of 0xFF indicates PHB was not found in VPD Data.
++ */
++static u8 __init iseries_parse_phbid(u8 *area, int len)
++{
++	while (len > 0) {
++		if ((*area == 'B') && (*(area + 1) == 'U')
++				&& (*(area + 2) == 'S')) {
++			area += 3;
++			while (*area == ' ')
++				area++;
++			return *area & 0x0F;
++		}
++		area++;
++		len--;
++	}
++	return 0xff;
++}
++
++/*
++ * Parse out the VPD Areas
++ */
++static void __init iseries_parse_vpd(u8 *data, int data_len,
++		HvAgentId agent, u8 *frame, char card[4])
++{
++	u8 phb = 0xff;
++
++	while (data_len > 0) {
++		int len;
++		u8 tag = *data;
++
++		if (tag == VPD_END_OF_AREA)
++			break;
++		len = *(data + 1) + (*(data + 2) * 256);
++		data += 3;
++		data_len -= 3;
++		if (tag == VPD_ID_STRING)
++			phb = iseries_parse_phbid(data, len);
++		else if (tag == VPD_VENDOR_AREA)
++			iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,
++					agent, &phb, frame, card);
++		/* Point to next Area. */
++		data += len;
++		data_len -= len;
++	}
++}
++
++static int __init iseries_get_location_code(u16 bus, HvAgentId agent,
++		u8 *frame, char card[4])
++{
++	int status = 0;
++	int bus_vpd_len = 0;
++	u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
++
++	if (bus_vpd == NULL) {
++		printk("PCI: Bus VPD Buffer allocation failure.\n");
++		return 0;
++	}
++	bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),
++					BUS_VPDSIZE);
++	if (bus_vpd_len == 0) {
++		printk("PCI: Bus VPD Buffer zero length.\n");
++		goto out_free;
++	}
++	/* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */
++	/* Make sure this is what I think it is */
++	if (*bus_vpd != VPD_ID_STRING) {
++		printk("PCI: Bus VPD Buffer missing starting tag.\n");
++		goto out_free;
++	}
++	iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);
++	status = 1;
++out_free:
++	kfree(bus_vpd);
++	return status;
++}
++
++/*
++ * Prints the device information.
++ * - Pass in pci_dev* pointer to the device.
++ * - Pass in the device count
++ *
++ * Format:
++ * PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet
++ * controller
++ */
++static void __init iseries_device_information(struct pci_dev *pdev,
++					      u16 bus, HvSubBusNumber subbus)
++{
++	u8 frame = 0;
++	char card[4];
++	HvAgentId agent;
++
++	agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
++			ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
++
++	if (iseries_get_location_code(bus, agent, &frame, card)) {
++		printk(KERN_INFO "PCI: %s, Vendor %04X Frame%3d, "
++		       "Card %4s  0x%04X\n", pci_name(pdev), pdev->vendor,
++		       frame, card, (int)(pdev->class >> 8));
++	}
++}
++
++/*
+  * iomm_table_allocate_entry
+  *
+  * Adds pci_dev entry in address translation table
+@@ -87,7 +313,7 @@
+  * - CurrentIndex is incremented to keep track of the last entry.
+  * - Builds the resource entry for allocated BARs.
+  */
+-static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
++static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
+ {
+ 	struct resource *bar_res = &dev->resource[bar_num];
+ 	long bar_size = pci_resource_len(dev, bar_num);
+@@ -101,7 +327,6 @@
+ 	 * Set Resource values.
+ 	 */
+ 	spin_lock(&iomm_table_lock);
+-	bar_res->name = pci_io_text;
+ 	bar_res->start = BASE_IO_MEMORY +
+ 		IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
+ 	bar_res->end = bar_res->start + bar_size - 1;
+@@ -110,7 +335,8 @@
+ 	 */
+ 	while (bar_size > 0 ) {
+ 		iomm_table[current_iomm_table_entry] = dev->sysdata;
+-		iobar_table[current_iomm_table_entry] = bar_num;
++		ds_addr_table[current_iomm_table_entry] =
++			iseries_ds_addr(dev->sysdata) | (bar_num << 24);
+ 		bar_size -= IOMM_TABLE_ENTRY_SIZE;
+ 		++current_iomm_table_entry;
+ 	}
+@@ -130,7 +356,7 @@
+  * - Loops through The Bar resources(0 - 5) including the ROM
+  *   is resource(6).
+  */
+-static void allocate_device_bars(struct pci_dev *dev)
++static void __init allocate_device_bars(struct pci_dev *dev)
+ {
+ 	int bar_num;
+ 
+@@ -145,79 +371,19 @@
+  * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
+  * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
+  */
+-static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
+-		int AgentId, int HvRc)
++static void pci_log_error(char *error, int bus, int subbus,
++		int agent, int hv_res)
+ {
+-	if (HvRc == 0x0302)
++	if (hv_res == 0x0302)
+ 		return;
+ 	printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
+-	       Error_Text, Bus, SubBus, AgentId, HvRc);
+-}
+-
+-/*
+- * iSeries_pci_final_fixup(void)
+- */
+-void __init iSeries_pci_final_fixup(void)
+-{
+-	struct pci_dev *pdev = NULL;
+-	struct device_node *node;
+-	int DeviceCount = 0;
+-
+-	/* Fix up at the device node and pci_dev relationship */
+-	mf_display_src(0xC9000100);
+-
+-	printk("pcibios_final_fixup\n");
+-	for_each_pci_dev(pdev) {
+-		node = find_Device_Node(pdev->bus->number, pdev->devfn);
+-		printk("pci dev %p (%x.%x), node %p\n", pdev,
+-		       pdev->bus->number, pdev->devfn, node);
+-
+-		if (node != NULL) {
+-			struct pci_dn *pdn = PCI_DN(node);
+-			const u32 *agent;
+-
+-			agent = of_get_property(node, "linux,agent-id", NULL);
+-			if ((pdn != NULL) && (agent != NULL)) {
+-				u8 irq = iSeries_allocate_IRQ(pdn->busno, 0,
+-						pdn->bussubno);
+-				int err;
+-
+-				err = HvCallXm_connectBusUnit(pdn->busno, pdn->bussubno,
+-						*agent, irq);
+-				if (err)
+-					pci_Log_Error("Connect Bus Unit",
+-						pdn->busno, pdn->bussubno, *agent, err);
+-				else {
+-					err = HvCallPci_configStore8(pdn->busno, pdn->bussubno,
+-							*agent,
+-							PCI_INTERRUPT_LINE,
+-							irq);
+-					if (err)
+-						pci_Log_Error("PciCfgStore Irq Failed!",
+-							pdn->busno, pdn->bussubno, *agent, err);
+-				}
+-				if (!err)
+-					pdev->irq = irq;
+-			}
+-
+-			++DeviceCount;
+-			pdev->sysdata = (void *)node;
+-			PCI_DN(node)->pcidev = pdev;
+-			allocate_device_bars(pdev);
+-			iSeries_Device_Information(pdev, DeviceCount);
+-			iommu_devnode_init_iSeries(pdev, node);
+-		} else
+-			printk("PCI: Device Tree not found for 0x%016lX\n",
+-					(unsigned long)pdev);
+-	}
+-	iSeries_activate_IRQs();
+-	mf_display_src(0xC9000200);
++	       error, bus, subbus, agent, hv_res);
+ }
+ 
+ /*
+  * Look down the chain to find the matching Device Device
+  */
+-static struct device_node *find_Device_Node(int bus, int devfn)
++static struct device_node *find_device_node(int bus, int devfn)
+ {
+ 	struct device_node *node;
+ 
+@@ -230,22 +396,66 @@
+ 	return NULL;
+ }
+ 
+-#if 0
+ /*
+- * Returns the device node for the passed pci_dev
+- * Sanity Check Node PciDev to passed pci_dev
+- * If none is found, returns a NULL which the client must handle.
++ * iSeries_pcibios_fixup_resources
++ *
++ * Fixes up all resources for devices
+  */
+-static struct device_node *get_Device_Node(struct pci_dev *pdev)
++void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
+ {
++	const u32 *agent;
++	const u32 *sub_bus;
++	unsigned char bus = pdev->bus->number;
+ 	struct device_node *node;
++	int i;
++
++	node = find_device_node(bus, pdev->devfn);
++	pr_debug("PCI: iSeries %s, pdev %p, node %p\n",
++		 pci_name(pdev), pdev, node);
++	if (!node) {
++		printk("PCI: %s disabled, device tree entry not found !\n",
++		       pci_name(pdev));
++		for (i = 0; i <= PCI_ROM_RESOURCE; i++)
++			pdev->resource[i].flags = 0;
++		return;
++	}
++	sub_bus = of_get_property(node, "linux,subbus", NULL);
++	agent = of_get_property(node, "linux,agent-id", NULL);
++	if (agent && sub_bus) {
++		u8 irq = iSeries_allocate_IRQ(bus, 0, *sub_bus);
++		int err;
++
++		err = HvCallXm_connectBusUnit(bus, *sub_bus, *agent, irq);
++		if (err)
++			pci_log_error("Connect Bus Unit",
++				      bus, *sub_bus, *agent, err);
++		else {
++			err = HvCallPci_configStore8(bus, *sub_bus,
++					*agent, PCI_INTERRUPT_LINE, irq);
++			if (err)
++				pci_log_error("PciCfgStore Irq Failed!",
++						bus, *sub_bus, *agent, err);
++			else
++				pdev->irq = irq;
++		}
++	}
+ 
+-	node = pdev->sysdata;
+-	if (node == NULL || PCI_DN(node)->pcidev != pdev)
+-		node = find_Device_Node(pdev->bus->number, pdev->devfn);
+-	return node;
++	pdev->sysdata = node;
++	allocate_device_bars(pdev);
++	iseries_device_information(pdev, bus, *sub_bus);
++	iommu_devnode_init_iSeries(pdev, node);
++}
++
++/*
++ * iSeries_pci_final_fixup(void)
++ */
++void __init iSeries_pci_final_fixup(void)
++{
++	/* Fix up at the device node and pci_dev relationship */
++	mf_display_src(0xC9000100);
++	iSeries_activate_IRQs();
++	mf_display_src(0xC9000200);
+ }
+-#endif
+ 
+ /*
+  * Config space read and write functions.
+@@ -269,7 +479,7 @@
+ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ 		int offset, int size, u32 *val)
+ {
+-	struct device_node *node = find_Device_Node(bus->number, devfn);
++	struct device_node *node = find_device_node(bus->number, devfn);
+ 	u64 fn;
+ 	struct HvCallPci_LoadReturn ret;
+ 
+@@ -299,7 +509,7 @@
+ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+ 		int offset, int size, u32 val)
+ {
+-	struct device_node *node = find_Device_Node(bus->number, devfn);
++	struct device_node *node = find_device_node(bus->number, devfn);
+ 	u64 fn;
+ 	u64 ret;
+ 
+@@ -331,22 +541,22 @@
+  * PCI: Device 23.90 ReadL Retry( 1)
+  * PCI: Device 23.90 ReadL Retry Successful(1)
+  */
+-static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
++static int check_return_code(char *type, struct device_node *dn,
+ 		int *retry, u64 ret)
+ {
+ 	if (ret != 0)  {
+-		struct pci_dn *pdn = PCI_DN(DevNode);
++		struct pci_dn *pdn = PCI_DN(dn);
+ 
+ 		(*retry)++;
+ 		printk("PCI: %s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X\n",
+-				TextHdr, pdn->busno, pdn->devfn,
++				type, pdn->busno, pdn->devfn,
+ 				*retry, (int)ret);
+ 		/*
+ 		 * Bump the retry and check for retry count exceeded.
+ 		 * If, Exceeded, panic the system.
+ 		 */
+-		if (((*retry) > Pci_Retry_Max) &&
+-				(Pci_Error_Flag > 0)) {
++		if (((*retry) > PCI_RETRY_MAX) &&
++				(limit_pci_retries > 0)) {
+ 			mf_display_src(0xB6000103);
+ 			panic_timeout = 0;
+ 			panic("PCI: Hardware I/O Error, SRC B6000103, "
+@@ -363,28 +573,39 @@
+  * the exposure of being device global.
+  */
+ static inline struct device_node *xlate_iomm_address(
+-		const volatile void __iomem *IoAddress,
+-		u64 *dsaptr, u64 *BarOffsetPtr)
++		const volatile void __iomem *addr,
++		u64 *dsaptr, u64 *bar_offset, const char *func)
+ {
+-	unsigned long OrigIoAddr;
+-	unsigned long BaseIoAddr;
+-	unsigned long TableIndex;
+-	struct device_node *DevNode;
++	unsigned long orig_addr;
++	unsigned long base_addr;
++	unsigned long ind;
++	struct device_node *dn;
+ 
+-	OrigIoAddr = (unsigned long __force)IoAddress;
+-	if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory))
++	orig_addr = (unsigned long __force)addr;
++	if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) {
++		static unsigned long last_jiffies;
++		static int num_printed;
++
++		if ((jiffies - last_jiffies) > 60 * HZ) {
++			last_jiffies = jiffies;
++			num_printed = 0;
++		}
++		if (num_printed++ < 10)
++			printk(KERN_ERR
++				"iSeries_%s: invalid access at IO address %p\n",
++				func, addr);
+ 		return NULL;
+-	BaseIoAddr = OrigIoAddr - BASE_IO_MEMORY;
+-	TableIndex = BaseIoAddr / IOMM_TABLE_ENTRY_SIZE;
+-	DevNode = iomm_table[TableIndex];
+-
+-	if (DevNode != NULL) {
+-		int barnum = iobar_table[TableIndex];
+-		*dsaptr = iseries_ds_addr(DevNode) | (barnum << 24);
+-		*BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE;
++	}
++	base_addr = orig_addr - BASE_IO_MEMORY;
++	ind = base_addr / IOMM_TABLE_ENTRY_SIZE;
++	dn = iomm_table[ind];
++
++	if (dn != NULL) {
++		*dsaptr = ds_addr_table[ind];
++		*bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE;
+ 	} else
+-		panic("PCI: Invalid PCI IoAddress detected!\n");
+-	return DevNode;
++		panic("PCI: Invalid PCI IO address detected!\n");
++	return dn;
+ }
+ 
+ /*
+@@ -392,91 +613,58 @@
+  * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
+  * else, data is returned in Big Endian format.
+  */
+-static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
++static u8 iseries_readb(const volatile void __iomem *addr)
+ {
+-	u64 BarOffset;
++	u64 bar_offset;
+ 	u64 dsa;
+ 	int retry = 0;
+ 	struct HvCallPci_LoadReturn ret;
+-	struct device_node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
++	struct device_node *dn =
++		xlate_iomm_address(addr, &dsa, &bar_offset, "read_byte");
+ 
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n",
+-			       IoAddress);
++	if (dn == NULL)
+ 		return 0xff;
+-	}
+ 	do {
+-		HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
+-	} while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0);
++		HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0);
++	} while (check_return_code("RDB", dn, &retry, ret.rc) != 0);
+ 
+ 	return ret.value;
+ }
+ 
+-static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
++static u16 iseries_readw_be(const volatile void __iomem *addr)
+ {
+-	u64 BarOffset;
++	u64 bar_offset;
+ 	u64 dsa;
+ 	int retry = 0;
+ 	struct HvCallPci_LoadReturn ret;
+-	struct device_node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
++	struct device_node *dn =
++		xlate_iomm_address(addr, &dsa, &bar_offset, "read_word");
+ 
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n",
+-			       IoAddress);
++	if (dn == NULL)
+ 		return 0xffff;
+-	}
+ 	do {
+ 		HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
+-				BarOffset, 0);
+-	} while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0);
++				bar_offset, 0);
++	} while (check_return_code("RDW", dn, &retry, ret.rc) != 0);
+ 
+ 	return ret.value;
+ }
+ 
+-static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
++static u32 iseries_readl_be(const volatile void __iomem *addr)
+ {
+-	u64 BarOffset;
++	u64 bar_offset;
+ 	u64 dsa;
+ 	int retry = 0;
+ 	struct HvCallPci_LoadReturn ret;
+-	struct device_node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
++	struct device_node *dn =
++		xlate_iomm_address(addr, &dsa, &bar_offset, "read_long");
+ 
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
+-
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n",
+-			       IoAddress);
++	if (dn == NULL)
+ 		return 0xffffffff;
+-	}
+ 	do {
+ 		HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
+-				BarOffset, 0);
+-	} while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0);
++				bar_offset, 0);
++	} while (check_return_code("RDL", dn, &retry, ret.rc) != 0);
+ 
+ 	return ret.value;
+ }
+@@ -485,134 +673,72 @@
+  * Write MM I/O Instructions for the iSeries
+  *
+  */
+-static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
++static void iseries_writeb(u8 data, volatile void __iomem *addr)
+ {
+-	u64 BarOffset;
++	u64 bar_offset;
+ 	u64 dsa;
+ 	int retry = 0;
+ 	u64 rc;
+-	struct device_node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
++	struct device_node *dn =
++		xlate_iomm_address(addr, &dsa, &bar_offset, "write_byte");
+ 
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress);
++	if (dn == NULL)
+ 		return;
+-	}
+ 	do {
+-		rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
+-	} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
++		rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0);
++	} while (check_return_code("WWB", dn, &retry, rc) != 0);
+ }
+ 
+-static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
++static void iseries_writew_be(u16 data, volatile void __iomem *addr)
+ {
+-	u64 BarOffset;
++	u64 bar_offset;
+ 	u64 dsa;
+ 	int retry = 0;
+ 	u64 rc;
+-	struct device_node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
++	struct device_node *dn =
++		xlate_iomm_address(addr, &dsa, &bar_offset, "write_word");
+ 
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
+-
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n",
+-			       IoAddress);
++	if (dn == NULL)
+ 		return;
+-	}
+ 	do {
+-		rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, data, 0);
+-	} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
++		rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0);
++	} while (check_return_code("WWW", dn, &retry, rc) != 0);
+ }
+ 
+-static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
++static void iseries_writel_be(u32 data, volatile void __iomem *addr)
+ {
+-	u64 BarOffset;
++	u64 bar_offset;
+ 	u64 dsa;
+ 	int retry = 0;
+ 	u64 rc;
+-	struct device_node *DevNode =
+-		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
+-
+-	if (DevNode == NULL) {
+-		static unsigned long last_jiffies;
+-		static int num_printed;
++	struct device_node *dn =
++		xlate_iomm_address(addr, &dsa, &bar_offset, "write_long");
+ 
+-		if ((jiffies - last_jiffies) > 60 * HZ) {
+-			last_jiffies = jiffies;
+-			num_printed = 0;
+-		}
+-		if (num_printed++ < 10)
+-			printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n",
+-			       IoAddress);
++	if (dn == NULL)
+ 		return;
+-	}
+ 	do {
+-		rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, data, 0);
+-	} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
+-}
+-
+-static u8 iseries_readb(const volatile void __iomem *addr)
+-{
+-	return iSeries_Read_Byte(addr);
++		rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0);
++	} while (check_return_code("WWL", dn, &retry, rc) != 0);
+ }
+ 
+ static u16 iseries_readw(const volatile void __iomem *addr)
+ {
+-	return le16_to_cpu(iSeries_Read_Word(addr));
++	return le16_to_cpu(iseries_readw_be(addr));
+ }
+ 
+ static u32 iseries_readl(const volatile void __iomem *addr)
+ {
+-	return le32_to_cpu(iSeries_Read_Long(addr));
+-}
+-
+-static u16 iseries_readw_be(const volatile void __iomem *addr)
+-{
+-	return iSeries_Read_Word(addr);
+-}
+-
+-static u32 iseries_readl_be(const volatile void __iomem *addr)
+-{
+-	return iSeries_Read_Long(addr);
+-}
+-
+-static void iseries_writeb(u8 data, volatile void __iomem *addr)
+-{
+-	iSeries_Write_Byte(data, addr);
++	return le32_to_cpu(iseries_readl_be(addr));
+ }
+ 
+ static void iseries_writew(u16 data, volatile void __iomem *addr)
+ {
+-	iSeries_Write_Word(cpu_to_le16(data), addr);
++	iseries_writew_be(cpu_to_le16(data), addr);
+ }
+ 
+ static void iseries_writel(u32 data, volatile void __iomem *addr)
+ {
+-	iSeries_Write_Long(cpu_to_le32(data), addr);
+-}
+-
+-static void iseries_writew_be(u16 data, volatile void __iomem *addr)
+-{
+-	iSeries_Write_Word(data, addr);
+-}
+-
+-static void iseries_writel_be(u32 data, volatile void __iomem *addr)
+-{
+-	iSeries_Write_Long(data, addr);
++	iseries_writel(cpu_to_le32(data), addr);
+ }
+ 
+ static void iseries_readsb(const volatile void __iomem *addr, void *buf,
+@@ -620,7 +746,7 @@
+ {
+ 	u8 *dst = buf;
+ 	while(count-- > 0)
+-		*(dst++) = iSeries_Read_Byte(addr);
++		*(dst++) = iseries_readb(addr);
+ }
+ 
+ static void iseries_readsw(const volatile void __iomem *addr, void *buf,
+@@ -628,7 +754,7 @@
+ {
+ 	u16 *dst = buf;
+ 	while(count-- > 0)
+-		*(dst++) = iSeries_Read_Word(addr);
++		*(dst++) = iseries_readw_be(addr);
+ }
+ 
+ static void iseries_readsl(const volatile void __iomem *addr, void *buf,
+@@ -636,7 +762,7 @@
+ {
+ 	u32 *dst = buf;
+ 	while(count-- > 0)
+-		*(dst++) = iSeries_Read_Long(addr);
++		*(dst++) = iseries_readl_be(addr);
+ }
+ 
+ static void iseries_writesb(volatile void __iomem *addr, const void *buf,
+@@ -644,7 +770,7 @@
+ {
+ 	const u8 *src = buf;
+ 	while(count-- > 0)
+-		iSeries_Write_Byte(*(src++), addr);
++		iseries_writeb(*(src++), addr);
+ }
+ 
+ static void iseries_writesw(volatile void __iomem *addr, const void *buf,
+@@ -652,7 +778,7 @@
+ {
+ 	const u16 *src = buf;
+ 	while(count-- > 0)
+-		iSeries_Write_Word(*(src++), addr);
++		iseries_writew_be(*(src++), addr);
+ }
+ 
+ static void iseries_writesl(volatile void __iomem *addr, const void *buf,
+@@ -660,7 +786,7 @@
+ {
+ 	const u32 *src = buf;
+ 	while(count-- > 0)
+-		iSeries_Write_Long(*(src++), addr);
++		iseries_writel_be(*(src++), addr);
+ }
+ 
+ static void iseries_memset_io(volatile void __iomem *addr, int c,
+@@ -669,7 +795,7 @@
+ 	volatile char __iomem *d = addr;
+ 
+ 	while (n-- > 0)
+-		iSeries_Write_Byte(c, d++);
++		iseries_writeb(c, d++);
+ }
+ 
+ static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
+@@ -679,7 +805,7 @@
+ 	const volatile char __iomem *s = src;
+ 
+ 	while (n-- > 0)
+-		*d++ = iSeries_Read_Byte(s++);
++		*d++ = iseries_readb(s++);
+ }
+ 
+ static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
+@@ -689,7 +815,7 @@
+ 	volatile char __iomem *d = dest;
+ 
+ 	while (n-- > 0)
+-		iSeries_Write_Byte(*s++, d++);
++		iseries_writeb(*s++, d++);
+ }
+ 
+ /* We only set MMIO ops. The default PIO ops will be default
+@@ -742,6 +868,8 @@
+ 	/* Install IO hooks */
+ 	ppc_pci_io = iseries_pci_io;
+ 
++	pci_probe_only = 1;
++
+ 	/* iSeries has no IO space in the common sense, it needs to set
+ 	 * the IO base to 0
+ 	 */
+@@ -767,11 +895,21 @@
+ 		phb = pcibios_alloc_controller(node);
+ 		if (phb == NULL)
+ 			continue;
++		/* All legacy iSeries PHBs are in domain zero */
++		phb->global_number = 0;
+ 
+-		phb->pci_mem_offset = bus;
+ 		phb->first_busno = bus;
+ 		phb->last_busno = bus;
+ 		phb->ops = &iSeries_pci_ops;
++		phb->io_base_virt = (void __iomem *)_IO_BASE;
++		phb->io_resource.flags = IORESOURCE_IO;
++		phb->io_resource.start = BASE_IO_MEMORY;
++		phb->io_resource.end = END_IO_MEMORY;
++		phb->io_resource.name = "iSeries PCI IO";
++		phb->mem_resources[0].flags = IORESOURCE_MEM;
++		phb->mem_resources[0].start = BASE_IO_MEMORY;
++		phb->mem_resources[0].end = END_IO_MEMORY;
++		phb->mem_resources[0].name = "Series PCI MEM";
+ 	}
+ 
+ 	of_node_put(root);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/iseries/pci.h powerpc.git/arch/powerpc/platforms/iseries/pci.h
+--- linux-2.6.24/arch/powerpc/platforms/iseries/pci.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/iseries/pci.h	2008-01-28 20:25:49.000000000 +0100
+@@ -30,10 +30,6 @@
+  * End Change Activity
+  */
+ 
+-#include <asm/pci-bridge.h>
+-
+-struct pci_dev;				/* For Forward Reference */
+-
+ /*
+  * Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
+  * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h
+@@ -47,17 +43,16 @@
+ #define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus)		((subbus >> 5) & 0x7)
+ #define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)	((subbus >> 2) & 0x7)
+ 
+-/*
+- * Generate a Direct Select Address for the Hypervisor
+- */
+-static inline u64 iseries_ds_addr(struct device_node *node)
+-{
+-	struct pci_dn *pdn = PCI_DN(node);
+-
+-	return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40)
+-			+ ((u64)0x10 << 32);
+-}
++struct pci_dev;
+ 
+-extern void	iSeries_Device_Information(struct pci_dev*, int);
++#ifdef CONFIG_PCI
++extern void	iSeries_pcibios_init(void);
++extern void	iSeries_pci_final_fixup(void);
++extern void 	iSeries_pcibios_fixup_resources(struct pci_dev *dev);
++#else
++static inline void	iSeries_pcibios_init(void) { }
++static inline void	iSeries_pci_final_fixup(void) { }
++static inline void 	iSeries_pcibios_fixup_resources(struct pci_dev *dev) {}
++#endif
+ 
+ #endif /* _PLATFORMS_ISERIES_PCI_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/iseries/setup.c powerpc.git/arch/powerpc/platforms/iseries/setup.c
+--- linux-2.6.24/arch/powerpc/platforms/iseries/setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/iseries/setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -63,6 +63,7 @@
+ #include "main_store.h"
+ #include "call_sm.h"
+ #include "call_hpt.h"
++#include "pci.h"
+ 
+ #ifdef DEBUG
+ #define DBG(fmt...) udbg_printf(fmt)
+@@ -74,11 +75,6 @@
+ static unsigned long build_iSeries_Memory_Map(void);
+ static void iseries_shared_idle(void);
+ static void iseries_dedicated_idle(void);
+-#ifdef CONFIG_PCI
+-extern void iSeries_pci_final_fixup(void);
+-#else
+-static void iSeries_pci_final_fixup(void) { }
+-#endif
+ 
+ 
+ struct MemoryBlock {
+@@ -112,13 +108,13 @@
+ 	 * correctly.
+ 	 */
+ 	mb_array[0].logicalStart = 0;
+-	mb_array[0].logicalEnd = 0x100000000;
++	mb_array[0].logicalEnd = 0x100000000UL;
+ 	mb_array[0].absStart = 0;
+-	mb_array[0].absEnd = 0x100000000;
++	mb_array[0].absEnd = 0x100000000UL;
+ 
+ 	if (holeSize) {
+ 		numMemoryBlocks = 2;
+-		holeStart = holeStart & 0x000fffffffffffff;
++		holeStart = holeStart & 0x000fffffffffffffUL;
+ 		holeStart = addr_to_chunk(holeStart);
+ 		holeFirstChunk = holeStart;
+ 		holeSize = addr_to_chunk(holeSize);
+@@ -128,9 +124,9 @@
+ 		mb_array[0].logicalEnd = holeFirstChunk;
+ 		mb_array[0].absEnd = holeFirstChunk;
+ 		mb_array[1].logicalStart = holeFirstChunk;
+-		mb_array[1].logicalEnd = 0x100000000 - holeSizeChunks;
++		mb_array[1].logicalEnd = 0x100000000UL - holeSizeChunks;
+ 		mb_array[1].absStart = holeFirstChunk + holeSizeChunks;
+-		mb_array[1].absEnd = 0x100000000;
++		mb_array[1].absEnd = 0x100000000UL;
+ 	}
+ 	return numMemoryBlocks;
+ }
+@@ -234,9 +230,9 @@
+ 				mb_array[i].logicalEnd,
+ 				mb_array[i].absStart, mb_array[i].absEnd);
+ 		mb_array[i].absStart = addr_to_chunk(mb_array[i].absStart &
+-				0x000fffffffffffff);
++				0x000fffffffffffffUL);
+ 		mb_array[i].absEnd = addr_to_chunk(mb_array[i].absEnd &
+-				0x000fffffffffffff);
++				0x000fffffffffffffUL);
+ 		mb_array[i].logicalStart =
+ 			addr_to_chunk(mb_array[i].logicalStart);
+ 		mb_array[i].logicalEnd = addr_to_chunk(mb_array[i].logicalEnd);
+@@ -320,7 +316,7 @@
+ };
+ EXPORT_SYMBOL(mschunks_map);
+ 
+-void mschunks_alloc(unsigned long num_chunks)
++static void mschunks_alloc(unsigned long num_chunks)
+ {
+ 	klimit = _ALIGN(klimit, sizeof(u32));
+ 	mschunks_map.mapping = (u32 *)klimit;
+@@ -499,6 +495,8 @@
+ 			itVpdAreas.xSlicMaxLogicalProcs);
+ 	printk("Max physical processors = %d\n",
+ 			itVpdAreas.xSlicMaxPhysicalProcs);
++
++	iSeries_pcibios_init();
+ }
+ 
+ static void iSeries_show_cpuinfo(struct seq_file *m)
+@@ -641,24 +639,25 @@
+ }
+ 
+ define_machine(iseries) {
+-	.name		= "iSeries",
+-	.setup_arch	= iSeries_setup_arch,
+-	.show_cpuinfo	= iSeries_show_cpuinfo,
+-	.init_IRQ	= iSeries_init_IRQ,
+-	.get_irq	= iSeries_get_irq,
+-	.init_early	= iSeries_init_early,
+-	.pcibios_fixup	= iSeries_pci_final_fixup,
+-	.restart	= mf_reboot,
+-	.power_off	= mf_power_off,
+-	.halt		= mf_power_off,
+-	.get_boot_time	= iSeries_get_boot_time,
+-	.set_rtc_time	= iSeries_set_rtc_time,
+-	.get_rtc_time	= iSeries_get_rtc_time,
+-	.calibrate_decr	= generic_calibrate_decr,
+-	.progress	= iSeries_progress,
+-	.probe		= iseries_probe,
+-	.ioremap	= iseries_ioremap,
+-	.iounmap	= iseries_iounmap,
++	.name			= "iSeries",
++	.setup_arch		= iSeries_setup_arch,
++	.show_cpuinfo		= iSeries_show_cpuinfo,
++	.init_IRQ		= iSeries_init_IRQ,
++	.get_irq		= iSeries_get_irq,
++	.init_early		= iSeries_init_early,
++	.pcibios_fixup		= iSeries_pci_final_fixup,
++	.pcibios_fixup_resources= iSeries_pcibios_fixup_resources,
++	.restart		= mf_reboot,
++	.power_off		= mf_power_off,
++	.halt			= mf_power_off,
++	.get_boot_time		= iSeries_get_boot_time,
++	.set_rtc_time		= iSeries_set_rtc_time,
++	.get_rtc_time		= iSeries_get_rtc_time,
++	.calibrate_decr		= generic_calibrate_decr,
++	.progress		= iSeries_progress,
++	.probe			= iseries_probe,
++	.ioremap		= iseries_ioremap,
++	.iounmap		= iseries_iounmap,
+ 	/* XXX Implement enable_pmcs for iSeries */
+ };
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/iseries/setup.h powerpc.git/arch/powerpc/platforms/iseries/setup.h
+--- linux-2.6.24/arch/powerpc/platforms/iseries/setup.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/iseries/setup.h	2008-01-28 20:25:49.000000000 +0100
+@@ -17,6 +17,7 @@
+ #ifndef	__ISERIES_SETUP_H__
+ #define	__ISERIES_SETUP_H__
+ 
++extern void *iSeries_early_setup(void);
+ extern unsigned long iSeries_get_boot_time(void);
+ extern int iSeries_set_rtc_time(struct rtc_time *tm);
+ extern void iSeries_get_rtc_time(struct rtc_time *tm);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/iseries/vpdinfo.c powerpc.git/arch/powerpc/platforms/iseries/vpdinfo.c
+--- linux-2.6.24/arch/powerpc/platforms/iseries/vpdinfo.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/iseries/vpdinfo.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,275 +0,0 @@
+-/*
+- * This code gets the card location of the hardware
+- * Copyright (C) 2001  <Allan H Trautman> <IBM Corp>
+- * Copyright (C) 2005  Stephen Rothwel, IBM Corp
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the:
+- * Free Software Foundation, Inc.,
+- * 59 Temple Place, Suite 330,
+- * Boston, MA  02111-1307  USA
+- *
+- * Change Activity:
+- *   Created, Feb 2, 2001
+- *   Ported to ppc64, August 20, 2001
+- * End Change Activity
+- */
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <asm/types.h>
+-#include <asm/resource.h>
+-#include <asm/abs_addr.h>
+-#include <asm/pci-bridge.h>
+-#include <asm/iseries/hv_types.h>
+-
+-#include "pci.h"
+-#include "call_pci.h"
+-
+-/*
+- * Size of Bus VPD data
+- */
+-#define BUS_VPDSIZE      1024
+-
+-/*
+- * Bus Vpd Tags
+- */
+-#define  VpdEndOfAreaTag   0x79
+-#define  VpdIdStringTag    0x82
+-#define  VpdVendorAreaTag  0x84
+-
+-/*
+- * Mfg Area Tags
+- */
+-#define  VpdFruFrameId    0x4649     // "FI"
+-#define  VpdSlotMapFormat 0x4D46     // "MF"
+-#define  VpdSlotMap       0x534D     // "SM"
+-
+-/*
+- * Structures of the areas
+- */
+-struct MfgVpdAreaStruct {
+-	u16 Tag;
+-	u8  TagLength;
+-	u8  AreaData1;
+-	u8  AreaData2;
+-};
+-typedef struct MfgVpdAreaStruct MfgArea;
+-#define MFG_ENTRY_SIZE   3
+-
+-struct SlotMapStruct {
+-	u8   AgentId;
+-	u8   SecondaryAgentId;
+-	u8   PhbId;
+-	char CardLocation[3];
+-	char Parms[8];
+-	char Reserved[2];
+-};
+-typedef struct SlotMapStruct SlotMap;
+-#define SLOT_ENTRY_SIZE   16
+-
+-/*
+- * Parse the Slot Area
+- */
+-static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
+-		HvAgentId agent, u8 *PhbId, char card[4])
+-{
+-	int SlotMapLen = MapLen;
+-	SlotMap *SlotMapPtr = MapPtr;
+-
+-	/*
+-	 * Parse Slot label until we find the one requested
+-	 */
+-	while (SlotMapLen > 0) {
+-		if (SlotMapPtr->AgentId == agent) {
+-			/*
+-			 * If Phb wasn't found, grab the entry first one found.
+-			 */
+-			if (*PhbId == 0xff)
+-				*PhbId = SlotMapPtr->PhbId;
+-			/* Found it, extract the data. */
+-			if (SlotMapPtr->PhbId == *PhbId) {
+-				memcpy(card, &SlotMapPtr->CardLocation, 3);
+-				card[3]  = 0;
+-				break;
+-			}
+-		}
+-		/* Point to the next Slot */
+-		SlotMapPtr = (SlotMap *)((char *)SlotMapPtr + SLOT_ENTRY_SIZE);
+-		SlotMapLen -= SLOT_ENTRY_SIZE;
+-	}
+-}
+-
+-/*
+- * Parse the Mfg Area
+- */
+-static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
+-		HvAgentId agent, u8 *PhbId,
+-		u8 *frame, char card[4])
+-{
+-	MfgArea *MfgAreaPtr = (MfgArea *)AreaData;
+-	int MfgAreaLen = AreaLen;
+-	u16 SlotMapFmt = 0;
+-
+-	/* Parse Mfg Data */
+-	while (MfgAreaLen > 0) {
+-		int MfgTagLen = MfgAreaPtr->TagLength;
+-		/* Frame ID         (FI 4649020310 ) */
+-		if (MfgAreaPtr->Tag == VpdFruFrameId)		/* FI  */
+-			*frame = MfgAreaPtr->AreaData1;
+-		/* Slot Map Format  (MF 4D46020004 ) */
+-		else if (MfgAreaPtr->Tag == VpdSlotMapFormat)	/* MF  */
+-			SlotMapFmt = (MfgAreaPtr->AreaData1 * 256)
+-				+ MfgAreaPtr->AreaData2;
+-		/* Slot Map         (SM 534D90 */
+-		else if (MfgAreaPtr->Tag == VpdSlotMap)	{	/* SM  */
+-			SlotMap *SlotMapPtr;
+-
+-			if (SlotMapFmt == 0x1004)
+-				SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
+-						+ MFG_ENTRY_SIZE + 1);
+-			else
+-				SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
+-						+ MFG_ENTRY_SIZE);
+-			iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen,
+-					agent, PhbId, card);
+-		}
+-		/*
+-		 * Point to the next Mfg Area
+-		 * Use defined size, sizeof give wrong answer
+-		 */
+-		MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen
+-				+ MFG_ENTRY_SIZE);
+-		MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE);
+-	}
+-}
+-
+-/*
+- * Look for "BUS".. Data is not Null terminated.
+- * PHBID of 0xFF indicates PHB was not found in VPD Data.
+- */
+-static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
+-{
+-	u8 *PhbPtr = AreaPtr;
+-	int DataLen = AreaLength;
+-	char PhbId = 0xFF;
+-
+-	while (DataLen > 0) {
+-		if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U')
+-				&& (*(PhbPtr + 2) == 'S')) {
+-			PhbPtr += 3;
+-			while (*PhbPtr == ' ')
+-				++PhbPtr;
+-			PhbId = (*PhbPtr & 0x0F);
+-			break;
+-		}
+-		++PhbPtr;
+-		--DataLen;
+-	}
+-	return PhbId;
+-}
+-
+-/*
+- * Parse out the VPD Areas
+- */
+-static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
+-		HvAgentId agent, u8 *frame, char card[4])
+-{
+-	u8 *TagPtr = VpdData;
+-	int DataLen = VpdDataLen - 3;
+-	u8 PhbId = 0xff;
+-
+-	while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
+-		int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
+-		u8 *AreaData  = TagPtr + 3;
+-
+-		if (*TagPtr == VpdIdStringTag)
+-			PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
+-		else if (*TagPtr == VpdVendorAreaTag)
+-			iSeries_Parse_MfgArea(AreaData, AreaLen,
+-					agent, &PhbId, frame, card);
+-		/* Point to next Area. */
+-		TagPtr  = AreaData + AreaLen;
+-		DataLen -= AreaLen;
+-	}
+-}
+-
+-static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
+-		u8 *frame, char card[4])
+-{
+-	int status = 0;
+-	int BusVpdLen = 0;
+-	u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
+-
+-	if (BusVpdPtr == NULL) {
+-		printk("PCI: Bus VPD Buffer allocation failure.\n");
+-		return 0;
+-	}
+-	BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
+-					BUS_VPDSIZE);
+-	if (BusVpdLen == 0) {
+-		printk("PCI: Bus VPD Buffer zero length.\n");
+-		goto out_free;
+-	}
+-	/* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */
+-	/* Make sure this is what I think it is */
+-	if (*BusVpdPtr != VpdIdStringTag) {	/* 0x82 */
+-		printk("PCI: Bus VPD Buffer missing starting tag.\n");
+-		goto out_free;
+-	}
+-	iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
+-	status = 1;
+-out_free:
+-	kfree(BusVpdPtr);
+-	return status;
+-}
+-
+-/*
+- * Prints the device information.
+- * - Pass in pci_dev* pointer to the device.
+- * - Pass in the device count
+- *
+- * Format:
+- * PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet
+- * controller
+- */
+-void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
+-{
+-	struct device_node *DevNode = PciDev->sysdata;
+-	struct pci_dn *pdn;
+-	u16 bus;
+-	u8 frame = 0;
+-	char card[4];
+-	HvSubBusNumber subbus;
+-	HvAgentId agent;
+-
+-	if (DevNode == NULL) {
+-		printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n",
+-				count);
+-		return;
+-	}
+-
+-	pdn = PCI_DN(DevNode);
+-	bus = pdn->busno;
+-	subbus = pdn->bussubno;
+-	agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
+-			ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
+-
+-	if (iSeries_Get_Location_Code(bus, agent, &frame, card)) {
+-		printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
+-			"Card %4s  0x%04X\n", count, bus,
+-			PCI_SLOT(PciDev->devfn), PciDev->vendor, frame,
+-			card, (int)(PciDev->class >> 8));
+-	}
+-}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/maple/Kconfig powerpc.git/arch/powerpc/platforms/maple/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/maple/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/maple/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -1,6 +1,7 @@
+ config PPC_MAPLE
+ 	depends on PPC_MULTIPLATFORM && PPC64
+ 	bool "Maple 970FX Evaluation Board"
++	select PCI
+ 	select MPIC
+ 	select U3_DART
+ 	select MPIC_U3_HT_IRQS
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/maple/pci.c powerpc.git/arch/powerpc/platforms/maple/pci.c
+--- linux-2.6.24/arch/powerpc/platforms/maple/pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/maple/pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -558,7 +558,7 @@
+ 	 * safe assumptions hopefully.
+ 	 */
+ 	if (u3_agp) {
+-		struct device_node *np = u3_agp->arch_data;
++		struct device_node *np = u3_agp->dn;
+ 		PCI_DN(np)->busno = 0xf0;
+ 		for (np = np->child; np; np = np->sibling)
+ 			PCI_DN(np)->busno = 0xf0;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/maple/setup.c powerpc.git/arch/powerpc/platforms/maple/setup.c
+--- linux-2.6.24/arch/powerpc/platforms/maple/setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/maple/setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -42,6 +42,7 @@
+ #include <linux/serial.h>
+ #include <linux/smp.h>
+ #include <linux/bitops.h>
++#include <linux/of_device.h>
+ 
+ #include <asm/processor.h>
+ #include <asm/sections.h>
+@@ -56,7 +57,6 @@
+ #include <asm/dma.h>
+ #include <asm/cputable.h>
+ #include <asm/time.h>
+-#include <asm/of_device.h>
+ #include <asm/lmb.h>
+ #include <asm/mpic.h>
+ #include <asm/rtas.h>
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/Kconfig powerpc.git/arch/powerpc/platforms/pasemi/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -3,6 +3,7 @@
+ 	bool "PA Semi SoC-based platforms"
+ 	default n
+ 	select MPIC
++	select PCI
+ 	select PPC_UDBG_16550
+ 	select PPC_NATIVE
+ 	select MPIC_BROKEN_REGREAD
+@@ -17,7 +18,7 @@
+ 	bool "PA Semi IOMMU support"
+ 	depends on PPC_PASEMI
+ 	help
+-	  IOMMU support for PA6T-1682M
++	  IOMMU support for PA Semi PWRficient
+ 
+ config PPC_PASEMI_IOMMU_DMA_FORCE
+ 	bool "Force DMA engine to use IOMMU"
+@@ -36,13 +37,4 @@
+ 	help
+ 	  Driver for MDIO via GPIO on PWRficient platforms
+ 
+-config ELECTRA_IDE
+-      tristate "Electra IDE driver"
+-      default y
+-      depends on PPC_PASEMI && ATA
+-      select PATA_PLATFORM
+-      help
+-	This includes driver support for the Electra on-board IDE
+-	interface.
+-
+ endmenu
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/Makefile powerpc.git/arch/powerpc/platforms/pasemi/Makefile
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -1,4 +1,3 @@
+ obj-y	+= setup.o pci.o time.o idle.o powersave.o iommu.o
+ obj-$(CONFIG_PPC_PASEMI_MDIO)	+= gpio_mdio.o
+-obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o
+ obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/cpufreq.c powerpc.git/arch/powerpc/platforms/pasemi/cpufreq.c
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/cpufreq.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/cpufreq.c	2008-01-28 20:25:49.000000000 +0100
+@@ -32,6 +32,7 @@
+ #include <asm/io.h>
+ #include <asm/prom.h>
+ #include <asm/time.h>
++#include <asm/smp.h>
+ 
+ #define SDCASR_REG		0x0100
+ #define SDCASR_REG_STRIDE	0x1000
+@@ -124,6 +125,11 @@
+ 	local_irq_restore(flags);
+ }
+ 
++int check_astate(void)
++{
++	return get_cur_astate(hard_smp_processor_id());
++}
++
+ void restore_astate(int cpu)
+ {
+ 	set_astate(cpu, current_astate);
+@@ -147,7 +153,10 @@
+ 	if (!cpu)
+ 		goto out;
+ 
+-	dn = of_find_compatible_node(NULL, "sdc", "1682m-sdc");
++	dn = of_find_compatible_node(NULL, NULL, "1682m-sdc");
++	if (!dn)
++		dn = of_find_compatible_node(NULL, NULL,
++					     "pasemi,pwrficient-sdc");
+ 	if (!dn)
+ 		goto out;
+ 	err = of_address_to_resource(dn, 0, &res);
+@@ -160,7 +169,10 @@
+ 		goto out;
+ 	}
+ 
+-	dn = of_find_compatible_node(NULL, "gizmo", "1682m-gizmo");
++	dn = of_find_compatible_node(NULL, NULL, "1682m-gizmo");
++	if (!dn)
++		dn = of_find_compatible_node(NULL, NULL,
++					     "pasemi,pwrficient-gizmo");
+ 	if (!dn) {
+ 		err = -ENODEV;
+ 		goto out_unmap_sdcasr;
+@@ -292,7 +304,8 @@
+ 
+ static int __init pas_cpufreq_init(void)
+ {
+-	if (!machine_is_compatible("PA6T-1682M"))
++	if (!machine_is_compatible("PA6T-1682M") &&
++	    !machine_is_compatible("pasemi,pwrficient"))
+ 		return -ENODEV;
+ 
+ 	return cpufreq_register_driver(&pas_cpufreq_driver);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/electra_ide.c powerpc.git/arch/powerpc/platforms/pasemi/electra_ide.c
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/electra_ide.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/electra_ide.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,96 +0,0 @@
+-/*
+- * Copyright (C) 2007 PA Semi, Inc
+- *
+- * Maintained by: Olof Johansson <olof@lixom.net>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+- */
+-
+-#include <linux/platform_device.h>
+-
+-#include <asm/prom.h>
+-#include <asm/system.h>
+-
+-/* The electra IDE interface is incredibly simple: Just a device on the localbus
+- * with interrupts hooked up to one of the GPIOs. The device tree contains the
+- * address window and interrupt mappings already, and the pata_platform driver handles
+- * the rest. We just need to hook the two up.
+- */
+-
+-#define MAX_IFS	4	/* really, we have only one */
+-
+-static struct platform_device *pdevs[MAX_IFS];
+-
+-static int __devinit electra_ide_init(void)
+-{
+-	struct device_node *np;
+-	struct resource r[3];
+-	int ret = 0;
+-	int i;
+-
+-	np = of_find_compatible_node(NULL, "ide", "electra-ide");
+-	i = 0;
+-
+-	while (np && i < MAX_IFS) {
+-		memset(r, 0, sizeof(r));
+-
+-		/* pata_platform wants two address ranges: one for the base registers,
+-		 * another for the control (altstatus). It's located at offset 0x3f6 in
+-		 * the window, but the device tree only has one large register window
+-		 * that covers both ranges. So we need to split it up by hand here:
+-		 */
+-
+-		ret = of_address_to_resource(np, 0, &r[0]);
+-		if (ret)
+-			goto out;
+-		ret = of_address_to_resource(np, 0, &r[1]);
+-		if (ret)
+-			goto out;
+-
+-		r[1].start += 0x3f6;
+-		r[0].end = r[1].start-1;
+-
+-		r[2].start = irq_of_parse_and_map(np, 0);
+-		r[2].end = irq_of_parse_and_map(np, 0);
+-		r[2].flags = IORESOURCE_IRQ;
+-
+-		pr_debug("registering platform device at 0x%lx/0x%lx, irq is %ld\n",
+-			 r[0].start, r[1].start, r[2].start);
+-		pdevs[i] = platform_device_register_simple("pata_platform", i, r, 3);
+-		if (IS_ERR(pdevs[i])) {
+-			ret = PTR_ERR(pdevs[i]);
+-			pdevs[i] = NULL;
+-			goto out;
+-		}
+-		np = of_find_compatible_node(np, "ide", "electra-ide");
+-	}
+-out:
+-	return ret;
+-}
+-module_init(electra_ide_init);
+-
+-static void __devexit electra_ide_exit(void)
+-{
+-	int i;
+-
+-	for (i = 0; i < MAX_IFS; i++)
+-		if (pdevs[i])
+-			platform_device_unregister(pdevs[i]);
+-}
+-module_exit(electra_ide_exit);
+-
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
+-MODULE_DESCRIPTION("PA Semi Electra IDE driver");
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/gpio_mdio.c powerpc.git/arch/powerpc/platforms/pasemi/gpio_mdio.c
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/gpio_mdio.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/gpio_mdio.c	2008-01-28 20:25:49.000000000 +0100
+@@ -30,7 +30,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/phy.h>
+ #include <linux/platform_device.h>
+-#include <asm/of_platform.h>
++#include <linux/of_platform.h>
+ 
+ #define DELAY 1
+ 
+@@ -218,45 +218,27 @@
+ 				     const struct of_device_id *match)
+ {
+ 	struct device *dev = &ofdev->dev;
+-	struct device_node *np = ofdev->node;
+-	struct device_node *gpio_np;
++	struct device_node *phy_dn, *np = ofdev->node;
+ 	struct mii_bus *new_bus;
+-	struct resource res;
+ 	struct gpio_priv *priv;
+ 	const unsigned int *prop;
+-	int err = 0;
++	int err;
+ 	int i;
+ 
+-	gpio_np = of_find_compatible_node(NULL, "gpio", "1682m-gpio");
+-
+-	if (!gpio_np)
+-		return -ENODEV;
+-
+-	err = of_address_to_resource(gpio_np, 0, &res);
+-	of_node_put(gpio_np);
+-
+-	if (err)
+-		return -EINVAL;
+-
+-	if (!gpio_regs)
+-		gpio_regs = ioremap(res.start, 0x100);
+-
+-	if (!gpio_regs)
+-		return -EPERM;
+-
++	err = -ENOMEM;
+ 	priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL);
+-	if (priv == NULL)
+-		return -ENOMEM;
++	if (!priv)
++		goto out;
+ 
+ 	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+ 
+-	if (new_bus == NULL)
+-		return -ENOMEM;
++	if (!new_bus)
++		goto out_free_priv;
+ 
+-	new_bus->name = "pasemi gpio mdio bus",
+-	new_bus->read = &gpio_mdio_read,
+-	new_bus->write = &gpio_mdio_write,
+-	new_bus->reset = &gpio_mdio_reset,
++	new_bus->name = "pasemi gpio mdio bus";
++	new_bus->read = &gpio_mdio_read;
++	new_bus->write = &gpio_mdio_write;
++	new_bus->reset = &gpio_mdio_reset;
+ 
+ 	prop = of_get_property(np, "reg", NULL);
+ 	new_bus->id = *prop;
+@@ -265,9 +247,24 @@
+ 	new_bus->phy_mask = 0;
+ 
+ 	new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+-	for(i = 0; i < PHY_MAX_ADDR; ++i)
+-		new_bus->irq[i] = irq_create_mapping(NULL, 10);
+ 
++	if (!new_bus->irq)
++		goto out_free_bus;
++
++	for (i = 0; i < PHY_MAX_ADDR; i++)
++		new_bus->irq[i] = NO_IRQ;
++
++	for (phy_dn = of_get_next_child(np, NULL);
++	     phy_dn != NULL;
++	     phy_dn = of_get_next_child(np, phy_dn)) {
++		const unsigned int *ip, *regp;
++
++		ip = of_get_property(phy_dn, "interrupts", NULL);
++		regp = of_get_property(phy_dn, "reg", NULL);
++		if (!ip || !regp || *regp >= PHY_MAX_ADDR)
++			continue;
++		new_bus->irq[*regp] = irq_create_mapping(NULL, *ip);
++	}
+ 
+ 	prop = of_get_property(np, "mdc-pin", NULL);
+ 	priv->mdc_pin = *prop;
+@@ -280,17 +277,21 @@
+ 
+ 	err = mdiobus_register(new_bus);
+ 
+-	if (0 != err) {
++	if (err != 0) {
+ 		printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n",
+ 				new_bus->name, err);
+-		goto bus_register_fail;
++		goto out_free_irq;
+ 	}
+ 
+ 	return 0;
+ 
+-bus_register_fail:
++out_free_irq:
++	kfree(new_bus->irq);
++out_free_bus:
+ 	kfree(new_bus);
+-
++out_free_priv:
++	kfree(priv);
++out:
+ 	return err;
+ }
+ 
+@@ -317,6 +318,7 @@
+ 	},
+ 	{},
+ };
++MODULE_DEVICE_TABLE(of, gpio_mdio_match);
+ 
+ static struct of_platform_driver gpio_mdio_driver =
+ {
+@@ -330,12 +332,32 @@
+ 
+ int gpio_mdio_init(void)
+ {
++	struct device_node *np;
++
++	np = of_find_compatible_node(NULL, NULL, "1682m-gpio");
++	if (!np)
++		np = of_find_compatible_node(NULL, NULL,
++					     "pasemi,pwrficient-gpio");
++	if (!np)
++		return -ENODEV;
++	gpio_regs = of_iomap(np, 0);
++	of_node_put(np);
++
++	if (!gpio_regs)
++		return -ENODEV;
++
+ 	return of_register_platform_driver(&gpio_mdio_driver);
+ }
++module_init(gpio_mdio_init);
+ 
+ void gpio_mdio_exit(void)
+ {
+ 	of_unregister_platform_driver(&gpio_mdio_driver);
++	if (gpio_regs)
++		iounmap(gpio_regs);
+ }
+-device_initcall(gpio_mdio_init);
++module_exit(gpio_mdio_exit);
+ 
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Olof Johansson <olof@lixom.net>");
++MODULE_DESCRIPTION("Driver for MDIO over GPIO on PA Semi PWRficient-based boards");
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/idle.c powerpc.git/arch/powerpc/platforms/pasemi/idle.c
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/idle.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/idle.c	2008-01-28 20:25:49.000000000 +0100
+@@ -74,9 +74,6 @@
+ 
+ static int __init pasemi_idle_init(void)
+ {
+-	if (!machine_is(pasemi))
+-		return -ENODEV;
+-
+ #ifndef CONFIG_PPC_PASEMI_CPUFREQ
+ 	printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n");
+ 	current_mode = 0;
+@@ -88,7 +85,7 @@
+ 
+ 	return 0;
+ }
+-late_initcall(pasemi_idle_init);
++machine_late_initcall(pasemi, pasemi_idle_init);
+ 
+ static int __init idle_param(char *p)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/pasemi.h powerpc.git/arch/powerpc/platforms/pasemi/pasemi.h
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/pasemi.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/pasemi.h	2008-01-28 20:25:49.000000000 +0100
+@@ -16,8 +16,14 @@
+ 
+ /* Restore astate to last set */
+ #ifdef CONFIG_PPC_PASEMI_CPUFREQ
++extern int check_astate(void);
+ extern void restore_astate(int cpu);
+ #else
++static inline int check_astate(void)
++{
++	/* Always return >0 so we never power save */
++	return 1;
++}
+ static inline void restore_astate(int cpu)
+ {
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/powersave.S powerpc.git/arch/powerpc/platforms/pasemi/powersave.S
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/powersave.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/powersave.S	2008-01-28 20:25:49.000000000 +0100
+@@ -62,7 +62,16 @@
+ 	mflr	r0
+ 	std	r0, 16(r1)
+ 	stdu	r1,-64(r1)
++#ifdef CONFIG_PPC_PASEMI_CPUFREQ
++	std	r3, 48(r1)
+ 
++	/* Only do power savings when in astate 0 */
++	bl	.check_astate
++	cmpwi	r3,0
++	bne	1f
++
++	ld	r3, 48(r1)
++#endif
+ 	LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE)
+ 	mfmsr	r4
+ 	andc	r5,r4,r6
+@@ -73,7 +82,7 @@
+ 
+ 	mtmsrd	r4,0
+ 
+-	addi	r1,r1,64
++1:	addi	r1,r1,64
+ 	ld	r0,16(r1)
+ 	mtlr	r0
+ 	blr
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pasemi/setup.c powerpc.git/arch/powerpc/platforms/pasemi/setup.c
+--- linux-2.6.24/arch/powerpc/platforms/pasemi/setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pasemi/setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -27,6 +27,7 @@
+ #include <linux/delay.h>
+ #include <linux/console.h>
+ #include <linux/pci.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/prom.h>
+ #include <asm/system.h>
+@@ -35,7 +36,7 @@
+ #include <asm/mpic.h>
+ #include <asm/smp.h>
+ #include <asm/time.h>
+-#include <asm/of_platform.h>
++#include <asm/mmu.h>
+ 
+ #include <pcmcia/ss.h>
+ #include <pcmcia/cistpl.h>
+@@ -43,6 +44,10 @@
+ 
+ #include "pasemi.h"
+ 
++#if !defined(CONFIG_SMP)
++static void smp_send_stop(void) {}
++#endif
++
+ /* SDC reset register, must be pre-mapped at reset time */
+ static void __iomem *reset_reg;
+ 
+@@ -56,10 +61,14 @@
+ 
+ static struct mce_regs mce_regs[MAX_MCE_REGS];
+ static int num_mce_regs;
++static int nmi_virq = NO_IRQ;
+ 
+ 
+ static void pas_restart(char *cmd)
+ {
++	/* Need to put others cpu in hold loop so they're not sleeping */
++	smp_send_stop();
++	udelay(10000);
+ 	printk("Restarting...\n");
+ 	while (1)
+ 		out_le32(reset_reg, 0x6000000);
+@@ -126,9 +135,6 @@
+ 	struct pci_dev *dev;
+ 	int reg;
+ 
+-	if (!machine_is(pasemi))
+-		return -ENODEV;
+-
+ 	/* Remap various SoC status registers for use by the MCE handler */
+ 
+ 	reg = 0;
+@@ -172,7 +178,7 @@
+ 
+ 	return 0;
+ }
+-device_initcall(pas_setup_mce_regs);
++machine_device_initcall(pasemi, pas_setup_mce_regs);
+ 
+ static __init void pas_init_IRQ(void)
+ {
+@@ -181,6 +187,8 @@
+ 	unsigned long openpic_addr;
+ 	const unsigned int *opprop;
+ 	int naddr, opplen;
++	int mpic_flags;
++	const unsigned int *nmiprop;
+ 	struct mpic *mpic;
+ 
+ 	mpic_node = NULL;
+@@ -213,13 +221,26 @@
+ 	openpic_addr = of_read_number(opprop, naddr);
+ 	printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
+ 
++	mpic_flags = MPIC_PRIMARY | MPIC_LARGE_VECTORS | MPIC_NO_BIAS;
++
++	nmiprop = of_get_property(mpic_node, "nmi-source", NULL);
++	if (nmiprop)
++		mpic_flags |= MPIC_ENABLE_MCK;
++
+ 	mpic = mpic_alloc(mpic_node, openpic_addr,
+-			  MPIC_PRIMARY|MPIC_LARGE_VECTORS,
+-			  0, 0, " PAS-OPIC  ");
++			  mpic_flags, 0, 0, "PASEMI-OPIC");
+ 	BUG_ON(!mpic);
+ 
+ 	mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
+ 	mpic_init(mpic);
++	/* The NMI/MCK source needs to be prio 15 */
++	if (nmiprop) {
++		nmi_virq = irq_create_mapping(NULL, *nmiprop);
++		mpic_irq_set_priority(nmi_virq, 15);
++		set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
++		mpic_unmask_irq(nmi_virq);
++	}
++
+ 	of_node_put(mpic_node);
+ 	of_node_put(root);
+ }
+@@ -239,6 +260,14 @@
+ 
+ 	srr0 = regs->nip;
+ 	srr1 = regs->msr;
++
++	if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
++		printk(KERN_ERR "NMI delivered\n");
++		debugger(regs);
++		mpic_end_irq(nmi_virq);
++		goto out;
++	}
++
+ 	dsisr = mfspr(SPRN_DSISR);
+ 	printk(KERN_ERR "Machine Check on CPU %d\n", cpu);
+ 	printk(KERN_ERR "SRR0  0x%016lx SRR1 0x%016lx\n", srr0, srr1);
+@@ -295,14 +324,14 @@
+ 		int i;
+ 
+ 		printk(KERN_ERR "slb contents:\n");
+-		for (i = 0; i < SLB_NUM_ENTRIES; i++) {
++		for (i = 0; i < mmu_slb_size; i++) {
+ 			asm volatile("slbmfee  %0,%1" : "=r" (e) : "r" (i));
+ 			asm volatile("slbmfev  %0,%1" : "=r" (v) : "r" (i));
+ 			printk(KERN_ERR "%02d %016lx %016lx\n", i, e, v);
+ 		}
+ 	}
+ 
+-
++out:
+ 	/* SRR1[62] is from MSR[62] if recoverable, so pass that back */
+ 	return !!(srr1 & 0x2);
+ }
+@@ -362,16 +391,17 @@
+ 
+ 
+ static struct of_device_id pasemi_bus_ids[] = {
++	/* Unfortunately needed for legacy firmwares */
+ 	{ .type = "localbus", },
+ 	{ .type = "sdc", },
++	/* These are the proper entries, which newer firmware uses */
++	{ .compatible = "pasemi,localbus", },
++	{ .compatible = "pasemi,sdc", },
+ 	{},
+ };
+ 
+ static int __init pasemi_publish_devices(void)
+ {
+-	if (!machine_is(pasemi))
+-		return 0;
+-
+ 	pasemi_pcmcia_init();
+ 
+ 	/* Publish OF platform devices for SDC and other non-PCI devices */
+@@ -379,7 +409,7 @@
+ 
+ 	return 0;
+ }
+-device_initcall(pasemi_publish_devices);
++machine_device_initcall(pasemi, pasemi_publish_devices);
+ 
+ 
+ /*
+@@ -389,7 +419,8 @@
+ {
+ 	unsigned long root = of_get_flat_dt_root();
+ 
+-	if (!of_flat_dt_is_compatible(root, "PA6T-1682M"))
++	if (!of_flat_dt_is_compatible(root, "PA6T-1682M") &&
++	    !of_flat_dt_is_compatible(root, "pasemi,pwrficient"))
+ 		return 0;
+ 
+ 	hpte_init_native();
+@@ -400,7 +431,7 @@
+ }
+ 
+ define_machine(pasemi) {
+-	.name			= "PA Semi PA6T-1682M",
++	.name			= "PA Semi PWRficient",
+ 	.probe			= pas_probe,
+ 	.setup_arch		= pas_setup_arch,
+ 	.init_early		= pas_init_early,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/powermac/low_i2c.c powerpc.git/arch/powerpc/platforms/powermac/low_i2c.c
+--- linux-2.6.24/arch/powerpc/platforms/powermac/low_i2c.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/powermac/low_i2c.c	2008-01-28 20:25:49.000000000 +0100
+@@ -585,8 +585,7 @@
+ 	struct device_node *np, *child, *parent;
+ 
+ 	/* Probe keywest-i2c busses */
+-	for (np = NULL;
+-	     (np = of_find_compatible_node(np, "i2c","keywest-i2c")) != NULL;){
++	for_each_compatible_node(np, "i2c","keywest-i2c") {
+ 		struct pmac_i2c_host_kw *host;
+ 		int multibus, chans, i;
+ 
+@@ -1462,9 +1461,6 @@
+ 		return 0;
+ 	i2c_inited = 1;
+ 
+-	if (!machine_is(powermac))
+-		return 0;
+-
+ 	/* Probe keywest-i2c busses */
+ 	kw_i2c_probe();
+ 
+@@ -1483,7 +1479,7 @@
+ 
+ 	return 0;
+ }
+-arch_initcall(pmac_i2c_init);
++machine_arch_initcall(powermac, pmac_i2c_init);
+ 
+ /* Since pmac_i2c_init can be called too early for the platform device
+  * registration, we need to do it at a later time. In our case, subsys
+@@ -1515,4 +1511,4 @@
+ 
+ 	return 0;
+ }
+-subsys_initcall(pmac_i2c_create_platform_devices);
++machine_subsys_initcall(powermac, pmac_i2c_create_platform_devices);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/powermac/pci.c powerpc.git/arch/powerpc/platforms/powermac/pci.c
+--- linux-2.6.24/arch/powerpc/platforms/powermac/pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/powermac/pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -40,8 +40,6 @@
+ static int has_uninorth;
+ #ifdef CONFIG_PPC64
+ static struct pci_controller *u3_agp;
+-static struct pci_controller *u4_pcie;
+-static struct pci_controller *u3_ht;
+ #else
+ static int has_second_ohare;
+ #endif /* CONFIG_PPC64 */
+@@ -314,12 +312,15 @@
+ 
+ 	/* We only allow config cycles to devices that are in OF device-tree
+ 	 * as we are apparently having some weird things going on with some
+-	 * revs of K2 on recent G5s
++	 * revs of K2 on recent G5s, except for the host bridge itself, which
++	 * is missing from the tree but we know we can probe.
+ 	 */
+ 	if (bus->self)
+ 		busdn = pci_device_to_OF_node(bus->self);
++	else if (devfn == 0)
++		return 0;
+ 	else
+-		busdn = hose->arch_data;
++		busdn = hose->dn;
+ 	for (dn = busdn->child; dn; dn = dn->sibling)
+ 		if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn)
+ 			break;
+@@ -344,14 +345,15 @@
+ 		+ (((unsigned int)bus) << 16) \
+ 		+ 0x01000000UL)
+ 
+-static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
+-					     u8 bus, u8 devfn, u8 offset)
++static void __iomem *u3_ht_cfg_access(struct pci_controller *hose, u8 bus,
++				      u8 devfn, u8 offset, int *swap)
+ {
++	*swap = 1;
+ 	if (bus == hose->first_busno) {
+-		/* For now, we don't self probe U3 HT bridge */
+-		if (PCI_SLOT(devfn) == 0)
+-			return NULL;
+-		return hose->cfg_data + U3_HT_CFA0(devfn, offset);
++		if (devfn != 0)
++			return hose->cfg_data + U3_HT_CFA0(devfn, offset);
++		*swap = 0;
++		return ((void __iomem *)hose->cfg_addr) + (offset << 2);
+ 	} else
+ 		return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
+ }
+@@ -360,14 +362,15 @@
+ 				    int offset, int len, u32 *val)
+ {
+ 	struct pci_controller *hose;
+-	volatile void __iomem *addr;
++	void __iomem *addr;
++	int swap;
+ 
+ 	hose = pci_bus_to_host(bus);
+ 	if (hose == NULL)
+ 		return PCIBIOS_DEVICE_NOT_FOUND;
+ 	if (offset >= 0x100)
+ 		return  PCIBIOS_BAD_REGISTER_NUMBER;
+-	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
++	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap);
+ 	if (!addr)
+ 		return PCIBIOS_DEVICE_NOT_FOUND;
+ 
+@@ -397,10 +400,10 @@
+ 		*val = in_8(addr);
+ 		break;
+ 	case 2:
+-		*val = in_le16(addr);
++		*val = swap ? in_le16(addr) : in_be16(addr);
+ 		break;
+ 	default:
+-		*val = in_le32(addr);
++		*val = swap ? in_le32(addr) : in_be32(addr);
+ 		break;
+ 	}
+ 	return PCIBIOS_SUCCESSFUL;
+@@ -410,14 +413,15 @@
+ 				     int offset, int len, u32 val)
+ {
+ 	struct pci_controller *hose;
+-	volatile void __iomem *addr;
++	void __iomem *addr;
++	int swap;
+ 
+ 	hose = pci_bus_to_host(bus);
+ 	if (hose == NULL)
+ 		return PCIBIOS_DEVICE_NOT_FOUND;
+ 	if (offset >= 0x100)
+ 		return  PCIBIOS_BAD_REGISTER_NUMBER;
+-	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
++	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap);
+ 	if (!addr)
+ 		return PCIBIOS_DEVICE_NOT_FOUND;
+ 
+@@ -439,10 +443,10 @@
+ 		out_8(addr, val);
+ 		break;
+ 	case 2:
+-		out_le16(addr, val);
++		swap ? out_le16(addr, val) : out_be16(addr, val);
+ 		break;
+ 	default:
+-		out_le32((u32 __iomem *)addr, val);
++		swap ? out_le32(addr, val) : out_be32(addr, val);
+ 		break;
+ 	}
+ 	return PCIBIOS_SUCCESSFUL;
+@@ -725,7 +729,7 @@
+ static int __init setup_uninorth(struct pci_controller *hose,
+ 				 struct resource *addr)
+ {
+-	pci_assign_all_buses = 1;
++	ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+ 	has_uninorth = 1;
+ 	hose->ops = &macrisc_pci_ops;
+ 	hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
+@@ -773,31 +777,72 @@
+ 	 */
+ 	hose->first_busno = 0x00;
+ 	hose->last_busno = 0xff;
+-	u4_pcie = hose;
+ }
+ 
+-static void __init setup_u3_ht(struct pci_controller* hose)
++static void __init parse_region_decode(struct pci_controller *hose,
++				       u32 decode)
+ {
+-	struct device_node *np = (struct device_node *)hose->arch_data;
+-	struct pci_controller *other = NULL;
+-	int i, cur;
++	unsigned long base, end, next = -1;
++	int i, cur = -1;
+ 
++	/* Iterate through all bits. We ignore the last bit as this region is
++	 * reserved for the ROM among other niceties
++	 */
++	for (i = 0; i < 31; i++) {
++		if ((decode & (0x80000000 >> i)) == 0)
++			continue;
++		if (i < 16) {
++			base = 0xf0000000 | (((u32)i) << 24);
++			end = base + 0x00ffffff;
++		} else {
++			base = ((u32)i-16) << 28;
++			end = base + 0x0fffffff;
++		}
++		if (base != next) {
++			if (++cur >= 3) {
++				printk(KERN_WARNING "PCI: Too many ranges !\n");
++				break;
++			}
++			hose->mem_resources[cur].flags = IORESOURCE_MEM;
++			hose->mem_resources[cur].name = hose->dn->full_name;
++			hose->mem_resources[cur].start = base;
++			hose->mem_resources[cur].end = end;
++			DBG("  %d: 0x%08lx-0x%08lx\n", cur, base, end);
++		} else {
++			DBG("   :           -0x%08lx\n", end);
++			hose->mem_resources[cur].end = end;
++		}
++		next = end + 1;
++	}
++}
++
++static void __init setup_u3_ht(struct pci_controller* hose)
++{
++	struct device_node *np = hose->dn;
++	struct resource cfg_res, self_res;
++	u32 decode;
+ 
+ 	hose->ops = &u3_ht_pci_ops;
+ 
+-	/* We hard code the address because of the different size of
+-	 * the reg address cell, we shall fix that by killing struct
+-	 * reg_property and using some accessor functions instead
++	/* Get base addresses from OF tree
+ 	 */
+-	hose->cfg_data = ioremap(0xf2000000, 0x02000000);
++	if (of_address_to_resource(np, 0, &cfg_res) ||
++	    of_address_to_resource(np, 1, &self_res)) {
++		printk(KERN_ERR "PCI: Failed to get U3/U4 HT resources !\n");
++		return;
++	}
++
++	/* Map external cfg space access into cfg_data and self registers
++	 * into cfg_addr
++	 */
++	hose->cfg_data = ioremap(cfg_res.start, 0x02000000);
++	hose->cfg_addr = ioremap(self_res.start,
++				 self_res.end - self_res.start + 1);
+ 
+ 	/*
+-	 * /ht node doesn't expose a "ranges" property, so we "remove"
+-	 * regions that have been allocated to AGP. So far, this version of
+-	 * the code doesn't assign any of the 0xfxxxxxxx "fine" memory regions
+-	 * to /ht. We need to fix that sooner or later by either parsing all
+-	 * child "ranges" properties or figuring out the U3 address space
+-	 * decoding logic and then read its configuration register (if any).
++	 * /ht node doesn't expose a "ranges" property, we read the register
++	 * that controls the decoding logic and use that for memory regions.
++	 * The IO region is hard coded since it is fixed in HW as well.
+ 	 */
+ 	hose->io_base_phys = 0xf4000000;
+ 	hose->pci_io_size = 0x00400000;
+@@ -808,76 +853,33 @@
+ 	hose->pci_mem_offset = 0;
+ 	hose->first_busno = 0;
+ 	hose->last_busno = 0xef;
+-	hose->mem_resources[0].name = np->full_name;
+-	hose->mem_resources[0].start = 0x80000000;
+-	hose->mem_resources[0].end = 0xefffffff;
+-	hose->mem_resources[0].flags = IORESOURCE_MEM;
+-
+-	u3_ht = hose;
+-
+-	if (u3_agp != NULL)
+-		other = u3_agp;
+-	else if (u4_pcie != NULL)
+-		other = u4_pcie;
+ 
+-	if (other == NULL) {
+-		DBG("U3/4 has no AGP/PCIE, using full resource range\n");
+-		return;
+-	}
++	/* Note: fix offset when cfg_addr becomes a void * */
++	decode = in_be32(hose->cfg_addr + 0x80);
+ 
+-	/* Fixup bus range vs. PCIE */
+-	if (u4_pcie)
+-		hose->last_busno = u4_pcie->first_busno - 1;
+-
+-	/* We "remove" the AGP resources from the resources allocated to HT,
+-	 * that is we create "holes". However, that code does assumptions
+-	 * that so far happen to be true (cross fingers...), typically that
+-	 * resources in the AGP node are properly ordered
+-	 */
+-	cur = 0;
+-	for (i=0; i<3; i++) {
+-		struct resource *res = &other->mem_resources[i];
+-		if (res->flags != IORESOURCE_MEM)
+-			continue;
+-		/* We don't care about "fine" resources */
+-		if (res->start >= 0xf0000000)
+-			continue;
+-		/* Check if it's just a matter of "shrinking" us in one
+-		 * direction
+-		 */
+-		if (hose->mem_resources[cur].start == res->start) {
+-			DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
+-			    cur, hose->mem_resources[cur].start,
+-			    res->end + 1);
+-			hose->mem_resources[cur].start = res->end + 1;
+-			continue;
+-		}
+-		if (hose->mem_resources[cur].end == res->end) {
+-			DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
+-			    cur, hose->mem_resources[cur].end,
+-			    res->start - 1);
+-			hose->mem_resources[cur].end = res->start - 1;
+-			continue;
+-		}
+-		/* No, it's not the case, we need a hole */
+-		if (cur == 2) {
+-			/* not enough resources for a hole, we drop part
+-			 * of the range
+-			 */
+-			printk(KERN_WARNING "Running out of resources"
+-			       " for /ht host !\n");
+-			hose->mem_resources[cur].end = res->start - 1;
+-			continue;
+-		}
+-		cur++;
+-		DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
+-		    cur-1, res->start - 1, cur, res->end + 1);
+-		hose->mem_resources[cur].name = np->full_name;
+-		hose->mem_resources[cur].flags = IORESOURCE_MEM;
+-		hose->mem_resources[cur].start = res->end + 1;
+-		hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
+-		hose->mem_resources[cur-1].end = res->start - 1;
+-	}
++	DBG("PCI: Apple HT bridge decode register: 0x%08x\n", decode);
++
++	/* NOTE: The decode register setup is a bit weird... region
++	 * 0xf8000000 for example is marked as enabled in there while it's
++	 & actually the memory controller registers.
++	 * That means that we are incorrectly attributing it to HT.
++	 *
++	 * In a similar vein, region 0xf4000000 is actually the HT IO space but
++	 * also marked as enabled in here and 0xf9000000 is used by some other
++	 * internal bits of the northbridge.
++	 *
++	 * Unfortunately, we can't just mask out those bit as we would end
++	 * up with more regions than we can cope (linux can only cope with
++	 * 3 memory regions for a PHB at this stage).
++	 *
++	 * So for now, we just do a little hack. We happen to -know- that
++	 * Apple firmware doesn't assign things below 0xfa000000 for that
++	 * bridge anyway so we mask out all bits we don't want.
++	 */
++	decode &= 0x003fffff;
++
++	/* Now parse the resulting bits and build resources */
++	parse_region_decode(hose, decode);
+ }
+ #endif /* CONFIG_PPC64 */
+ 
+@@ -994,6 +996,8 @@
+ 	struct device_node *np, *root;
+ 	struct device_node *ht = NULL;
+ 
++	ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN;
++
+ 	root = of_find_node_by_path("/");
+ 	if (root == NULL) {
+ 		printk(KERN_CRIT "pmac_pci_init: can't find root "
+@@ -1032,15 +1036,15 @@
+ 	 * future though
+ 	 */
+ 	if (u3_agp) {
+-		struct device_node *np = u3_agp->arch_data;
++		struct device_node *np = u3_agp->dn;
+ 		PCI_DN(np)->busno = 0xf0;
+ 		for (np = np->child; np; np = np->sibling)
+ 			PCI_DN(np)->busno = 0xf0;
+ 	}
+ 	/* pmac_check_ht_link(); */
+ 
+-	/* Tell pci.c to not use the common resource allocation mechanism */
+-	pci_probe_only = 1;
++	/* We can allocate missing resources if any */
++	pci_probe_only = 0;
+ 
+ #else /* CONFIG_PPC64 */
+ 	init_p2pbridge();
+@@ -1051,13 +1055,13 @@
+ 	 * some offset between bus number and domains for now when we
+ 	 * assign all busses should help for now
+ 	 */
+-	if (pci_assign_all_buses)
++	if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
+ 		pcibios_assign_bus_offset = 0x10;
+ #endif
+ }
+ 
+-int
+-pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
++#ifdef CONFIG_PPC32
++int pmac_pci_enable_device_hook(struct pci_dev *dev)
+ {
+ 	struct device_node* node;
+ 	int updatecfg = 0;
+@@ -1099,24 +1103,21 @@
+ 		updatecfg = 1;
+ 	}
+ 
++	/*
++	 * Fixup various header fields on 32 bits. We don't do that on
++	 * 64 bits as some of these have strange values behind the HT
++	 * bridge and we must not, for example, enable MWI or set the
++	 * cache line size on them.
++	 */
+ 	if (updatecfg) {
+ 		u16 cmd;
+ 
+-		/*
+-		 * Make sure PCI is correctly configured
+-		 *
+-		 * We use old pci_bios versions of the function since, by
+-		 * default, gmac is not powered up, and so will be absent
+-		 * from the kernel initial PCI lookup.
+-		 *
+-		 * Should be replaced by 2.4 new PCI mechanisms and really
+-		 * register the device.
+-		 */
+ 		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ 		cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
+ 			| PCI_COMMAND_INVALIDATE;
+ 		pci_write_config_word(dev, PCI_COMMAND, cmd);
+ 		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
++
+ 		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+ 				      L1_CACHE_BYTES >> 2);
+ 	}
+@@ -1124,6 +1125,18 @@
+ 	return 0;
+ }
+ 
++void __devinit pmac_pci_fixup_ohci(struct pci_dev *dev)
++{
++	struct device_node *node = pci_device_to_OF_node(dev);
++
++	/* We don't want to assign resources to USB controllers
++	 * absent from the OF tree (iBook second controller)
++	 */
++	if (dev->class == PCI_CLASS_SERIAL_USB_OHCI && !node)
++		dev->resource[0].flags = 0;
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_ANY_ID, pmac_pci_fixup_ohci);
++
+ /* We power down some devices after they have been probed. They'll
+  * be powered back on later on
+  */
+@@ -1171,7 +1184,6 @@
+ 	of_node_put(nd);
+ }
+ 
+-#ifdef CONFIG_PPC32
+ void pmac_pci_fixup_cardbus(struct pci_dev* dev)
+ {
+ 	if (!machine_is(powermac))
+@@ -1259,7 +1271,7 @@
+ 	}
+ }
+ DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
+-#endif
++#endif /* CONFIG_PPC32 */
+ 
+ /*
+  * Disable second function on K2-SATA, it's broken
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/powermac/pfunc_base.c powerpc.git/arch/powerpc/platforms/powermac/pfunc_base.c
+--- linux-2.6.24/arch/powerpc/platforms/powermac/pfunc_base.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/powermac/pfunc_base.c	2008-01-28 20:25:49.000000000 +0100
+@@ -363,8 +363,7 @@
+ 
+ 	return 0;
+ }
+-
+-arch_initcall(pmac_pfunc_base_install);
++machine_arch_initcall(powermac, pmac_pfunc_base_install);
+ 
+ #ifdef CONFIG_PM
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/powermac/pic.c powerpc.git/arch/powerpc/platforms/powermac/pic.c
+--- linux-2.6.24/arch/powerpc/platforms/powermac/pic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/powermac/pic.c	2008-01-28 20:25:49.000000000 +0100
+@@ -690,6 +690,5 @@
+ 	sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
+ 	return 0;
+ }
+-
+-subsys_initcall(init_pmacpic_sysfs);
++machine_subsys_initcall(powermac, init_pmacpic_sysfs);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/powermac/pmac.h powerpc.git/arch/powerpc/platforms/powermac/pmac.h
+--- linux-2.6.24/arch/powerpc/platforms/powermac/pmac.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/powermac/pmac.h	2008-01-28 20:25:49.000000000 +0100
+@@ -26,7 +26,7 @@
+ extern void pmac_nvram_update(void);
+ extern unsigned char pmac_nvram_read_byte(int addr);
+ extern void pmac_nvram_write_byte(int addr, unsigned char val);
+-extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
++extern int pmac_pci_enable_device_hook(struct pci_dev *dev);
+ extern void pmac_pcibios_after_init(void);
+ extern int of_show_percpuinfo(struct seq_file *m, int i);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/powermac/setup.c powerpc.git/arch/powerpc/platforms/powermac/setup.c
+--- linux-2.6.24/arch/powerpc/platforms/powermac/setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/powermac/setup.c	2008-01-28 20:25:49.000000000 +0100
+@@ -51,6 +51,8 @@
+ #include <linux/root_dev.h>
+ #include <linux/bitops.h>
+ #include <linux/suspend.h>
++#include <linux/of_device.h>
++#include <linux/of_platform.h>
+ 
+ #include <asm/reg.h>
+ #include <asm/sections.h>
+@@ -68,8 +70,6 @@
+ #include <asm/btext.h>
+ #include <asm/pmac_feature.h>
+ #include <asm/time.h>
+-#include <asm/of_device.h>
+-#include <asm/of_platform.h>
+ #include <asm/mmu_context.h>
+ #include <asm/iommu.h>
+ #include <asm/smu.h>
+@@ -94,7 +94,6 @@
+ #define DEFAULT_ROOT_DEVICE Root_SDA1	/* sda1 - slightly silly choice */
+ 
+ #ifdef CONFIG_PPC64
+-#include <asm/udbg.h>
+ int sccdbg;
+ #endif
+ 
+@@ -398,17 +397,13 @@
+ 
+ static int pmac_late_init(void)
+ {
+-	if (!machine_is(powermac))
+-		return -ENODEV;
+-
+ 	initializing = 0;
+ 	/* this is udbg (which is __init) and we can later use it during
+ 	 * cpu hotplug (in smp_core99_kick_cpu) */
+ 	ppc_md.progress = NULL;
+ 	return 0;
+ }
+-
+-late_initcall(pmac_late_init);
++machine_late_initcall(powermac, pmac_late_init);
+ 
+ /*
+  * This is __init_refok because we check for "initializing" before
+@@ -535,9 +530,6 @@
+ 	if (machine_is(chrp))
+ 		return -1;
+ 
+-	if (!machine_is(powermac))
+-		return 0;
+-
+ 	np = of_find_node_by_name(NULL, "valkyrie");
+ 	if (np)
+ 		of_platform_device_create(np, "valkyrie", NULL);
+@@ -552,8 +544,7 @@
+ 
+ 	return 0;
+ }
+-
+-device_initcall(pmac_declare_of_platform_devices);
++machine_device_initcall(powermac, pmac_declare_of_platform_devices);
+ 
+ /*
+  * Called very early, MMU is off, device-tree isn't unflattened
+@@ -613,9 +604,11 @@
+ 
+ 	/* We need to use normal PCI probing for the AGP bus,
+ 	 * since the device for the AGP bridge isn't in the tree.
++	 * Same for the PCIe host on U4 and the HT host bridge.
+ 	 */
+ 	if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
+-				  of_device_is_compatible(node, "u4-pcie")))
++				  of_device_is_compatible(node, "u4-pcie") ||
++				  of_device_is_compatible(node, "u3-ht")))
+ 		return PCI_PROBE_NORMAL;
+ 	return PCI_PROBE_DEVTREE;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/powermac/time.c powerpc.git/arch/powerpc/platforms/powermac/time.c
+--- linux-2.6.24/arch/powerpc/platforms/powermac/time.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/powermac/time.c	2008-01-28 20:25:49.000000000 +0100
+@@ -84,12 +84,14 @@
+ 	return delta;
+ }
+ 
++#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
+ static void to_rtc_time(unsigned long now, struct rtc_time *tm)
+ {
+ 	to_tm(now, tm);
+ 	tm->tm_year -= 1900;
+ 	tm->tm_mon -= 1;
+ }
++#endif
+ 
+ static unsigned long from_rtc_time(struct rtc_time *tm)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/ps3/Kconfig powerpc.git/arch/powerpc/platforms/ps3/Kconfig
+--- linux-2.6.24/arch/powerpc/platforms/ps3/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/ps3/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -61,17 +61,6 @@
+ 	  This support is mainly for Linux kernel development.  If unsure,
+ 	  say N.
+ 
+-config PS3_USE_LPAR_ADDR
+-	depends on PPC_PS3 && EXPERIMENTAL
+-	bool "PS3 use lpar address space"
+-	default y
+-	help
+-	  This option is solely for experimentation by experts.  Disables
+-	  translation of lpar addresses.  SPE support currently won't work
+-	  without this set to y.
+-
+-	  If you have any doubt, choose the default y.
+-
+ config PS3_VUART
+ 	depends on PPC_PS3
+ 	tristate
+@@ -138,4 +127,17 @@
+ 	  be disabled on the kernel command line using "ps3flash=off", to
+ 	  not allocate this fixed buffer.
+ 
++config PS3_LPM
++	tristate "PS3 Logical Performance Monitor support"
++	depends on PPC_PS3
++	help
++	  Include support for the PS3 Logical Performance Monitor.
++
++	  This support is required to use the logical performance monitor
++	  of the PS3's LV1 hypervisor.
++
++	  If you intend to use the advanced performance monitoring and
++	  profiling support of the Cell processor with programs like
++	  oprofile and perfmon2, then say Y or M, otherwise say N.
++
+ endmenu
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/ps3/device-init.c powerpc.git/arch/powerpc/platforms/ps3/device-init.c
+--- linux-2.6.24/arch/powerpc/platforms/ps3/device-init.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/ps3/device-init.c	2008-01-28 20:25:49.000000000 +0100
+@@ -23,6 +23,7 @@
+ #include <linux/kernel.h>
+ #include <linux/kthread.h>
+ #include <linux/init.h>
++#include <linux/reboot.h>
+ 
+ #include <asm/firmware.h>
+ #include <asm/lv1call.h>
+@@ -30,6 +31,89 @@
+ 
+ #include "platform.h"
+ 
++static int __init ps3_register_lpm_devices(void)
++{
++	int result;
++	u64 tmp1;
++	u64 tmp2;
++	struct ps3_system_bus_device *dev;
++
++	pr_debug(" -> %s:%d\n", __func__, __LINE__);
++
++	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
++	if (!dev)
++		return -ENOMEM;
++
++	dev->match_id = PS3_MATCH_ID_LPM;
++	dev->dev_type = PS3_DEVICE_TYPE_LPM;
++
++	/* The current lpm driver only supports a single BE processor. */
++
++	result = ps3_repository_read_be_node_id(0, &dev->lpm.node_id);
++
++	if (result) {
++		pr_debug("%s:%d: ps3_repository_read_be_node_id failed \n",
++			__func__, __LINE__);
++		goto fail_read_repo;
++	}
++
++	result = ps3_repository_read_lpm_privileges(dev->lpm.node_id, &tmp1,
++		&dev->lpm.rights);
++
++	if (result) {
++		pr_debug("%s:%d: ps3_repository_read_lpm_privleges failed \n",
++			__func__, __LINE__);
++		goto fail_read_repo;
++	}
++
++	lv1_get_logical_partition_id(&tmp2);
++
++	if (tmp1 != tmp2) {
++		pr_debug("%s:%d: wrong lpar\n",
++			__func__, __LINE__);
++		result = -ENODEV;
++		goto fail_rights;
++	}
++
++	if (!(dev->lpm.rights & PS3_LPM_RIGHTS_USE_LPM)) {
++		pr_debug("%s:%d: don't have rights to use lpm\n",
++			__func__, __LINE__);
++		result = -EPERM;
++		goto fail_rights;
++	}
++
++	pr_debug("%s:%d: pu_id %lu, rights %lu(%lxh)\n",
++		__func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights,
++		dev->lpm.rights);
++
++	result = ps3_repository_read_pu_id(0, &dev->lpm.pu_id);
++
++	if (result) {
++		pr_debug("%s:%d: ps3_repository_read_pu_id failed \n",
++			__func__, __LINE__);
++		goto fail_read_repo;
++	}
++
++	result = ps3_system_bus_device_register(dev);
++
++	if (result) {
++		pr_debug("%s:%d ps3_system_bus_device_register failed\n",
++			__func__, __LINE__);
++		goto fail_register;
++	}
++
++	pr_debug(" <- %s:%d\n", __func__, __LINE__);
++	return 0;
++
++
++fail_register:
++fail_rights:
++fail_read_repo:
++	kfree(dev);
++	pr_debug(" <- %s:%d: failed\n", __func__, __LINE__);
++	return result;
++}
++
+ /**
+  * ps3_setup_gelic_device - Setup and register a gelic device instance.
+  *
+@@ -238,166 +322,6 @@
+ 	return result;
+ }
+ 
+-static int ps3stor_wait_for_completion(u64 dev_id, u64 tag,
+-				       unsigned int timeout)
+-{
+-	int result = -1;
+-	unsigned int retries = 0;
+-	u64 status;
+-
+-	for (retries = 0; retries < timeout; retries++) {
+-		result = lv1_storage_check_async_status(dev_id, tag, &status);
+-		if (!result)
+-			break;
+-
+-		msleep(1);
+-	}
+-
+-	if (result)
+-		pr_debug("%s:%u: check_async_status: %s, status %lx\n",
+-			 __func__, __LINE__, ps3_result(result), status);
+-
+-	return result;
+-}
+-
+-/**
+- * ps3_storage_wait_for_device - Wait for a storage device to become ready.
+- * @repo: The repository device to wait for.
+- *
+- * Uses the hypervisor's storage device notification mechanism to wait until
+- * a storage device is ready.  The device notification mechanism uses a
+- * psuedo device (id = -1) to asynchronously notify the guest when storage
+- * devices become ready.  The notification device has a block size of 512
+- * bytes.
+- */
+-
+-static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
+-{
+-	int error = -ENODEV;
+-	int result;
+-	const u64 notification_dev_id = (u64)-1LL;
+-	const unsigned int timeout = HZ;
+-	u64 lpar;
+-	u64 tag;
+-	void *buf;
+-	enum ps3_notify_type {
+-		notify_device_ready = 0,
+-		notify_region_probe = 1,
+-		notify_region_update = 2,
+-	};
+-	struct {
+-		u64 operation_code;	/* must be zero */
+-		u64 event_mask;		/* OR of 1UL << enum ps3_notify_type */
+-	} *notify_cmd;
+-	struct {
+-		u64 event_type;		/* enum ps3_notify_type */
+-		u64 bus_id;
+-		u64 dev_id;
+-		u64 dev_type;
+-		u64 dev_port;
+-	} *notify_event;
+-
+-	pr_debug(" -> %s:%u: (%u:%u:%u)\n", __func__, __LINE__, repo->bus_id,
+-		 repo->dev_id, repo->dev_type);
+-
+-	buf = kzalloc(512, GFP_KERNEL);
+-	if (!buf)
+-		return -ENOMEM;
+-
+-	lpar = ps3_mm_phys_to_lpar(__pa(buf));
+-	notify_cmd = buf;
+-	notify_event = buf;
+-
+-	result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
+-	if (result) {
+-		printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
+-		       __LINE__, ps3_result(result));
+-		goto fail_free;
+-	}
+-
+-	/* Setup and write the request for device notification. */
+-
+-	notify_cmd->operation_code = 0; /* must be zero */
+-	notify_cmd->event_mask = 1UL << notify_region_probe;
+-
+-	result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
+-				   &tag);
+-	if (result) {
+-		printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
+-		       ps3_result(result));
+-		goto fail_close;
+-	}
+-
+-	/* Wait for the write completion */
+-
+-	result = ps3stor_wait_for_completion(notification_dev_id, tag,
+-					     timeout);
+-	if (result) {
+-		printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
+-		       __LINE__, ps3_result(result));
+-		goto fail_close;
+-	}
+-
+-	/* Loop here processing the requested notification events. */
+-
+-	while (1) {
+-		memset(notify_event, 0, sizeof(*notify_event));
+-
+-		result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0,
+-					  lpar, &tag);
+-		if (result) {
+-			printk(KERN_ERR "%s:%u: write failed %s\n", __func__,
+-			       __LINE__, ps3_result(result));
+-			break;
+-		}
+-
+-		result = ps3stor_wait_for_completion(notification_dev_id, tag,
+-						     timeout);
+-		if (result) {
+-			printk(KERN_ERR "%s:%u: read not completed %s\n",
+-			       __func__, __LINE__, ps3_result(result));
+-			break;
+-		}
+-
+-		pr_debug("%s:%d: notify event (%u:%u:%u): event_type 0x%lx, "
+-			 "port %lu\n", __func__, __LINE__, repo->bus_index,
+-			 repo->dev_index, repo->dev_type,
+-			 notify_event->event_type, notify_event->dev_port);
+-
+-		if (notify_event->event_type != notify_region_probe ||
+-		    notify_event->bus_id != repo->bus_id) {
+-			pr_debug("%s:%u: bad notify_event: event %lu, "
+-				 "dev_id %lu, dev_type %lu\n",
+-				 __func__, __LINE__, notify_event->event_type,
+-				 notify_event->dev_id, notify_event->dev_type);
+-			break;
+-		}
+-
+-		if (notify_event->dev_id == repo->dev_id &&
+-		    notify_event->dev_type == repo->dev_type) {
+-			pr_debug("%s:%u: device ready (%u:%u:%u)\n", __func__,
+-				 __LINE__, repo->bus_index, repo->dev_index,
+-				 repo->dev_type);
+-			error = 0;
+-			break;
+-		}
+-
+-		if (notify_event->dev_id == repo->dev_id &&
+-		    notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) {
+-			pr_debug("%s:%u: no access: dev_id %u\n", __func__,
+-				 __LINE__, repo->dev_id);
+-			break;
+-		}
+-	}
+-
+-fail_close:
+-	lv1_close_device(repo->bus_id, notification_dev_id);
+-fail_free:
+-	kfree(buf);
+-	pr_debug(" <- %s:%u\n", __func__, __LINE__);
+-	return error;
+-}
+-
+ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
+ 				 enum ps3_match_id match_id)
+ {
+@@ -449,16 +373,6 @@
+ 		goto fail_find_interrupt;
+ 	}
+ 
+-	/* FIXME: Arrange to only do this on a 'cold' boot */
+-
+-	result = ps3_storage_wait_for_device(repo);
+-	if (result) {
+-		printk(KERN_ERR "%s:%u: storage_notification failed %d\n",
+-		       __func__, __LINE__, result);
+-		result = -ENODEV;
+-		goto fail_probe_notification;
+-	}
+-
+ 	for (i = 0; i < num_regions; i++) {
+ 		unsigned int id;
+ 		u64 start, size;
+@@ -494,7 +408,6 @@
+ 
+ fail_device_register:
+ fail_read_region:
+-fail_probe_notification:
+ fail_find_interrupt:
+ 	kfree(p);
+ fail_malloc:
+@@ -659,62 +572,268 @@
+ 	return result;
+ }
+ 
++static void ps3_find_and_add_device(u64 bus_id, u64 dev_id)
++{
++	struct ps3_repository_device repo;
++	int res;
++	unsigned int retries;
++	unsigned long rem;
++
++	/*
++	 * On some firmware versions (e.g. 1.90), the device may not show up
++	 * in the repository immediately
++	 */
++	for (retries = 0; retries < 10; retries++) {
++		res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id);
++		if (!res)
++			goto found;
++
++		rem = msleep_interruptible(100);
++		if (rem)
++			break;
++	}
++	pr_warning("%s:%u: device %lu:%lu not found\n", __func__, __LINE__,
++		   bus_id, dev_id);
++	return;
++
++found:
++	if (retries)
++		pr_debug("%s:%u: device %lu:%lu found after %u retries\n",
++			 __func__, __LINE__, bus_id, dev_id, retries);
++
++	ps3_register_repository_device(&repo);
++	return;
++}
++
++#define PS3_NOTIFICATION_DEV_ID		ULONG_MAX
++#define PS3_NOTIFICATION_INTERRUPT_ID	0
++
++struct ps3_notification_device {
++	struct ps3_system_bus_device sbd;
++	spinlock_t lock;
++	u64 tag;
++	u64 lv1_status;
++	struct completion done;
++};
++
++enum ps3_notify_type {
++	notify_device_ready = 0,
++	notify_region_probe = 1,
++	notify_region_update = 2,
++};
++
++struct ps3_notify_cmd {
++	u64 operation_code;		/* must be zero */
++	u64 event_mask;			/* OR of 1UL << enum ps3_notify_type */
++};
++
++struct ps3_notify_event {
++	u64 event_type;			/* enum ps3_notify_type */
++	u64 bus_id;
++	u64 dev_id;
++	u64 dev_type;
++	u64 dev_port;
++};
++
++static irqreturn_t ps3_notification_interrupt(int irq, void *data)
++{
++	struct ps3_notification_device *dev = data;
++	int res;
++	u64 tag, status;
++
++	spin_lock(&dev->lock);
++	res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag,
++					   &status);
++	if (tag != dev->tag)
++		pr_err("%s:%u: tag mismatch, got %lx, expected %lx\n",
++		       __func__, __LINE__, tag, dev->tag);
++
++	if (res) {
++		pr_err("%s:%u: res %d status 0x%lx\n", __func__, __LINE__, res,
++		       status);
++	} else {
++		pr_debug("%s:%u: completed, status 0x%lx\n", __func__,
++			 __LINE__, status);
++		dev->lv1_status = status;
++		complete(&dev->done);
++	}
++	spin_unlock(&dev->lock);
++	return IRQ_HANDLED;
++}
++
++static int ps3_notification_read_write(struct ps3_notification_device *dev,
++				       u64 lpar, int write)
++{
++	const char *op = write ? "write" : "read";
++	unsigned long flags;
++	int res;
++
++	init_completion(&dev->done);
++	spin_lock_irqsave(&dev->lock, flags);
++	res = write ? lv1_storage_write(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
++					&dev->tag)
++		    : lv1_storage_read(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
++				       &dev->tag);
++	spin_unlock_irqrestore(&dev->lock, flags);
++	if (res) {
++		pr_err("%s:%u: %s failed %d\n", __func__, __LINE__, op, res);
++		return -EPERM;
++	}
++	pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op);
++
++	res = wait_event_interruptible(dev->done.wait,
++				       dev->done.done || kthread_should_stop());
++	if (kthread_should_stop())
++		res = -EINTR;
++	if (res) {
++		pr_debug("%s:%u: interrupted %s\n", __func__, __LINE__, op);
++		return res;
++	}
++
++	if (dev->lv1_status) {
++		pr_err("%s:%u: %s not completed, status 0x%lx\n", __func__,
++		       __LINE__, op, dev->lv1_status);
++		return -EIO;
++	}
++	pr_debug("%s:%u: notification %s completed\n", __func__, __LINE__, op);
++
++	return 0;
++}
++
++static struct task_struct *probe_task;
++
+ /**
+  * ps3_probe_thread - Background repository probing at system startup.
+  *
+  * This implementation only supports background probing on a single bus.
++ * It uses the hypervisor's storage device notification mechanism to wait until
++ * a storage device is ready.  The device notification mechanism uses a
++ * pseudo device to asynchronously notify the guest when storage devices become
++ * ready.  The notification device has a block size of 512 bytes.
+  */
+ 
+ static int ps3_probe_thread(void *data)
+ {
+-	struct ps3_repository_device *repo = data;
+-	int result;
+-	unsigned int ms = 250;
++	struct ps3_notification_device dev;
++	int res;
++	unsigned int irq;
++	u64 lpar;
++	void *buf;
++	struct ps3_notify_cmd *notify_cmd;
++	struct ps3_notify_event *notify_event;
+ 
+ 	pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
+ 
+-	do {
+-		try_to_freeze();
++	buf = kzalloc(512, GFP_KERNEL);
++	if (!buf)
++		return -ENOMEM;
+ 
+-		pr_debug("%s:%u: probing...\n", __func__, __LINE__);
++	lpar = ps3_mm_phys_to_lpar(__pa(buf));
++	notify_cmd = buf;
++	notify_event = buf;
++
++	/* dummy system bus device */
++	dev.sbd.bus_id = (u64)data;
++	dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
++	dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
++
++	res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0);
++	if (res) {
++		pr_err("%s:%u: lv1_open_device failed %s\n", __func__,
++		       __LINE__, ps3_result(res));
++		goto fail_free;
++	}
++
++	res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY,
++					      &irq);
++	if (res) {
++		pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
++		       __func__, __LINE__, res);
++	       goto fail_close_device;
++	}
++
++	spin_lock_init(&dev.lock);
++
++	res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED,
++			  "ps3_notification", &dev);
++	if (res) {
++		pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
++		       res);
++		goto fail_sb_event_receive_port_destroy;
++	}
++
++	/* Setup and write the request for device notification. */
++	notify_cmd->operation_code = 0; /* must be zero */
++	notify_cmd->event_mask = 1UL << notify_region_probe;
+ 
+-		do {
+-			result = ps3_repository_find_device(repo);
++	res = ps3_notification_read_write(&dev, lpar, 1);
++	if (res)
++		goto fail_free_irq;
+ 
+-			if (result == -ENODEV)
+-				pr_debug("%s:%u: nothing new\n", __func__,
+-					__LINE__);
+-			else if (result)
+-				pr_debug("%s:%u: find device error.\n",
+-					__func__, __LINE__);
+-			else {
+-				pr_debug("%s:%u: found device (%u:%u:%u)\n",
+-					 __func__, __LINE__, repo->bus_index,
+-					 repo->dev_index, repo->dev_type);
+-				ps3_register_repository_device(repo);
+-				ps3_repository_bump_device(repo);
+-				ms = 250;
+-			}
+-		} while (!result);
++	/* Loop here processing the requested notification events. */
++	do {
++		try_to_freeze();
+ 
+-		pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms);
++		memset(notify_event, 0, sizeof(*notify_event));
+ 
+-		if ( ms > 60000)
++		res = ps3_notification_read_write(&dev, lpar, 0);
++		if (res)
+ 			break;
+ 
+-		msleep_interruptible(ms);
++		pr_debug("%s:%u: notify event type 0x%lx bus id %lu dev id %lu"
++			 " type %lu port %lu\n", __func__, __LINE__,
++			 notify_event->event_type, notify_event->bus_id,
++			 notify_event->dev_id, notify_event->dev_type,
++			 notify_event->dev_port);
++
++		if (notify_event->event_type != notify_region_probe ||
++		    notify_event->bus_id != dev.sbd.bus_id) {
++			pr_warning("%s:%u: bad notify_event: event %lu, "
++				   "dev_id %lu, dev_type %lu\n",
++				   __func__, __LINE__, notify_event->event_type,
++				   notify_event->dev_id,
++				   notify_event->dev_type);
++			continue;
++		}
+ 
+-		/* An exponential backoff. */
+-		ms <<= 1;
++		ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id);
+ 
+ 	} while (!kthread_should_stop());
+ 
++fail_free_irq:
++	free_irq(irq, &dev);
++fail_sb_event_receive_port_destroy:
++	ps3_sb_event_receive_port_destroy(&dev.sbd, irq);
++fail_close_device:
++	lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id);
++fail_free:
++	kfree(buf);
++
++	probe_task = NULL;
++
+ 	pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
+ 
+ 	return 0;
+ }
+ 
+ /**
++ * ps3_stop_probe_thread - Stops the background probe thread.
++ *
++ */
++
++static int ps3_stop_probe_thread(struct notifier_block *nb, unsigned long code,
++				 void *data)
++{
++	if (probe_task)
++		kthread_stop(probe_task);
++	return 0;
++}
++
++static struct notifier_block nb = {
++	.notifier_call = ps3_stop_probe_thread
++};
++
++/**
+  * ps3_start_probe_thread - Starts the background probe thread.
+  *
+  */
+@@ -723,7 +842,7 @@
+ {
+ 	int result;
+ 	struct task_struct *task;
+-	static struct ps3_repository_device repo; /* must be static */
++	struct ps3_repository_device repo;
+ 
+ 	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+ 
+@@ -746,7 +865,8 @@
+ 		return -ENODEV;
+ 	}
+ 
+-	task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type);
++	task = kthread_run(ps3_probe_thread, (void *)repo.bus_id,
++			   "ps3-probe-%u", bus_type);
+ 
+ 	if (IS_ERR(task)) {
+ 		result = PTR_ERR(task);
+@@ -755,6 +875,9 @@
+ 		return result;
+ 	}
+ 
++	probe_task = task;
++	register_reboot_notifier(&nb);
++
+ 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ 	return 0;
+ }
+@@ -787,6 +910,8 @@
+ 
+ 	ps3_register_sound_devices();
+ 
++	ps3_register_lpm_devices();
++
+ 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ 	return 0;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/ps3/mm.c powerpc.git/arch/powerpc/platforms/ps3/mm.c
+--- linux-2.6.24/arch/powerpc/platforms/ps3/mm.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/ps3/mm.c	2008-01-28 20:25:49.000000000 +0100
+@@ -36,11 +36,6 @@
+ #endif
+ 
+ enum {
+-#if defined(CONFIG_PS3_USE_LPAR_ADDR)
+-	USE_LPAR_ADDR = 1,
+-#else
+-	USE_LPAR_ADDR = 0,
+-#endif
+ #if defined(CONFIG_PS3_DYNAMIC_DMA)
+ 	USE_DYNAMIC_DMA = 1,
+ #else
+@@ -137,11 +132,8 @@
+ unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr)
+ {
+ 	BUG_ON(is_kernel_addr(phys_addr));
+-	if (USE_LPAR_ADDR)
+-		return phys_addr;
+-	else
+-		return (phys_addr < map.rm.size || phys_addr >= map.total)
+-			? phys_addr : phys_addr + map.r1.offset;
++	return (phys_addr < map.rm.size || phys_addr >= map.total)
++		? phys_addr : phys_addr + map.r1.offset;
+ }
+ 
+ EXPORT_SYMBOL(ps3_mm_phys_to_lpar);
+@@ -309,7 +301,7 @@
+ 
+ 	BUG_ON(!mem_init_done);
+ 
+-	start_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size;
++	start_addr = map.rm.size;
+ 	start_pfn = start_addr >> PAGE_SHIFT;
+ 	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ 
+@@ -359,7 +351,7 @@
+ static void  __maybe_unused _dma_dump_region(const struct ps3_dma_region *r,
+ 	const char *func, int line)
+ {
+-	DBG("%s:%d: dev        %u:%u\n", func, line, r->dev->bus_id,
++	DBG("%s:%d: dev        %lu:%lu\n", func, line, r->dev->bus_id,
+ 		r->dev->dev_id);
+ 	DBG("%s:%d: page_size  %u\n", func, line, r->page_size);
+ 	DBG("%s:%d: bus_addr   %lxh\n", func, line, r->bus_addr);
+@@ -394,7 +386,7 @@
+ static void _dma_dump_chunk (const struct dma_chunk* c, const char* func,
+ 	int line)
+ {
+-	DBG("%s:%d: r.dev        %u:%u\n", func, line,
++	DBG("%s:%d: r.dev        %lu:%lu\n", func, line,
+ 		c->region->dev->bus_id, c->region->dev->dev_id);
+ 	DBG("%s:%d: r.bus_addr   %lxh\n", func, line, c->region->bus_addr);
+ 	DBG("%s:%d: r.page_size  %u\n", func, line, c->region->page_size);
+@@ -658,7 +650,7 @@
+ 	BUG_ON(!r);
+ 
+ 	if (!r->dev->bus_id) {
+-		pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
++		pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__,
+ 			r->dev->bus_id, r->dev->dev_id);
+ 		return 0;
+ 	}
+@@ -724,7 +716,7 @@
+ 	BUG_ON(!r);
+ 
+ 	if (!r->dev->bus_id) {
+-		pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
++		pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__,
+ 			r->dev->bus_id, r->dev->dev_id);
+ 		return 0;
+ 	}
+@@ -1007,7 +999,7 @@
+ 
+ 	if (r->offset + r->len > map.rm.size) {
+ 		/* Map (part of) 2nd RAM chunk */
+-		virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size;
++		virt_addr = map.rm.size;
+ 		len = r->len;
+ 		if (r->offset >= map.rm.size)
+ 			virt_addr += r->offset - map.rm.size;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/ps3/platform.h powerpc.git/arch/powerpc/platforms/ps3/platform.h
+--- linux-2.6.24/arch/powerpc/platforms/ps3/platform.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/ps3/platform.h	2008-01-28 20:25:49.000000000 +0100
+@@ -89,13 +89,11 @@
+ 	PS3_DEV_TYPE_STOR_ROM = TYPE_ROM,	/* 5 */
+ 	PS3_DEV_TYPE_SB_GPIO = 6,
+ 	PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC,	/* 14 */
+-	PS3_DEV_TYPE_STOR_DUMMY = 32,
+-	PS3_DEV_TYPE_NOACCESS = 255,
+ };
+ 
+ int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
+ 	u64 *value);
+-int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id);
++int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id);
+ int ps3_repository_read_bus_type(unsigned int bus_index,
+ 	enum ps3_bus_type *bus_type);
+ int ps3_repository_read_bus_num_dev(unsigned int bus_index,
+@@ -119,7 +117,7 @@
+ int ps3_repository_read_dev_str(unsigned int bus_index,
+ 	unsigned int dev_index, const char *dev_str, u64 *value);
+ int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
+-	unsigned int *dev_id);
++	u64 *dev_id);
+ int ps3_repository_read_dev_type(unsigned int bus_index,
+ 	unsigned int dev_index, enum ps3_dev_type *dev_type);
+ int ps3_repository_read_dev_intr(unsigned int bus_index,
+@@ -138,21 +136,17 @@
+ /* repository bus enumerators */
+ 
+ struct ps3_repository_device {
+-	enum ps3_bus_type bus_type;
+ 	unsigned int bus_index;
+-	unsigned int bus_id;
+-	enum ps3_dev_type dev_type;
+ 	unsigned int dev_index;
+-	unsigned int dev_id;
++	enum ps3_bus_type bus_type;
++	enum ps3_dev_type dev_type;
++	u64 bus_id;
++	u64 dev_id;
+ };
+ 
+-static inline struct ps3_repository_device *ps3_repository_bump_device(
+-	struct ps3_repository_device *repo)
+-{
+-	repo->dev_index++;
+-	return repo;
+-}
+ int ps3_repository_find_device(struct ps3_repository_device *repo);
++int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
++				     u64 bus_id, u64 dev_id);
+ int ps3_repository_find_devices(enum ps3_bus_type bus_type,
+ 	int (*callback)(const struct ps3_repository_device *repo));
+ int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
+@@ -186,10 +180,10 @@
+ 	unsigned int dev_index, unsigned int region_index,
+ 	unsigned int *region_id, u64 *region_start, u64 *region_size);
+ 
+-/* repository pu and memory info */
++/* repository logical pu and memory info */
+ 
+-int ps3_repository_read_num_pu(unsigned int *num_pu);
+-int ps3_repository_read_ppe_id(unsigned int *pu_index, unsigned int *ppe_id);
++int ps3_repository_read_num_pu(u64 *num_pu);
++int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id);
+ int ps3_repository_read_rm_base(unsigned int ppe_id, u64 *rm_base);
+ int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size);
+ int ps3_repository_read_region_total(u64 *region_total);
+@@ -200,9 +194,15 @@
+ 
+ int ps3_repository_read_num_be(unsigned int *num_be);
+ int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id);
++int ps3_repository_read_be_id(u64 node_id, u64 *be_id);
+ int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq);
+ int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq);
+ 
++/* repository performance monitor info */
++
++int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
++	u64 *rights);
++
+ /* repository 'Other OS' area */
+ 
+ int ps3_repository_read_boot_dat_addr(u64 *lpar_addr);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/ps3/repository.c powerpc.git/arch/powerpc/platforms/ps3/repository.c
+--- linux-2.6.24/arch/powerpc/platforms/ps3/repository.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/ps3/repository.c	2008-01-28 20:25:49.000000000 +0100
+@@ -33,7 +33,7 @@
+ };
+ 
+ #define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__)
+-static void _dump_field(const char *hdr, u64 n, const char* func, int line)
++static void _dump_field(const char *hdr, u64 n, const char *func, int line)
+ {
+ #if defined(DEBUG)
+ 	char s[16];
+@@ -50,8 +50,8 @@
+ 
+ #define dump_node_name(_a, _b, _c, _d, _e) \
+ 	_dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__)
+-static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
+-	u64 n4, const char* func, int line)
++static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
++	u64 n4, const char *func, int line)
+ {
+ 	pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
+ 	_dump_field("n1: ", n1, func, line);
+@@ -63,7 +63,7 @@
+ #define dump_node(_a, _b, _c, _d, _e, _f, _g) \
+ 	_dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
+ static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
+-	u64 v1, u64 v2, const char* func, int line)
++	u64 v1, u64 v2, const char *func, int line)
+ {
+ 	pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
+ 	_dump_field("n1: ", n1, func, line);
+@@ -165,21 +165,18 @@
+ 		make_first_field("bus", bus_index),
+ 		make_field(bus_str, 0),
+ 		0, 0,
+-		value, 0);
++		value, NULL);
+ }
+ 
+-int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id)
++int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id)
+ {
+ 	int result;
+-	u64 v1;
+-	u64 v2; /* unused */
+ 
+ 	result = read_node(PS3_LPAR_ID_PME,
+ 		make_first_field("bus", bus_index),
+ 		make_field("id", 0),
+ 		0, 0,
+-		&v1, &v2);
+-	*bus_id = v1;
++		bus_id, NULL);
+ 	return result;
+ }
+ 
+@@ -193,7 +190,7 @@
+ 		make_first_field("bus", bus_index),
+ 		make_field("type", 0),
+ 		0, 0,
+-		&v1, 0);
++		&v1, NULL);
+ 	*bus_type = v1;
+ 	return result;
+ }
+@@ -208,7 +205,7 @@
+ 		make_first_field("bus", bus_index),
+ 		make_field("num_dev", 0),
+ 		0, 0,
+-		&v1, 0);
++		&v1, NULL);
+ 	*num_dev = v1;
+ 	return result;
+ }
+@@ -221,22 +218,20 @@
+ 		make_field("dev", dev_index),
+ 		make_field(dev_str, 0),
+ 		0,
+-		value, 0);
++		value, NULL);
+ }
+ 
+ int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
+-	unsigned int *dev_id)
++	u64 *dev_id)
+ {
+ 	int result;
+-	u64 v1;
+ 
+ 	result = read_node(PS3_LPAR_ID_PME,
+ 		make_first_field("bus", bus_index),
+ 		make_field("dev", dev_index),
+ 		make_field("id", 0),
+ 		0,
+-		&v1, 0);
+-	*dev_id = v1;
++		dev_id, NULL);
+ 	return result;
+ }
+ 
+@@ -251,14 +246,14 @@
+ 		make_field("dev", dev_index),
+ 		make_field("type", 0),
+ 		0,
+-		&v1, 0);
++		&v1, NULL);
+ 	*dev_type = v1;
+ 	return result;
+ }
+ 
+ int ps3_repository_read_dev_intr(unsigned int bus_index,
+ 	unsigned int dev_index, unsigned int intr_index,
+-	enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id)
++	enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id)
+ {
+ 	int result;
+ 	u64 v1;
+@@ -287,7 +282,7 @@
+ 		make_field("dev", dev_index),
+ 		make_field("reg", reg_index),
+ 		make_field("type", 0),
+-		&v1, 0);
++		&v1, NULL);
+ 	*reg_type = v1;
+ 	return result;
+ }
+@@ -332,7 +327,7 @@
+ 		return result;
+ 	}
+ 
+-	pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n",
++	pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %lu, num_dev %u\n",
+ 		__func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
+ 		num_dev);
+ 
+@@ -349,47 +344,95 @@
+ 		return result;
+ 	}
+ 
+-	if (tmp.bus_type == PS3_BUS_TYPE_STORAGE) {
+-		/*
+-		 * A storage device may show up in the repository before the
+-		 * hypervisor has finished probing its type and regions
+-		 */
+-		unsigned int num_regions;
+-
+-		if (tmp.dev_type == PS3_DEV_TYPE_STOR_DUMMY) {
+-			pr_debug("%s:%u storage device not ready\n", __func__,
+-				 __LINE__);
+-			return -ENODEV;
+-		}
++	result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
++		&tmp.dev_id);
+ 
+-		result = ps3_repository_read_stor_dev_num_regions(tmp.bus_index,
+-								  tmp.dev_index,
+-								  &num_regions);
++	if (result) {
++		pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__,
++		__LINE__);
++		return result;
++	}
++
++	pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %lu\n",
++		__func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
++
++	*repo = tmp;
++	return 0;
++}
++
++int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
++				     u64 bus_id, u64 dev_id)
++{
++	int result = -ENODEV;
++	struct ps3_repository_device tmp;
++	unsigned int num_dev;
++
++	pr_debug(" -> %s:%u: find device by id %lu:%lu\n", __func__, __LINE__,
++		 bus_id, dev_id);
++
++	for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) {
++		result = ps3_repository_read_bus_id(tmp.bus_index,
++						    &tmp.bus_id);
+ 		if (result) {
+-			pr_debug("%s:%d read_stor_dev_num_regions failed\n",
+-				 __func__, __LINE__);
++			pr_debug("%s:%u read_bus_id(%u) failed\n", __func__,
++				 __LINE__, tmp.bus_index);
+ 			return result;
+ 		}
+ 
+-		if (!num_regions) {
+-			pr_debug("%s:%u storage device has no regions yet\n",
+-				 __func__, __LINE__);
+-			return -ENODEV;
+-		}
++		if (tmp.bus_id == bus_id)
++			goto found_bus;
++
++		pr_debug("%s:%u: skip, bus_id %lu\n", __func__, __LINE__,
++			 tmp.bus_id);
+ 	}
++	pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__);
++	return result;
+ 
+-	result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
+-		&tmp.dev_id);
++found_bus:
++	result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type);
++	if (result) {
++		pr_debug("%s:%u read_bus_type(%u) failed\n", __func__,
++			 __LINE__, tmp.bus_index);
++		return result;
++	}
+ 
++	result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
+ 	if (result) {
+-		pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__,
+-		__LINE__);
++		pr_debug("%s:%u read_bus_num_dev failed\n", __func__,
++			 __LINE__);
+ 		return result;
+ 	}
+ 
+-	pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n",
+-		__func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
++	for (tmp.dev_index = 0; tmp.dev_index < num_dev; tmp.dev_index++) {
++		result = ps3_repository_read_dev_id(tmp.bus_index,
++						    tmp.dev_index,
++						    &tmp.dev_id);
++		if (result) {
++			pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__,
++				 __LINE__, tmp.bus_index, tmp.dev_index);
++			return result;
++		}
++
++		if (tmp.dev_id == dev_id)
++			goto found_dev;
++
++		pr_debug("%s:%u: skip, dev_id %lu\n", __func__, __LINE__,
++			 tmp.dev_id);
++	}
++	pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__);
++	return result;
++
++found_dev:
++	result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
++					      &tmp.dev_type);
++	if (result) {
++		pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__);
++		return result;
++	}
+ 
++	pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%lu:%lu)\n",
++		 __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index,
++		 tmp.dev_index, tmp.bus_id, tmp.dev_id);
+ 	*repo = tmp;
+ 	return 0;
+ }
+@@ -402,50 +445,34 @@
+ 
+ 	pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
+ 
+-	for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
++	repo.bus_type = bus_type;
++	result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
++	if (result) {
++		pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__);
++		return result;
++	}
+ 
+-		result = ps3_repository_read_bus_type(repo.bus_index,
+-			&repo.bus_type);
++	result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
++	if (result) {
++		pr_debug("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__,
++			 repo.bus_index);
++		return result;
++	}
+ 
+-		if (result) {
+-			pr_debug("%s:%d read_bus_type(%u) failed\n",
+-				__func__, __LINE__, repo.bus_index);
++	for (repo.dev_index = 0; ; repo.dev_index++) {
++		result = ps3_repository_find_device(&repo);
++		if (result == -ENODEV) {
++			result = 0;
++			break;
++		} else if (result)
+ 			break;
+-		}
+-
+-		if (repo.bus_type != bus_type) {
+-			pr_debug("%s:%d: skip, bus_type %u\n", __func__,
+-				__LINE__, repo.bus_type);
+-			continue;
+-		}
+-
+-		result = ps3_repository_read_bus_id(repo.bus_index,
+-			&repo.bus_id);
+ 
++		result = callback(&repo);
+ 		if (result) {
+-			pr_debug("%s:%d read_bus_id(%u) failed\n",
+-				__func__, __LINE__, repo.bus_index);
+-			continue;
+-		}
+-
+-		for (repo.dev_index = 0; ; repo.dev_index++) {
+-			result = ps3_repository_find_device(&repo);
+-
+-			if (result == -ENODEV) {
+-				result = 0;
+-				break;
+-			} else if (result)
+-				break;
+-
+-			result = callback(&repo);
+-
+-			if (result) {
+-				pr_debug("%s:%d: abort at callback\n", __func__,
+-					__LINE__);
+-				break;
+-			}
++			pr_debug("%s:%d: abort at callback\n", __func__,
++				__LINE__);
++			break;
+ 		}
+-		break;
+ 	}
+ 
+ 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+@@ -561,7 +588,7 @@
+ 		make_first_field("bus", bus_index),
+ 		make_field("dev", dev_index),
+ 		make_field("port", 0),
+-		0, port, 0);
++		0, port, NULL);
+ }
+ 
+ int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,
+@@ -571,7 +598,7 @@
+ 		make_first_field("bus", bus_index),
+ 		make_field("dev", dev_index),
+ 		make_field("blk_size", 0),
+-		0, blk_size, 0);
++		0, blk_size, NULL);
+ }
+ 
+ int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,
+@@ -581,7 +608,7 @@
+ 		make_first_field("bus", bus_index),
+ 		make_field("dev", dev_index),
+ 		make_field("n_blocks", 0),
+-		0, num_blocks, 0);
++		0, num_blocks, NULL);
+ }
+ 
+ int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,
+@@ -594,7 +621,7 @@
+ 		make_first_field("bus", bus_index),
+ 		make_field("dev", dev_index),
+ 		make_field("n_regs", 0),
+-		0, &v1, 0);
++		0, &v1, NULL);
+ 	*num_regions = v1;
+ 	return result;
+ }
+@@ -611,7 +638,7 @@
+ 	    make_field("dev", dev_index),
+ 	    make_field("region", region_index),
+ 	    make_field("id", 0),
+-	    &v1, 0);
++	    &v1, NULL);
+ 	*region_id = v1;
+ 	return result;
+ }
+@@ -624,7 +651,7 @@
+ 	    make_field("dev", dev_index),
+ 	    make_field("region", region_index),
+ 	    make_field("size", 0),
+-	    region_size, 0);
++	    region_size, NULL);
+ }
+ 
+ int ps3_repository_read_stor_dev_region_start(unsigned int bus_index,
+@@ -635,7 +662,7 @@
+ 	    make_field("dev", dev_index),
+ 	    make_field("region", region_index),
+ 	    make_field("start", 0),
+-	    region_start, 0);
++	    region_start, NULL);
+ }
+ 
+ int ps3_repository_read_stor_dev_info(unsigned int bus_index,
+@@ -684,6 +711,35 @@
+ 	return result;
+ }
+ 
++/**
++ * ps3_repository_read_num_pu - Number of logical PU processors for this lpar.
++ */
++
++int ps3_repository_read_num_pu(u64 *num_pu)
++{
++	*num_pu = 0;
++	return read_node(PS3_LPAR_ID_CURRENT,
++			   make_first_field("bi", 0),
++			   make_field("pun", 0),
++			   0, 0,
++			   num_pu, NULL);
++}
++
++/**
++ * ps3_repository_read_pu_id - Read the logical PU id.
++ * @pu_index: Zero based index.
++ * @pu_id: The logical PU id.
++ */
++
++int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id)
++{
++	return read_node(PS3_LPAR_ID_CURRENT,
++		make_first_field("bi", 0),
++		make_field("pu", pu_index),
++		0, 0,
++		pu_id, NULL);
++}
++
+ int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
+ {
+ 	return read_node(PS3_LPAR_ID_CURRENT,
+@@ -691,7 +747,7 @@
+ 		make_field("pu", 0),
+ 		ppe_id,
+ 		make_field("rm_size", 0),
+-		rm_size, 0);
++		rm_size, NULL);
+ }
+ 
+ int ps3_repository_read_region_total(u64 *region_total)
+@@ -700,7 +756,7 @@
+ 		make_first_field("bi", 0),
+ 		make_field("rgntotal", 0),
+ 		0, 0,
+-		region_total, 0);
++		region_total, NULL);
+ }
+ 
+ /**
+@@ -736,7 +792,7 @@
+ 		make_first_field("bi", 0),
+ 		make_field("spun", 0),
+ 		0, 0,
+-		&v1, 0);
++		&v1, NULL);
+ 	*num_spu_reserved = v1;
+ 	return result;
+ }
+@@ -755,7 +811,7 @@
+ 		make_first_field("bi", 0),
+ 		make_field("spursvn", 0),
+ 		0, 0,
+-		&v1, 0);
++		&v1, NULL);
+ 	*num_resource_id = v1;
+ 	return result;
+ }
+@@ -768,7 +824,7 @@
+  */
+ 
+ int ps3_repository_read_spu_resource_id(unsigned int res_index,
+-	enum ps3_spu_resource_type* resource_type, unsigned int *resource_id)
++	enum ps3_spu_resource_type *resource_type, unsigned int *resource_id)
+ {
+ 	int result;
+ 	u64 v1;
+@@ -785,14 +841,14 @@
+ 	return result;
+ }
+ 
+-int ps3_repository_read_boot_dat_address(u64 *address)
++static int ps3_repository_read_boot_dat_address(u64 *address)
+ {
+ 	return read_node(PS3_LPAR_ID_CURRENT,
+ 		make_first_field("bi", 0),
+ 		make_field("boot_dat", 0),
+ 		make_field("address", 0),
+ 		0,
+-		address, 0);
++		address, NULL);
+ }
+ 
+ int ps3_repository_read_boot_dat_size(unsigned int *size)
+@@ -805,7 +861,7 @@
+ 		make_field("boot_dat", 0),
+ 		make_field("size", 0),
+ 		0,
+-		&v1, 0);
++		&v1, NULL);
+ 	*size = v1;
+ 	return result;
+ }
+@@ -820,7 +876,7 @@
+ 		make_field("vir_uart", 0),
+ 		make_field("port", 0),
+ 		make_field("avset", 0),
+-		&v1, 0);
++		&v1, NULL);
+ 	*port = v1;
+ 	return result;
+ }
+@@ -835,7 +891,7 @@
+ 		make_field("vir_uart", 0),
+ 		make_field("port", 0),
+ 		make_field("sysmgr", 0),
+-		&v1, 0);
++		&v1, NULL);
+ 	*port = v1;
+ 	return result;
+ }
+@@ -856,6 +912,10 @@
+ 		: ps3_repository_read_boot_dat_size(size);
+ }
+ 
++/**
++ * ps3_repository_read_num_be - Number of physical BE processors in the system.
++ */
++
+ int ps3_repository_read_num_be(unsigned int *num_be)
+ {
+ 	int result;
+@@ -866,11 +926,17 @@
+ 		0,
+ 		0,
+ 		0,
+-		&v1, 0);
++		&v1, NULL);
+ 	*num_be = v1;
+ 	return result;
+ }
+ 
++/**
++ * ps3_repository_read_be_node_id - Read the physical BE processor node id.
++ * @be_index: Zero based index.
++ * @node_id: The BE processor node id.
++ */
++
+ int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
+ {
+ 	return read_node(PS3_LPAR_ID_PME,
+@@ -878,7 +944,23 @@
+ 		0,
+ 		0,
+ 		0,
+-		node_id, 0);
++		node_id, NULL);
++}
++
++/**
++ * ps3_repository_read_be_id - Read the physical BE processor id.
++ * @node_id: The BE processor node id.
++ * @be_id: The BE processor id.
++ */
++
++int ps3_repository_read_be_id(u64 node_id, u64 *be_id)
++{
++	return read_node(PS3_LPAR_ID_PME,
++		make_first_field("be", 0),
++		node_id,
++		0,
++		0,
++		be_id, NULL);
+ }
+ 
+ int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
+@@ -888,7 +970,7 @@
+ 		node_id,
+ 		make_field("clock", 0),
+ 		0,
+-		tb_freq, 0);
++		tb_freq, NULL);
+ }
+ 
+ int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
+@@ -897,11 +979,29 @@
+ 	u64 node_id;
+ 
+ 	*tb_freq = 0;
+-	result = ps3_repository_read_be_node_id(0, &node_id);
++	result = ps3_repository_read_be_node_id(be_index, &node_id);
+ 	return result ? result
+ 		: ps3_repository_read_tb_freq(node_id, tb_freq);
+ }
+ 
++int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
++	u64 *rights)
++{
++	int result;
++	u64 node_id;
++
++	*lpar = 0;
++	*rights = 0;
++	result = ps3_repository_read_be_node_id(be_index, &node_id);
++	return result ? result
++		: read_node(PS3_LPAR_ID_PME,
++			    make_first_field("be", 0),
++			    node_id,
++			    make_field("lpm", 0),
++			    make_field("priv", 0),
++			    lpar, rights);
++}
++
+ #if defined(DEBUG)
+ 
+ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
+@@ -1034,7 +1134,7 @@
+ 			continue;
+ 		}
+ 
+-		pr_debug("%s:%d  (%u:%u): dev_type %u, dev_id %u\n", __func__,
++		pr_debug("%s:%d  (%u:%u): dev_type %u, dev_id %lu\n", __func__,
+ 			__LINE__, repo->bus_index, repo->dev_index,
+ 			repo->dev_type, repo->dev_id);
+ 
+@@ -1091,7 +1191,7 @@
+ 			continue;
+ 		}
+ 
+-		pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
++		pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n",
+ 			__func__, __LINE__, repo.bus_index, repo.bus_type,
+ 			repo.bus_id, num_dev);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/ps3/spu.c powerpc.git/arch/powerpc/platforms/ps3/spu.c
+--- linux-2.6.24/arch/powerpc/platforms/ps3/spu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/ps3/spu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -28,6 +28,7 @@
+ #include <asm/spu_priv1.h>
+ #include <asm/lv1call.h>
+ 
++#include "../cell/spufs/spufs.h"
+ #include "platform.h"
+ 
+ /* spu_management_ops */
+@@ -419,10 +420,34 @@
+ 	return 0;
+ }
+ 
++/**
++ * ps3_enable_spu - Enable SPU run control.
++ *
++ * An outstanding enhancement for the PS3 would be to add a guard to check
++ * for incorrect access to the spu problem state when the spu context is
++ * disabled.  This check could be implemented with a flag added to the spu
++ * context that would inhibit mapping problem state pages, and a routine
++ * to unmap spu problem state pages.  When the spu is enabled with
++ * ps3_enable_spu() the flag would be set allowing pages to be mapped,
++ * and when the spu is disabled with ps3_disable_spu() the flag would be
++ * cleared and the mapped problem state pages would be unmapped.
++ */
++
++static void ps3_enable_spu(struct spu_context *ctx)
++{
++}
++
++static void ps3_disable_spu(struct spu_context *ctx)
++{
++	ctx->ops->runcntl_stop(ctx);
++}
++
+ const struct spu_management_ops spu_management_ps3_ops = {
+ 	.enumerate_spus = ps3_enumerate_spus,
+ 	.create_spu = ps3_create_spu,
+ 	.destroy_spu = ps3_destroy_spu,
++	.enable_spu = ps3_enable_spu,
++	.disable_spu = ps3_disable_spu,
+ 	.init_affinity = ps3_init_affinity,
+ };
+ 
+@@ -505,8 +530,6 @@
+ 	static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK
+ 		| MFC_STATE1_PROBLEM_STATE_MASK);
+ 
+-	sr1 |= MFC_STATE1_MASTER_RUN_CONTROL_MASK;
+-
+ 	BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed));
+ 
+ 	spu_pdata(spu)->cache.sr1 = sr1;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/ps3/system-bus.c powerpc.git/arch/powerpc/platforms/ps3/system-bus.c
+--- linux-2.6.24/arch/powerpc/platforms/ps3/system-bus.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/ps3/system-bus.c	2008-01-28 20:25:49.000000000 +0100
+@@ -42,8 +42,8 @@
+ 	int gpu;
+ } static usage_hack;
+ 
+-static int ps3_is_device(struct ps3_system_bus_device *dev,
+-			 unsigned int bus_id, unsigned int dev_id)
++static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id,
++			 u64 dev_id)
+ {
+ 	return dev->bus_id == bus_id && dev->dev_id == dev_id;
+ }
+@@ -182,8 +182,8 @@
+ 	case PS3_MATCH_ID_SYSTEM_MANAGER:
+ 		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
+ 			__LINE__, dev->match_id);
+-		pr_debug("%s:%d: bus_id: %u\n", __func__,
+-			__LINE__, dev->bus_id);
++		pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__,
++			dev->bus_id);
+ 		BUG();
+ 		return -EINVAL;
+ 
+@@ -220,8 +220,8 @@
+ 	case PS3_MATCH_ID_SYSTEM_MANAGER:
+ 		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
+ 			__LINE__, dev->match_id);
+-		pr_debug("%s:%d: bus_id: %u\n", __func__,
+-			__LINE__, dev->bus_id);
++		pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__,
++			dev->bus_id);
+ 		BUG();
+ 		return -EINVAL;
+ 
+@@ -240,7 +240,7 @@
+ static void _dump_mmio_region(const struct ps3_mmio_region* r,
+ 	const char* func, int line)
+ {
+-	pr_debug("%s:%d: dev       %u:%u\n", func, line, r->dev->bus_id,
++	pr_debug("%s:%d: dev       %lu:%lu\n", func, line, r->dev->bus_id,
+ 		r->dev->dev_id);
+ 	pr_debug("%s:%d: bus_addr  %lxh\n", func, line, r->bus_addr);
+ 	pr_debug("%s:%d: len       %lxh\n", func, line, r->len);
+@@ -715,6 +715,7 @@
+ 	static unsigned int dev_ioc0_count;
+ 	static unsigned int dev_sb_count;
+ 	static unsigned int dev_vuart_count;
++	static unsigned int dev_lpm_count;
+ 
+ 	if (!dev->core.parent)
+ 		dev->core.parent = &ps3_system_bus;
+@@ -737,6 +738,10 @@
+ 		snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
+ 			"vuart_%02x", ++dev_vuart_count);
+ 		break;
++	case PS3_DEVICE_TYPE_LPM:
++		snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
++			"lpm_%02x", ++dev_lpm_count);
++		break;
+ 	default:
+ 		BUG();
+ 	};
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pseries/eeh.c powerpc.git/arch/powerpc/platforms/pseries/eeh.c
+--- linux-2.6.24/arch/powerpc/platforms/pseries/eeh.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pseries/eeh.c	2008-01-28 20:25:49.000000000 +0100
+@@ -29,6 +29,8 @@
+ #include <linux/rbtree.h>
+ #include <linux/seq_file.h>
+ #include <linux/spinlock.h>
++#include <linux/of.h>
++
+ #include <asm/atomic.h>
+ #include <asm/eeh.h>
+ #include <asm/eeh_event.h>
+@@ -169,7 +171,6 @@
+  */
+ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
+ {
+-	struct device_node *dn;
+ 	struct pci_dev *dev = pdn->pcidev;
+ 	u32 cfg;
+ 	int cap, i;
+@@ -243,12 +244,12 @@
+ 
+ 	/* Gather status on devices under the bridge */
+ 	if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
+-		dn = pdn->node->child;
+-		while (dn) {
++		struct device_node *dn;
++
++		for_each_child_of_node(pdn->node, dn) {
+ 			pdn = PCI_DN(dn);
+ 			if (pdn)
+ 				n += gather_pci_data(pdn, buf+n, len-n);
+-			dn = dn->sibling;
+ 		}
+ 	}
+ 
+@@ -372,7 +373,7 @@
+ 	return dn;
+ }
+ 
+-/** Mark all devices that are peers of this device as failed.
++/** Mark all devices that are children of this device as failed.
+  *  Mark the device driver too, so that it can see the failure
+  *  immediately; this is critical, since some drivers poll
+  *  status registers in interrupts ... If a driver is polling,
+@@ -380,9 +381,11 @@
+  *  an interrupt context, which is bad.
+  */
+ 
+-static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
++static void __eeh_mark_slot(struct device_node *parent, int mode_flag)
+ {
+-	while (dn) {
++	struct device_node *dn;
++
++	for_each_child_of_node(parent, dn) {
+ 		if (PCI_DN(dn)) {
+ 			/* Mark the pci device driver too */
+ 			struct pci_dev *dev = PCI_DN(dn)->pcidev;
+@@ -392,10 +395,8 @@
+ 			if (dev && dev->driver)
+ 				dev->error_state = pci_channel_io_frozen;
+ 
+-			if (dn->child)
+-				__eeh_mark_slot (dn->child, mode_flag);
++			__eeh_mark_slot(dn, mode_flag);
+ 		}
+-		dn = dn->sibling;
+ 	}
+ }
+ 
+@@ -415,19 +416,19 @@
+ 	if (dev)
+ 		dev->error_state = pci_channel_io_frozen;
+ 
+-	__eeh_mark_slot (dn->child, mode_flag);
++	__eeh_mark_slot(dn, mode_flag);
+ }
+ 
+-static void __eeh_clear_slot (struct device_node *dn, int mode_flag)
++static void __eeh_clear_slot(struct device_node *parent, int mode_flag)
+ {
+-	while (dn) {
++	struct device_node *dn;
++
++	for_each_child_of_node(parent, dn) {
+ 		if (PCI_DN(dn)) {
+ 			PCI_DN(dn)->eeh_mode &= ~mode_flag;
+ 			PCI_DN(dn)->eeh_check_count = 0;
+-			if (dn->child)
+-				__eeh_clear_slot (dn->child, mode_flag);
++			__eeh_clear_slot(dn, mode_flag);
+ 		}
+-		dn = dn->sibling;
+ 	}
+ }
+ 
+@@ -444,7 +445,7 @@
+ 
+ 	PCI_DN(dn)->eeh_mode &= ~mode_flag;
+ 	PCI_DN(dn)->eeh_check_count = 0;
+-	__eeh_clear_slot (dn->child, mode_flag);
++	__eeh_clear_slot(dn, mode_flag);
+ 	spin_unlock_irqrestore(&confirm_error_lock, flags);
+ }
+ 
+@@ -480,6 +481,7 @@
+ 		no_dn++;
+ 		return 0;
+ 	}
++	dn = find_device_pe(dn);
+ 	pdn = PCI_DN(dn);
+ 
+ 	/* Access to IO BARs might get this far and still not want checking. */
+@@ -545,7 +547,7 @@
+ 
+ 	/* Note that config-io to empty slots may fail;
+ 	 * they are empty when they don't have children. */
+-	if ((rets[0] == 5) && (dn->child == NULL)) {
++	if ((rets[0] == 5) && (rets[2] == 0) && (dn->child == NULL)) {
+ 		false_positives++;
+ 		pdn->eeh_false_positives ++;
+ 		rc = 0;
+@@ -848,11 +850,8 @@
+ 	if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code))
+ 		__restore_bars (pdn);
+ 
+-	dn = pdn->node->child;
+-	while (dn) {
++	for_each_child_of_node(pdn->node, dn)
+ 		eeh_restore_bars (PCI_DN(dn));
+-		dn = dn->sibling;
+-	}
+ }
+ 
+ /**
+@@ -1130,7 +1129,8 @@
+ void eeh_add_device_tree_early(struct device_node *dn)
+ {
+ 	struct device_node *sib;
+-	for (sib = dn->child; sib; sib = sib->sibling)
++
++	for_each_child_of_node(dn, sib)
+ 		eeh_add_device_tree_early(sib);
+ 	eeh_add_device_early(dn);
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pseries/eeh_driver.c powerpc.git/arch/powerpc/platforms/pseries/eeh_driver.c
+--- linux-2.6.24/arch/powerpc/platforms/pseries/eeh_driver.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pseries/eeh_driver.c	2008-01-28 20:25:49.000000000 +0100
+@@ -310,8 +310,6 @@
+ 	const char *location, *pci_str, *drv_str;
+ 
+ 	frozen_dn = find_device_pe(event->dn);
+-	frozen_bus = pcibios_find_pci_bus(frozen_dn);
+-
+ 	if (!frozen_dn) {
+ 
+ 		location = of_get_property(event->dn, "ibm,loc-code", NULL);
+@@ -321,6 +319,8 @@
+ 		        location, pci_name(event->dev));
+ 		return NULL;
+ 	}
++
++	frozen_bus = pcibios_find_pci_bus(frozen_dn);
+ 	location = of_get_property(frozen_dn, "ibm,loc-code", NULL);
+ 	location = location ? location : "unknown";
+ 
+@@ -354,13 +354,6 @@
+ 	if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES)
+ 		goto excess_failures;
+ 
+-	/* Get the current PCI slot state. */
+-	rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000);
+-	if (rc < 0) {
+-		printk(KERN_WARNING "EEH: Permanent failure\n");
+-		goto hard_fail;
+-	}
+-
+ 	printk(KERN_WARNING
+ 	   "EEH: This PCI device has failed %d times in the last hour:\n",
+ 		frozen_pdn->eeh_freeze_count);
+@@ -376,6 +369,14 @@
+ 	 */
+ 	pci_walk_bus(frozen_bus, eeh_report_error, &result);
+ 
++	/* Get the current PCI slot state. This can take a long time,
++	 * sometimes over 3 seconds for certain systems. */
++	rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000);
++	if (rc < 0) {
++		printk(KERN_WARNING "EEH: Permanent failure\n");
++		goto hard_fail;
++	}
++
+ 	/* Since rtas may enable MMIO when posting the error log,
+ 	 * don't post the error log until after all dev drivers
+ 	 * have been informed.
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pseries/iommu.c powerpc.git/arch/powerpc/platforms/pseries/iommu.c
+--- linux-2.6.24/arch/powerpc/platforms/pseries/iommu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pseries/iommu.c	2008-01-28 20:25:49.000000000 +0100
+@@ -251,7 +251,7 @@
+ 	const unsigned long *basep;
+ 	const u32 *sizep;
+ 
+-	node = (struct device_node *)phb->arch_data;
++	node = phb->dn;
+ 
+ 	basep = of_get_property(node, "linux,tce-base", NULL);
+ 	sizep = of_get_property(node, "linux,tce-size", NULL);
+@@ -296,11 +296,12 @@
+ static void iommu_table_setparms_lpar(struct pci_controller *phb,
+ 				      struct device_node *dn,
+ 				      struct iommu_table *tbl,
+-				      const void *dma_window)
++				      const void *dma_window,
++				      int bussubno)
+ {
+ 	unsigned long offset, size;
+ 
+-	tbl->it_busno  = PCI_DN(dn)->bussubno;
++	tbl->it_busno  = bussubno;
+ 	of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
+ 
+ 	tbl->it_base   = 0;
+@@ -420,17 +421,10 @@
+ 	    pdn->full_name, ppci->iommu_table);
+ 
+ 	if (!ppci->iommu_table) {
+-		/* Bussubno hasn't been copied yet.
+-		 * Do it now because iommu_table_setparms_lpar needs it.
+-		 */
+-
+-		ppci->bussubno = bus->number;
+-
+ 		tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
+ 				   ppci->phb->node);
+-
+-		iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
+-
++		iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window,
++			bus->number);
+ 		ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
+ 		DBG("  created table: %p\n", ppci->iommu_table);
+ 	}
+@@ -523,14 +517,10 @@
+ 
+ 	pci = PCI_DN(pdn);
+ 	if (!pci->iommu_table) {
+-		/* iommu_table_setparms_lpar needs bussubno. */
+-		pci->bussubno = pci->phb->bus->number;
+-
+ 		tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
+ 				   pci->phb->node);
+-
+-		iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
+-
++		iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window,
++			pci->phb->bus->number);
+ 		pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
+ 		DBG("  created table: %p\n", pci->iommu_table);
+ 	} else {
+@@ -556,7 +546,7 @@
+ 	case PSERIES_RECONFIG_REMOVE:
+ 		if (pci && pci->iommu_table &&
+ 		    of_get_property(np, "ibm,dma-window", NULL))
+-			iommu_free_table(np);
++			iommu_free_table(pci->iommu_table, np->full_name);
+ 		break;
+ 	default:
+ 		err = NOTIFY_DONE;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pseries/pci_dlpar.c powerpc.git/arch/powerpc/platforms/pseries/pci_dlpar.c
+--- linux-2.6.24/arch/powerpc/platforms/pseries/pci_dlpar.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pseries/pci_dlpar.c	2008-01-28 20:25:49.000000000 +0100
+@@ -83,7 +83,7 @@
+ 
+ /* Must be called before pci_bus_add_devices */
+ void
+-pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
++pcibios_fixup_new_pci_devices(struct pci_bus *bus)
+ {
+ 	struct pci_dev *dev;
+ 
+@@ -98,8 +98,6 @@
+ 			/* Fill device archdata and setup iommu table */
+ 			pcibios_setup_new_device(dev);
+ 
+-			if(fix_bus)
+-				pcibios_fixup_device_resources(dev, bus);
+ 			pci_read_irq_line(dev);
+ 			for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ 				struct resource *r = &dev->resource[i];
+@@ -132,8 +130,8 @@
+ 
+ 	pci_scan_child_bus(child_bus);
+ 
+-	/* Fixup new pci devices without touching bus struct */
+-	pcibios_fixup_new_pci_devices(child_bus, 0);
++	/* Fixup new pci devices */
++	pcibios_fixup_new_pci_devices(child_bus);
+ 
+ 	/* Make the discovered devices available */
+ 	pci_bus_add_devices(child_bus);
+@@ -169,7 +167,7 @@
+ 		/* use ofdt-based probe */
+ 		of_scan_bus(dn, bus);
+ 		if (!list_empty(&bus->devices)) {
+-			pcibios_fixup_new_pci_devices(bus, 0);
++			pcibios_fixup_new_pci_devices(bus);
+ 			pci_bus_add_devices(bus);
+ 			eeh_add_device_tree_late(bus);
+ 		}
+@@ -178,7 +176,7 @@
+ 		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+ 		num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ 		if (num) {
+-			pcibios_fixup_new_pci_devices(bus, 1);
++			pcibios_fixup_new_pci_devices(bus);
+ 			pci_bus_add_devices(bus);
+ 			eeh_add_device_tree_late(bus);
+ 		}
+@@ -208,7 +206,7 @@
+ 		eeh_add_device_tree_early(dn);
+ 
+ 	scan_phb(phb);
+-	pcibios_fixup_new_pci_devices(phb->bus, 0);
++	pcibios_fixup_new_pci_devices(phb->bus);
+ 	pci_bus_add_devices(phb->bus);
+ 	eeh_add_device_tree_late(phb->bus);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pseries/plpar_wrappers.h powerpc.git/arch/powerpc/platforms/pseries/plpar_wrappers.h
+--- linux-2.6.24/arch/powerpc/platforms/pseries/plpar_wrappers.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pseries/plpar_wrappers.h	2008-01-28 20:25:49.000000000 +0100
+@@ -8,11 +8,6 @@
+ 	return plpar_hcall_norets(H_POLL_PENDING);
+ }
+ 
+-static inline long prod_processor(void)
+-{
+-	return plpar_hcall_norets(H_PROD);
+-}
+-
+ static inline long cede_processor(void)
+ {
+ 	return plpar_hcall_norets(H_CEDE);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pseries/smp.c powerpc.git/arch/powerpc/platforms/pseries/smp.c
+--- linux-2.6.24/arch/powerpc/platforms/pseries/smp.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pseries/smp.c	2008-01-28 20:25:49.000000000 +0100
+@@ -46,6 +46,7 @@
+ #include <asm/pSeries_reconfig.h>
+ #include <asm/mpic.h>
+ #include <asm/vdso_datapage.h>
++#include <asm/cputhreads.h>
+ 
+ #include "plpar_wrappers.h"
+ #include "pseries.h"
+@@ -202,7 +203,7 @@
+ 	 */
+ 	if (system_state < SYSTEM_RUNNING &&
+ 	    cpu_has_feature(CPU_FTR_SMT) &&
+-	    !smt_enabled_at_boot && nr % 2 != 0)
++	    !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
+ 		return 0;
+ 
+ 	return 1;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pseries/xics.c powerpc.git/arch/powerpc/platforms/pseries/xics.c
+--- linux-2.6.24/arch/powerpc/platforms/pseries/xics.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pseries/xics.c	2008-01-28 20:25:49.000000000 +0100
+@@ -87,19 +87,25 @@
+ /* Direct HW low level accessors */
+ 
+ 
+-static inline unsigned int direct_xirr_info_get(int n_cpu)
++static inline unsigned int direct_xirr_info_get(void)
+ {
+-	return in_be32(&xics_per_cpu[n_cpu]->xirr.word);
++	int cpu = smp_processor_id();
++
++	return in_be32(&xics_per_cpu[cpu]->xirr.word);
+ }
+ 
+-static inline void direct_xirr_info_set(int n_cpu, int value)
++static inline void direct_xirr_info_set(int value)
+ {
+-	out_be32(&xics_per_cpu[n_cpu]->xirr.word, value);
++	int cpu = smp_processor_id();
++
++	out_be32(&xics_per_cpu[cpu]->xirr.word, value);
+ }
+ 
+-static inline void direct_cppr_info(int n_cpu, u8 value)
++static inline void direct_cppr_info(u8 value)
+ {
+-	out_8(&xics_per_cpu[n_cpu]->xirr.bytes[0], value);
++	int cpu = smp_processor_id();
++
++	out_8(&xics_per_cpu[cpu]->xirr.bytes[0], value);
+ }
+ 
+ static inline void direct_qirr_info(int n_cpu, u8 value)
+@@ -111,7 +117,7 @@
+ /* LPAR low level accessors */
+ 
+ 
+-static inline unsigned int lpar_xirr_info_get(int n_cpu)
++static inline unsigned int lpar_xirr_info_get(void)
+ {
+ 	unsigned long lpar_rc;
+ 	unsigned long return_value;
+@@ -122,7 +128,7 @@
+ 	return (unsigned int)return_value;
+ }
+ 
+-static inline void lpar_xirr_info_set(int n_cpu, int value)
++static inline void lpar_xirr_info_set(int value)
+ {
+ 	unsigned long lpar_rc;
+ 	unsigned long val64 = value & 0xffffffff;
+@@ -133,7 +139,7 @@
+ 		      val64);
+ }
+ 
+-static inline void lpar_cppr_info(int n_cpu, u8 value)
++static inline void lpar_cppr_info(u8 value)
+ {
+ 	unsigned long lpar_rc;
+ 
+@@ -275,21 +281,19 @@
+ 
+ static void xics_eoi_direct(unsigned int virq)
+ {
+-	int cpu = smp_processor_id();
+ 	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
+ 
+ 	iosync();
+-	direct_xirr_info_set(cpu, (0xff << 24) | irq);
++	direct_xirr_info_set((0xff << 24) | irq);
+ }
+ 
+ 
+ static void xics_eoi_lpar(unsigned int virq)
+ {
+-	int cpu = smp_processor_id();
+ 	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
+ 
+ 	iosync();
+-	lpar_xirr_info_set(cpu, (0xff << 24) | irq);
++	lpar_xirr_info_set((0xff << 24) | irq);
+ }
+ 
+ static inline unsigned int xics_remap_irq(unsigned int vec)
+@@ -312,16 +316,12 @@
+ 
+ static unsigned int xics_get_irq_direct(void)
+ {
+-	unsigned int cpu = smp_processor_id();
+-
+-	return xics_remap_irq(direct_xirr_info_get(cpu));
++	return xics_remap_irq(direct_xirr_info_get());
+ }
+ 
+ static unsigned int xics_get_irq_lpar(void)
+ {
+-	unsigned int cpu = smp_processor_id();
+-
+-	return xics_remap_irq(lpar_xirr_info_get(cpu));
++	return xics_remap_irq(lpar_xirr_info_get());
+ }
+ 
+ #ifdef CONFIG_SMP
+@@ -387,12 +387,12 @@
+ 
+ #endif /* CONFIG_SMP */
+ 
+-static void xics_set_cpu_priority(int cpu, unsigned char cppr)
++static void xics_set_cpu_priority(unsigned char cppr)
+ {
+ 	if (firmware_has_feature(FW_FEATURE_LPAR))
+-		lpar_cppr_info(cpu, cppr);
++		lpar_cppr_info(cppr);
+ 	else
+-		direct_cppr_info(cpu, cppr);
++		direct_cppr_info(cppr);
+ 	iosync();
+ }
+ 
+@@ -440,9 +440,7 @@
+ 
+ void xics_setup_cpu(void)
+ {
+-	int cpu = smp_processor_id();
+-
+-	xics_set_cpu_priority(cpu, 0xff);
++	xics_set_cpu_priority(0xff);
+ 
+ 	/*
+ 	 * Put the calling processor into the GIQ.  This is really only
+@@ -783,7 +781,7 @@
+ 	unsigned int ipi;
+ 	struct irq_desc *desc;
+ 
+-	xics_set_cpu_priority(cpu, 0);
++	xics_set_cpu_priority(0);
+ 
+ 	/*
+ 	 * Clear IPI
+@@ -824,10 +822,11 @@
+ void xics_migrate_irqs_away(void)
+ {
+ 	int status;
+-	unsigned int irq, virq, cpu = smp_processor_id();
++	int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
++	unsigned int irq, virq;
+ 
+ 	/* Reject any interrupt that was queued to us... */
+-	xics_set_cpu_priority(cpu, 0);
++	xics_set_cpu_priority(0);
+ 
+ 	/* remove ourselves from the global interrupt queue */
+ 	status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
+@@ -835,7 +834,7 @@
+ 	WARN_ON(status < 0);
+ 
+ 	/* Allow IPIs again... */
+-	xics_set_cpu_priority(cpu, DEFAULT_PRIORITY);
++	xics_set_cpu_priority(DEFAULT_PRIORITY);
+ 
+ 	for_each_irq(virq) {
+ 		struct irq_desc *desc;
+@@ -874,7 +873,7 @@
+ 		 * The irq has to be migrated only in the single cpu
+ 		 * case.
+ 		 */
+-		if (xics_status[0] != get_hard_smp_processor_id(cpu))
++		if (xics_status[0] != hw_cpu)
+ 			goto unlock;
+ 
+ 		printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/platforms/pseries/xics.h powerpc.git/arch/powerpc/platforms/pseries/xics.h
+--- linux-2.6.24/arch/powerpc/platforms/pseries/xics.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/platforms/pseries/xics.h	2008-01-28 20:25:49.000000000 +0100
+@@ -21,9 +21,6 @@
+ extern  void xics_request_IPIs(void);
+ extern void xics_migrate_irqs_away(void);
+ 
+-/* first argument is ignored for now*/
+-void pSeriesLP_cppr_info(int n_cpu, u8 value);
+-
+ struct xics_ipi_struct {
+ 	volatile unsigned long value;
+ } ____cacheline_aligned;
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/Kconfig powerpc.git/arch/powerpc/sysdev/Kconfig
+--- linux-2.6.24/arch/powerpc/sysdev/Kconfig	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,8 @@
++# For a description of the syntax of this configuration file,
++# see Documentation/kbuild/kconfig-language.txt.
++#
++
++config PPC4xx_PCI_EXPRESS
++	bool
++	depends on PCI && 4xx
++	default n
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/Makefile powerpc.git/arch/powerpc/sysdev/Makefile
+--- linux-2.6.24/arch/powerpc/sysdev/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/Makefile	2008-01-28 20:25:49.000000000 +0100
+@@ -2,7 +2,7 @@
+ EXTRA_CFLAGS			+= -mno-minimal-toc
+ endif
+ 
+-mpic-msi-obj-$(CONFIG_PCI_MSI)	+= mpic_msi.o mpic_u3msi.o
++mpic-msi-obj-$(CONFIG_PCI_MSI)	+= mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
+ obj-$(CONFIG_MPIC)		+= mpic.o $(mpic-msi-obj-y)
+ 
+ obj-$(CONFIG_PPC_MPC106)	+= grackle.o
+@@ -12,6 +12,7 @@
+ obj-$(CONFIG_MMIO_NVRAM)	+= mmio_nvram.o
+ obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
+ obj-$(CONFIG_FSL_PCI)		+= fsl_pci.o
++obj-$(CONFIG_RAPIDIO)		+= fsl_rio.o
+ obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pci.o tsi108_dev.o
+ obj-$(CONFIG_QUICC_ENGINE)	+= qe_lib/
+ obj-$(CONFIG_PPC_BESTCOMM)	+= bestcomm/
+@@ -24,9 +25,13 @@
+ ifeq ($(CONFIG_PPC_MERGE),y)
+ obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
+ obj-$(CONFIG_PPC_I8259)		+= i8259.o
+-obj-$(CONFIG_PPC_83xx)		+= ipic.o
++obj-$(CONFIG_IPIC)		+= ipic.o
+ obj-$(CONFIG_4xx)		+= uic.o
+ obj-$(CONFIG_XILINX_VIRTEX)	+= xilinx_intc.o
++obj-$(CONFIG_OF_RTC)		+= of_rtc.o
++ifeq ($(CONFIG_PCI),y)
++obj-$(CONFIG_4xx)		+= ppc4xx_pci.o
++endif
+ endif
+ 
+ # Temporary hack until we have migrated to asm-powerpc
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/axonram.c powerpc.git/arch/powerpc/sysdev/axonram.c
+--- linux-2.6.24/arch/powerpc/sysdev/axonram.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/axonram.c	2008-01-28 20:25:49.000000000 +0100
+@@ -42,8 +42,9 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
+-#include <asm/of_device.h>
+-#include <asm/of_platform.h>
++#include <linux/of_device.h>
++#include <linux/of_platform.h>
++
+ #include <asm/page.h>
+ #include <asm/prom.h>
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/bestcomm/bestcomm.h powerpc.git/arch/powerpc/sysdev/bestcomm/bestcomm.h
+--- linux-2.6.24/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/bestcomm/bestcomm.h	2008-01-28 20:25:49.000000000 +0100
+@@ -20,7 +20,7 @@
+ 
+ 
+ /* ======================================================================== */
+-/* Generic task managment                                                   */
++/* Generic task management                                                   */
+ /* ======================================================================== */
+ 
+ /**
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/commproc.c powerpc.git/arch/powerpc/sysdev/commproc.c
+--- linux-2.6.24/arch/powerpc/sysdev/commproc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/commproc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -240,6 +240,34 @@
+ #endif
+ }
+ 
++static DEFINE_SPINLOCK(cmd_lock);
++
++#define MAX_CR_CMD_LOOPS        10000
++
++int cpm_command(u32 command, u8 opcode)
++{
++	int i, ret;
++	unsigned long flags;
++
++	if (command & 0xffffff0f)
++		return -EINVAL;
++
++	spin_lock_irqsave(&cmd_lock, flags);
++
++	ret = 0;
++	out_be16(&cpmp->cp_cpcr, command | CPM_CR_FLG | (opcode << 8));
++	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
++		if ((in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0)
++			goto out;
++
++	printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__);
++	ret = -EIO;
++out:
++	spin_unlock_irqrestore(&cmd_lock, flags);
++	return ret;
++}
++EXPORT_SYMBOL(cpm_command);
++
+ /* We used to do this earlier, but have to postpone as long as possible
+  * to ensure the kernel VM is now running.
+  */
+@@ -408,7 +436,7 @@
+ #endif /* !CONFIG_PPC_CPM_NEW_BINDING */
+ 
+ struct cpm_ioport16 {
+-	__be16 dir, par, sor, dat, intr;
++	__be16 dir, par, odr_sor, dat, intr;
+ 	__be16 res[3];
+ };
+ 
+@@ -438,6 +466,13 @@
+ 	else
+ 		clrbits32(&iop->par, pin);
+ 
++	if (port == CPM_PORTB) {
++		if (flags & CPM_PIN_OPENDRAIN)
++			setbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin);
++		else
++			clrbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin);
++	}
++
+ 	if (port == CPM_PORTE) {
+ 		if (flags & CPM_PIN_SECONDARY)
+ 			setbits32(&iop->sor, pin);
+@@ -471,11 +506,17 @@
+ 	else
+ 		clrbits16(&iop->par, pin);
+ 
++	if (port == CPM_PORTA) {
++		if (flags & CPM_PIN_OPENDRAIN)
++			setbits16(&iop->odr_sor, pin);
++		else
++			clrbits16(&iop->odr_sor, pin);
++	}
+ 	if (port == CPM_PORTC) {
+ 		if (flags & CPM_PIN_SECONDARY)
+-			setbits16(&iop->sor, pin);
++			setbits16(&iop->odr_sor, pin);
+ 		else
+-			clrbits16(&iop->sor, pin);
++			clrbits16(&iop->odr_sor, pin);
+ 	}
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/cpm2_common.c powerpc.git/arch/powerpc/sysdev/cpm2_common.c
+--- linux-2.6.24/arch/powerpc/sysdev/cpm2_common.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/cpm2_common.c	2008-01-28 20:25:49.000000000 +0100
+@@ -82,6 +82,31 @@
+ 	cpmp = &cpm2_immr->im_cpm;
+ }
+ 
++static DEFINE_SPINLOCK(cmd_lock);
++
++#define MAX_CR_CMD_LOOPS        10000
++
++int cpm_command(u32 command, u8 opcode)
++{
++	int i, ret;
++	unsigned long flags;
++
++	spin_lock_irqsave(&cmd_lock, flags);
++
++	ret = 0;
++	out_be32(&cpmp->cp_cpcr, command | opcode | CPM_CR_FLG);
++	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
++		if ((in_be32(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0)
++			goto out;
++
++	printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__);
++	ret = -EIO;
++out:
++	spin_unlock_irqrestore(&cmd_lock, flags);
++	return ret;
++}
++EXPORT_SYMBOL(cpm_command);
++
+ /* Set a baud rate generator.  This needs lots of work.  There are
+  * eight BRGs, which can be connected to the CPM channels or output
+  * as clocks.  The BRGs are in two different block of internal
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/fsl_pci.c powerpc.git/arch/powerpc/sysdev/fsl_pci.c
+--- linux-2.6.24/arch/powerpc/sysdev/fsl_pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/fsl_pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -33,8 +33,8 @@
+ 	struct ccsr_pci __iomem *pci;
+ 	int i;
+ 
+-	pr_debug("PCI memory map start 0x%x, size 0x%x\n", rsrc->start,
+-			rsrc->end - rsrc->start + 1);
++	pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
++		    (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1);
+ 	pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);
+ 
+ 	/* Disable all windows (except powar0 since its ignored) */
+@@ -46,17 +46,17 @@
+ 	/* Setup outbound MEM window */
+ 	for(i = 0; i < 3; i++)
+ 		if (hose->mem_resources[i].flags & IORESOURCE_MEM){
+-			pr_debug("PCI MEM resource start 0x%08x, size 0x%08x.\n",
+-				hose->mem_resources[i].start,
+-				hose->mem_resources[i].end
+-				  - hose->mem_resources[i].start + 1);
+-			out_be32(&pci->pow[i+1].potar,
+-				(hose->mem_resources[i].start >> 12)
+-				& 0x000fffff);
++			resource_size_t pci_addr_start =
++				 hose->mem_resources[i].start -
++				 hose->pci_mem_offset;
++			pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n",
++				(u64)hose->mem_resources[i].start,
++				(u64)hose->mem_resources[i].end
++				  - (u64)hose->mem_resources[i].start + 1);
++			out_be32(&pci->pow[i+1].potar, (pci_addr_start >> 12));
+ 			out_be32(&pci->pow[i+1].potear, 0);
+ 			out_be32(&pci->pow[i+1].powbar,
+-				(hose->mem_resources[i].start >> 12)
+-				& 0x000fffff);
++				(hose->mem_resources[i].start >> 12));
+ 			/* Enable, Mem R/W */
+ 			out_be32(&pci->pow[i+1].powar, 0x80044000
+ 				| (__ilog2(hose->mem_resources[i].end
+@@ -65,15 +65,14 @@
+ 
+ 	/* Setup outbound IO window */
+ 	if (hose->io_resource.flags & IORESOURCE_IO){
+-		pr_debug("PCI IO resource start 0x%08x, size 0x%08x, phy base 0x%08x.\n",
+-			hose->io_resource.start,
+-			hose->io_resource.end - hose->io_resource.start + 1,
+-			hose->io_base_phys);
+-		out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12)
+-				& 0x000fffff);
++		pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, "
++			 "phy base 0x%016llx.\n",
++			(u64)hose->io_resource.start,
++			(u64)hose->io_resource.end - (u64)hose->io_resource.start + 1,
++			(u64)hose->io_base_phys);
++		out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12));
+ 		out_be32(&pci->pow[i+1].potear, 0);
+-		out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12)
+-				& 0x000fffff);
++		out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12));
+ 		/* Enable, IO R/W */
+ 		out_be32(&pci->pow[i+1].powar, 0x80088000
+ 			| (__ilog2(hose->io_resource.end
+@@ -107,55 +106,17 @@
+ 	}
+ }
+ 
+-static void __init quirk_fsl_pcie_transparent(struct pci_dev *dev)
+-{
+-	struct resource *res;
+-	int i, res_idx = PCI_BRIDGE_RESOURCES;
+-	struct pci_controller *hose;
++static int fsl_pcie_bus_fixup;
+ 
++static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
++{
+ 	/* if we aren't a PCIe don't bother */
+ 	if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
+ 		return ;
+ 
+-	/*
+-	 * Make the bridge be transparent.
+-	 */
+-	dev->transparent = 1;
+-
+-	hose = pci_bus_to_host(dev->bus);
+-	if (!hose) {
+-		printk(KERN_ERR "Can't find hose for bus %d\n",
+-		       dev->bus->number);
+-		return;
+-	}
+-
+-	/* Clear out any of the virtual P2P bridge registers */
+-	pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0);
+-	pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, 0);
+-	pci_write_config_byte(dev, PCI_IO_BASE, 0x10);
+-	pci_write_config_byte(dev, PCI_IO_LIMIT, 0);
+-	pci_write_config_word(dev, PCI_MEMORY_BASE, 0x10);
+-	pci_write_config_word(dev, PCI_MEMORY_LIMIT, 0);
+-	pci_write_config_word(dev, PCI_PREF_BASE_UPPER32, 0x0);
+-	pci_write_config_word(dev, PCI_PREF_LIMIT_UPPER32, 0x0);
+-	pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x10);
+-	pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0);
+-
+-	if (hose->io_resource.flags) {
+-		res = &dev->resource[res_idx++];
+-		res->start = hose->io_resource.start;
+-		res->end = hose->io_resource.end;
+-		res->flags = hose->io_resource.flags;
+-		update_bridge_resource(dev, res);
+-	}
+-
+-	for (i = 0; i < 3; i++) {
+-		res = &dev->resource[res_idx + i];
+-		res->start = hose->mem_resources[i].start;
+-		res->end = hose->mem_resources[i].end;
+-		res->flags = hose->mem_resources[i].flags;
+-		update_bridge_resource(dev, res);
+-	}
++	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
++	fsl_pcie_bus_fixup = 1;
++	return ;
+ }
+ 
+ int __init fsl_pcie_check_link(struct pci_controller *hose)
+@@ -172,11 +133,24 @@
+ 	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+ 	int i;
+ 
+-	/* deal with bogus pci_bus when we don't have anything connected on PCIe */
+-	if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) {
+-		if (bus->parent) {
+-			for (i = 0; i < 4; ++i)
+-				bus->resource[i] = bus->parent->resource[i];
++	if ((bus->parent == hose->bus) &&
++	    ((fsl_pcie_bus_fixup &&
++	      early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) ||
++	     (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)))
++	{
++		for (i = 0; i < 4; ++i) {
++			struct resource *res = bus->resource[i];
++			struct resource *par = bus->parent->resource[i];
++			if (res) {
++				res->start = 0;
++				res->end   = 0;
++				res->flags = 0;
++			}
++			if (res && par) {
++				res->start = par->start;
++				res->end   = par->end;
++				res->flags = par->flags;
++			}
+ 		}
+ 	}
+ }
+@@ -202,7 +176,7 @@
+ 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
+ 			" bus 0\n", dev->full_name);
+ 
+-	pci_assign_all_buses = 1;
++	ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+ 	hose = pcibios_alloc_controller(dev);
+ 	if (!hose)
+ 		return -ENOMEM;
+@@ -222,7 +196,7 @@
+ 			hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ 	}
+ 
+-	printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx."
++	printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
+ 		"Firmware bus number: %d->%d\n",
+ 		(unsigned long long)rsrc.start, hose->first_busno,
+ 		hose->last_busno);
+@@ -240,23 +214,23 @@
+ 	return 0;
+ }
+ 
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_transparent);
+-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_transparent);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
++DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/fsl_rio.c powerpc.git/arch/powerpc/sysdev/fsl_rio.c
+--- linux-2.6.24/arch/powerpc/sysdev/fsl_rio.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/fsl_rio.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,932 @@
++/*
++ * MPC85xx RapidIO support
++ *
++ * Copyright 2005 MontaVista Software, Inc.
++ * Matt Porter <mporter@kernel.crashing.org>
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++#include <linux/rio.h>
++#include <linux/rio_drv.h>
++
++#include <asm/io.h>
++
++#define RIO_REGS_BASE		(CCSRBAR + 0xc0000)
++#define RIO_ATMU_REGS_OFFSET	0x10c00
++#define RIO_MSG_REGS_OFFSET	0x11000
++#define RIO_MAINT_WIN_SIZE	0x400000
++#define RIO_DBELL_WIN_SIZE	0x1000
++
++#define RIO_MSG_OMR_MUI		0x00000002
++#define RIO_MSG_OSR_TE		0x00000080
++#define RIO_MSG_OSR_QOI		0x00000020
++#define RIO_MSG_OSR_QFI		0x00000010
++#define RIO_MSG_OSR_MUB		0x00000004
++#define RIO_MSG_OSR_EOMI	0x00000002
++#define RIO_MSG_OSR_QEI		0x00000001
++
++#define RIO_MSG_IMR_MI		0x00000002
++#define RIO_MSG_ISR_TE		0x00000080
++#define RIO_MSG_ISR_QFI		0x00000010
++#define RIO_MSG_ISR_DIQI	0x00000001
++
++#define RIO_MSG_DESC_SIZE	32
++#define RIO_MSG_BUFFER_SIZE	4096
++#define RIO_MIN_TX_RING_SIZE	2
++#define RIO_MAX_TX_RING_SIZE	2048
++#define RIO_MIN_RX_RING_SIZE	2
++#define RIO_MAX_RX_RING_SIZE	2048
++
++#define DOORBELL_DMR_DI		0x00000002
++#define DOORBELL_DSR_TE		0x00000080
++#define DOORBELL_DSR_QFI	0x00000010
++#define DOORBELL_DSR_DIQI	0x00000001
++#define DOORBELL_TID_OFFSET	0x03
++#define DOORBELL_SID_OFFSET	0x05
++#define DOORBELL_INFO_OFFSET	0x06
++
++#define DOORBELL_MESSAGE_SIZE	0x08
++#define DBELL_SID(x)		(*(u8 *)(x + DOORBELL_SID_OFFSET))
++#define DBELL_TID(x)		(*(u8 *)(x + DOORBELL_TID_OFFSET))
++#define DBELL_INF(x)		(*(u16 *)(x + DOORBELL_INFO_OFFSET))
++
++struct rio_atmu_regs {
++	u32 rowtar;
++	u32 pad1;
++	u32 rowbar;
++	u32 pad2;
++	u32 rowar;
++	u32 pad3[3];
++};
++
++struct rio_msg_regs {
++	u32 omr;
++	u32 osr;
++	u32 pad1;
++	u32 odqdpar;
++	u32 pad2;
++	u32 osar;
++	u32 odpr;
++	u32 odatr;
++	u32 odcr;
++	u32 pad3;
++	u32 odqepar;
++	u32 pad4[13];
++	u32 imr;
++	u32 isr;
++	u32 pad5;
++	u32 ifqdpar;
++	u32 pad6;
++	u32 ifqepar;
++	u32 pad7[250];
++	u32 dmr;
++	u32 dsr;
++	u32 pad8;
++	u32 dqdpar;
++	u32 pad9;
++	u32 dqepar;
++	u32 pad10[26];
++	u32 pwmr;
++	u32 pwsr;
++	u32 pad11;
++	u32 pwqbar;
++};
++
++struct rio_tx_desc {
++	u32 res1;
++	u32 saddr;
++	u32 dport;
++	u32 dattr;
++	u32 res2;
++	u32 res3;
++	u32 dwcnt;
++	u32 res4;
++};
++
++static u32 regs_win;
++static struct rio_atmu_regs *atmu_regs;
++static struct rio_atmu_regs *maint_atmu_regs;
++static struct rio_atmu_regs *dbell_atmu_regs;
++static u32 dbell_win;
++static u32 maint_win;
++static struct rio_msg_regs *msg_regs;
++
++static struct rio_dbell_ring {
++	void *virt;
++	dma_addr_t phys;
++} dbell_ring;
++
++static struct rio_msg_tx_ring {
++	void *virt;
++	dma_addr_t phys;
++	void *virt_buffer[RIO_MAX_TX_RING_SIZE];
++	dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE];
++	int tx_slot;
++	int size;
++	void *dev_id;
++} msg_tx_ring;
++
++static struct rio_msg_rx_ring {
++	void *virt;
++	dma_addr_t phys;
++	void *virt_buffer[RIO_MAX_RX_RING_SIZE];
++	int rx_slot;
++	int size;
++	void *dev_id;
++} msg_rx_ring;
++
++/**
++ * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
++ * @index: ID of RapidIO interface
++ * @destid: Destination ID of target device
++ * @data: 16-bit info field of RapidIO doorbell message
++ *
++ * Sends a MPC85xx doorbell message. Returns %0 on success or
++ * %-EINVAL on failure.
++ */
++static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
++{
++	pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
++		 index, destid, data);
++	out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
++	out_be16((void *)(dbell_win), data);
++
++	return 0;
++}
++
++/**
++ * mpc85xx_local_config_read - Generate a MPC85xx local config space read
++ * @index: ID of RapdiIO interface
++ * @offset: Offset into configuration space
++ * @len: Length (in bytes) of the maintenance transaction
++ * @data: Value to be read into
++ *
++ * Generates a MPC85xx local configuration space read. Returns %0 on
++ * success or %-EINVAL on failure.
++ */
++static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
++{
++	pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
++		 offset);
++	*data = in_be32((void *)(regs_win + offset));
++
++	return 0;
++}
++
++/**
++ * mpc85xx_local_config_write - Generate a MPC85xx local config space write
++ * @index: ID of RapdiIO interface
++ * @offset: Offset into configuration space
++ * @len: Length (in bytes) of the maintenance transaction
++ * @data: Value to be written
++ *
++ * Generates a MPC85xx local configuration space write. Returns %0 on
++ * success or %-EINVAL on failure.
++ */
++static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
++{
++	pr_debug
++	    ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
++	     index, offset, data);
++	out_be32((void *)(regs_win + offset), data);
++
++	return 0;
++}
++
++/**
++ * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
++ * @index: ID of RapdiIO interface
++ * @destid: Destination ID of transaction
++ * @hopcount: Number of hops to target device
++ * @offset: Offset into configuration space
++ * @len: Length (in bytes) of the maintenance transaction
++ * @val: Location to be read into
++ *
++ * Generates a MPC85xx read maintenance transaction. Returns %0 on
++ * success or %-EINVAL on failure.
++ */
++static int
++mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
++			u32 * val)
++{
++	u8 *data;
++
++	pr_debug
++	    ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
++	     index, destid, hopcount, offset, len);
++	out_be32((void *)&maint_atmu_regs->rowtar,
++		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
++
++	data = (u8 *) maint_win + offset;
++	switch (len) {
++	case 1:
++		*val = in_8((u8 *) data);
++		break;
++	case 2:
++		*val = in_be16((u16 *) data);
++		break;
++	default:
++		*val = in_be32((u32 *) data);
++		break;
++	}
++
++	return 0;
++}
++
++/**
++ * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
++ * @index: ID of RapdiIO interface
++ * @destid: Destination ID of transaction
++ * @hopcount: Number of hops to target device
++ * @offset: Offset into configuration space
++ * @len: Length (in bytes) of the maintenance transaction
++ * @val: Value to be written
++ *
++ * Generates an MPC85xx write maintenance transaction. Returns %0 on
++ * success or %-EINVAL on failure.
++ */
++static int
++mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
++			 int len, u32 val)
++{
++	u8 *data;
++	pr_debug
++	    ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
++	     index, destid, hopcount, offset, len, val);
++	out_be32((void *)&maint_atmu_regs->rowtar,
++		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
++
++	data = (u8 *) maint_win + offset;
++	switch (len) {
++	case 1:
++		out_8((u8 *) data, val);
++		break;
++	case 2:
++		out_be16((u16 *) data, val);
++		break;
++	default:
++		out_be32((u32 *) data, val);
++		break;
++	}
++
++	return 0;
++}
++
++/**
++ * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
++ * @mport: Master port with outbound message queue
++ * @rdev: Target of outbound message
++ * @mbox: Outbound mailbox
++ * @buffer: Message to add to outbound queue
++ * @len: Length of message
++ *
++ * Adds the @buffer message to the MPC85xx outbound message queue. Returns
++ * %0 on success or %-EINVAL on failure.
++ */
++int
++rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
++			void *buffer, size_t len)
++{
++	u32 omr;
++	struct rio_tx_desc *desc =
++	    (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
++	int ret = 0;
++
++	pr_debug
++	    ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n",
++	     rdev->destid, mbox, (int)buffer, len);
++
++	if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	/* Copy and clear rest of buffer */
++	memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
++	if (len < (RIO_MAX_MSG_SIZE - 4))
++		memset((void *)((u32) msg_tx_ring.
++				virt_buffer[msg_tx_ring.tx_slot] + len), 0,
++		       RIO_MAX_MSG_SIZE - len);
++
++	/* Set mbox field for message */
++	desc->dport = mbox & 0x3;
++
++	/* Enable EOMI interrupt, set priority, and set destid */
++	desc->dattr = 0x28000000 | (rdev->destid << 2);
++
++	/* Set transfer size aligned to next power of 2 (in double words) */
++	desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
++
++	/* Set snooping and source buffer address */
++	desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
++
++	/* Increment enqueue pointer */
++	omr = in_be32((void *)&msg_regs->omr);
++	out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
++
++	/* Go to next descriptor */
++	if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
++		msg_tx_ring.tx_slot = 0;
++
++      out:
++	return ret;
++}
++
++EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
++
++/**
++ * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
++ * @irq: Linux interrupt number
++ * @dev_instance: Pointer to interrupt-specific data
++ *
++ * Handles outbound message interrupts. Executes a register outbound
++ * mailbox event handler and acks the interrupt occurrence.
++ */
++static irqreturn_t
++mpc85xx_rio_tx_handler(int irq, void *dev_instance)
++{
++	int osr;
++	struct rio_mport *port = (struct rio_mport *)dev_instance;
++
++	osr = in_be32((void *)&msg_regs->osr);
++
++	if (osr & RIO_MSG_OSR_TE) {
++		pr_info("RIO: outbound message transmission error\n");
++		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
++		goto out;
++	}
++
++	if (osr & RIO_MSG_OSR_QOI) {
++		pr_info("RIO: outbound message queue overflow\n");
++		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
++		goto out;
++	}
++
++	if (osr & RIO_MSG_OSR_EOMI) {
++		u32 dqp = in_be32((void *)&msg_regs->odqdpar);
++		int slot = (dqp - msg_tx_ring.phys) >> 5;
++		port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot);
++
++		/* Ack the end-of-message interrupt */
++		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
++	}
++
++      out:
++	return IRQ_HANDLED;
++}
++
++/**
++ * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox
++ * @mport: Master port implementing the outbound message unit
++ * @dev_id: Device specific pointer to pass on event
++ * @mbox: Mailbox to open
++ * @entries: Number of entries in the outbound mailbox ring
++ *
++ * Initializes buffer ring, request the outbound message interrupt,
++ * and enables the outbound message unit. Returns %0 on success and
++ * %-EINVAL or %-ENOMEM on failure.
++ */
++int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
++{
++	int i, j, rc = 0;
++
++	if ((entries < RIO_MIN_TX_RING_SIZE) ||
++	    (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
++		rc = -EINVAL;
++		goto out;
++	}
++
++	/* Initialize shadow copy ring */
++	msg_tx_ring.dev_id = dev_id;
++	msg_tx_ring.size = entries;
++
++	for (i = 0; i < msg_tx_ring.size; i++) {
++		if (!
++		    (msg_tx_ring.virt_buffer[i] =
++		     dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
++					&msg_tx_ring.phys_buffer[i],
++					GFP_KERNEL))) {
++			rc = -ENOMEM;
++			for (j = 0; j < msg_tx_ring.size; j++)
++				if (msg_tx_ring.virt_buffer[j])
++					dma_free_coherent(NULL,
++							  RIO_MSG_BUFFER_SIZE,
++							  msg_tx_ring.
++							  virt_buffer[j],
++							  msg_tx_ring.
++							  phys_buffer[j]);
++			goto out;
++		}
++	}
++
++	/* Initialize outbound message descriptor ring */
++	if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
++						    msg_tx_ring.size *
++						    RIO_MSG_DESC_SIZE,
++						    &msg_tx_ring.phys,
++						    GFP_KERNEL))) {
++		rc = -ENOMEM;
++		goto out_dma;
++	}
++	memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
++	msg_tx_ring.tx_slot = 0;
++
++	/* Point dequeue/enqueue pointers at first entry in ring */
++	out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
++	out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
++
++	/* Configure for snooping */
++	out_be32((void *)&msg_regs->osar, 0x00000004);
++
++	/* Clear interrupt status */
++	out_be32((void *)&msg_regs->osr, 0x000000b3);
++
++	/* Hook up outbound message handler */
++	if ((rc =
++	     request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
++			 "msg_tx", (void *)mport)) < 0)
++		goto out_irq;
++
++	/*
++	 * Configure outbound message unit
++	 *      Snooping
++	 *      Interrupts (all enabled, except QEIE)
++	 *      Chaining mode
++	 *      Disable
++	 */
++	out_be32((void *)&msg_regs->omr, 0x00100220);
++
++	/* Set number of entries */
++	out_be32((void *)&msg_regs->omr,
++		 in_be32((void *)&msg_regs->omr) |
++		 ((get_bitmask_order(entries) - 2) << 12));
++
++	/* Now enable the unit */
++	out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
++
++      out:
++	return rc;
++
++      out_irq:
++	dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
++			  msg_tx_ring.virt, msg_tx_ring.phys);
++
++      out_dma:
++	for (i = 0; i < msg_tx_ring.size; i++)
++		dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
++				  msg_tx_ring.virt_buffer[i],
++				  msg_tx_ring.phys_buffer[i]);
++
++	return rc;
++}
++
++/**
++ * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox
++ * @mport: Master port implementing the outbound message unit
++ * @mbox: Mailbox to close
++ *
++ * Disables the outbound message unit, free all buffers, and
++ * frees the outbound message interrupt.
++ */
++void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
++{
++	/* Disable inbound message unit */
++	out_be32((void *)&msg_regs->omr, 0);
++
++	/* Free ring */
++	dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
++			  msg_tx_ring.virt, msg_tx_ring.phys);
++
++	/* Free interrupt */
++	free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
++}
++
++/**
++ * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
++ * @irq: Linux interrupt number
++ * @dev_instance: Pointer to interrupt-specific data
++ *
++ * Handles inbound message interrupts. Executes a registered inbound
++ * mailbox event handler and acks the interrupt occurrence.
++ */
++static irqreturn_t
++mpc85xx_rio_rx_handler(int irq, void *dev_instance)
++{
++	int isr;
++	struct rio_mport *port = (struct rio_mport *)dev_instance;
++
++	isr = in_be32((void *)&msg_regs->isr);
++
++	if (isr & RIO_MSG_ISR_TE) {
++		pr_info("RIO: inbound message reception error\n");
++		out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
++		goto out;
++	}
++
++	/* XXX Need to check/dispatch until queue empty */
++	if (isr & RIO_MSG_ISR_DIQI) {
++		/*
++		 * We implement *only* mailbox 0, but can receive messages
++		 * for any mailbox/letter to that mailbox destination. So,
++		 * make the callback with an unknown/invalid mailbox number
++		 * argument.
++		 */
++		port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1);
++
++		/* Ack the queueing interrupt */
++		out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
++	}
++
++      out:
++	return IRQ_HANDLED;
++}
++
++/**
++ * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox
++ * @mport: Master port implementing the inbound message unit
++ * @dev_id: Device specific pointer to pass on event
++ * @mbox: Mailbox to open
++ * @entries: Number of entries in the inbound mailbox ring
++ *
++ * Initializes buffer ring, request the inbound message interrupt,
++ * and enables the inbound message unit. Returns %0 on success
++ * and %-EINVAL or %-ENOMEM on failure.
++ */
++int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
++{
++	int i, rc = 0;
++
++	if ((entries < RIO_MIN_RX_RING_SIZE) ||
++	    (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
++		rc = -EINVAL;
++		goto out;
++	}
++
++	/* Initialize client buffer ring */
++	msg_rx_ring.dev_id = dev_id;
++	msg_rx_ring.size = entries;
++	msg_rx_ring.rx_slot = 0;
++	for (i = 0; i < msg_rx_ring.size; i++)
++		msg_rx_ring.virt_buffer[i] = NULL;
++
++	/* Initialize inbound message ring */
++	if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
++						    msg_rx_ring.size *
++						    RIO_MAX_MSG_SIZE,
++						    &msg_rx_ring.phys,
++						    GFP_KERNEL))) {
++		rc = -ENOMEM;
++		goto out;
++	}
++
++	/* Point dequeue/enqueue pointers at first entry in ring */
++	out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
++	out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
++
++	/* Clear interrupt status */
++	out_be32((void *)&msg_regs->isr, 0x00000091);
++
++	/* Hook up inbound message handler */
++	if ((rc =
++	     request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
++			 "msg_rx", (void *)mport)) < 0) {
++		dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
++				  msg_tx_ring.virt_buffer[i],
++				  msg_tx_ring.phys_buffer[i]);
++		goto out;
++	}
++
++	/*
++	 * Configure inbound message unit:
++	 *      Snooping
++	 *      4KB max message size
++	 *      Unmask all interrupt sources
++	 *      Disable
++	 */
++	out_be32((void *)&msg_regs->imr, 0x001b0060);
++
++	/* Set number of queue entries */
++	out_be32((void *)&msg_regs->imr,
++		 in_be32((void *)&msg_regs->imr) |
++		 ((get_bitmask_order(entries) - 2) << 12));
++
++	/* Now enable the unit */
++	out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
++
++      out:
++	return rc;
++}
++
++/**
++ * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox
++ * @mport: Master port implementing the inbound message unit
++ * @mbox: Mailbox to close
++ *
++ * Disables the inbound message unit, free all buffers, and
++ * frees the inbound message interrupt.
++ */
++void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
++{
++	/* Disable inbound message unit */
++	out_be32((void *)&msg_regs->imr, 0);
++
++	/* Free ring */
++	dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
++			  msg_rx_ring.virt, msg_rx_ring.phys);
++
++	/* Free interrupt */
++	free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
++}
++
++/**
++ * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
++ * @mport: Master port implementing the inbound message unit
++ * @mbox: Inbound mailbox number
++ * @buf: Buffer to add to inbound queue
++ *
++ * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
++ * %0 on success or %-EINVAL on failure.
++ */
++int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
++{
++	int rc = 0;
++
++	pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
++		 msg_rx_ring.rx_slot);
++
++	if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
++		printk(KERN_ERR
++		       "RIO: error adding inbound buffer %d, buffer exists\n",
++		       msg_rx_ring.rx_slot);
++		rc = -EINVAL;
++		goto out;
++	}
++
++	msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
++	if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
++		msg_rx_ring.rx_slot = 0;
++
++      out:
++	return rc;
++}
++
++EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
++
++/**
++ * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit
++ * @mport: Master port implementing the inbound message unit
++ * @mbox: Inbound mailbox number
++ *
++ * Gets the next available inbound message from the inbound message queue.
++ * A pointer to the message is returned on success or NULL on failure.
++ */
++void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
++{
++	u32 imr;
++	u32 phys_buf, virt_buf;
++	void *buf = NULL;
++	int buf_idx;
++
++	phys_buf = in_be32((void *)&msg_regs->ifqdpar);
++
++	/* If no more messages, then bail out */
++	if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
++		goto out2;
++
++	virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
++	buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
++	buf = msg_rx_ring.virt_buffer[buf_idx];
++
++	if (!buf) {
++		printk(KERN_ERR
++		       "RIO: inbound message copy failed, no buffers\n");
++		goto out1;
++	}
++
++	/* Copy max message size, caller is expected to allocate that big */
++	memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
++
++	/* Clear the available buffer */
++	msg_rx_ring.virt_buffer[buf_idx] = NULL;
++
++      out1:
++	imr = in_be32((void *)&msg_regs->imr);
++	out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
++
++      out2:
++	return buf;
++}
++
++EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
++
++/**
++ * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
++ * @irq: Linux interrupt number
++ * @dev_instance: Pointer to interrupt-specific data
++ *
++ * Handles doorbell interrupts. Parses a list of registered
++ * doorbell event handlers and executes a matching event handler.
++ */
++static irqreturn_t
++mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
++{
++	int dsr;
++	struct rio_mport *port = (struct rio_mport *)dev_instance;
++
++	dsr = in_be32((void *)&msg_regs->dsr);
++
++	if (dsr & DOORBELL_DSR_TE) {
++		pr_info("RIO: doorbell reception error\n");
++		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
++		goto out;
++	}
++
++	if (dsr & DOORBELL_DSR_QFI) {
++		pr_info("RIO: doorbell queue full\n");
++		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
++		goto out;
++	}
++
++	/* XXX Need to check/dispatch until queue empty */
++	if (dsr & DOORBELL_DSR_DIQI) {
++		u32 dmsg =
++		    (u32) dbell_ring.virt +
++		    (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
++		u32 dmr;
++		struct rio_dbell *dbell;
++		int found = 0;
++
++		pr_debug
++		    ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n",
++		     DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
++
++		list_for_each_entry(dbell, &port->dbells, node) {
++			if ((dbell->res->start <= DBELL_INF(dmsg)) &&
++			    (dbell->res->end >= DBELL_INF(dmsg))) {
++				found = 1;
++				break;
++			}
++		}
++		if (found) {
++			dbell->dinb(port, dbell->dev_id, DBELL_SID(dmsg), DBELL_TID(dmsg),
++				    DBELL_INF(dmsg));
++		} else {
++			pr_debug
++			    ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
++			     DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
++		}
++		dmr = in_be32((void *)&msg_regs->dmr);
++		out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
++		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
++	}
++
++      out:
++	return IRQ_HANDLED;
++}
++
++/**
++ * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
++ * @mport: Master port implementing the inbound doorbell unit
++ *
++ * Initializes doorbell unit hardware and inbound DMA buffer
++ * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
++ * or %-ENOMEM on failure.
++ */
++static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
++{
++	int rc = 0;
++
++	/* Map outbound doorbell window immediately after maintenance window */
++	if (!(dbell_win =
++	      (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
++			    RIO_DBELL_WIN_SIZE))) {
++		printk(KERN_ERR
++		       "RIO: unable to map outbound doorbell window\n");
++		rc = -ENOMEM;
++		goto out;
++	}
++
++	/* Initialize inbound doorbells */
++	if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
++						   512 * DOORBELL_MESSAGE_SIZE,
++						   &dbell_ring.phys,
++						   GFP_KERNEL))) {
++		printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
++		rc = -ENOMEM;
++		iounmap((void *)dbell_win);
++		goto out;
++	}
++
++	/* Point dequeue/enqueue pointers at first entry in ring */
++	out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
++	out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
++
++	/* Clear interrupt status */
++	out_be32((void *)&msg_regs->dsr, 0x00000091);
++
++	/* Hook up doorbell handler */
++	if ((rc =
++	     request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
++			 "dbell_rx", (void *)mport) < 0)) {
++		iounmap((void *)dbell_win);
++		dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
++				  dbell_ring.virt, dbell_ring.phys);
++		printk(KERN_ERR
++		       "MPC85xx RIO: unable to request inbound doorbell irq");
++		goto out;
++	}
++
++	/* Configure doorbells for snooping, 512 entries, and enable */
++	out_be32((void *)&msg_regs->dmr, 0x00108161);
++
++      out:
++	return rc;
++}
++
++static char *cmdline = NULL;
++
++static int mpc85xx_rio_get_hdid(int index)
++{
++	/* XXX Need to parse multiple entries in some format */
++	if (!cmdline)
++		return -1;
++
++	return simple_strtol(cmdline, NULL, 0);
++}
++
++static int mpc85xx_rio_get_cmdline(char *s)
++{
++	if (!s)
++		return 0;
++
++	cmdline = s;
++	return 1;
++}
++
++__setup("riohdid=", mpc85xx_rio_get_cmdline);
++
++/**
++ * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
++ * @law_start: Starting physical address of RapidIO LAW
++ * @law_size: Size of RapidIO LAW
++ *
++ * Initializes MPC85xx RapidIO hardware interface, configures
++ * master port with system-specific info, and registers the
++ * master port with the RapidIO subsystem.
++ */
++void mpc85xx_rio_setup(int law_start, int law_size)
++{
++	struct rio_ops *ops;
++	struct rio_mport *port;
++
++	ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
++	ops->lcread = mpc85xx_local_config_read;
++	ops->lcwrite = mpc85xx_local_config_write;
++	ops->cread = mpc85xx_rio_config_read;
++	ops->cwrite = mpc85xx_rio_config_write;
++	ops->dsend = mpc85xx_rio_doorbell_send;
++
++	port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
++	port->id = 0;
++	port->index = 0;
++	INIT_LIST_HEAD(&port->dbells);
++	port->iores.start = law_start;
++	port->iores.end = law_start + law_size;
++	port->iores.flags = IORESOURCE_MEM;
++
++	rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
++	rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
++	rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
++	strcpy(port->name, "RIO0 mport");
++
++	port->ops = ops;
++	port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
++
++	rio_register_mport(port);
++
++	regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
++	atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
++	maint_atmu_regs = atmu_regs + 1;
++	dbell_atmu_regs = atmu_regs + 2;
++	msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
++
++	/* Configure maintenance transaction window */
++	out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
++	out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
++
++	maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
++
++	/* Configure outbound doorbell window */
++	out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
++	out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
++	mpc85xx_rio_doorbell_init(port);
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/fsl_rio.h powerpc.git/arch/powerpc/sysdev/fsl_rio.h
+--- linux-2.6.24/arch/powerpc/sysdev/fsl_rio.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/fsl_rio.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,20 @@
++/*
++ * MPC85xx RapidIO definitions
++ *
++ * Copyright 2005 MontaVista Software, Inc.
++ * Matt Porter <mporter@kernel.crashing.org>
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++
++#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
++#define __PPC_SYSLIB_PPC85XX_RIO_H
++
++#include <linux/init.h>
++
++extern void mpc85xx_rio_setup(int law_start, int law_size);
++
++#endif				/* __PPC_SYSLIB_PPC85XX_RIO_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/fsl_soc.c powerpc.git/arch/powerpc/sysdev/fsl_soc.c
+--- linux-2.6.24/arch/powerpc/sysdev/fsl_soc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/fsl_soc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -24,6 +24,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/of_platform.h>
+ #include <linux/phy.h>
++#include <linux/phy_fixed.h>
+ #include <linux/spi/spi.h>
+ #include <linux/fsl_devices.h>
+ #include <linux/fs_enet_pd.h>
+@@ -54,10 +55,18 @@
+ 	soc = of_find_node_by_type(NULL, "soc");
+ 	if (soc) {
+ 		int size;
+-		const void *prop = of_get_property(soc, "reg", &size);
++		u32 naddr;
++		const u32 *prop = of_get_property(soc, "#address-cells", &size);
+ 
++		if (prop && size == 4)
++			naddr = *prop;
++		else
++			naddr = 2;
++
++		prop = of_get_property(soc, "ranges", &size);
+ 		if (prop)
+-			immrbase = of_translate_address(soc, prop);
++			immrbase = of_translate_address(soc, prop + naddr);
++
+ 		of_node_put(soc);
+ 	}
+ 
+@@ -130,17 +139,51 @@
+ EXPORT_SYMBOL(get_baudrate);
+ #endif /* CONFIG_CPM2 */
+ 
+-static int __init gfar_mdio_of_init(void)
++#ifdef CONFIG_FIXED_PHY
++static int __init of_add_fixed_phys(void)
+ {
++	int ret;
+ 	struct device_node *np;
+-	unsigned int i;
++	u32 *fixed_link;
++	struct fixed_phy_status status = {};
++
++	for_each_node_by_name(np, "ethernet") {
++		fixed_link  = (u32 *)of_get_property(np, "fixed-link", NULL);
++		if (!fixed_link)
++			continue;
++
++		status.link = 1;
++		status.duplex = fixed_link[1];
++		status.speed = fixed_link[2];
++		status.pause = fixed_link[3];
++		status.asym_pause = fixed_link[4];
++
++		ret = fixed_phy_add(PHY_POLL, fixed_link[0], &status);
++		if (ret) {
++			of_node_put(np);
++			return ret;
++		}
++	}
++
++	return 0;
++}
++arch_initcall(of_add_fixed_phys);
++#endif /* CONFIG_FIXED_PHY */
++
++static int __init gfar_mdio_of_init(void)
++{
++	struct device_node *np = NULL;
+ 	struct platform_device *mdio_dev;
+ 	struct resource res;
+ 	int ret;
+ 
+-	for (np = NULL, i = 0;
+-	     (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL;
+-	     i++) {
++	np = of_find_compatible_node(np, NULL, "fsl,gianfar-mdio");
++
++	/* try the deprecated version */
++	if (!np)
++		np = of_find_compatible_node(np, "mdio", "gianfar");
++
++	if (np) {
+ 		int k;
+ 		struct device_node *child = NULL;
+ 		struct gianfar_mdio_data mdio_data;
+@@ -179,11 +222,13 @@
+ 			goto unreg;
+ 	}
+ 
++	of_node_put(np);
+ 	return 0;
+ 
+ unreg:
+ 	platform_device_unregister(mdio_dev);
+ err:
++	of_node_put(np);
+ 	return ret;
+ }
+ 
+@@ -193,7 +238,6 @@
+ static const char *gfar_rx_intr = "rx";
+ static const char *gfar_err_intr = "error";
+ 
+-
+ static int __init gfar_of_init(void)
+ {
+ 	struct device_node *np;
+@@ -277,29 +321,43 @@
+ 			gfar_data.interface = PHY_INTERFACE_MODE_MII;
+ 
+ 		ph = of_get_property(np, "phy-handle", NULL);
+-		phy = of_find_node_by_phandle(*ph);
++		if (ph == NULL) {
++			u32 *fixed_link;
+ 
+-		if (phy == NULL) {
+-			ret = -ENODEV;
+-			goto unreg;
+-		}
++			fixed_link = (u32 *)of_get_property(np, "fixed-link",
++							   NULL);
++			if (!fixed_link) {
++				ret = -ENODEV;
++				goto unreg;
++			}
+ 
+-		mdio = of_get_parent(phy);
++			gfar_data.bus_id = 0;
++			gfar_data.phy_id = fixed_link[0];
++		} else {
++			phy = of_find_node_by_phandle(*ph);
++
++			if (phy == NULL) {
++				ret = -ENODEV;
++				goto unreg;
++			}
++
++			mdio = of_get_parent(phy);
++
++			id = of_get_property(phy, "reg", NULL);
++			ret = of_address_to_resource(mdio, 0, &res);
++			if (ret) {
++				of_node_put(phy);
++				of_node_put(mdio);
++				goto unreg;
++			}
++
++			gfar_data.phy_id = *id;
++			gfar_data.bus_id = res.start;
+ 
+-		id = of_get_property(phy, "reg", NULL);
+-		ret = of_address_to_resource(mdio, 0, &res);
+-		if (ret) {
+ 			of_node_put(phy);
+ 			of_node_put(mdio);
+-			goto unreg;
+ 		}
+ 
+-		gfar_data.phy_id = *id;
+-		gfar_data.bus_id = res.start;
+-
+-		of_node_put(phy);
+-		of_node_put(mdio);
+-
+ 		ret =
+ 		    platform_device_add_data(gfar_dev, &gfar_data,
+ 					     sizeof(struct
+@@ -390,13 +448,11 @@
+ static int __init fsl_i2c_of_init(void)
+ {
+ 	struct device_node *np;
+-	unsigned int i;
++	unsigned int i = 0;
+ 	struct platform_device *i2c_dev;
+ 	int ret;
+ 
+-	for (np = NULL, i = 0;
+-	     (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
+-	     i++) {
++	for_each_compatible_node(np, NULL, "fsl-i2c") {
+ 		struct resource r[2];
+ 		struct fsl_i2c_platform_data i2c_data;
+ 		const unsigned char *flags = NULL;
+@@ -432,7 +488,7 @@
+ 		if (ret)
+ 			goto unreg;
+ 
+-		of_register_i2c_devices(np, i);
++		of_register_i2c_devices(np, i++);
+ 	}
+ 
+ 	return 0;
+@@ -528,14 +584,12 @@
+ static int __init fsl_usb_of_init(void)
+ {
+ 	struct device_node *np;
+-	unsigned int i;
++	unsigned int i = 0;
+ 	struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL,
+ 		*usb_dev_dr_client = NULL;
+ 	int ret;
+ 
+-	for (np = NULL, i = 0;
+-	     (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL;
+-	     i++) {
++	for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
+ 		struct resource r[2];
+ 		struct fsl_usb2_platform_data usb_data;
+ 		const unsigned char *prop = NULL;
+@@ -578,11 +632,10 @@
+ 						    fsl_usb2_platform_data));
+ 		if (ret)
+ 			goto unreg_mph;
++		i++;
+ 	}
+ 
+-	for (np = NULL;
+-	     (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
+-	     i++) {
++	for_each_compatible_node(np, NULL, "fsl-usb2-dr") {
+ 		struct resource r[2];
+ 		struct fsl_usb2_platform_data usb_data;
+ 		const unsigned char *prop = NULL;
+@@ -654,6 +707,7 @@
+ 						fsl_usb2_platform_data))))
+ 				goto unreg_dr;
+ 		}
++		i++;
+ 	}
+ 	return 0;
+ 
+@@ -1125,13 +1179,12 @@
+ 
+ static int __init fsl_pcmcia_of_init(void)
+ {
+-	struct device_node *np = NULL;
++	struct device_node *np;
+ 	/*
+ 	 * Register all the devices which type is "pcmcia"
+ 	 */
+-	while ((np = of_find_compatible_node(np,
+-			"pcmcia", "fsl,pq-pcmcia")) != NULL)
+-			    of_platform_device_create(np, "m8xx-pcmcia", NULL);
++	for_each_compatible_node(np, "pcmcia", "fsl,pq-pcmcia")
++		of_platform_device_create(np, "m8xx-pcmcia", NULL);
+ 	return 0;
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/grackle.c powerpc.git/arch/powerpc/sysdev/grackle.c
+--- linux-2.6.24/arch/powerpc/sysdev/grackle.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/grackle.c	2008-01-28 20:25:49.000000000 +0100
+@@ -57,7 +57,7 @@
+ {
+ 	setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
+ 	if (machine_is_compatible("PowerMac1,1"))
+-		pci_assign_all_buses = 1;
++		ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+ 	if (machine_is_compatible("AAPL,PowerBook1998"))
+ 		grackle_set_loop_snoop(hose, 1);
+ #if 0	/* Disabled for now, HW problems ??? */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/ipic.c powerpc.git/arch/powerpc/sysdev/ipic.c
+--- linux-2.6.24/arch/powerpc/sysdev/ipic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/ipic.c	2008-01-28 20:25:49.000000000 +0100
+@@ -30,11 +30,67 @@
+ #include "ipic.h"
+ 
+ static struct ipic * primary_ipic;
++static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
+ static DEFINE_SPINLOCK(ipic_lock);
+ 
+ static struct ipic_info ipic_info[] = {
++	[1] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_C,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 16,
++		.prio_mask = 0,
++	},
++	[2] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_C,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 17,
++		.prio_mask = 1,
++	},
++	[3] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_C,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 18,
++		.prio_mask = 2,
++	},
++	[4] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_C,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 19,
++		.prio_mask = 3,
++	},
++	[5] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_C,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 20,
++		.prio_mask = 4,
++	},
++	[6] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_C,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 21,
++		.prio_mask = 5,
++	},
++	[7] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_C,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 22,
++		.prio_mask = 6,
++	},
++	[8] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_C,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 23,
++		.prio_mask = 7,
++	},
+ 	[9] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_D,
+ 		.force	= IPIC_SIFCR_H,
+@@ -42,7 +98,6 @@
+ 		.prio_mask = 0,
+ 	},
+ 	[10] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_D,
+ 		.force	= IPIC_SIFCR_H,
+@@ -50,15 +105,27 @@
+ 		.prio_mask = 1,
+ 	},
+ 	[11] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_D,
+ 		.force	= IPIC_SIFCR_H,
+ 		.bit	= 26,
+ 		.prio_mask = 2,
+ 	},
++	[12] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_D,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 27,
++		.prio_mask = 3,
++	},
++	[13] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_D,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 28,
++		.prio_mask = 4,
++	},
+ 	[14] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_D,
+ 		.force	= IPIC_SIFCR_H,
+@@ -66,7 +133,6 @@
+ 		.prio_mask = 5,
+ 	},
+ 	[15] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_D,
+ 		.force	= IPIC_SIFCR_H,
+@@ -74,7 +140,6 @@
+ 		.prio_mask = 6,
+ 	},
+ 	[16] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_D,
+ 		.force	= IPIC_SIFCR_H,
+@@ -82,7 +147,7 @@
+ 		.prio_mask = 7,
+ 	},
+ 	[17] = {
+-		.pend	= IPIC_SEPNR,
++		.ack	= IPIC_SEPNR,
+ 		.mask	= IPIC_SEMSR,
+ 		.prio	= IPIC_SMPRR_A,
+ 		.force	= IPIC_SEFCR,
+@@ -90,7 +155,7 @@
+ 		.prio_mask = 5,
+ 	},
+ 	[18] = {
+-		.pend	= IPIC_SEPNR,
++		.ack	= IPIC_SEPNR,
+ 		.mask	= IPIC_SEMSR,
+ 		.prio	= IPIC_SMPRR_A,
+ 		.force	= IPIC_SEFCR,
+@@ -98,7 +163,7 @@
+ 		.prio_mask = 6,
+ 	},
+ 	[19] = {
+-		.pend	= IPIC_SEPNR,
++		.ack	= IPIC_SEPNR,
+ 		.mask	= IPIC_SEMSR,
+ 		.prio	= IPIC_SMPRR_A,
+ 		.force	= IPIC_SEFCR,
+@@ -106,7 +171,7 @@
+ 		.prio_mask = 7,
+ 	},
+ 	[20] = {
+-		.pend	= IPIC_SEPNR,
++		.ack	= IPIC_SEPNR,
+ 		.mask	= IPIC_SEMSR,
+ 		.prio	= IPIC_SMPRR_B,
+ 		.force	= IPIC_SEFCR,
+@@ -114,7 +179,7 @@
+ 		.prio_mask = 4,
+ 	},
+ 	[21] = {
+-		.pend	= IPIC_SEPNR,
++		.ack	= IPIC_SEPNR,
+ 		.mask	= IPIC_SEMSR,
+ 		.prio	= IPIC_SMPRR_B,
+ 		.force	= IPIC_SEFCR,
+@@ -122,7 +187,7 @@
+ 		.prio_mask = 5,
+ 	},
+ 	[22] = {
+-		.pend	= IPIC_SEPNR,
++		.ack	= IPIC_SEPNR,
+ 		.mask	= IPIC_SEMSR,
+ 		.prio	= IPIC_SMPRR_B,
+ 		.force	= IPIC_SEFCR,
+@@ -130,7 +195,7 @@
+ 		.prio_mask = 6,
+ 	},
+ 	[23] = {
+-		.pend	= IPIC_SEPNR,
++		.ack	= IPIC_SEPNR,
+ 		.mask	= IPIC_SEMSR,
+ 		.prio	= IPIC_SMPRR_B,
+ 		.force	= IPIC_SEFCR,
+@@ -138,7 +203,6 @@
+ 		.prio_mask = 7,
+ 	},
+ 	[32] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_A,
+ 		.force	= IPIC_SIFCR_H,
+@@ -146,7 +210,6 @@
+ 		.prio_mask = 0,
+ 	},
+ 	[33] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_A,
+ 		.force	= IPIC_SIFCR_H,
+@@ -154,7 +217,6 @@
+ 		.prio_mask = 1,
+ 	},
+ 	[34] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_A,
+ 		.force	= IPIC_SIFCR_H,
+@@ -162,7 +224,6 @@
+ 		.prio_mask = 2,
+ 	},
+ 	[35] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_A,
+ 		.force	= IPIC_SIFCR_H,
+@@ -170,7 +231,6 @@
+ 		.prio_mask = 3,
+ 	},
+ 	[36] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_A,
+ 		.force	= IPIC_SIFCR_H,
+@@ -178,7 +238,6 @@
+ 		.prio_mask = 4,
+ 	},
+ 	[37] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_A,
+ 		.force	= IPIC_SIFCR_H,
+@@ -186,7 +245,6 @@
+ 		.prio_mask = 5,
+ 	},
+ 	[38] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_A,
+ 		.force	= IPIC_SIFCR_H,
+@@ -194,15 +252,69 @@
+ 		.prio_mask = 6,
+ 	},
+ 	[39] = {
+-		.pend	= IPIC_SIPNR_H,
+ 		.mask	= IPIC_SIMSR_H,
+ 		.prio	= IPIC_SIPRR_A,
+ 		.force	= IPIC_SIFCR_H,
+ 		.bit	= 7,
+ 		.prio_mask = 7,
+ 	},
++	[40] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_B,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 8,
++		.prio_mask = 0,
++	},
++	[41] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_B,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 9,
++		.prio_mask = 1,
++	},
++	[42] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_B,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 10,
++		.prio_mask = 2,
++	},
++	[43] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_B,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 11,
++		.prio_mask = 3,
++	},
++	[44] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_B,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 12,
++		.prio_mask = 4,
++	},
++	[45] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_B,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 13,
++		.prio_mask = 5,
++	},
++	[46] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_B,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 14,
++		.prio_mask = 6,
++	},
++	[47] = {
++		.mask	= IPIC_SIMSR_H,
++		.prio	= IPIC_SIPRR_B,
++		.force	= IPIC_SIFCR_H,
++		.bit	= 15,
++		.prio_mask = 7,
++	},
+ 	[48] = {
+-		.pend	= IPIC_SEPNR,
+ 		.mask	= IPIC_SEMSR,
+ 		.prio	= IPIC_SMPRR_A,
+ 		.force	= IPIC_SEFCR,
+@@ -210,7 +322,6 @@
+ 		.prio_mask = 4,
+ 	},
+ 	[64] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= IPIC_SMPRR_A,
+ 		.force	= IPIC_SIFCR_L,
+@@ -218,7 +329,6 @@
+ 		.prio_mask = 0,
+ 	},
+ 	[65] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= IPIC_SMPRR_A,
+ 		.force	= IPIC_SIFCR_L,
+@@ -226,7 +336,6 @@
+ 		.prio_mask = 1,
+ 	},
+ 	[66] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= IPIC_SMPRR_A,
+ 		.force	= IPIC_SIFCR_L,
+@@ -234,7 +343,6 @@
+ 		.prio_mask = 2,
+ 	},
+ 	[67] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= IPIC_SMPRR_A,
+ 		.force	= IPIC_SIFCR_L,
+@@ -242,7 +350,6 @@
+ 		.prio_mask = 3,
+ 	},
+ 	[68] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= IPIC_SMPRR_B,
+ 		.force	= IPIC_SIFCR_L,
+@@ -250,7 +357,6 @@
+ 		.prio_mask = 0,
+ 	},
+ 	[69] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= IPIC_SMPRR_B,
+ 		.force	= IPIC_SIFCR_L,
+@@ -258,7 +364,6 @@
+ 		.prio_mask = 1,
+ 	},
+ 	[70] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= IPIC_SMPRR_B,
+ 		.force	= IPIC_SIFCR_L,
+@@ -266,7 +371,6 @@
+ 		.prio_mask = 2,
+ 	},
+ 	[71] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= IPIC_SMPRR_B,
+ 		.force	= IPIC_SIFCR_L,
+@@ -274,91 +378,120 @@
+ 		.prio_mask = 3,
+ 	},
+ 	[72] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 8,
+ 	},
+ 	[73] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 9,
+ 	},
+ 	[74] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 10,
+ 	},
+ 	[75] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 11,
+ 	},
+ 	[76] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 12,
+ 	},
+ 	[77] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 13,
+ 	},
+ 	[78] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 14,
+ 	},
+ 	[79] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 15,
+ 	},
+ 	[80] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 16,
+ 	},
++	[81] = {
++		.mask	= IPIC_SIMSR_L,
++		.prio	= 0,
++		.force	= IPIC_SIFCR_L,
++		.bit	= 17,
++	},
++	[82] = {
++		.mask	= IPIC_SIMSR_L,
++		.prio	= 0,
++		.force	= IPIC_SIFCR_L,
++		.bit	= 18,
++	},
++	[83] = {
++		.mask	= IPIC_SIMSR_L,
++		.prio	= 0,
++		.force	= IPIC_SIFCR_L,
++		.bit	= 19,
++	},
+ 	[84] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 20,
+ 	},
+ 	[85] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 21,
+ 	},
++	[86] = {
++		.mask	= IPIC_SIMSR_L,
++		.prio	= 0,
++		.force	= IPIC_SIFCR_L,
++		.bit	= 22,
++	},
++	[87] = {
++		.mask	= IPIC_SIMSR_L,
++		.prio	= 0,
++		.force	= IPIC_SIFCR_L,
++		.bit	= 23,
++	},
++	[88] = {
++		.mask	= IPIC_SIMSR_L,
++		.prio	= 0,
++		.force	= IPIC_SIFCR_L,
++		.bit	= 24,
++	},
++	[89] = {
++		.mask	= IPIC_SIMSR_L,
++		.prio	= 0,
++		.force	= IPIC_SIFCR_L,
++		.bit	= 25,
++	},
+ 	[90] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+ 		.bit	= 26,
+ 	},
+ 	[91] = {
+-		.pend	= IPIC_SIPNR_L,
+ 		.mask	= IPIC_SIMSR_L,
+ 		.prio	= 0,
+ 		.force	= IPIC_SIFCR_L,
+@@ -412,6 +545,10 @@
+ 	temp &= ~(1 << (31 - ipic_info[src].bit));
+ 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
+ 
++	/* mb() can't guarantee that masking is finished.  But it does finish
++	 * for nearly all cases. */
++	mb();
++
+ 	spin_unlock_irqrestore(&ipic_lock, flags);
+ }
+ 
+@@ -424,9 +561,13 @@
+ 
+ 	spin_lock_irqsave(&ipic_lock, flags);
+ 
+-	temp = ipic_read(ipic->regs, ipic_info[src].pend);
++	temp = ipic_read(ipic->regs, ipic_info[src].ack);
+ 	temp |= (1 << (31 - ipic_info[src].bit));
+-	ipic_write(ipic->regs, ipic_info[src].pend, temp);
++	ipic_write(ipic->regs, ipic_info[src].ack, temp);
++
++	/* mb() can't guarantee that ack is finished.  But it does finish
++	 * for nearly all cases. */
++	mb();
+ 
+ 	spin_unlock_irqrestore(&ipic_lock, flags);
+ }
+@@ -444,9 +585,13 @@
+ 	temp &= ~(1 << (31 - ipic_info[src].bit));
+ 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
+ 
+-	temp = ipic_read(ipic->regs, ipic_info[src].pend);
++	temp = ipic_read(ipic->regs, ipic_info[src].ack);
+ 	temp |= (1 << (31 - ipic_info[src].bit));
+-	ipic_write(ipic->regs, ipic_info[src].pend, temp);
++	ipic_write(ipic->regs, ipic_info[src].ack, temp);
++
++	/* mb() can't guarantee that ack is finished.  But it does finish
++	 * for nearly all cases. */
++	mb();
+ 
+ 	spin_unlock_irqrestore(&ipic_lock, flags);
+ }
+@@ -468,14 +613,22 @@
+ 			flow_type);
+ 		return -EINVAL;
+ 	}
++	/* ipic supports only edge mode on external interrupts */
++	if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
++		printk(KERN_ERR "ipic: edge sense not supported on internal "
++				"interrupts\n");
++		return -EINVAL;
++	}
+ 
+ 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+ 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
+ 	if (flow_type & IRQ_TYPE_LEVEL_LOW)  {
+ 		desc->status |= IRQ_LEVEL;
+ 		desc->handle_irq = handle_level_irq;
++		desc->chip = &ipic_level_irq_chip;
+ 	} else {
+ 		desc->handle_irq = handle_edge_irq;
++		desc->chip = &ipic_edge_irq_chip;
+ 	}
+ 
+ 	/* only EXT IRQ senses are programmable on ipic
+@@ -500,7 +653,16 @@
+ 	return 0;
+ }
+ 
+-static struct irq_chip ipic_irq_chip = {
++/* level interrupts and edge interrupts have different ack operations */
++static struct irq_chip ipic_level_irq_chip = {
++	.typename	= " IPIC  ",
++	.unmask		= ipic_unmask_irq,
++	.mask		= ipic_mask_irq,
++	.mask_ack	= ipic_mask_irq,
++	.set_type	= ipic_set_irq_type,
++};
++
++static struct irq_chip ipic_edge_irq_chip = {
+ 	.typename	= " IPIC  ",
+ 	.unmask		= ipic_unmask_irq,
+ 	.mask		= ipic_mask_irq,
+@@ -519,13 +681,9 @@
+ 			 irq_hw_number_t hw)
+ {
+ 	struct ipic *ipic = h->host_data;
+-	struct irq_chip *chip;
+-
+-	/* Default chip */
+-	chip = &ipic->hc_irq;
+ 
+ 	set_irq_chip_data(virq, ipic);
+-	set_irq_chip_and_handler(virq, chip, handle_level_irq);
++	set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
+ 
+ 	/* Set default irq type */
+ 	set_irq_type(virq, IRQ_TYPE_NONE);
+@@ -584,7 +742,6 @@
+ 	ipic->regs = ioremap(res.start, res.end - res.start + 1);
+ 
+ 	ipic->irqhost->host_data = ipic;
+-	ipic->hc_irq = ipic_irq_chip;
+ 
+ 	/* init hw */
+ 	ipic_write(ipic->regs, IPIC_SICNR, 0x0);
+@@ -593,6 +750,10 @@
+ 	 * configure SICFR accordingly */
+ 	if (flags & IPIC_SPREADMODE_GRP_A)
+ 		temp |= SICFR_IPSA;
++	if (flags & IPIC_SPREADMODE_GRP_B)
++		temp |= SICFR_IPSB;
++	if (flags & IPIC_SPREADMODE_GRP_C)
++		temp |= SICFR_IPSC;
+ 	if (flags & IPIC_SPREADMODE_GRP_D)
+ 		temp |= SICFR_IPSD;
+ 	if (flags & IPIC_SPREADMODE_MIX_A)
+@@ -600,7 +761,7 @@
+ 	if (flags & IPIC_SPREADMODE_MIX_B)
+ 		temp |= SICFR_MPSB;
+ 
+-	ipic_write(ipic->regs, IPIC_SICNR, temp);
++	ipic_write(ipic->regs, IPIC_SICFR, temp);
+ 
+ 	/* handle MCP route */
+ 	temp = 0;
+@@ -672,10 +833,12 @@
+ 
+ void ipic_set_default_priority(void)
+ {
+-	ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT);
+-	ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT);
+-	ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT);
+-	ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT);
++	ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT);
++	ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT);
++	ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT);
++	ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT);
++	ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT);
++	ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT);
+ }
+ 
+ void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/ipic.h powerpc.git/arch/powerpc/sysdev/ipic.h
+--- linux-2.6.24/arch/powerpc/sysdev/ipic.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/ipic.h	2008-01-28 20:25:49.000000000 +0100
+@@ -23,13 +23,12 @@
+ #define IPIC_IRQ_EXT7 23
+ 
+ /* Default Priority Registers */
+-#define IPIC_SIPRR_A_DEFAULT 0x05309770
+-#define IPIC_SIPRR_D_DEFAULT 0x05309770
+-#define IPIC_SMPRR_A_DEFAULT 0x05309770
+-#define IPIC_SMPRR_B_DEFAULT 0x05309770
++#define IPIC_PRIORITY_DEFAULT 0x05309770
+ 
+ /* System Global Interrupt Configuration Register */
+ #define	SICFR_IPSA	0x00010000
++#define	SICFR_IPSB	0x00020000
++#define	SICFR_IPSC	0x00040000
+ #define	SICFR_IPSD	0x00080000
+ #define	SICFR_MPSA	0x00200000
+ #define	SICFR_MPSB	0x00400000
+@@ -45,13 +44,11 @@
+ 
+ 	/* The remapper for this IPIC */
+ 	struct irq_host		*irqhost;
+-
+-	/* The "linux" controller struct */
+-	struct irq_chip		hc_irq;
+ };
+ 
+ struct ipic_info {
+-	u8	pend;		/* pending register offset from base */
++	u8	ack;		/* pending register offset from base if the irq
++				   supports ack operation */
+ 	u8	mask;		/* mask register offset from base */
+ 	u8	prio;		/* priority register offset from base */
+ 	u8	force;		/* force register offset from base */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/mmio_nvram.c powerpc.git/arch/powerpc/sysdev/mmio_nvram.c
+--- linux-2.6.24/arch/powerpc/sysdev/mmio_nvram.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/mmio_nvram.c	2008-01-28 20:25:49.000000000 +0100
+@@ -99,7 +99,7 @@
+ 	nvram_addr = r.start;
+ 	mmio_nvram_len = r.end - r.start + 1;
+ 	if ( (!mmio_nvram_len) || (!nvram_addr) ) {
+-		printk(KERN_WARNING "nvram: address or lenght is 0\n");
++		printk(KERN_WARNING "nvram: address or length is 0\n");
+ 		ret = -EIO;
+ 		goto out;
+ 	}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/mpic.c powerpc.git/arch/powerpc/sysdev/mpic.c
+--- linux-2.6.24/arch/powerpc/sysdev/mpic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/mpic.c	2008-01-28 20:25:49.000000000 +0100
+@@ -83,6 +83,7 @@
+ 		MPIC_CPU_WHOAMI,
+ 		MPIC_CPU_INTACK,
+ 		MPIC_CPU_EOI,
++		MPIC_CPU_MCACK,
+ 
+ 		MPIC_IRQ_BASE,
+ 		MPIC_IRQ_STRIDE,
+@@ -121,6 +122,7 @@
+ 		TSI108_CPU_WHOAMI,
+ 		TSI108_CPU_INTACK,
+ 		TSI108_CPU_EOI,
++		TSI108_CPU_MCACK,
+ 
+ 		TSI108_IRQ_BASE,
+ 		TSI108_IRQ_STRIDE,
+@@ -265,7 +267,7 @@
+  */
+ 
+ 
+-static void _mpic_map_mmio(struct mpic *mpic, unsigned long phys_addr,
++static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr,
+ 			   struct mpic_reg_bank *rb, unsigned int offset,
+ 			   unsigned int size)
+ {
+@@ -285,7 +287,7 @@
+ 	BUG_ON(!DCR_MAP_OK(rb->dhost));
+ }
+ 
+-static inline void mpic_map(struct mpic *mpic, unsigned long phys_addr,
++static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr,
+ 			    struct mpic_reg_bank *rb, unsigned int offset,
+ 			    unsigned int size)
+ {
+@@ -612,12 +614,11 @@
+ }
+ 
+ #ifdef CONFIG_SMP
+-static irqreturn_t mpic_ipi_action(int irq, void *dev_id)
++static irqreturn_t mpic_ipi_action(int irq, void *data)
+ {
+-	struct mpic *mpic;
++	long ipi = (long)data;
+ 
+-	mpic = mpic_find(irq, NULL);
+-	smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]);
++	smp_message_recv(ipi);
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -842,6 +843,24 @@
+ 	return 0;
+ }
+ 
++void mpic_set_vector(unsigned int virq, unsigned int vector)
++{
++	struct mpic *mpic = mpic_from_irq(virq);
++	unsigned int src = mpic_irq_to_hw(virq);
++	unsigned int vecpri;
++
++	DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n",
++	    mpic, virq, src, vector);
++
++	if (src >= mpic->irq_count)
++		return;
++
++	vecpri = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
++	vecpri = vecpri & ~MPIC_INFO(VECPRI_VECTOR_MASK);
++	vecpri |= vector;
++	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
++}
++
+ static struct irq_chip mpic_irq_chip = {
+ 	.mask		= mpic_mask_irq,
+ 	.unmask		= mpic_unmask_irq,
+@@ -1109,6 +1128,11 @@
+ 			mb();
+ 	}
+ 
++	if (flags & MPIC_ENABLE_MCK)
++		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
++			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
++			   | MPIC_GREG_GCONF_MCK);
++
+ 	/* Read feature register, calculate num CPUs and, for non-ISU
+ 	 * MPICs, num sources as well. On ISU MPICs, sources are counted
+ 	 * as ISUs are added
+@@ -1230,6 +1254,8 @@
+ 		mpic_u3msi_init(mpic);
+ 	}
+ 
++	mpic_pasemi_msi_init(mpic);
++
+ 	for (i = 0; i < mpic->num_sources; i++) {
+ 		/* start with vector = source number, and masked */
+ 		u32 vecpri = MPIC_VECPRI_MASK | i |
+@@ -1253,6 +1279,11 @@
+ 			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
+ 			   | MPIC_GREG_GCONF_8259_PTHROU_DIS);
+ 
++	if (mpic->flags & MPIC_NO_BIAS)
++		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
++			mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
++			| MPIC_GREG_GCONF_NO_BIAS);
++
+ 	/* Set current processor priority to 0 */
+ 	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
+ 
+@@ -1419,13 +1450,13 @@
+ 		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
+ }
+ 
+-unsigned int mpic_get_one_irq(struct mpic *mpic)
++static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg)
+ {
+ 	u32 src;
+ 
+-	src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK);
++	src = mpic_cpu_read(reg) & MPIC_INFO(VECPRI_VECTOR_MASK);
+ #ifdef DEBUG_LOW
+-	DBG("%s: get_one_irq(): %d\n", mpic->name, src);
++	DBG("%s: get_one_irq(reg 0x%x): %d\n", mpic->name, reg, src);
+ #endif
+ 	if (unlikely(src == mpic->spurious_vec)) {
+ 		if (mpic->flags & MPIC_SPV_EOI)
+@@ -1443,6 +1474,11 @@
+ 	return irq_linear_revmap(mpic->irqhost, src);
+ }
+ 
++unsigned int mpic_get_one_irq(struct mpic *mpic)
++{
++	return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_INTACK));
++}
++
+ unsigned int mpic_get_irq(void)
+ {
+ 	struct mpic *mpic = mpic_primary;
+@@ -1452,12 +1488,20 @@
+ 	return mpic_get_one_irq(mpic);
+ }
+ 
++unsigned int mpic_get_mcirq(void)
++{
++	struct mpic *mpic = mpic_primary;
++
++	BUG_ON(mpic == NULL);
++
++	return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_MCACK));
++}
+ 
+ #ifdef CONFIG_SMP
+ void mpic_request_ipis(void)
+ {
+ 	struct mpic *mpic = mpic_primary;
+-	int i, err;
++	long i, err;
+ 	static char *ipi_names[] = {
+ 		"IPI0 (call function)",
+ 		"IPI1 (reschedule)",
+@@ -1472,14 +1516,14 @@
+ 		unsigned int vipi = irq_create_mapping(mpic->irqhost,
+ 						       mpic->ipi_vecs[0] + i);
+ 		if (vipi == NO_IRQ) {
+-			printk(KERN_ERR "Failed to map IPI %d\n", i);
++			printk(KERN_ERR "Failed to map IPI %ld\n", i);
+ 			break;
+ 		}
+ 		err = request_irq(vipi, mpic_ipi_action,
+ 				  IRQF_DISABLED|IRQF_PERCPU,
+-				  ipi_names[i], mpic);
++				  ipi_names[i], (void *)i);
+ 		if (err) {
+-			printk(KERN_ERR "Request of irq %d for IPI %d failed\n",
++			printk(KERN_ERR "Request of irq %d for IPI %ld failed\n",
+ 			       vipi, i);
+ 			break;
+ 		}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/mpic.h powerpc.git/arch/powerpc/sysdev/mpic.h
+--- linux-2.6.24/arch/powerpc/sysdev/mpic.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/mpic.h	2008-01-28 20:25:49.000000000 +0100
+@@ -17,6 +17,7 @@
+ extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num);
+ extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num);
+ extern int mpic_u3msi_init(struct mpic *mpic);
++extern int mpic_pasemi_msi_init(struct mpic *mpic);
+ #else
+ static inline void mpic_msi_reserve_hwirq(struct mpic *mpic,
+ 					  irq_hw_number_t hwirq)
+@@ -28,12 +29,15 @@
+ {
+ 	return -1;
+ }
++
++static inline int mpic_pasemi_msi_init(struct mpic *mpic)
++{
++	return -1;
++}
+ #endif
+ 
+ extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
+-extern void mpic_end_irq(unsigned int irq);
+-extern void mpic_mask_irq(unsigned int irq);
+-extern void mpic_unmask_irq(unsigned int irq);
++extern void mpic_set_vector(unsigned int virq, unsigned int vector);
+ extern void mpic_set_affinity(unsigned int irq, cpumask_t cpumask);
+ 
+ #endif /* _POWERPC_SYSDEV_MPIC_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/mpic_pasemi_msi.c powerpc.git/arch/powerpc/sysdev/mpic_pasemi_msi.c
+--- linux-2.6.24/arch/powerpc/sysdev/mpic_pasemi_msi.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/mpic_pasemi_msi.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,172 @@
++/*
++ * Copyright 2007, Olof Johansson, PA Semi
++ *
++ * Based on arch/powerpc/sysdev/mpic_u3msi.c:
++ *
++ * Copyright 2006, Segher Boessenkool, IBM Corporation.
++ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
++ *
++ * 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; version 2 of the
++ * License.
++ *
++ */
++
++#undef DEBUG
++
++#include <linux/irq.h>
++#include <linux/bootmem.h>
++#include <linux/msi.h>
++#include <asm/mpic.h>
++#include <asm/prom.h>
++#include <asm/hw_irq.h>
++#include <asm/ppc-pci.h>
++
++#include "mpic.h"
++
++/* Allocate 16 interrupts per device, to give an alignment of 16,
++ * since that's the size of the grouping w.r.t. affinity. If someone
++ * needs more than 32 MSI's down the road we'll have to rethink this,
++ * but it should be OK for now.
++ */
++#define ALLOC_CHUNK 16
++
++#define PASEMI_MSI_ADDR 0xfc080000
++
++/* A bit ugly, can we get this from the pci_dev somehow? */
++static struct mpic *msi_mpic;
++
++
++static void mpic_pasemi_msi_mask_irq(unsigned int irq)
++{
++	pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq);
++	mask_msi_irq(irq);
++	mpic_mask_irq(irq);
++}
++
++static void mpic_pasemi_msi_unmask_irq(unsigned int irq)
++{
++	pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq);
++	mpic_unmask_irq(irq);
++	unmask_msi_irq(irq);
++}
++
++static struct irq_chip mpic_pasemi_msi_chip = {
++	.shutdown	= mpic_pasemi_msi_mask_irq,
++	.mask		= mpic_pasemi_msi_mask_irq,
++	.unmask		= mpic_pasemi_msi_unmask_irq,
++	.eoi		= mpic_end_irq,
++	.set_type	= mpic_set_irq_type,
++	.set_affinity	= mpic_set_affinity,
++	.typename	= "PASEMI-MSI ",
++};
++
++static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
++{
++	if (type == PCI_CAP_ID_MSIX)
++		pr_debug("pasemi_msi: MSI-X untested, trying anyway\n");
++
++	return 0;
++}
++
++static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
++{
++	struct msi_desc *entry;
++
++	pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev);
++
++	list_for_each_entry(entry, &pdev->msi_list, list) {
++		if (entry->irq == NO_IRQ)
++			continue;
++
++		set_irq_msi(entry->irq, NULL);
++		mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq),
++				     ALLOC_CHUNK);
++		irq_dispose_mapping(entry->irq);
++	}
++
++	return;
++}
++
++static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
++{
++	irq_hw_number_t hwirq;
++	unsigned int virq;
++	struct msi_desc *entry;
++	struct msi_msg msg;
++	u64 addr;
++
++	pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n",
++		 pdev, nvec, type);
++
++	msg.address_hi = 0;
++	msg.address_lo = PASEMI_MSI_ADDR;
++
++	list_for_each_entry(entry, &pdev->msi_list, list) {
++		/* Allocate 16 interrupts for now, since that's the grouping for
++		 * affinity. This can be changed later if it turns out 32 is too
++		 * few MSIs for someone, but restrictions will apply to how the
++		 * sources can be changed independently.
++		 */
++		hwirq = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK);
++		if (hwirq < 0) {
++			pr_debug("pasemi_msi: failed allocating hwirq\n");
++			return hwirq;
++		}
++
++		virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
++		if (virq == NO_IRQ) {
++			pr_debug("pasemi_msi: failed mapping hwirq 0x%lx\n", hwirq);
++			mpic_msi_free_hwirqs(msi_mpic, hwirq, ALLOC_CHUNK);
++			return -ENOSPC;
++		}
++
++		/* Vector on MSI is really an offset, the hardware adds
++		 * it to the value written at the magic address. So set
++		 * it to 0 to remain sane.
++		 */
++		mpic_set_vector(virq, 0);
++
++		set_irq_msi(virq, entry);
++		set_irq_chip(virq, &mpic_pasemi_msi_chip);
++		set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
++
++		pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%lx\n",
++			  virq, hwirq, addr);
++
++		/* Likewise, the device writes [0...511] into the target
++		 * register to generate MSI [512...1023]
++		 */
++		msg.data = hwirq-0x200;
++		write_msi_msg(virq, &msg);
++	}
++
++	return 0;
++}
++
++int mpic_pasemi_msi_init(struct mpic *mpic)
++{
++	int rc;
++
++	if (!mpic->irqhost->of_node ||
++	    !of_device_is_compatible(mpic->irqhost->of_node,
++				     "pasemi,pwrficient-openpic"))
++		return -ENODEV;
++
++	rc = mpic_msi_init_allocator(mpic);
++	if (rc) {
++		pr_debug("pasemi_msi: Error allocating bitmap!\n");
++		return rc;
++	}
++
++	pr_debug("pasemi_msi: Registering PA Semi MPIC MSI callbacks\n");
++
++	msi_mpic = mpic;
++	WARN_ON(ppc_md.setup_msi_irqs);
++	ppc_md.setup_msi_irqs = pasemi_msi_setup_msi_irqs;
++	ppc_md.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs;
++	ppc_md.msi_check_device = pasemi_msi_check_device;
++
++	return 0;
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/mv64x60_dev.c powerpc.git/arch/powerpc/sysdev/mv64x60_dev.c
+--- linux-2.6.24/arch/powerpc/sysdev/mv64x60_dev.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/mv64x60_dev.c	2008-01-28 20:25:49.000000000 +0100
+@@ -241,7 +241,7 @@
+ 
+ 	/* only register the shared platform device the first time through */
+ 	if (id == 0 && (err = eth_register_shared_pdev(np)))
+-		return err;;
++		return err;
+ 
+ 	memset(r, 0, sizeof(r));
+ 	of_irq_to_resource(np, 0, &r[0]);
+@@ -451,22 +451,19 @@
+ 	int id;
+ 	int err;
+ 
+-	for (id = 0;
+-	     (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); id++)
+-		if ((err = mv64x60_mpsc_device_setup(np, id)))
++	id = 0;
++	for_each_compatible_node(np, "serial", "marvell,mpsc")
++		if ((err = mv64x60_mpsc_device_setup(np, id++)))
+ 			goto error;
+ 
+-	for (id = 0;
+-	     (np = of_find_compatible_node(np, "network",
+-					   "marvell,mv64x60-eth"));
+-	     id++)
+-		if ((err = mv64x60_eth_device_setup(np, id)))
++	id = 0;
++	for_each_compatible_node(np, "network", "marvell,mv64x60-eth")
++		if ((err = mv64x60_eth_device_setup(np, id++)))
+ 			goto error;
+ 
+-	for (id = 0;
+-	     (np = of_find_compatible_node(np, "i2c", "marvell,mv64x60-i2c"));
+-	     id++)
+-		if ((err = mv64x60_i2c_device_setup(np, id)))
++	id = 0;
++	for_each_compatible_node(np, "i2c", "marvell,mv64x60-i2c")
++		if ((err = mv64x60_i2c_device_setup(np, id++)))
+ 			goto error;
+ 
+ 	/* support up to one watchdog timer */
+@@ -477,7 +474,6 @@
+ 		of_node_put(np);
+ 	}
+ 
+-
+ 	return 0;
+ 
+ error:
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/mv64x60_pci.c powerpc.git/arch/powerpc/sysdev/mv64x60_pci.c
+--- linux-2.6.24/arch/powerpc/sysdev/mv64x60_pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/mv64x60_pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -164,8 +164,8 @@
+ 
+ void __init mv64x60_pci_init(void)
+ {
+-	struct device_node *np = NULL;
++	struct device_node *np;
+ 
+-	while ((np = of_find_compatible_node(np, "pci", "marvell,mv64x60-pci")))
++	for_each_compatible_node(np, "pci", "marvell,mv64x60-pci")
+ 		mv64x60_add_bridge(np);
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/mv64x60_udbg.c powerpc.git/arch/powerpc/sysdev/mv64x60_udbg.c
+--- linux-2.6.24/arch/powerpc/sysdev/mv64x60_udbg.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/mv64x60_udbg.c	2008-01-28 20:25:49.000000000 +0100
+@@ -85,10 +85,10 @@
+ 	if (!stdout)
+ 		return;
+ 
+-	for (np = NULL;
+-	     (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); )
++	for_each_compatible_node(np, "serial", "marvell,mpsc") {
+ 		if (np == stdout)
+ 			break;
++	}
+ 
+ 	of_node_put(stdout);
+ 	if (!np)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/of_rtc.c powerpc.git/arch/powerpc/sysdev/of_rtc.c
+--- linux-2.6.24/arch/powerpc/sysdev/of_rtc.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/of_rtc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,59 @@
++/*
++ * Instantiate mmio-mapped RTC chips based on device tree information
++ *
++ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/init.h>
++#include <linux/of_platform.h>
++
++static __initdata struct {
++	const char *compatible;
++	char *plat_name;
++} of_rtc_table[] = {
++	{ "ds1743-nvram", "rtc-ds1742" },
++};
++
++void __init of_instantiate_rtc(void)
++{
++	struct device_node *node;
++	int err;
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(of_rtc_table); i++) {
++		char *plat_name = of_rtc_table[i].plat_name;
++
++		for_each_compatible_node(node, NULL,
++					 of_rtc_table[i].compatible) {
++			struct resource *res;
++
++			res = kmalloc(sizeof(*res), GFP_KERNEL);
++			if (!res) {
++				printk(KERN_ERR "OF RTC: Out of memory "
++				       "allocating resource structure for %s\n",
++				       node->full_name);
++				continue;
++			}
++
++			err = of_address_to_resource(node, 0, res);
++			if (err) {
++				printk(KERN_ERR "OF RTC: Error "
++				       "translating resources for %s\n",
++				       node->full_name);
++				continue;
++			}
++
++			printk(KERN_INFO "OF_RTC: %s is a %s @ 0x%llx-0x%llx\n",
++			       node->full_name, plat_name,
++			       (unsigned long long)res->start,
++			       (unsigned long long)res->end);
++			platform_device_register_simple(plat_name, -1, res, 1);
++		}
++	}
++}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/pmi.c powerpc.git/arch/powerpc/sysdev/pmi.c
+--- linux-2.6.24/arch/powerpc/sysdev/pmi.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/pmi.c	2008-01-28 20:25:49.000000000 +0100
+@@ -28,9 +28,9 @@
+ #include <linux/completion.h>
+ #include <linux/spinlock.h>
+ #include <linux/workqueue.h>
++#include <linux/of_device.h>
++#include <linux/of_platform.h>
+ 
+-#include <asm/of_device.h>
+-#include <asm/of_platform.h>
+ #include <asm/io.h>
+ #include <asm/pmi.h>
+ #include <asm/prom.h>
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/ppc4xx_pci.c powerpc.git/arch/powerpc/sysdev/ppc4xx_pci.c
+--- linux-2.6.24/arch/powerpc/sysdev/ppc4xx_pci.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/ppc4xx_pci.c	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,1528 @@
++/*
++ * PCI / PCI-X / PCI-Express support for 4xx parts
++ *
++ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
++ *
++ * Most PCI Express code is coming from Stefan Roese implementation for
++ * arch/ppc in the Denx tree, slightly reworked by me.
++ *
++ * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
++ *
++ * Some of that comes itself from a previous implementation for 440SPE only
++ * by Roland Dreier:
++ *
++ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
++ * Roland Dreier <rolandd@cisco.com>
++ *
++ */
++
++#undef DEBUG
++
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/of.h>
++#include <linux/bootmem.h>
++#include <linux/delay.h>
++
++#include <asm/io.h>
++#include <asm/pci-bridge.h>
++#include <asm/machdep.h>
++#include <asm/dcr.h>
++#include <asm/dcr-regs.h>
++
++#include "ppc4xx_pci.h"
++
++static int dma_offset_set;
++
++/* Move that to a useable header */
++extern unsigned long total_memory;
++
++#define U64_TO_U32_LOW(val)	((u32)((val) & 0x00000000ffffffffULL))
++#define U64_TO_U32_HIGH(val)	((u32)((val) >> 32))
++
++#ifdef CONFIG_RESOURCES_64BIT
++#define RES_TO_U32_LOW(val)	U64_TO_U32_LOW(val)
++#define RES_TO_U32_HIGH(val)	U64_TO_U32_HIGH(val)
++#else
++#define RES_TO_U32_LOW(val)	(val)
++#define RES_TO_U32_HIGH(val)	(0)
++#endif
++
++static inline int ppc440spe_revA(void)
++{
++	/* Catch both 440SPe variants, with and without RAID6 support */
++        if ((mfspr(SPRN_PVR) & 0xffefffff) == 0x53421890)
++                return 1;
++        else
++                return 0;
++}
++
++static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev)
++{
++	struct pci_controller *hose;
++	int i;
++
++	if (dev->devfn != 0 || dev->bus->self != NULL)
++		return;
++
++	hose = pci_bus_to_host(dev->bus);
++	if (hose == NULL)
++		return;
++
++	if (!of_device_is_compatible(hose->dn, "ibm,plb-pciex") &&
++	    !of_device_is_compatible(hose->dn, "ibm,plb-pcix") &&
++	    !of_device_is_compatible(hose->dn, "ibm,plb-pci"))
++		return;
++
++	/* Hide the PCI host BARs from the kernel as their content doesn't
++	 * fit well in the resource management
++	 */
++	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
++		dev->resource[i].start = dev->resource[i].end = 0;
++		dev->resource[i].flags = 0;
++	}
++
++	printk(KERN_INFO "PCI: Hiding 4xx host bridge resources %s\n",
++	       pci_name(dev));
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_ppc4xx_pci_bridge);
++
++static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
++					  void __iomem *reg,
++					  struct resource *res)
++{
++	u64 size;
++	const u32 *ranges;
++	int rlen;
++	int pna = of_n_addr_cells(hose->dn);
++	int np = pna + 5;
++
++	/* Default */
++	res->start = 0;
++	res->end = size = 0x80000000;
++	res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
++
++	/* Get dma-ranges property */
++	ranges = of_get_property(hose->dn, "dma-ranges", &rlen);
++	if (ranges == NULL)
++		goto out;
++
++	/* Walk it */
++	while ((rlen -= np * 4) >= 0) {
++		u32 pci_space = ranges[0];
++		u64 pci_addr = of_read_number(ranges + 1, 2);
++		u64 cpu_addr = of_translate_dma_address(hose->dn, ranges + 3);
++		size = of_read_number(ranges + pna + 3, 2);
++		ranges += np;
++		if (cpu_addr == OF_BAD_ADDR || size == 0)
++			continue;
++
++		/* We only care about memory */
++		if ((pci_space & 0x03000000) != 0x02000000)
++			continue;
++
++		/* We currently only support memory at 0, and pci_addr
++		 * within 32 bits space
++		 */
++		if (cpu_addr != 0 || pci_addr > 0xffffffff) {
++			printk(KERN_WARNING "%s: Ignored unsupported dma range"
++			       " 0x%016llx...0x%016llx -> 0x%016llx\n",
++			       hose->dn->full_name,
++			       pci_addr, pci_addr + size - 1, cpu_addr);
++			continue;
++		}
++
++		/* Check if not prefetchable */
++		if (!(pci_space & 0x40000000))
++			res->flags &= ~IORESOURCE_PREFETCH;
++
++
++		/* Use that */
++		res->start = pci_addr;
++#ifndef CONFIG_RESOURCES_64BIT
++		/* Beware of 32 bits resources */
++		if ((pci_addr + size) > 0x100000000ull)
++			res->end = 0xffffffff;
++		else
++#endif
++			res->end = res->start + size - 1;
++		break;
++	}
++
++	/* We only support one global DMA offset */
++	if (dma_offset_set && pci_dram_offset != res->start) {
++		printk(KERN_ERR "%s: dma-ranges(s) mismatch\n",
++		       hose->dn->full_name);
++		return -ENXIO;
++	}
++
++	/* Check that we can fit all of memory as we don't support
++	 * DMA bounce buffers
++	 */
++	if (size < total_memory) {
++		printk(KERN_ERR "%s: dma-ranges too small "
++		       "(size=%llx total_memory=%lx)\n",
++		       hose->dn->full_name, size, total_memory);
++		return -ENXIO;
++	}
++
++	/* Check we are a power of 2 size and that base is a multiple of size*/
++	if (!is_power_of_2(size) ||
++	    (res->start & (size - 1)) != 0) {
++		printk(KERN_ERR "%s: dma-ranges unaligned\n",
++		       hose->dn->full_name);
++		return -ENXIO;
++	}
++
++	/* Check that we are fully contained within 32 bits space */
++	if (res->end > 0xffffffff) {
++		printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n",
++		       hose->dn->full_name);
++		return -ENXIO;
++	}
++ out:
++	dma_offset_set = 1;
++	pci_dram_offset = res->start;
++
++	printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n",
++	       pci_dram_offset);
++	return 0;
++}
++
++/*
++ * 4xx PCI 2.x part
++ */
++
++static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose,
++					     void __iomem *reg)
++{
++	u32 la, ma, pcila, pciha;
++	int i, j;
++
++	/* Setup outbound memory windows */
++	for (i = j = 0; i < 3; i++) {
++		struct resource *res = &hose->mem_resources[i];
++
++		/* we only care about memory windows */
++		if (!(res->flags & IORESOURCE_MEM))
++			continue;
++		if (j > 2) {
++			printk(KERN_WARNING "%s: Too many ranges\n",
++			       hose->dn->full_name);
++			break;
++		}
++
++		/* Calculate register values */
++		la = res->start;
++		pciha = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
++		pcila = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
++
++		ma = res->end + 1 - res->start;
++		if (!is_power_of_2(ma) || ma < 0x1000 || ma > 0xffffffffu) {
++			printk(KERN_WARNING "%s: Resource out of range\n",
++			       hose->dn->full_name);
++			continue;
++		}
++		ma = (0xffffffffu << ilog2(ma)) | 0x1;
++		if (res->flags & IORESOURCE_PREFETCH)
++			ma |= 0x2;
++
++		/* Program register values */
++		writel(la, reg + PCIL0_PMM0LA + (0x10 * j));
++		writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * j));
++		writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * j));
++		writel(ma, reg + PCIL0_PMM0MA + (0x10 * j));
++		j++;
++	}
++}
++
++static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose,
++					     void __iomem *reg,
++					     const struct resource *res)
++{
++	resource_size_t size = res->end - res->start + 1;
++	u32 sa;
++
++	/* Calculate window size */
++	sa = (0xffffffffu << ilog2(size)) | 1;
++	sa |= 0x1;
++
++	/* RAM is always at 0 local for now */
++	writel(0, reg + PCIL0_PTM1LA);
++	writel(sa, reg + PCIL0_PTM1MS);
++
++	/* Map on PCI side */
++	early_write_config_dword(hose, hose->first_busno, 0,
++				 PCI_BASE_ADDRESS_1, res->start);
++	early_write_config_dword(hose, hose->first_busno, 0,
++				 PCI_BASE_ADDRESS_2, 0x00000000);
++	early_write_config_word(hose, hose->first_busno, 0,
++				PCI_COMMAND, 0x0006);
++}
++
++static void __init ppc4xx_probe_pci_bridge(struct device_node *np)
++{
++	/* NYI */
++	struct resource rsrc_cfg;
++	struct resource rsrc_reg;
++	struct resource dma_window;
++	struct pci_controller *hose = NULL;
++	void __iomem *reg = NULL;
++	const int *bus_range;
++	int primary = 0;
++
++	/* Fetch config space registers address */
++	if (of_address_to_resource(np, 0, &rsrc_cfg)) {
++		printk(KERN_ERR "%s:Can't get PCI config register base !",
++		       np->full_name);
++		return;
++	}
++	/* Fetch host bridge internal registers address */
++	if (of_address_to_resource(np, 3, &rsrc_reg)) {
++		printk(KERN_ERR "%s: Can't get PCI internal register base !",
++		       np->full_name);
++		return;
++	}
++
++	/* Check if primary bridge */
++	if (of_get_property(np, "primary", NULL))
++		primary = 1;
++
++	/* Get bus range if any */
++	bus_range = of_get_property(np, "bus-range", NULL);
++
++	/* Map registers */
++	reg = ioremap(rsrc_reg.start, rsrc_reg.end + 1 - rsrc_reg.start);
++	if (reg == NULL) {
++		printk(KERN_ERR "%s: Can't map registers !", np->full_name);
++		goto fail;
++	}
++
++	/* Allocate the host controller data structure */
++	hose = pcibios_alloc_controller(np);
++	if (!hose)
++		goto fail;
++
++	hose->first_busno = bus_range ? bus_range[0] : 0x0;
++	hose->last_busno = bus_range ? bus_range[1] : 0xff;
++
++	/* Setup config space */
++	setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0);
++
++	/* Disable all windows */
++	writel(0, reg + PCIL0_PMM0MA);
++	writel(0, reg + PCIL0_PMM1MA);
++	writel(0, reg + PCIL0_PMM2MA);
++	writel(0, reg + PCIL0_PTM1MS);
++	writel(0, reg + PCIL0_PTM2MS);
++
++	/* Parse outbound mapping resources */
++	pci_process_bridge_OF_ranges(hose, np, primary);
++
++	/* Parse inbound mapping resources */
++	if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0)
++		goto fail;
++
++	/* Configure outbound ranges POMs */
++	ppc4xx_configure_pci_PMMs(hose, reg);
++
++	/* Configure inbound ranges PIMs */
++	ppc4xx_configure_pci_PTMs(hose, reg, &dma_window);
++
++	/* We don't need the registers anymore */
++	iounmap(reg);
++	return;
++
++ fail:
++	if (hose)
++		pcibios_free_controller(hose);
++	if (reg)
++		iounmap(reg);
++}
++
++/*
++ * 4xx PCI-X part
++ */
++
++static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
++					      void __iomem *reg)
++{
++	u32 lah, lal, pciah, pcial, sa;
++	int i, j;
++
++	/* Setup outbound memory windows */
++	for (i = j = 0; i < 3; i++) {
++		struct resource *res = &hose->mem_resources[i];
++
++		/* we only care about memory windows */
++		if (!(res->flags & IORESOURCE_MEM))
++			continue;
++		if (j > 1) {
++			printk(KERN_WARNING "%s: Too many ranges\n",
++			       hose->dn->full_name);
++			break;
++		}
++
++		/* Calculate register values */
++		lah = RES_TO_U32_HIGH(res->start);
++		lal = RES_TO_U32_LOW(res->start);
++		pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
++		pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
++		sa = res->end + 1 - res->start;
++		if (!is_power_of_2(sa) || sa < 0x100000 ||
++		    sa > 0xffffffffu) {
++			printk(KERN_WARNING "%s: Resource out of range\n",
++			       hose->dn->full_name);
++			continue;
++		}
++		sa = (0xffffffffu << ilog2(sa)) | 0x1;
++
++		/* Program register values */
++		if (j == 0) {
++			writel(lah, reg + PCIX0_POM0LAH);
++			writel(lal, reg + PCIX0_POM0LAL);
++			writel(pciah, reg + PCIX0_POM0PCIAH);
++			writel(pcial, reg + PCIX0_POM0PCIAL);
++			writel(sa, reg + PCIX0_POM0SA);
++		} else {
++			writel(lah, reg + PCIX0_POM1LAH);
++			writel(lal, reg + PCIX0_POM1LAL);
++			writel(pciah, reg + PCIX0_POM1PCIAH);
++			writel(pcial, reg + PCIX0_POM1PCIAL);
++			writel(sa, reg + PCIX0_POM1SA);
++		}
++		j++;
++	}
++}
++
++static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose,
++					      void __iomem *reg,
++					      const struct resource *res,
++					      int big_pim,
++					      int enable_msi_hole)
++{
++	resource_size_t size = res->end - res->start + 1;
++	u32 sa;
++
++	/* RAM is always at 0 */
++	writel(0x00000000, reg + PCIX0_PIM0LAH);
++	writel(0x00000000, reg + PCIX0_PIM0LAL);
++
++	/* Calculate window size */
++	sa = (0xffffffffu << ilog2(size)) | 1;
++	sa |= 0x1;
++	if (res->flags & IORESOURCE_PREFETCH)
++		sa |= 0x2;
++	if (enable_msi_hole)
++		sa |= 0x4;
++	writel(sa, reg + PCIX0_PIM0SA);
++	if (big_pim)
++		writel(0xffffffff, reg + PCIX0_PIM0SAH);
++
++	/* Map on PCI side */
++	writel(0x00000000, reg + PCIX0_BAR0H);
++	writel(res->start, reg + PCIX0_BAR0L);
++	writew(0x0006, reg + PCIX0_COMMAND);
++}
++
++static void __init ppc4xx_probe_pcix_bridge(struct device_node *np)
++{
++	struct resource rsrc_cfg;
++	struct resource rsrc_reg;
++	struct resource dma_window;
++	struct pci_controller *hose = NULL;
++	void __iomem *reg = NULL;
++	const int *bus_range;
++	int big_pim = 0, msi = 0, primary = 0;
++
++	/* Fetch config space registers address */
++	if (of_address_to_resource(np, 0, &rsrc_cfg)) {
++		printk(KERN_ERR "%s:Can't get PCI-X config register base !",
++		       np->full_name);
++		return;
++	}
++	/* Fetch host bridge internal registers address */
++	if (of_address_to_resource(np, 3, &rsrc_reg)) {
++		printk(KERN_ERR "%s: Can't get PCI-X internal register base !",
++		       np->full_name);
++		return;
++	}
++
++	/* Check if it supports large PIMs (440GX) */
++	if (of_get_property(np, "large-inbound-windows", NULL))
++		big_pim = 1;
++
++	/* Check if we should enable MSIs inbound hole */
++	if (of_get_property(np, "enable-msi-hole", NULL))
++		msi = 1;
++
++	/* Check if primary bridge */
++	if (of_get_property(np, "primary", NULL))
++		primary = 1;
++
++	/* Get bus range if any */
++	bus_range = of_get_property(np, "bus-range", NULL);
++
++	/* Map registers */
++	reg = ioremap(rsrc_reg.start, rsrc_reg.end + 1 - rsrc_reg.start);
++	if (reg == NULL) {
++		printk(KERN_ERR "%s: Can't map registers !", np->full_name);
++		goto fail;
++	}
++
++	/* Allocate the host controller data structure */
++	hose = pcibios_alloc_controller(np);
++	if (!hose)
++		goto fail;
++
++	hose->first_busno = bus_range ? bus_range[0] : 0x0;
++	hose->last_busno = bus_range ? bus_range[1] : 0xff;
++
++	/* Setup config space */
++	setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0);
++
++	/* Disable all windows */
++	writel(0, reg + PCIX0_POM0SA);
++	writel(0, reg + PCIX0_POM1SA);
++	writel(0, reg + PCIX0_POM2SA);
++	writel(0, reg + PCIX0_PIM0SA);
++	writel(0, reg + PCIX0_PIM1SA);
++	writel(0, reg + PCIX0_PIM2SA);
++	if (big_pim) {
++		writel(0, reg + PCIX0_PIM0SAH);
++		writel(0, reg + PCIX0_PIM2SAH);
++	}
++
++	/* Parse outbound mapping resources */
++	pci_process_bridge_OF_ranges(hose, np, primary);
++
++	/* Parse inbound mapping resources */
++	if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0)
++		goto fail;
++
++	/* Configure outbound ranges POMs */
++	ppc4xx_configure_pcix_POMs(hose, reg);
++
++	/* Configure inbound ranges PIMs */
++	ppc4xx_configure_pcix_PIMs(hose, reg, &dma_window, big_pim, msi);
++
++	/* We don't need the registers anymore */
++	iounmap(reg);
++	return;
++
++ fail:
++	if (hose)
++		pcibios_free_controller(hose);
++	if (reg)
++		iounmap(reg);
++}
++
++#ifdef CONFIG_PPC4xx_PCI_EXPRESS
++
++/*
++ * 4xx PCI-Express part
++ *
++ * We support 3 parts currently based on the compatible property:
++ *
++ * ibm,plb-pciex-440spe
++ * ibm,plb-pciex-405ex
++ *
++ * Anything else will be rejected for now as they are all subtly
++ * different unfortunately.
++ *
++ */
++
++#define MAX_PCIE_BUS_MAPPED	0x40
++
++struct ppc4xx_pciex_port
++{
++	struct pci_controller	*hose;
++	struct device_node	*node;
++	unsigned int		index;
++	int			endpoint;
++	int			link;
++	int			has_ibpre;
++	unsigned int		sdr_base;
++	dcr_host_t		dcrs;
++	struct resource		cfg_space;
++	struct resource		utl_regs;
++	void __iomem		*utl_base;
++};
++
++static struct ppc4xx_pciex_port *ppc4xx_pciex_ports;
++static unsigned int ppc4xx_pciex_port_count;
++
++struct ppc4xx_pciex_hwops
++{
++	int (*core_init)(struct device_node *np);
++	int (*port_init_hw)(struct ppc4xx_pciex_port *port);
++	int (*setup_utl)(struct ppc4xx_pciex_port *port);
++};
++
++static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops;
++
++#ifdef CONFIG_44x
++
++/* Check various reset bits of the 440SPe PCIe core */
++static int __init ppc440spe_pciex_check_reset(struct device_node *np)
++{
++	u32 valPE0, valPE1, valPE2;
++	int err = 0;
++
++	/* SDR0_PEGPLLLCT1 reset */
++	if (!(mfdcri(SDR0, PESDR0_PLLLCT1) & 0x01000000)) {
++		/*
++		 * the PCIe core was probably already initialised
++		 * by firmware - let's re-reset RCSSET regs
++		 *
++		 * -- Shouldn't we also re-reset the whole thing ? -- BenH
++		 */
++		pr_debug("PCIE: SDR0_PLLLCT1 already reset.\n");
++		mtdcri(SDR0, PESDR0_440SPE_RCSSET, 0x01010000);
++		mtdcri(SDR0, PESDR1_440SPE_RCSSET, 0x01010000);
++		mtdcri(SDR0, PESDR2_440SPE_RCSSET, 0x01010000);
++	}
++
++	valPE0 = mfdcri(SDR0, PESDR0_440SPE_RCSSET);
++	valPE1 = mfdcri(SDR0, PESDR1_440SPE_RCSSET);
++	valPE2 = mfdcri(SDR0, PESDR2_440SPE_RCSSET);
++
++	/* SDR0_PExRCSSET rstgu */
++	if (!(valPE0 & 0x01000000) ||
++	    !(valPE1 & 0x01000000) ||
++	    !(valPE2 & 0x01000000)) {
++		printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n");
++		err = -1;
++	}
++
++	/* SDR0_PExRCSSET rstdl */
++	if (!(valPE0 & 0x00010000) ||
++	    !(valPE1 & 0x00010000) ||
++	    !(valPE2 & 0x00010000)) {
++		printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n");
++		err = -1;
++	}
++
++	/* SDR0_PExRCSSET rstpyn */
++	if ((valPE0 & 0x00001000) ||
++	    (valPE1 & 0x00001000) ||
++	    (valPE2 & 0x00001000)) {
++		printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstpyn error\n");
++		err = -1;
++	}
++
++	/* SDR0_PExRCSSET hldplb */
++	if ((valPE0 & 0x10000000) ||
++	    (valPE1 & 0x10000000) ||
++	    (valPE2 & 0x10000000)) {
++		printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n");
++		err = -1;
++	}
++
++	/* SDR0_PExRCSSET rdy */
++	if ((valPE0 & 0x00100000) ||
++	    (valPE1 & 0x00100000) ||
++	    (valPE2 & 0x00100000)) {
++		printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n");
++		err = -1;
++	}
++
++	/* SDR0_PExRCSSET shutdown */
++	if ((valPE0 & 0x00000100) ||
++	    (valPE1 & 0x00000100) ||
++	    (valPE2 & 0x00000100)) {
++		printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n");
++		err = -1;
++	}
++
++	return err;
++}
++
++/* Global PCIe core initializations for 440SPe core */
++static int __init ppc440spe_pciex_core_init(struct device_node *np)
++{
++	int time_out = 20;
++
++	/* Set PLL clock receiver to LVPECL */
++	mtdcri(SDR0, PESDR0_PLLLCT1, mfdcri(SDR0, PESDR0_PLLLCT1) | 1 << 28);
++
++	/* Shouldn't we do all the calibration stuff etc... here ? */
++	if (ppc440spe_pciex_check_reset(np))
++		return -ENXIO;
++
++	if (!(mfdcri(SDR0, PESDR0_PLLLCT2) & 0x10000)) {
++		printk(KERN_INFO "PCIE: PESDR_PLLCT2 resistance calibration "
++		       "failed (0x%08x)\n",
++		       mfdcri(SDR0, PESDR0_PLLLCT2));
++		return -1;
++	}
++
++	/* De-assert reset of PCIe PLL, wait for lock */
++	mtdcri(SDR0, PESDR0_PLLLCT1,
++	       mfdcri(SDR0, PESDR0_PLLLCT1) & ~(1 << 24));
++	udelay(3);
++
++	while (time_out) {
++		if (!(mfdcri(SDR0, PESDR0_PLLLCT3) & 0x10000000)) {
++			time_out--;
++			udelay(1);
++		} else
++			break;
++	}
++	if (!time_out) {
++		printk(KERN_INFO "PCIE: VCO output not locked\n");
++		return -1;
++	}
++
++	pr_debug("PCIE initialization OK\n");
++
++	return 3;
++}
++
++static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
++{
++	u32 val = 1 << 24;
++
++	if (port->endpoint)
++		val = PTYPE_LEGACY_ENDPOINT << 20;
++	else
++		val = PTYPE_ROOT_PORT << 20;
++
++	if (port->index == 0)
++		val |= LNKW_X8 << 12;
++	else
++		val |= LNKW_X4 << 12;
++
++	mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val);
++	mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x20222222);
++	if (ppc440spe_revA())
++		mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x11000000);
++	mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL0SET1, 0x35000000);
++	mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL1SET1, 0x35000000);
++	mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL2SET1, 0x35000000);
++	mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL3SET1, 0x35000000);
++	if (port->index == 0) {
++		mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL4SET1,
++		       0x35000000);
++		mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL5SET1,
++		       0x35000000);
++		mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL6SET1,
++		       0x35000000);
++		mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL7SET1,
++		       0x35000000);
++	}
++	val = mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET);
++	mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
++	       (val & ~(1 << 24 | 1 << 16)) | 1 << 12);
++
++	return 0;
++}
++
++static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
++{
++	return ppc440spe_pciex_init_port_hw(port);
++}
++
++static int ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
++{
++	int rc = ppc440spe_pciex_init_port_hw(port);
++
++	port->has_ibpre = 1;
++
++	return rc;
++}
++
++static int ppc440speA_pciex_init_utl(struct ppc4xx_pciex_port *port)
++{
++	/* XXX Check what that value means... I hate magic */
++	dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x68782800);
++
++	/*
++	 * Set buffer allocations and then assert VRB and TXE.
++	 */
++	out_be32(port->utl_base + PEUTL_OUTTR,   0x08000000);
++	out_be32(port->utl_base + PEUTL_INTR,    0x02000000);
++	out_be32(port->utl_base + PEUTL_OPDBSZ,  0x10000000);
++	out_be32(port->utl_base + PEUTL_PBBSZ,   0x53000000);
++	out_be32(port->utl_base + PEUTL_IPHBSZ,  0x08000000);
++	out_be32(port->utl_base + PEUTL_IPDBSZ,  0x10000000);
++	out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000);
++	out_be32(port->utl_base + PEUTL_PCTL,    0x80800066);
++
++	return 0;
++}
++
++static int ppc440speB_pciex_init_utl(struct ppc4xx_pciex_port *port)
++{
++	/* Report CRS to the operating system */
++	out_be32(port->utl_base + PEUTL_PBCTL,    0x08000000);
++
++	return 0;
++}
++
++static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata =
++{
++	.core_init	= ppc440spe_pciex_core_init,
++	.port_init_hw	= ppc440speA_pciex_init_port_hw,
++	.setup_utl	= ppc440speA_pciex_init_utl,
++};
++
++static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata =
++{
++	.core_init	= ppc440spe_pciex_core_init,
++	.port_init_hw	= ppc440speB_pciex_init_port_hw,
++	.setup_utl	= ppc440speB_pciex_init_utl,
++};
++
++#endif /* CONFIG_44x */
++
++#ifdef CONFIG_40x
++
++static int __init ppc405ex_pciex_core_init(struct device_node *np)
++{
++	/* Nothing to do, return 2 ports */
++	return 2;
++}
++
++static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port)
++{
++	/* Assert the PE0_PHY reset */
++	mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01010000);
++	msleep(1);
++
++	/* deassert the PE0_hotreset */
++	if (port->endpoint)
++		mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01111000);
++	else
++		mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01101000);
++
++	/* poll for phy !reset */
++	/* XXX FIXME add timeout */
++	while (!(mfdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSTA) & 0x00001000))
++		;
++
++	/* deassert the PE0_gpl_utl_reset */
++	mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000);
++}
++
++static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
++{
++	u32 val;
++
++	if (port->endpoint)
++		val = PTYPE_LEGACY_ENDPOINT;
++	else
++		val = PTYPE_ROOT_PORT;
++
++	mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET,
++	       1 << 24 | val << 20 | LNKW_X1 << 12);
++
++	mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000);
++	mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000);
++	mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET1, 0x720F0000);
++	mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET2, 0x70600003);
++
++	/*
++	 * Only reset the PHY when no link is currently established.
++	 * This is for the Atheros PCIe board which has problems to establish
++	 * the link (again) after this PHY reset. All other currently tested
++	 * PCIe boards don't show this problem.
++	 * This has to be re-tested and fixed in a later release!
++	 */
++#if 0 /* XXX FIXME: Not resetting the PHY will leave all resources
++       * configured as done previously by U-Boot. Then Linux will currently
++       * not reassign them. So the PHY reset is now done always. This will
++       * lead to problems with the Atheros PCIe board again.
++       */
++	val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
++	if (!(val & 0x00001000))
++		ppc405ex_pcie_phy_reset(port);
++#else
++	ppc405ex_pcie_phy_reset(port);
++#endif
++
++	dcr_write(port->dcrs, DCRO_PEGPL_CFG, 0x10000000);  /* guarded on */
++
++	port->has_ibpre = 1;
++
++	return 0;
++}
++
++static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
++{
++	dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0);
++
++	/*
++	 * Set buffer allocations and then assert VRB and TXE.
++	 */
++	out_be32(port->utl_base + PEUTL_OUTTR,   0x02000000);
++	out_be32(port->utl_base + PEUTL_INTR,    0x02000000);
++	out_be32(port->utl_base + PEUTL_OPDBSZ,  0x04000000);
++	out_be32(port->utl_base + PEUTL_PBBSZ,   0x21000000);
++	out_be32(port->utl_base + PEUTL_IPHBSZ,  0x02000000);
++	out_be32(port->utl_base + PEUTL_IPDBSZ,  0x04000000);
++	out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000);
++	out_be32(port->utl_base + PEUTL_PCTL,    0x80800066);
++
++	out_be32(port->utl_base + PEUTL_PBCTL,   0x08000000);
++
++	return 0;
++}
++
++static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata =
++{
++	.core_init	= ppc405ex_pciex_core_init,
++	.port_init_hw	= ppc405ex_pciex_init_port_hw,
++	.setup_utl	= ppc405ex_pciex_init_utl,
++};
++
++#endif /* CONFIG_40x */
++
++
++/* Check that the core has been initied and if not, do it */
++static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
++{
++	static int core_init;
++	int count = -ENODEV;
++
++	if (core_init++)
++		return 0;
++
++#ifdef CONFIG_44x
++	if (of_device_is_compatible(np, "ibm,plb-pciex-440spe")) {
++		if (ppc440spe_revA())
++			ppc4xx_pciex_hwops = &ppc440speA_pcie_hwops;
++		else
++			ppc4xx_pciex_hwops = &ppc440speB_pcie_hwops;
++	}
++#endif /* CONFIG_44x    */
++#ifdef CONFIG_40x
++	if (of_device_is_compatible(np, "ibm,plb-pciex-405ex"))
++		ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops;
++#endif
++	if (ppc4xx_pciex_hwops == NULL) {
++		printk(KERN_WARNING "PCIE: unknown host type %s\n",
++		       np->full_name);
++		return -ENODEV;
++	}
++
++	count = ppc4xx_pciex_hwops->core_init(np);
++	if (count > 0) {
++		ppc4xx_pciex_ports =
++		       kzalloc(count * sizeof(struct ppc4xx_pciex_port),
++			       GFP_KERNEL);
++		if (ppc4xx_pciex_ports) {
++			ppc4xx_pciex_port_count = count;
++			return 0;
++		}
++		printk(KERN_WARNING "PCIE: failed to allocate ports array\n");
++		return -ENOMEM;
++	}
++	return -ENODEV;
++}
++
++static void __init ppc4xx_pciex_port_init_mapping(struct ppc4xx_pciex_port *port)
++{
++	/* We map PCI Express configuration based on the reg property */
++	dcr_write(port->dcrs, DCRO_PEGPL_CFGBAH,
++		  RES_TO_U32_HIGH(port->cfg_space.start));
++	dcr_write(port->dcrs, DCRO_PEGPL_CFGBAL,
++		  RES_TO_U32_LOW(port->cfg_space.start));
++
++	/* XXX FIXME: Use size from reg property. For now, map 512M */
++	dcr_write(port->dcrs, DCRO_PEGPL_CFGMSK, 0xe0000001);
++
++	/* We map UTL registers based on the reg property */
++	dcr_write(port->dcrs, DCRO_PEGPL_REGBAH,
++		  RES_TO_U32_HIGH(port->utl_regs.start));
++	dcr_write(port->dcrs, DCRO_PEGPL_REGBAL,
++		  RES_TO_U32_LOW(port->utl_regs.start));
++
++	/* XXX FIXME: Use size from reg property */
++	dcr_write(port->dcrs, DCRO_PEGPL_REGMSK, 0x00007001);
++
++	/* Disable all other outbound windows */
++	dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, 0);
++	dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, 0);
++	dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0);
++	dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0);
++}
++
++static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port,
++					   unsigned int sdr_offset,
++					   unsigned int mask,
++					   unsigned int value,
++					   int timeout_ms)
++{
++	u32 val;
++
++	while(timeout_ms--) {
++		val = mfdcri(SDR0, port->sdr_base + sdr_offset);
++		if ((val & mask) == value) {
++			pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n",
++				 port->index, sdr_offset, timeout_ms, val);
++			return 0;
++		}
++		msleep(1);
++	}
++	return -1;
++}
++
++static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
++{
++	int rc = 0;
++
++	/* Init HW */
++	if (ppc4xx_pciex_hwops->port_init_hw)
++		rc = ppc4xx_pciex_hwops->port_init_hw(port);
++	if (rc != 0)
++		return rc;
++
++	printk(KERN_INFO "PCIE%d: Checking link...\n",
++	       port->index);
++
++	/* Wait for reset to complete */
++	if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) {
++		printk(KERN_WARNING "PCIE%d: PGRST failed\n",
++		       port->index);
++		return -1;
++	}
++
++	/* Check for card presence detect if supported, if not, just wait for
++	 * link unconditionally.
++	 *
++	 * note that we don't fail if there is no link, we just filter out
++	 * config space accesses. That way, it will be easier to implement
++	 * hotplug later on.
++	 */
++	if (!port->has_ibpre ||
++	    !ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
++				      1 << 28, 1 << 28, 100)) {
++		printk(KERN_INFO
++		       "PCIE%d: Device detected, waiting for link...\n",
++		       port->index);
++		if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
++					     0x1000, 0x1000, 2000))
++			printk(KERN_WARNING
++			       "PCIE%d: Link up failed\n", port->index);
++		else {
++			printk(KERN_INFO
++			       "PCIE%d: link is up !\n", port->index);
++			port->link = 1;
++		}
++	} else
++		printk(KERN_INFO "PCIE%d: No device detected.\n", port->index);
++
++	/*
++	 * Initialize mapping: disable all regions and configure
++	 * CFG and REG regions based on resources in the device tree
++	 */
++	ppc4xx_pciex_port_init_mapping(port);
++
++	/*
++	 * Map UTL
++	 */
++	port->utl_base = ioremap(port->utl_regs.start, 0x100);
++	BUG_ON(port->utl_base == NULL);
++
++	/*
++	 * Setup UTL registers --BenH.
++	 */
++	if (ppc4xx_pciex_hwops->setup_utl)
++		ppc4xx_pciex_hwops->setup_utl(port);
++
++	/*
++	 * Check for VC0 active and assert RDY.
++	 */
++	if (port->link &&
++	    ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
++				     1 << 16, 1 << 16, 5000)) {
++		printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index);
++		port->link = 0;
++	}
++
++	mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
++	       mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | 1 << 20);
++	msleep(100);
++
++	return 0;
++}
++
++static int ppc4xx_pciex_validate_bdf(struct ppc4xx_pciex_port *port,
++				     struct pci_bus *bus,
++				     unsigned int devfn)
++{
++	static int message;
++
++	/* Endpoint can not generate upstream(remote) config cycles */
++	if (port->endpoint && bus->number != port->hose->first_busno)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	/* Check we are within the mapped range */
++	if (bus->number > port->hose->last_busno) {
++		if (!message) {
++			printk(KERN_WARNING "Warning! Probing bus %u"
++			       " out of range !\n", bus->number);
++			message++;
++		}
++		return PCIBIOS_DEVICE_NOT_FOUND;
++	}
++
++	/* The root complex has only one device / function */
++	if (bus->number == port->hose->first_busno && devfn != 0)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	/* The other side of the RC has only one device as well */
++	if (bus->number == (port->hose->first_busno + 1) &&
++	    PCI_SLOT(devfn) != 0)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	/* Check if we have a link */
++	if ((bus->number != port->hose->first_busno) && !port->link)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	return 0;
++}
++
++static void __iomem *ppc4xx_pciex_get_config_base(struct ppc4xx_pciex_port *port,
++						  struct pci_bus *bus,
++						  unsigned int devfn)
++{
++	int relbus;
++
++	/* Remove the casts when we finally remove the stupid volatile
++	 * in struct pci_controller
++	 */
++	if (bus->number == port->hose->first_busno)
++		return (void __iomem *)port->hose->cfg_addr;
++
++	relbus = bus->number - (port->hose->first_busno + 1);
++	return (void __iomem *)port->hose->cfg_data +
++		((relbus  << 20) | (devfn << 12));
++}
++
++static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
++				    int offset, int len, u32 *val)
++{
++	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
++	struct ppc4xx_pciex_port *port =
++		&ppc4xx_pciex_ports[hose->indirect_type];
++	void __iomem *addr;
++	u32 gpl_cfg;
++
++	BUG_ON(hose != port->hose);
++
++	if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = ppc4xx_pciex_get_config_base(port, bus, devfn);
++
++	/*
++	 * Reading from configuration space of non-existing device can
++	 * generate transaction errors. For the read duration we suppress
++	 * assertion of machine check exceptions to avoid those.
++	 */
++	gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG);
++	dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA);
++
++	/* Make sure no CRS is recorded */
++	out_be32(port->utl_base + PEUTL_RCSTA, 0x00040000);
++
++	switch (len) {
++	case 1:
++		*val = in_8((u8 *)(addr + offset));
++		break;
++	case 2:
++		*val = in_le16((u16 *)(addr + offset));
++		break;
++	default:
++		*val = in_le32((u32 *)(addr + offset));
++		break;
++	}
++
++	pr_debug("pcie-config-read: bus=%3d [%3d..%3d] devfn=0x%04x"
++		 " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n",
++		 bus->number, hose->first_busno, hose->last_busno,
++		 devfn, offset, len, addr + offset, *val);
++
++	/* Check for CRS (440SPe rev B does that for us but heh ..) */
++	if (in_be32(port->utl_base + PEUTL_RCSTA) & 0x00040000) {
++		pr_debug("Got CRS !\n");
++		if (len != 4 || offset != 0)
++			return PCIBIOS_DEVICE_NOT_FOUND;
++		*val = 0xffff0001;
++	}
++
++	dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg);
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int ppc4xx_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
++				     int offset, int len, u32 val)
++{
++	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
++	struct ppc4xx_pciex_port *port =
++		&ppc4xx_pciex_ports[hose->indirect_type];
++	void __iomem *addr;
++	u32 gpl_cfg;
++
++	if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0)
++		return PCIBIOS_DEVICE_NOT_FOUND;
++
++	addr = ppc4xx_pciex_get_config_base(port, bus, devfn);
++
++	/*
++	 * Reading from configuration space of non-existing device can
++	 * generate transaction errors. For the read duration we suppress
++	 * assertion of machine check exceptions to avoid those.
++	 */
++	gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG);
++	dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA);
++
++	pr_debug("pcie-config-write: bus=%3d [%3d..%3d] devfn=0x%04x"
++		 " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n",
++		 bus->number, hose->first_busno, hose->last_busno,
++		 devfn, offset, len, addr + offset, val);
++
++	switch (len) {
++	case 1:
++		out_8((u8 *)(addr + offset), val);
++		break;
++	case 2:
++		out_le16((u16 *)(addr + offset), val);
++		break;
++	default:
++		out_le32((u32 *)(addr + offset), val);
++		break;
++	}
++
++	dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg);
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops ppc4xx_pciex_pci_ops =
++{
++	.read  = ppc4xx_pciex_read_config,
++	.write = ppc4xx_pciex_write_config,
++};
++
++static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port,
++					       struct pci_controller *hose,
++					       void __iomem *mbase)
++{
++	u32 lah, lal, pciah, pcial, sa;
++	int i, j;
++
++	/* Setup outbound memory windows */
++	for (i = j = 0; i < 3; i++) {
++		struct resource *res = &hose->mem_resources[i];
++
++		/* we only care about memory windows */
++		if (!(res->flags & IORESOURCE_MEM))
++			continue;
++		if (j > 1) {
++			printk(KERN_WARNING "%s: Too many ranges\n",
++			       port->node->full_name);
++			break;
++		}
++
++		/* Calculate register values */
++		lah = RES_TO_U32_HIGH(res->start);
++		lal = RES_TO_U32_LOW(res->start);
++		pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
++		pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
++		sa = res->end + 1 - res->start;
++		if (!is_power_of_2(sa) || sa < 0x100000 ||
++		    sa > 0xffffffffu) {
++			printk(KERN_WARNING "%s: Resource out of range\n",
++			       port->node->full_name);
++			continue;
++		}
++		sa = (0xffffffffu << ilog2(sa)) | 0x1;
++
++		/* Program register values */
++		switch (j) {
++		case 0:
++			out_le32(mbase + PECFG_POM0LAH, pciah);
++			out_le32(mbase + PECFG_POM0LAL, pcial);
++			dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
++			dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
++			dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
++			dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3);
++			break;
++		case 1:
++			out_le32(mbase + PECFG_POM1LAH, pciah);
++			out_le32(mbase + PECFG_POM1LAL, pcial);
++			dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
++			dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
++			dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
++			dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3);
++			break;
++		}
++		j++;
++	}
++
++	/* Configure IO, always 64K starting at 0 */
++	if (hose->io_resource.flags & IORESOURCE_IO) {
++		lah = RES_TO_U32_HIGH(hose->io_base_phys);
++		lal = RES_TO_U32_LOW(hose->io_base_phys);
++		out_le32(mbase + PECFG_POM2LAH, 0);
++		out_le32(mbase + PECFG_POM2LAL, 0);
++		dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah);
++		dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
++		dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
++		dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0xffff0000 | 3);
++	}
++}
++
++static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
++					       struct pci_controller *hose,
++					       void __iomem *mbase,
++					       struct resource *res)
++{
++	resource_size_t size = res->end - res->start + 1;
++	u64 sa;
++
++	/* Calculate window size */
++	sa = (0xffffffffffffffffull << ilog2(size));;
++	if (res->flags & IORESOURCE_PREFETCH)
++		sa |= 0x8;
++
++	out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
++	out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
++
++	/* The setup of the split looks weird to me ... let's see if it works */
++	out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
++	out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
++	out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
++	out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
++	out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
++	out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
++
++	/* Enable inbound mapping */
++	out_le32(mbase + PECFG_PIMEN, 0x1);
++
++	out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start));
++	out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start));
++
++	/* Enable I/O, Mem, and Busmaster cycles */
++	out_le16(mbase + PCI_COMMAND,
++		 in_le16(mbase + PCI_COMMAND) |
++		 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
++}
++
++static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
++{
++	struct resource dma_window;
++	struct pci_controller *hose = NULL;
++	const int *bus_range;
++	int primary = 0, busses;
++	void __iomem *mbase = NULL, *cfg_data = NULL;
++
++	/* XXX FIXME: Handle endpoint mode properly */
++	if (port->endpoint) {
++		printk(KERN_WARNING "PCIE%d: Port in endpoint mode !\n",
++		       port->index);
++		return;
++	}
++
++	/* Check if primary bridge */
++	if (of_get_property(port->node, "primary", NULL))
++		primary = 1;
++
++	/* Get bus range if any */
++	bus_range = of_get_property(port->node, "bus-range", NULL);
++
++	/* Allocate the host controller data structure */
++	hose = pcibios_alloc_controller(port->node);
++	if (!hose)
++		goto fail;
++
++	/* We stick the port number in "indirect_type" so the config space
++	 * ops can retrieve the port data structure easily
++	 */
++	hose->indirect_type = port->index;
++
++	/* Get bus range */
++	hose->first_busno = bus_range ? bus_range[0] : 0x0;
++	hose->last_busno = bus_range ? bus_range[1] : 0xff;
++
++	/* Because of how big mapping the config space is (1M per bus), we
++	 * limit how many busses we support. In the long run, we could replace
++	 * that with something akin to kmap_atomic instead. We set aside 1 bus
++	 * for the host itself too.
++	 */
++	busses = hose->last_busno - hose->first_busno; /* This is off by 1 */
++	if (busses > MAX_PCIE_BUS_MAPPED) {
++		busses = MAX_PCIE_BUS_MAPPED;
++		hose->last_busno = hose->first_busno + busses;
++	}
++
++	/* We map the external config space in cfg_data and the host config
++	 * space in cfg_addr. External space is 1M per bus, internal space
++	 * is 4K
++	 */
++	cfg_data = ioremap(port->cfg_space.start +
++				 (hose->first_busno + 1) * 0x100000,
++				 busses * 0x100000);
++	mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000);
++	if (cfg_data == NULL || mbase == NULL) {
++		printk(KERN_ERR "%s: Can't map config space !",
++		       port->node->full_name);
++		goto fail;
++	}
++
++	hose->cfg_data = cfg_data;
++	hose->cfg_addr = mbase;
++
++	pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name,
++		 hose->first_busno, hose->last_busno);
++	pr_debug("     config space mapped at: root @0x%p, other @0x%p\n",
++		 hose->cfg_addr, hose->cfg_data);
++
++	/* Setup config space */
++	hose->ops = &ppc4xx_pciex_pci_ops;
++	port->hose = hose;
++	mbase = (void __iomem *)hose->cfg_addr;
++
++	/*
++	 * Set bus numbers on our root port
++	 */
++	out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno);
++	out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1);
++	out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno);
++
++	/*
++	 * OMRs are already reset, also disable PIMs
++	 */
++	out_le32(mbase + PECFG_PIMEN, 0);
++
++	/* Parse outbound mapping resources */
++	pci_process_bridge_OF_ranges(hose, port->node, primary);
++
++	/* Parse inbound mapping resources */
++	if (ppc4xx_parse_dma_ranges(hose, mbase, &dma_window) != 0)
++		goto fail;
++
++	/* Configure outbound ranges POMs */
++	ppc4xx_configure_pciex_POMs(port, hose, mbase);
++
++	/* Configure inbound ranges PIMs */
++	ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window);
++
++	/* The root complex doesn't show up if we don't set some vendor
++	 * and device IDs into it. Those are the same bogus one that the
++	 * initial code in arch/ppc add. We might want to change that.
++	 */
++	out_le16(mbase + 0x200, 0xaaa0 + port->index);
++	out_le16(mbase + 0x202, 0xbed0 + port->index);
++
++	/* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
++	out_le32(mbase + 0x208, 0x06040001);
++
++	printk(KERN_INFO "PCIE%d: successfully set as root-complex\n",
++	       port->index);
++	return;
++ fail:
++	if (hose)
++		pcibios_free_controller(hose);
++	if (cfg_data)
++		iounmap(cfg_data);
++	if (mbase)
++		iounmap(mbase);
++}
++
++static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
++{
++	struct ppc4xx_pciex_port *port;
++	const u32 *pval;
++	int portno;
++	unsigned int dcrs;
++
++	/* First, proceed to core initialization as we assume there's
++	 * only one PCIe core in the system
++	 */
++	if (ppc4xx_pciex_check_core_init(np))
++		return;
++
++	/* Get the port number from the device-tree */
++	pval = of_get_property(np, "port", NULL);
++	if (pval == NULL) {
++		printk(KERN_ERR "PCIE: Can't find port number for %s\n",
++		       np->full_name);
++		return;
++	}
++	portno = *pval;
++	if (portno >= ppc4xx_pciex_port_count) {
++		printk(KERN_ERR "PCIE: port number out of range for %s\n",
++		       np->full_name);
++		return;
++	}
++	port = &ppc4xx_pciex_ports[portno];
++	port->index = portno;
++	port->node = of_node_get(np);
++	pval = of_get_property(np, "sdr-base", NULL);
++	if (pval == NULL) {
++		printk(KERN_ERR "PCIE: missing sdr-base for %s\n",
++		       np->full_name);
++		return;
++	}
++	port->sdr_base = *pval;
++
++	/* XXX Currently, we only support root complex mode */
++	port->endpoint = 0;
++
++	/* Fetch config space registers address */
++	if (of_address_to_resource(np, 0, &port->cfg_space)) {
++		printk(KERN_ERR "%s: Can't get PCI-E config space !",
++		       np->full_name);
++		return;
++	}
++	/* Fetch host bridge internal registers address */
++	if (of_address_to_resource(np, 1, &port->utl_regs)) {
++		printk(KERN_ERR "%s: Can't get UTL register base !",
++		       np->full_name);
++		return;
++	}
++
++	/* Map DCRs */
++	dcrs = dcr_resource_start(np, 0);
++	if (dcrs == 0) {
++		printk(KERN_ERR "%s: Can't get DCR register base !",
++		       np->full_name);
++		return;
++	}
++	port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
++
++	/* Initialize the port specific registers */
++	if (ppc4xx_pciex_port_init(port)) {
++		printk(KERN_WARNING "PCIE%d: Port init failed\n", port->index);
++		return;
++	}
++
++	/* Setup the linux hose data structure */
++	ppc4xx_pciex_port_setup_hose(port);
++}
++
++#endif /* CONFIG_PPC4xx_PCI_EXPRESS */
++
++static int __init ppc4xx_pci_find_bridges(void)
++{
++	struct device_node *np;
++
++#ifdef CONFIG_PPC4xx_PCI_EXPRESS
++	for_each_compatible_node(np, NULL, "ibm,plb-pciex")
++		ppc4xx_probe_pciex_bridge(np);
++#endif
++	for_each_compatible_node(np, NULL, "ibm,plb-pcix")
++		ppc4xx_probe_pcix_bridge(np);
++	for_each_compatible_node(np, NULL, "ibm,plb-pci")
++		ppc4xx_probe_pci_bridge(np);
++
++	return 0;
++}
++arch_initcall(ppc4xx_pci_find_bridges);
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/ppc4xx_pci.h powerpc.git/arch/powerpc/sysdev/ppc4xx_pci.h
+--- linux-2.6.24/arch/powerpc/sysdev/ppc4xx_pci.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/ppc4xx_pci.h	2008-01-28 20:25:49.000000000 +0100
+@@ -0,0 +1,369 @@
++/*
++ * PCI / PCI-X / PCI-Express support for 4xx parts
++ *
++ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
++ *
++ * Bits and pieces extracted from arch/ppc support by
++ *
++ * Matt Porter <mporter@kernel.crashing.org>
++ *
++ * Copyright 2002-2005 MontaVista Software Inc.
++ */
++#ifndef __PPC4XX_PCI_H__
++#define __PPC4XX_PCI_H__
++
++/*
++ * 4xx PCI-X bridge register definitions
++ */
++#define PCIX0_VENDID		0x000
++#define PCIX0_DEVID		0x002
++#define PCIX0_COMMAND		0x004
++#define PCIX0_STATUS		0x006
++#define PCIX0_REVID		0x008
++#define PCIX0_CLS		0x009
++#define PCIX0_CACHELS		0x00c
++#define PCIX0_LATTIM		0x00d
++#define PCIX0_HDTYPE		0x00e
++#define PCIX0_BIST		0x00f
++#define PCIX0_BAR0L		0x010
++#define PCIX0_BAR0H		0x014
++#define PCIX0_BAR1		0x018
++#define PCIX0_BAR2L		0x01c
++#define PCIX0_BAR2H		0x020
++#define PCIX0_BAR3		0x024
++#define PCIX0_CISPTR		0x028
++#define PCIX0_SBSYSVID		0x02c
++#define PCIX0_SBSYSID		0x02e
++#define PCIX0_EROMBA		0x030
++#define PCIX0_CAP		0x034
++#define PCIX0_RES0		0x035
++#define PCIX0_RES1		0x036
++#define PCIX0_RES2		0x038
++#define PCIX0_INTLN		0x03c
++#define PCIX0_INTPN		0x03d
++#define PCIX0_MINGNT		0x03e
++#define PCIX0_MAXLTNCY		0x03f
++#define PCIX0_BRDGOPT1		0x040
++#define PCIX0_BRDGOPT2		0x044
++#define PCIX0_ERREN		0x050
++#define PCIX0_ERRSTS		0x054
++#define PCIX0_PLBBESR		0x058
++#define PCIX0_PLBBEARL		0x05c
++#define PCIX0_PLBBEARH		0x060
++#define PCIX0_POM0LAL		0x068
++#define PCIX0_POM0LAH		0x06c
++#define PCIX0_POM0SA		0x070
++#define PCIX0_POM0PCIAL		0x074
++#define PCIX0_POM0PCIAH		0x078
++#define PCIX0_POM1LAL		0x07c
++#define PCIX0_POM1LAH		0x080
++#define PCIX0_POM1SA		0x084
++#define PCIX0_POM1PCIAL		0x088
++#define PCIX0_POM1PCIAH		0x08c
++#define PCIX0_POM2SA		0x090
++#define PCIX0_PIM0SAL		0x098
++#define PCIX0_PIM0SA		PCIX0_PIM0SAL
++#define PCIX0_PIM0LAL		0x09c
++#define PCIX0_PIM0LAH		0x0a0
++#define PCIX0_PIM1SA		0x0a4
++#define PCIX0_PIM1LAL		0x0a8
++#define PCIX0_PIM1LAH		0x0ac
++#define PCIX0_PIM2SAL		0x0b0
++#define PCIX0_PIM2SA		PCIX0_PIM2SAL
++#define PCIX0_PIM2LAL		0x0b4
++#define PCIX0_PIM2LAH		0x0b8
++#define PCIX0_OMCAPID		0x0c0
++#define PCIX0_OMNIPTR		0x0c1
++#define PCIX0_OMMC		0x0c2
++#define PCIX0_OMMA		0x0c4
++#define PCIX0_OMMUA		0x0c8
++#define PCIX0_OMMDATA		0x0cc
++#define PCIX0_OMMEOI		0x0ce
++#define PCIX0_PMCAPID		0x0d0
++#define PCIX0_PMNIPTR		0x0d1
++#define PCIX0_PMC		0x0d2
++#define PCIX0_PMCSR		0x0d4
++#define PCIX0_PMCSRBSE		0x0d6
++#define PCIX0_PMDATA		0x0d7
++#define PCIX0_PMSCRR		0x0d8
++#define PCIX0_CAPID		0x0dc
++#define PCIX0_NIPTR		0x0dd
++#define PCIX0_CMD		0x0de
++#define PCIX0_STS		0x0e0
++#define PCIX0_IDR		0x0e4
++#define PCIX0_CID		0x0e8
++#define PCIX0_RID		0x0ec
++#define PCIX0_PIM0SAH		0x0f8
++#define PCIX0_PIM2SAH		0x0fc
++#define PCIX0_MSGIL		0x100
++#define PCIX0_MSGIH		0x104
++#define PCIX0_MSGOL		0x108
++#define PCIX0_MSGOH		0x10c
++#define PCIX0_IM		0x1f8
++
++/*
++ * 4xx PCI bridge register definitions
++ */
++#define PCIL0_PMM0LA		0x00
++#define PCIL0_PMM0MA		0x04
++#define PCIL0_PMM0PCILA		0x08
++#define PCIL0_PMM0PCIHA		0x0c
++#define PCIL0_PMM1LA		0x10
++#define PCIL0_PMM1MA		0x14
++#define PCIL0_PMM1PCILA		0x18
++#define PCIL0_PMM1PCIHA		0x1c
++#define PCIL0_PMM2LA		0x20
++#define PCIL0_PMM2MA		0x24
++#define PCIL0_PMM2PCILA		0x28
++#define PCIL0_PMM2PCIHA		0x2c
++#define PCIL0_PTM1MS		0x30
++#define PCIL0_PTM1LA		0x34
++#define PCIL0_PTM2MS		0x38
++#define PCIL0_PTM2LA		0x3c
++
++/*
++ * 4xx PCIe bridge register definitions
++ */
++
++/* DCR offsets */
++#define DCRO_PEGPL_CFGBAH		0x00
++#define DCRO_PEGPL_CFGBAL		0x01
++#define DCRO_PEGPL_CFGMSK		0x02
++#define DCRO_PEGPL_MSGBAH		0x03
++#define DCRO_PEGPL_MSGBAL		0x04
++#define DCRO_PEGPL_MSGMSK		0x05
++#define DCRO_PEGPL_OMR1BAH		0x06
++#define DCRO_PEGPL_OMR1BAL		0x07
++#define DCRO_PEGPL_OMR1MSKH		0x08
++#define DCRO_PEGPL_OMR1MSKL		0x09
++#define DCRO_PEGPL_OMR2BAH		0x0a
++#define DCRO_PEGPL_OMR2BAL		0x0b
++#define DCRO_PEGPL_OMR2MSKH		0x0c
++#define DCRO_PEGPL_OMR2MSKL		0x0d
++#define DCRO_PEGPL_OMR3BAH		0x0e
++#define DCRO_PEGPL_OMR3BAL		0x0f
++#define DCRO_PEGPL_OMR3MSKH		0x10
++#define DCRO_PEGPL_OMR3MSKL		0x11
++#define DCRO_PEGPL_REGBAH		0x12
++#define DCRO_PEGPL_REGBAL		0x13
++#define DCRO_PEGPL_REGMSK		0x14
++#define DCRO_PEGPL_SPECIAL		0x15
++#define DCRO_PEGPL_CFG			0x16
++#define DCRO_PEGPL_ESR			0x17
++#define DCRO_PEGPL_EARH			0x18
++#define DCRO_PEGPL_EARL			0x19
++#define DCRO_PEGPL_EATR			0x1a
++
++/* DMER mask */
++#define GPL_DMER_MASK_DISA	0x02000000
++
++/*
++ * System DCRs (SDRs)
++ */
++#define PESDR0_PLLLCT1			0x03a0
++#define PESDR0_PLLLCT2			0x03a1
++#define PESDR0_PLLLCT3			0x03a2
++
++/*
++ * 440SPe additional DCRs
++ */
++#define PESDR0_440SPE_UTLSET1		0x0300
++#define PESDR0_440SPE_UTLSET2		0x0301
++#define PESDR0_440SPE_DLPSET		0x0302
++#define PESDR0_440SPE_LOOP		0x0303
++#define PESDR0_440SPE_RCSSET		0x0304
++#define PESDR0_440SPE_RCSSTS		0x0305
++#define PESDR0_440SPE_HSSL0SET1		0x0306
++#define PESDR0_440SPE_HSSL0SET2		0x0307
++#define PESDR0_440SPE_HSSL0STS		0x0308
++#define PESDR0_440SPE_HSSL1SET1		0x0309
++#define PESDR0_440SPE_HSSL1SET2		0x030a
++#define PESDR0_440SPE_HSSL1STS		0x030b
++#define PESDR0_440SPE_HSSL2SET1		0x030c
++#define PESDR0_440SPE_HSSL2SET2		0x030d
++#define PESDR0_440SPE_HSSL2STS		0x030e
++#define PESDR0_440SPE_HSSL3SET1		0x030f
++#define PESDR0_440SPE_HSSL3SET2		0x0310
++#define PESDR0_440SPE_HSSL3STS		0x0311
++#define PESDR0_440SPE_HSSL4SET1		0x0312
++#define PESDR0_440SPE_HSSL4SET2		0x0313
++#define PESDR0_440SPE_HSSL4STS	       	0x0314
++#define PESDR0_440SPE_HSSL5SET1		0x0315
++#define PESDR0_440SPE_HSSL5SET2		0x0316
++#define PESDR0_440SPE_HSSL5STS		0x0317
++#define PESDR0_440SPE_HSSL6SET1		0x0318
++#define PESDR0_440SPE_HSSL6SET2		0x0319
++#define PESDR0_440SPE_HSSL6STS		0x031a
++#define PESDR0_440SPE_HSSL7SET1		0x031b
++#define PESDR0_440SPE_HSSL7SET2		0x031c
++#define PESDR0_440SPE_HSSL7STS		0x031d
++#define PESDR0_440SPE_HSSCTLSET		0x031e
++#define PESDR0_440SPE_LANE_ABCD		0x031f
++#define PESDR0_440SPE_LANE_EFGH		0x0320
++
++#define PESDR1_440SPE_UTLSET1		0x0340
++#define PESDR1_440SPE_UTLSET2		0x0341
++#define PESDR1_440SPE_DLPSET		0x0342
++#define PESDR1_440SPE_LOOP		0x0343
++#define PESDR1_440SPE_RCSSET		0x0344
++#define PESDR1_440SPE_RCSSTS		0x0345
++#define PESDR1_440SPE_HSSL0SET1		0x0346
++#define PESDR1_440SPE_HSSL0SET2		0x0347
++#define PESDR1_440SPE_HSSL0STS		0x0348
++#define PESDR1_440SPE_HSSL1SET1		0x0349
++#define PESDR1_440SPE_HSSL1SET2		0x034a
++#define PESDR1_440SPE_HSSL1STS		0x034b
++#define PESDR1_440SPE_HSSL2SET1		0x034c
++#define PESDR1_440SPE_HSSL2SET2		0x034d
++#define PESDR1_440SPE_HSSL2STS		0x034e
++#define PESDR1_440SPE_HSSL3SET1		0x034f
++#define PESDR1_440SPE_HSSL3SET2		0x0350
++#define PESDR1_440SPE_HSSL3STS		0x0351
++#define PESDR1_440SPE_HSSCTLSET		0x0352
++#define PESDR1_440SPE_LANE_ABCD		0x0353
++
++#define PESDR2_440SPE_UTLSET1		0x0370
++#define PESDR2_440SPE_UTLSET2		0x0371
++#define PESDR2_440SPE_DLPSET		0x0372
++#define PESDR2_440SPE_LOOP		0x0373
++#define PESDR2_440SPE_RCSSET		0x0374
++#define PESDR2_440SPE_RCSSTS		0x0375
++#define PESDR2_440SPE_HSSL0SET1		0x0376
++#define PESDR2_440SPE_HSSL0SET2		0x0377
++#define PESDR2_440SPE_HSSL0STS		0x0378
++#define PESDR2_440SPE_HSSL1SET1		0x0379
++#define PESDR2_440SPE_HSSL1SET2		0x037a
++#define PESDR2_440SPE_HSSL1STS		0x037b
++#define PESDR2_440SPE_HSSL2SET1		0x037c
++#define PESDR2_440SPE_HSSL2SET2		0x037d
++#define PESDR2_440SPE_HSSL2STS		0x037e
++#define PESDR2_440SPE_HSSL3SET1		0x037f
++#define PESDR2_440SPE_HSSL3SET2		0x0380
++#define PESDR2_440SPE_HSSL3STS		0x0381
++#define PESDR2_440SPE_HSSCTLSET		0x0382
++#define PESDR2_440SPE_LANE_ABCD		0x0383
++
++/*
++ * 405EX additional DCRs
++ */
++#define PESDR0_405EX_UTLSET1		0x0400
++#define PESDR0_405EX_UTLSET2		0x0401
++#define PESDR0_405EX_DLPSET		0x0402
++#define PESDR0_405EX_LOOP		0x0403
++#define PESDR0_405EX_RCSSET		0x0404
++#define PESDR0_405EX_RCSSTS		0x0405
++#define PESDR0_405EX_PHYSET1		0x0406
++#define PESDR0_405EX_PHYSET2		0x0407
++#define PESDR0_405EX_BIST		0x0408
++#define PESDR0_405EX_LPB		0x040B
++#define PESDR0_405EX_PHYSTA		0x040C
++
++#define PESDR1_405EX_UTLSET1		0x0440
++#define PESDR1_405EX_UTLSET2		0x0441
++#define PESDR1_405EX_DLPSET		0x0442
++#define PESDR1_405EX_LOOP		0x0443
++#define PESDR1_405EX_RCSSET		0x0444
++#define PESDR1_405EX_RCSSTS		0x0445
++#define PESDR1_405EX_PHYSET1		0x0446
++#define PESDR1_405EX_PHYSET2		0x0447
++#define PESDR1_405EX_BIST		0x0448
++#define PESDR1_405EX_LPB		0x044B
++#define PESDR1_405EX_PHYSTA		0x044C
++
++/*
++ * Of the above, some are common offsets from the base
++ */
++#define PESDRn_UTLSET1			0x00
++#define PESDRn_UTLSET2			0x01
++#define PESDRn_DLPSET			0x02
++#define PESDRn_LOOP			0x03
++#define PESDRn_RCSSET			0x04
++#define PESDRn_RCSSTS			0x05
++
++/* 440spe only */
++#define PESDRn_440SPE_HSSL0SET1		0x06
++#define PESDRn_440SPE_HSSL0SET2		0x07
++#define PESDRn_440SPE_HSSL0STS		0x08
++#define PESDRn_440SPE_HSSL1SET1		0x09
++#define PESDRn_440SPE_HSSL1SET2		0x0a
++#define PESDRn_440SPE_HSSL1STS		0x0b
++#define PESDRn_440SPE_HSSL2SET1		0x0c
++#define PESDRn_440SPE_HSSL2SET2		0x0d
++#define PESDRn_440SPE_HSSL2STS		0x0e
++#define PESDRn_440SPE_HSSL3SET1		0x0f
++#define PESDRn_440SPE_HSSL3SET2		0x10
++#define PESDRn_440SPE_HSSL3STS		0x11
++
++/* 440spe port 0 only */
++#define PESDRn_440SPE_HSSL4SET1		0x12
++#define PESDRn_440SPE_HSSL4SET2		0x13
++#define PESDRn_440SPE_HSSL4STS	       	0x14
++#define PESDRn_440SPE_HSSL5SET1		0x15
++#define PESDRn_440SPE_HSSL5SET2		0x16
++#define PESDRn_440SPE_HSSL5STS		0x17
++#define PESDRn_440SPE_HSSL6SET1		0x18
++#define PESDRn_440SPE_HSSL6SET2		0x19
++#define PESDRn_440SPE_HSSL6STS		0x1a
++#define PESDRn_440SPE_HSSL7SET1		0x1b
++#define PESDRn_440SPE_HSSL7SET2		0x1c
++#define PESDRn_440SPE_HSSL7STS		0x1d
++
++/* 405ex only */
++#define PESDRn_405EX_PHYSET1		0x06
++#define PESDRn_405EX_PHYSET2		0x07
++#define PESDRn_405EX_PHYSTA		0x0c
++
++/*
++ * UTL register offsets
++ */
++#define PEUTL_PBCTL		0x00
++#define PEUTL_PBBSZ		0x20
++#define PEUTL_OPDBSZ		0x68
++#define PEUTL_IPHBSZ		0x70
++#define PEUTL_IPDBSZ		0x78
++#define PEUTL_OUTTR		0x90
++#define PEUTL_INTR		0x98
++#define PEUTL_PCTL		0xa0
++#define PEUTL_RCSTA		0xB0
++#define PEUTL_RCIRQEN		0xb8
++
++/*
++ * Config space register offsets
++ */
++#define PECFG_ECRTCTL		0x074
++
++#define PECFG_BAR0LMPA		0x210
++#define PECFG_BAR0HMPA		0x214
++#define PECFG_BAR1MPA		0x218
++#define PECFG_BAR2LMPA		0x220
++#define PECFG_BAR2HMPA		0x224
++
++#define PECFG_PIMEN		0x33c
++#define PECFG_PIM0LAL		0x340
++#define PECFG_PIM0LAH		0x344
++#define PECFG_PIM1LAL		0x348
++#define PECFG_PIM1LAH		0x34c
++#define PECFG_PIM01SAL		0x350
++#define PECFG_PIM01SAH		0x354
++
++#define PECFG_POM0LAL		0x380
++#define PECFG_POM0LAH		0x384
++#define PECFG_POM1LAL		0x388
++#define PECFG_POM1LAH		0x38c
++#define PECFG_POM2LAL		0x390
++#define PECFG_POM2LAH		0x394
++
++
++enum
++{
++	PTYPE_ENDPOINT		= 0x0,
++	PTYPE_LEGACY_ENDPOINT	= 0x1,
++	PTYPE_ROOT_PORT		= 0x4,
++
++	LNKW_X1			= 0x1,
++	LNKW_X4			= 0x4,
++	LNKW_X8			= 0x8
++};
++
++
++#endif /* __PPC4XX_PCI_H__ */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/qe_lib/Kconfig powerpc.git/arch/powerpc/sysdev/qe_lib/Kconfig
+--- linux-2.6.24/arch/powerpc/sysdev/qe_lib/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/qe_lib/Kconfig	2008-01-28 20:25:49.000000000 +0100
+@@ -4,7 +4,7 @@
+ 
+ config UCC_SLOW
+ 	bool
+-	default n
++	default y if SERIAL_QE
+ 	help
+ 	  This option provides qe_lib support to UCC slow
+ 	  protocols: UART, BISYNC, QMC
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/qe_lib/qe.c powerpc.git/arch/powerpc/sysdev/qe_lib/qe.c
+--- linux-2.6.24/arch/powerpc/sysdev/qe_lib/qe.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/qe_lib/qe.c	2008-01-28 20:25:49.000000000 +0100
+@@ -25,6 +25,7 @@
+ #include <linux/module.h>
+ #include <linux/delay.h>
+ #include <linux/ioport.h>
++#include <linux/crc32.h>
+ #include <asm/irq.h>
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+@@ -167,19 +168,20 @@
+ 
+ /* Program the BRG to the given sampling rate and multiplier
+  *
+- * @brg: the BRG, 1-16
++ * @brg: the BRG, QE_BRG1 - QE_BRG16
+  * @rate: the desired sampling rate
+  * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
+  * GUMR_L[TDCR].  E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
+  * then 'multiplier' should be 8.
+- *
+- * Also note that the value programmed into the BRGC register must be even.
+  */
+-void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
++int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
+ {
+ 	u32 divisor, tempval;
+ 	u32 div16 = 0;
+ 
++	if ((brg < QE_BRG1) || (brg > QE_BRG16))
++		return -EINVAL;
++
+ 	divisor = get_brg_clk() / (rate * multiplier);
+ 
+ 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
+@@ -196,8 +198,43 @@
+ 	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
+ 		QE_BRGC_ENABLE | div16;
+ 
+-	out_be32(&qe_immr->brg.brgc[brg - 1], tempval);
++	out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
++
++	return 0;
++}
++EXPORT_SYMBOL(qe_setbrg);
++
++/* Convert a string to a QE clock source enum
++ *
++ * This function takes a string, typically from a property in the device
++ * tree, and returns the corresponding "enum qe_clock" value.
++*/
++enum qe_clock qe_clock_source(const char *source)
++{
++	unsigned int i;
++
++	if (strcasecmp(source, "none") == 0)
++		return QE_CLK_NONE;
++
++	if (strncasecmp(source, "brg", 3) == 0) {
++		i = simple_strtoul(source + 3, NULL, 10);
++		if ((i >= 1) && (i <= 16))
++			return (QE_BRG1 - 1) + i;
++		else
++			return QE_CLK_DUMMY;
++	}
++
++	if (strncasecmp(source, "clk", 3) == 0) {
++		i = simple_strtoul(source + 3, NULL, 10);
++		if ((i >= 1) && (i <= 24))
++			return (QE_CLK1 - 1) + i;
++		else
++			return QE_CLK_DUMMY;
++	}
++
++	return QE_CLK_DUMMY;
+ }
++EXPORT_SYMBOL(qe_clock_source);
+ 
+ /* Initialize SNUMs (thread serial numbers) according to
+  * QE Module Control chapter, SNUM table
+@@ -358,3 +395,249 @@
+ 	return (void *)&qe_immr->muram[offset];
+ }
+ EXPORT_SYMBOL(qe_muram_addr);
++
++/* The maximum number of RISCs we support */
++#define MAX_QE_RISC     2
++
++/* Firmware information stored here for qe_get_firmware_info() */
++static struct qe_firmware_info qe_firmware_info;
++
++/*
++ * Set to 1 if QE firmware has been uploaded, and therefore
++ * qe_firmware_info contains valid data.
++ */
++static int qe_firmware_uploaded;
++
++/*
++ * Upload a QE microcode
++ *
++ * This function is a worker function for qe_upload_firmware().  It does
++ * the actual uploading of the microcode.
++ */
++static void qe_upload_microcode(const void *base,
++	const struct qe_microcode *ucode)
++{
++	const __be32 *code = base + be32_to_cpu(ucode->code_offset);
++	unsigned int i;
++
++	if (ucode->major || ucode->minor || ucode->revision)
++		printk(KERN_INFO "qe-firmware: "
++			"uploading microcode '%s' version %u.%u.%u\n",
++			ucode->id, ucode->major, ucode->minor, ucode->revision);
++	else
++		printk(KERN_INFO "qe-firmware: "
++			"uploading microcode '%s'\n", ucode->id);
++
++	/* Use auto-increment */
++	out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
++		QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
++
++	for (i = 0; i < be32_to_cpu(ucode->count); i++)
++		out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
++}
++
++/*
++ * Upload a microcode to the I-RAM at a specific address.
++ *
++ * See Documentation/powerpc/qe-firmware.txt for information on QE microcode
++ * uploading.
++ *
++ * Currently, only version 1 is supported, so the 'version' field must be
++ * set to 1.
++ *
++ * The SOC model and revision are not validated, they are only displayed for
++ * informational purposes.
++ *
++ * 'calc_size' is the calculated size, in bytes, of the firmware structure and
++ * all of the microcode structures, minus the CRC.
++ *
++ * 'length' is the size that the structure says it is, including the CRC.
++ */
++int qe_upload_firmware(const struct qe_firmware *firmware)
++{
++	unsigned int i;
++	unsigned int j;
++	u32 crc;
++	size_t calc_size = sizeof(struct qe_firmware);
++	size_t length;
++	const struct qe_header *hdr;
++
++	if (!firmware) {
++		printk(KERN_ERR "qe-firmware: invalid pointer\n");
++		return -EINVAL;
++	}
++
++	hdr = &firmware->header;
++	length = be32_to_cpu(hdr->length);
++
++	/* Check the magic */
++	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
++	    (hdr->magic[2] != 'F')) {
++		printk(KERN_ERR "qe-firmware: not a microcode\n");
++		return -EPERM;
++	}
++
++	/* Check the version */
++	if (hdr->version != 1) {
++		printk(KERN_ERR "qe-firmware: unsupported version\n");
++		return -EPERM;
++	}
++
++	/* Validate some of the fields */
++	if ((firmware->count < 1) || (firmware->count >= MAX_QE_RISC)) {
++		printk(KERN_ERR "qe-firmware: invalid data\n");
++		return -EINVAL;
++	}
++
++	/* Validate the length and check if there's a CRC */
++	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
++
++	for (i = 0; i < firmware->count; i++)
++		/*
++		 * For situations where the second RISC uses the same microcode
++		 * as the first, the 'code_offset' and 'count' fields will be
++		 * zero, so it's okay to add those.
++		 */
++		calc_size += sizeof(__be32) *
++			be32_to_cpu(firmware->microcode[i].count);
++
++	/* Validate the length */
++	if (length != calc_size + sizeof(__be32)) {
++		printk(KERN_ERR "qe-firmware: invalid length\n");
++		return -EPERM;
++	}
++
++	/* Validate the CRC */
++	crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
++	if (crc != crc32(0, firmware, calc_size)) {
++		printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
++		return -EIO;
++	}
++
++	/*
++	 * If the microcode calls for it, split the I-RAM.
++	 */
++	if (!firmware->split)
++		setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
++
++	if (firmware->soc.model)
++		printk(KERN_INFO
++			"qe-firmware: firmware '%s' for %u V%u.%u\n",
++			firmware->id, be16_to_cpu(firmware->soc.model),
++			firmware->soc.major, firmware->soc.minor);
++	else
++		printk(KERN_INFO "qe-firmware: firmware '%s'\n",
++			firmware->id);
++
++	/*
++	 * The QE only supports one microcode per RISC, so clear out all the
++	 * saved microcode information and put in the new.
++	 */
++	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
++	strcpy(qe_firmware_info.id, firmware->id);
++	qe_firmware_info.extended_modes = firmware->extended_modes;
++	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
++		sizeof(firmware->vtraps));
++
++	/* Loop through each microcode. */
++	for (i = 0; i < firmware->count; i++) {
++		const struct qe_microcode *ucode = &firmware->microcode[i];
++
++		/* Upload a microcode if it's present */
++		if (ucode->code_offset)
++			qe_upload_microcode(firmware, ucode);
++
++		/* Program the traps for this processor */
++		for (j = 0; j < 16; j++) {
++			u32 trap = be32_to_cpu(ucode->traps[j]);
++
++			if (trap)
++				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
++		}
++
++		/* Enable traps */
++		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
++	}
++
++	qe_firmware_uploaded = 1;
++
++	return 0;
++}
++EXPORT_SYMBOL(qe_upload_firmware);
++
++/*
++ * Get info on the currently-loaded firmware
++ *
++ * This function also checks the device tree to see if the boot loader has
++ * uploaded a firmware already.
++ */
++struct qe_firmware_info *qe_get_firmware_info(void)
++{
++	static int initialized;
++	struct property *prop;
++	struct device_node *qe;
++	struct device_node *fw = NULL;
++	const char *sprop;
++	unsigned int i;
++
++	/*
++	 * If we haven't checked yet, and a driver hasn't uploaded a firmware
++	 * yet, then check the device tree for information.
++	 */
++	if (initialized || qe_firmware_uploaded)
++		return NULL;
++
++	initialized = 1;
++
++	/*
++	 * Newer device trees have an "fsl,qe" compatible property for the QE
++	 * node, but we still need to support older device trees.
++	*/
++	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
++	if (!qe) {
++		qe = of_find_node_by_type(NULL, "qe");
++		if (!qe)
++			return NULL;
++	}
++
++	/* Find the 'firmware' child node */
++	for_each_child_of_node(qe, fw) {
++		if (strcmp(fw->name, "firmware") == 0)
++			break;
++	}
++
++	of_node_put(qe);
++
++	/* Did we find the 'firmware' node? */
++	if (!fw)
++		return NULL;
++
++	qe_firmware_uploaded = 1;
++
++	/* Copy the data into qe_firmware_info*/
++	sprop = of_get_property(fw, "id", NULL);
++	if (sprop)
++		strncpy(qe_firmware_info.id, sprop,
++			sizeof(qe_firmware_info.id) - 1);
++
++	prop = of_find_property(fw, "extended-modes", NULL);
++	if (prop && (prop->length == sizeof(u64))) {
++		const u64 *iprop = prop->value;
++
++		qe_firmware_info.extended_modes = *iprop;
++	}
++
++	prop = of_find_property(fw, "virtual-traps", NULL);
++	if (prop && (prop->length == 32)) {
++		const u32 *iprop = prop->value;
++
++		for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
++			qe_firmware_info.vtraps[i] = iprop[i];
++	}
++
++	of_node_put(fw);
++
++	return &qe_firmware_info;
++}
++EXPORT_SYMBOL(qe_get_firmware_info);
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/qe_lib/ucc_slow.c powerpc.git/arch/powerpc/sysdev/qe_lib/ucc_slow.c
+--- linux-2.6.24/arch/powerpc/sysdev/qe_lib/ucc_slow.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/qe_lib/ucc_slow.c	2008-01-28 20:25:49.000000000 +0100
+@@ -19,6 +19,7 @@
+ #include <linux/stddef.h>
+ #include <linux/interrupt.h>
+ #include <linux/err.h>
++#include <linux/module.h>
+ 
+ #include <asm/io.h>
+ #include <asm/immap_qe.h>
+@@ -41,6 +42,7 @@
+ 	default: return QE_CR_SUBBLOCK_INVALID;
+ 	}
+ }
++EXPORT_SYMBOL(ucc_slow_get_qe_cr_subblock);
+ 
+ void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs)
+ {
+@@ -56,6 +58,7 @@
+ 	qe_issue_cmd(QE_GRACEFUL_STOP_TX, id,
+ 			 QE_CR_PROTOCOL_UNSPECIFIED, 0);
+ }
++EXPORT_SYMBOL(ucc_slow_graceful_stop_tx);
+ 
+ void ucc_slow_stop_tx(struct ucc_slow_private * uccs)
+ {
+@@ -65,6 +68,7 @@
+ 	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+ 	qe_issue_cmd(QE_STOP_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+ }
++EXPORT_SYMBOL(ucc_slow_stop_tx);
+ 
+ void ucc_slow_restart_tx(struct ucc_slow_private * uccs)
+ {
+@@ -74,6 +78,7 @@
+ 	id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+ 	qe_issue_cmd(QE_RESTART_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+ }
++EXPORT_SYMBOL(ucc_slow_restart_tx);
+ 
+ void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
+ {
+@@ -94,6 +99,7 @@
+ 	}
+ 	out_be32(&us_regs->gumr_l, gumr_l);
+ }
++EXPORT_SYMBOL(ucc_slow_enable);
+ 
+ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
+ {
+@@ -114,6 +120,7 @@
+ 	}
+ 	out_be32(&us_regs->gumr_l, gumr_l);
+ }
++EXPORT_SYMBOL(ucc_slow_disable);
+ 
+ /* Initialize the UCC for Slow operations
+  *
+@@ -347,6 +354,7 @@
+ 	*uccs_ret = uccs;
+ 	return 0;
+ }
++EXPORT_SYMBOL(ucc_slow_init);
+ 
+ void ucc_slow_free(struct ucc_slow_private * uccs)
+ {
+@@ -366,5 +374,5 @@
+ 
+ 	kfree(uccs);
+ }
+-
++EXPORT_SYMBOL(ucc_slow_free);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/tsi108_dev.c powerpc.git/arch/powerpc/sysdev/tsi108_dev.c
+--- linux-2.6.24/arch/powerpc/sysdev/tsi108_dev.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/tsi108_dev.c	2008-01-28 20:25:49.000000000 +0100
+@@ -66,14 +66,12 @@
+ static int __init tsi108_eth_of_init(void)
+ {
+ 	struct device_node *np;
+-	unsigned int i;
++	unsigned int i = 0;
+ 	struct platform_device *tsi_eth_dev;
+ 	struct resource res;
+ 	int ret;
+ 
+-	for (np = NULL, i = 0;
+-	     (np = of_find_compatible_node(np, "network", "tsi108-ethernet")) != NULL;
+-	     i++) {
++	for_each_compatible_node(np, "network", "tsi108-ethernet") {
+ 		struct resource r[2];
+ 		struct device_node *phy, *mdio;
+ 		hw_info tsi_eth_data;
+@@ -98,7 +96,7 @@
+ 			__FUNCTION__,r[1].name, r[1].start, r[1].end);
+ 
+ 		tsi_eth_dev =
+-		    platform_device_register_simple("tsi-ethernet", i, &r[0],
++		    platform_device_register_simple("tsi-ethernet", i++, &r[0],
+ 						    1);
+ 
+ 		if (IS_ERR(tsi_eth_dev)) {
+@@ -154,6 +152,7 @@
+ unreg:
+ 	platform_device_unregister(tsi_eth_dev);
+ err:
++	of_node_put(np);
+ 	return ret;
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/uic.c powerpc.git/arch/powerpc/sysdev/uic.c
+--- linux-2.6.24/arch/powerpc/sysdev/uic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/uic.c	2008-01-28 20:25:49.000000000 +0100
+@@ -53,21 +53,23 @@
+ 
+ 	/* The remapper for this UIC */
+ 	struct irq_host	*irqhost;
+-
+-	/* For secondary UICs, the cascade interrupt's irqaction */
+-	struct irqaction cascade;
+ };
+ 
+ static void uic_unmask_irq(unsigned int virq)
+ {
++	struct irq_desc *desc = get_irq_desc(virq);
+ 	struct uic *uic = get_irq_chip_data(virq);
+ 	unsigned int src = uic_irq_to_hw(virq);
+ 	unsigned long flags;
+-	u32 er;
++	u32 er, sr;
+ 
++	sr = 1 << (31-src);
+ 	spin_lock_irqsave(&uic->lock, flags);
++	/* ack level-triggered interrupts here */
++	if (desc->status & IRQ_LEVEL)
++		mtdcr(uic->dcrbase + UIC_SR, sr);
+ 	er = mfdcr(uic->dcrbase + UIC_ER);
+-	er |= 1 << (31 - src);
++	er |= sr;
+ 	mtdcr(uic->dcrbase + UIC_ER, er);
+ 	spin_unlock_irqrestore(&uic->lock, flags);
+ }
+@@ -99,6 +101,7 @@
+ 
+ static void uic_mask_ack_irq(unsigned int virq)
+ {
++	struct irq_desc *desc = get_irq_desc(virq);
+ 	struct uic *uic = get_irq_chip_data(virq);
+ 	unsigned int src = uic_irq_to_hw(virq);
+ 	unsigned long flags;
+@@ -109,7 +112,16 @@
+ 	er = mfdcr(uic->dcrbase + UIC_ER);
+ 	er &= ~sr;
+ 	mtdcr(uic->dcrbase + UIC_ER, er);
+-	mtdcr(uic->dcrbase + UIC_SR, sr);
++ 	/* On the UIC, acking (i.e. clearing the SR bit)
++	 * a level irq will have no effect if the interrupt
++	 * is still asserted by the device, even if
++	 * the interrupt is already masked. Therefore
++	 * we only ack the egde interrupts here, while
++	 * level interrupts are ack'ed after the actual
++	 * isr call in the uic_unmask_irq()
++	 */
++	if (!(desc->status & IRQ_LEVEL))
++		mtdcr(uic->dcrbase + UIC_SR, sr);
+ 	spin_unlock_irqrestore(&uic->lock, flags);
+ }
+ 
+@@ -173,64 +185,6 @@
+ 	.set_type	= uic_set_irq_type,
+ };
+ 
+-/**
+- *	handle_uic_irq - irq flow handler for UIC
+- *	@irq:	the interrupt number
+- *	@desc:	the interrupt description structure for this irq
+- *
+- * This is modified version of the generic handle_level_irq() suitable
+- * for the UIC.  On the UIC, acking (i.e. clearing the SR bit) a level
+- * irq will have no effect if the interrupt is still asserted by the
+- * device, even if the interrupt is already masked.  Therefore, unlike
+- * the standard handle_level_irq(), we must ack the interrupt *after*
+- * invoking the ISR (which should have de-asserted the interrupt in
+- * the external source).  For edge interrupts we ack at the beginning
+- * instead of the end, to keep the window in which we can miss an
+- * interrupt as small as possible.
+- */
+-void fastcall handle_uic_irq(unsigned int irq, struct irq_desc *desc)
+-{
+-	unsigned int cpu = smp_processor_id();
+-	struct irqaction *action;
+-	irqreturn_t action_ret;
+-
+-	spin_lock(&desc->lock);
+-	if (desc->status & IRQ_LEVEL)
+-		desc->chip->mask(irq);
+-	else
+-		desc->chip->mask_ack(irq);
+-
+-	if (unlikely(desc->status & IRQ_INPROGRESS))
+-		goto out_unlock;
+-	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+-	kstat_cpu(cpu).irqs[irq]++;
+-
+-	/*
+-	 * If its disabled or no action available
+-	 * keep it masked and get out of here
+-	 */
+-	action = desc->action;
+-	if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
+-		desc->status |= IRQ_PENDING;
+-		goto out_unlock;
+-	}
+-
+-	desc->status |= IRQ_INPROGRESS;
+-	desc->status &= ~IRQ_PENDING;
+-	spin_unlock(&desc->lock);
+-
+-	action_ret = handle_IRQ_event(irq, action);
+-
+-	spin_lock(&desc->lock);
+-	desc->status &= ~IRQ_INPROGRESS;
+-	if (desc->status & IRQ_LEVEL)
+-		desc->chip->ack(irq);
+-	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
+-		desc->chip->unmask(irq);
+-out_unlock:
+-	spin_unlock(&desc->lock);
+-}
+-
+ static int uic_host_map(struct irq_host *h, unsigned int virq,
+ 			irq_hw_number_t hw)
+ {
+@@ -239,7 +193,7 @@
+ 	set_irq_chip_data(virq, uic);
+ 	/* Despite the name, handle_level_irq() works for both level
+ 	 * and edge irqs on UIC.  FIXME: check this is correct */
+-	set_irq_chip_and_handler(virq, &uic_irq_chip, handle_uic_irq);
++	set_irq_chip_and_handler(virq, &uic_irq_chip, handle_level_irq);
+ 
+ 	/* Set default irq type */
+ 	set_irq_type(virq, IRQ_TYPE_NONE);
+@@ -264,23 +218,36 @@
+ 	.xlate	= uic_host_xlate,
+ };
+ 
+-irqreturn_t uic_cascade(int virq, void *data)
++void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
+ {
+-	struct uic *uic = data;
++	struct uic *uic = get_irq_data(virq);
+ 	u32 msr;
+ 	int src;
+ 	int subvirq;
+ 
++	spin_lock(&desc->lock);
++	if (desc->status & IRQ_LEVEL)
++		desc->chip->mask(virq);
++	else
++		desc->chip->mask_ack(virq);
++	spin_unlock(&desc->lock);
++
+ 	msr = mfdcr(uic->dcrbase + UIC_MSR);
+ 	if (!msr) /* spurious interrupt */
+-		return IRQ_HANDLED;
++		goto uic_irq_ret;
+ 
+ 	src = 32 - ffs(msr);
+ 
+ 	subvirq = irq_linear_revmap(uic->irqhost, src);
+ 	generic_handle_irq(subvirq);
+ 
+-	return IRQ_HANDLED;
++uic_irq_ret:
++	spin_lock(&desc->lock);
++	if (desc->status & IRQ_LEVEL)
++		desc->chip->ack(virq);
++	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
++		desc->chip->unmask(virq);
++	spin_unlock(&desc->lock);
+ }
+ 
+ static struct uic * __init uic_init_one(struct device_node *node)
+@@ -342,33 +309,27 @@
+ 	const u32 *interrupts;
+ 
+ 	/* First locate and initialize the top-level UIC */
+-
+-	np = of_find_compatible_node(NULL, NULL, "ibm,uic");
+-	while (np) {
++	for_each_compatible_node(np, NULL, "ibm,uic") {
+ 		interrupts = of_get_property(np, "interrupts", NULL);
+-		if (! interrupts)
++		if (!interrupts)
+ 			break;
+-
+-		np = of_find_compatible_node(np, NULL, "ibm,uic");
+ 	}
+ 
+ 	BUG_ON(!np); /* uic_init_tree() assumes there's a UIC as the
+ 		      * top-level interrupt controller */
+ 	primary_uic = uic_init_one(np);
+-	if (! primary_uic)
++	if (!primary_uic)
+ 		panic("Unable to initialize primary UIC %s\n", np->full_name);
+ 
+ 	irq_set_default_host(primary_uic->irqhost);
+ 	of_node_put(np);
+ 
+ 	/* The scan again for cascaded UICs */
+-	np = of_find_compatible_node(NULL, NULL, "ibm,uic");
+-	while (np) {
++	for_each_compatible_node(np, NULL, "ibm,uic") {
+ 		interrupts = of_get_property(np, "interrupts", NULL);
+ 		if (interrupts) {
+ 			/* Secondary UIC */
+ 			int cascade_virq;
+-			int ret;
+ 
+ 			uic = uic_init_one(np);
+ 			if (! uic)
+@@ -377,20 +338,11 @@
+ 
+ 			cascade_virq = irq_of_parse_and_map(np, 0);
+ 
+-			uic->cascade.handler = uic_cascade;
+-			uic->cascade.name = "UIC cascade";
+-			uic->cascade.dev_id = uic;
+-
+-			ret = setup_irq(cascade_virq, &uic->cascade);
+-			if (ret)
+-				printk(KERN_ERR "Failed to setup_irq(%d) for "
+-				       "UIC%d cascade\n", cascade_virq,
+-				       uic->index);
++			set_irq_data(cascade_virq, uic);
++			set_irq_chained_handler(cascade_virq, uic_irq_cascade);
+ 
+ 			/* FIXME: setup critical cascade?? */
+ 		}
+-
+-		np = of_find_compatible_node(np, NULL, "ibm,uic");
+ 	}
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/sysdev/xilinx_intc.c powerpc.git/arch/powerpc/sysdev/xilinx_intc.c
+--- linux-2.6.24/arch/powerpc/sysdev/xilinx_intc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/sysdev/xilinx_intc.c	2008-01-28 20:25:49.000000000 +0100
+@@ -135,10 +135,16 @@
+ 	struct device_node *np;
+ 
+ 	/* find top level interrupt controller */
+-	for_each_compatible_node(np, NULL, "xilinx,intc") {
++	for_each_compatible_node(np, NULL, "xlnx,opb-intc-1.00.c") {
+ 		if (!of_get_property(np, "interrupts", NULL))
+ 			break;
+ 	}
++	if (!np) {
++		for_each_compatible_node(np, NULL, "xlnx,xps-intc-1.00.a") {
++			if (!of_get_property(np, "interrupts", NULL))
++				break;
++		}
++	}
+ 
+ 	/* xilinx interrupt controller needs to be top level */
+ 	BUG_ON(!np);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/xmon/setjmp.S powerpc.git/arch/powerpc/xmon/setjmp.S
+--- linux-2.6.24/arch/powerpc/xmon/setjmp.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/xmon/setjmp.S	2008-01-28 20:25:49.000000000 +0100
+@@ -12,67 +12,6 @@
+ #include <asm/ppc_asm.h>
+ #include <asm/asm-offsets.h>
+ 
+-_GLOBAL(xmon_setjmp)
+-	mflr	r0
+-	PPC_STL	r0,0(r3)
+-	PPC_STL	r1,SZL(r3)
+-	PPC_STL	r2,2*SZL(r3)
+-	mfcr	r0
+-	PPC_STL	r0,3*SZL(r3)
+-	PPC_STL	r13,4*SZL(r3)
+-	PPC_STL	r14,5*SZL(r3)
+-	PPC_STL	r15,6*SZL(r3)
+-	PPC_STL	r16,7*SZL(r3)
+-	PPC_STL	r17,8*SZL(r3)
+-	PPC_STL	r18,9*SZL(r3)
+-	PPC_STL	r19,10*SZL(r3)
+-	PPC_STL	r20,11*SZL(r3)
+-	PPC_STL	r21,12*SZL(r3)
+-	PPC_STL	r22,13*SZL(r3)
+-	PPC_STL	r23,14*SZL(r3)
+-	PPC_STL	r24,15*SZL(r3)
+-	PPC_STL	r25,16*SZL(r3)
+-	PPC_STL	r26,17*SZL(r3)
+-	PPC_STL	r27,18*SZL(r3)
+-	PPC_STL	r28,19*SZL(r3)
+-	PPC_STL	r29,20*SZL(r3)
+-	PPC_STL	r30,21*SZL(r3)
+-	PPC_STL	r31,22*SZL(r3)
+-	li	r3,0
+-	blr
+-
+-_GLOBAL(xmon_longjmp)
+-	PPC_LCMPI r4,0
+-	bne	1f
+-	li	r4,1
+-1:	PPC_LL	r13,4*SZL(r3)
+-	PPC_LL	r14,5*SZL(r3)
+-	PPC_LL	r15,6*SZL(r3)
+-	PPC_LL	r16,7*SZL(r3)
+-	PPC_LL	r17,8*SZL(r3)
+-	PPC_LL	r18,9*SZL(r3)
+-	PPC_LL	r19,10*SZL(r3)
+-	PPC_LL	r20,11*SZL(r3)
+-	PPC_LL	r21,12*SZL(r3)
+-	PPC_LL	r22,13*SZL(r3)
+-	PPC_LL	r23,14*SZL(r3)
+-	PPC_LL	r24,15*SZL(r3)
+-	PPC_LL	r25,16*SZL(r3)
+-	PPC_LL	r26,17*SZL(r3)
+-	PPC_LL	r27,18*SZL(r3)
+-	PPC_LL	r28,19*SZL(r3)
+-	PPC_LL	r29,20*SZL(r3)
+-	PPC_LL	r30,21*SZL(r3)
+-	PPC_LL	r31,22*SZL(r3)
+-	PPC_LL	r0,3*SZL(r3)
+-	mtcrf	0x38,r0
+-	PPC_LL	r0,0(r3)
+-	PPC_LL	r1,SZL(r3)
+-	PPC_LL	r2,2*SZL(r3)
+-	mtlr	r0
+-	mr	r3,r4
+-	blr
+-
+ /*
+  * Grab the register values as they are now.
+  * This won't do a particularily good job because we really
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/powerpc/xmon/xmon.c powerpc.git/arch/powerpc/xmon/xmon.c
+--- linux-2.6.24/arch/powerpc/xmon/xmon.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/powerpc/xmon/xmon.c	2008-01-28 20:25:49.000000000 +0100
+@@ -40,6 +40,7 @@
+ #include <asm/spu.h>
+ #include <asm/spu_priv1.h>
+ #include <asm/firmware.h>
++#include <asm/setjmp.h>
+ 
+ #ifdef CONFIG_PPC64
+ #include <asm/hvcall.h>
+@@ -71,12 +72,9 @@
+ static int termch;
+ static char tmpstr[128];
+ 
+-#define JMP_BUF_LEN	23
+ static long bus_error_jmp[JMP_BUF_LEN];
+ static int catch_memory_errors;
+ static long *xmon_fault_jmp[NR_CPUS];
+-#define setjmp xmon_setjmp
+-#define longjmp xmon_longjmp
+ 
+ /* Breakpoint stuff */
+ struct bpt {
+@@ -153,13 +151,15 @@
+ 
+ static int do_spu_cmd(void);
+ 
++#ifdef CONFIG_44x
++static void dump_tlb_44x(void);
++#endif
++
+ int xmon_no_auto_backtrace;
+ 
+ extern void xmon_enter(void);
+ extern void xmon_leave(void);
+ 
+-extern long setjmp(long *);
+-extern void longjmp(long *, long);
+ extern void xmon_save_regs(struct pt_regs *);
+ 
+ #ifdef CONFIG_PPC64
+@@ -231,6 +231,9 @@
+ #ifdef CONFIG_PPC_STD_MMU_32
+ "  u	dump segment registers\n"
+ #endif
++#ifdef CONFIG_44x
++"  u	dump TLB\n"
++#endif
+ "  ?	help\n"
+ "  zr	reboot\n\
+   zh	halt\n"
+@@ -856,6 +859,11 @@
+ 			dump_segments();
+ 			break;
+ #endif
++#ifdef CONFIG_4xx
++		case 'u':
++			dump_tlb_44x();
++			break;
++#endif
+ 		default:
+ 			printf("Unrecognized command: ");
+ 		        do {
+@@ -2527,16 +2535,33 @@
+ static void dump_slb(void)
+ {
+ 	int i;
+-	unsigned long tmp;
++	unsigned long esid,vsid,valid;
++	unsigned long llp;
+ 
+ 	printf("SLB contents of cpu %x\n", smp_processor_id());
+ 
+-	for (i = 0; i < SLB_NUM_ENTRIES; i++) {
+-		asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));
+-		printf("%02d %016lx ", i, tmp);
+-
+-		asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));
+-		printf("%016lx\n", tmp);
++	for (i = 0; i < mmu_slb_size; i++) {
++		asm volatile("slbmfee  %0,%1" : "=r" (esid) : "r" (i));
++		asm volatile("slbmfev  %0,%1" : "=r" (vsid) : "r" (i));
++		valid = (esid & SLB_ESID_V);
++		if (valid | esid | vsid) {
++			printf("%02d %016lx %016lx", i, esid, vsid);
++			if (valid) {
++				llp = vsid & SLB_VSID_LLP;
++				if (vsid & SLB_VSID_B_1T) {
++					printf("  1T  ESID=%9lx  VSID=%13lx LLP:%3lx \n",
++						GET_ESID_1T(esid),
++						(vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
++						llp);
++				} else {
++					printf(" 256M ESID=%9lx  VSID=%13lx LLP:%3lx \n",
++						GET_ESID(esid),
++						(vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
++						llp);
++				}
++			} else
++				printf("\n");
++		}
+ 	}
+ }
+ 
+@@ -2581,6 +2606,32 @@
+ }
+ #endif
+ 
++#ifdef CONFIG_44x
++static void dump_tlb_44x(void)
++{
++	int i;
++
++	for (i = 0; i < PPC44x_TLB_SIZE; i++) {
++		unsigned long w0,w1,w2;
++		asm volatile("tlbre  %0,%1,0" : "=r" (w0) : "r" (i));
++		asm volatile("tlbre  %0,%1,1" : "=r" (w1) : "r" (i));
++		asm volatile("tlbre  %0,%1,2" : "=r" (w2) : "r" (i));
++		printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
++		if (w0 & PPC44x_TLB_VALID) {
++			printf("V %08x -> %01x%08x %c%c%c%c%c",
++			       w0 & PPC44x_TLB_EPN_MASK,
++			       w1 & PPC44x_TLB_ERPN_MASK,
++			       w1 & PPC44x_TLB_RPN_MASK,
++			       (w2 & PPC44x_TLB_W) ? 'W' : 'w',
++			       (w2 & PPC44x_TLB_I) ? 'I' : 'i',
++			       (w2 & PPC44x_TLB_M) ? 'M' : 'm',
++			       (w2 & PPC44x_TLB_G) ? 'G' : 'g',
++			       (w2 & PPC44x_TLB_E) ? 'E' : 'e');
++		}
++		printf("\n");
++	}
++}
++#endif /* CONFIG_44x */
+ void xmon_init(int enable)
+ {
+ #ifdef CONFIG_PPC_ISERIES
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/kernel/Makefile powerpc.git/arch/ppc/kernel/Makefile
+--- linux-2.6.24/arch/ppc/kernel/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/kernel/Makefile	2008-01-28 20:25:50.000000000 +0100
+@@ -13,7 +13,6 @@
+ 					ppc_htab.o
+ obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
+ obj-$(CONFIG_PCI)		+= pci.o
+-obj-$(CONFIG_RAPIDIO)		+= rio.o
+ obj-$(CONFIG_KGDB)		+= ppc-stub.o
+ obj-$(CONFIG_SMP)		+= smp.o smp-tbsync.o
+ obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/kernel/head_44x.S powerpc.git/arch/ppc/kernel/head_44x.S
+--- linux-2.6.24/arch/ppc/kernel/head_44x.S	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/kernel/head_44x.S	2008-01-28 20:25:50.000000000 +0100
+@@ -195,7 +195,7 @@
+ 	li	r5,0
+ 	ori	r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
+ 
+-        li      r0,0                    /* TLB slot 0 */
++	li	r0,62			/* TLB slot 62 */
+ 
+ 	tlbwe	r3,r0,PPC44x_TLB_PAGEID	/* Load the pageid fields */
+ 	tlbwe	r4,r0,PPC44x_TLB_XLAT	/* Load the translation fields */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/kernel/ppc_htab.c powerpc.git/arch/ppc/kernel/ppc_htab.c
+--- linux-2.6.24/arch/ppc/kernel/ppc_htab.c	2008-01-28 20:50:10.000000000 +0100
++++ powerpc.git/arch/ppc/kernel/ppc_htab.c	2008-01-28 20:25:50.000000000 +0100
+@@ -436,6 +436,7 @@
+  */
+ static ctl_table htab_ctl_table[]={
+ 	{
++		.ctl_name	= KERN_PPC_L2CR,
+ 		.procname	= "l2cr",
+ 		.mode		= 0644,
+ 		.proc_handler	= &proc_dol2crvec,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/kernel/rio.c powerpc.git/arch/ppc/kernel/rio.c
+--- linux-2.6.24/arch/ppc/kernel/rio.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/kernel/rio.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,52 +0,0 @@
+-/*
+- * RapidIO PPC32 support
+- *
+- * Copyright 2005 MontaVista Software, Inc.
+- * Matt Porter <mporter@kernel.crashing.org>
+- *
+- * This program is free software; you can redistribute  it and/or modify it
+- * under  the terms of  the GNU General  Public License as published by the
+- * Free Software Foundation;  either version 2 of the  License, or (at your
+- * option) any later version.
+- */
+-
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/rio.h>
+-
+-#include <asm/rio.h>
+-
+-/**
+- * platform_rio_init - Do platform specific RIO init
+- *
+- * Any platform specific initialization of RapdIO
+- * hardware is done here as well as registration
+- * of any active master ports in the system.
+- */
+-void __attribute__ ((weak))
+-    platform_rio_init(void)
+-{
+-	printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
+-}
+-
+-/**
+- * ppc_rio_init - Do PPC32 RIO init
+- *
+- * Calls platform-specific RIO init code and then calls
+- * rio_init_mports() to initialize any master ports that
+- * have been registered with the RIO subsystem.
+- */
+-static int __init ppc_rio_init(void)
+-{
+-	printk(KERN_INFO "RIO: RapidIO init\n");
+-
+-	/* Platform specific initialization */
+-	platform_rio_init();
+-
+-	/* Enumerate all registered ports */
+-	rio_init_mports();
+-
+-	return 0;
+-}
+-
+-subsys_initcall(ppc_rio_init);
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/kernel/setup.c powerpc.git/arch/ppc/kernel/setup.c
+--- linux-2.6.24/arch/ppc/kernel/setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/kernel/setup.c	2008-01-28 20:25:50.000000000 +0100
+@@ -37,7 +37,6 @@
+ #include <asm/nvram.h>
+ #include <asm/xmon.h>
+ #include <asm/ocp.h>
+-#include <asm/prom.h>
+ 
+ #define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \
+ 		      defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/kernel/traps.c powerpc.git/arch/ppc/kernel/traps.c
+--- linux-2.6.24/arch/ppc/kernel/traps.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/kernel/traps.c	2008-01-28 20:25:50.000000000 +0100
+@@ -231,39 +231,25 @@
+ {
+ }
+ 
+-void machine_check_exception(struct pt_regs *regs)
++#if defined(CONFIG_4xx)
++int machine_check_4xx(struct pt_regs *regs)
+ {
+ 	unsigned long reason = get_mc_reason(regs);
+ 
+-	if (user_mode(regs)) {
+-		regs->msr |= MSR_RI;
+-		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
+-		return;
+-	}
+-
+-#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
+-	/* the qspan pci read routines can cause machine checks -- Cort */
+-	bad_page_fault(regs, regs->dar, SIGBUS);
+-	return;
+-#endif
+-
+-	if (debugger_fault_handler) {
+-		debugger_fault_handler(regs);
+-		regs->msr |= MSR_RI;
+-		return;
+-	}
+-
+-	if (check_io_access(regs))
+-		return;
+-
+-#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
+ 	if (reason & ESR_IMCP) {
+ 		printk("Instruction");
+ 		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+ 	} else
+ 		printk("Data");
+ 	printk(" machine check in kernel mode.\n");
+-#elif defined(CONFIG_440A)
++
++	return 0;
++}
++
++int machine_check_440A(struct pt_regs *regs)
++{
++	unsigned long reason = get_mc_reason(regs);
++
+ 	printk("Machine check in kernel mode.\n");
+ 	if (reason & ESR_IMCP){
+ 		printk("Instruction Synchronous Machine Check exception\n");
+@@ -293,7 +279,13 @@
+ 		/* Clear MCSR */
+ 		mtspr(SPRN_MCSR, mcsr);
+ 	}
+-#elif defined (CONFIG_E500)
++	return 0;
++}
++#elif defined(CONFIG_E500)
++int machine_check_e500(struct pt_regs *regs)
++{
++	unsigned long reason = get_mc_reason(regs);
++
+ 	printk("Machine check in kernel mode.\n");
+ 	printk("Caused by (from MCSR=%lx): ", reason);
+ 
+@@ -305,8 +297,6 @@
+ 		printk("Data Cache Push Parity Error\n");
+ 	if (reason & MCSR_DCPERR)
+ 		printk("Data Cache Parity Error\n");
+-	if (reason & MCSR_GL_CI)
+-		printk("Guarded Load or Cache-Inhibited stwcx.\n");
+ 	if (reason & MCSR_BUS_IAERR)
+ 		printk("Bus - Instruction Address Error\n");
+ 	if (reason & MCSR_BUS_RAERR)
+@@ -318,12 +308,19 @@
+ 	if (reason & MCSR_BUS_RBERR)
+ 		printk("Bus - Read Data Bus Error\n");
+ 	if (reason & MCSR_BUS_WBERR)
+-		printk("Bus - Write Data Bus Error\n");
++		printk("Bus - Read Data Bus Error\n");
+ 	if (reason & MCSR_BUS_IPERR)
+ 		printk("Bus - Instruction Parity Error\n");
+ 	if (reason & MCSR_BUS_RPERR)
+ 		printk("Bus - Read Parity Error\n");
+-#elif defined (CONFIG_E200)
++
++	return 0;
++}
++#elif defined(CONFIG_E200)
++int machine_check_e200(struct pt_regs *regs)
++{
++	unsigned long reason = get_mc_reason(regs);
++
+ 	printk("Machine check in kernel mode.\n");
+ 	printk("Caused by (from MCSR=%lx): ", reason);
+ 
+@@ -341,7 +338,14 @@
+ 		printk("Bus - Read Bus Error on data load\n");
+ 	if (reason & MCSR_BUS_WRERR)
+ 		printk("Bus - Write Bus Error on buffered store or cache line push\n");
+-#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
++
++	return 0;
++}
++#else
++int machine_check_generic(struct pt_regs *regs)
++{
++	unsigned long reason = get_mc_reason(regs);
++
+ 	printk("Machine check in kernel mode.\n");
+ 	printk("Caused by (from SRR1=%lx): ", reason);
+ 	switch (reason & 0x601F0000) {
+@@ -371,7 +375,39 @@
+ 	default:
+ 		printk("Unknown values in msr\n");
+ 	}
+-#endif /* CONFIG_4xx */
++	return 0;
++}
++#endif /* everything else */
++
++void machine_check_exception(struct pt_regs *regs)
++{
++	int recover = 0;
++
++	if (cur_cpu_spec->machine_check)
++		recover = cur_cpu_spec->machine_check(regs);
++	if (recover > 0)
++		return;
++
++	if (user_mode(regs)) {
++		regs->msr |= MSR_RI;
++		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
++		return;
++	}
++
++#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
++	/* the qspan pci read routines can cause machine checks -- Cort */
++	bad_page_fault(regs, regs->dar, SIGBUS);
++	return;
++#endif
++
++	if (debugger_fault_handler) {
++		debugger_fault_handler(regs);
++		regs->msr |= MSR_RI;
++		return;
++	}
++
++	if (check_io_access(regs))
++		return;
+ 
+ 	/*
+ 	 * Optional platform-provided routine to print out
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/mm/44x_mmu.c powerpc.git/arch/ppc/mm/44x_mmu.c
+--- linux-2.6.24/arch/ppc/mm/44x_mmu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/mm/44x_mmu.c	2008-01-28 20:25:51.000000000 +0100
+@@ -60,38 +60,28 @@
+  * Just needed it declared someplace.
+  */
+ unsigned int tlb_44x_index = 0;
+-unsigned int tlb_44x_hwater = 62;
++unsigned int tlb_44x_hwater = PPC4XX_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
+ int icache_44x_need_flush;
+ 
+ /*
+  * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
+  */
+-static void __init
+-ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys)
++static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
+ {
+-	unsigned long attrib = 0;
+-
+-	__asm__ __volatile__("\
+-	clrrwi	%2,%2,10\n\
+-	ori	%2,%2,%4\n\
+-	clrrwi	%1,%1,10\n\
+-	li	%0,0\n\
+-	ori	%0,%0,%5\n\
+-	tlbwe	%2,%3,%6\n\
+-	tlbwe	%1,%3,%7\n\
+-	tlbwe	%0,%3,%8"
++	__asm__ __volatile__(
++		"tlbwe	%2,%3,%4\n"
++		"tlbwe	%1,%3,%5\n"
++		"tlbwe	%0,%3,%6\n"
+ 	:
+-	: "r" (attrib), "r" (phys), "r" (virt), "r" (slot),
+-	  "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M),
+-	  "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
++	: "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
++	  "r" (phys),
++	  "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M),
++	  "r" (tlb_44x_hwater--), /* slot for this TLB entry */
+ 	  "i" (PPC44x_TLB_PAGEID),
+ 	  "i" (PPC44x_TLB_XLAT),
+ 	  "i" (PPC44x_TLB_ATTRIB));
+ }
+ 
+-/*
+- * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+- */
+ void __init MMU_init_hw(void)
+ {
+ 	flush_instruction_cache();
+@@ -99,22 +89,13 @@
+ 
+ unsigned long __init mmu_mapin_ram(void)
+ {
+-	unsigned int pinned_tlbs = 1;
+-	int i;
+-
+-	/* Determine number of entries necessary to cover lowmem */
+-	pinned_tlbs = (unsigned int)
+-		(_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT);
+-
+-	/* Write upper watermark to save location */
+-	tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
++	unsigned long addr;
+ 
+-	/* If necessary, set additional pinned TLBs */
+-	if (pinned_tlbs > 1)
+-		for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
+-			unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE;
+-			ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
+-		}
++	/* Pin in enough TLBs to cover any lowmem not covered by the
++	 * initial 256M mapping established in head_44x.S */
++	for (addr = PPC_PIN_SIZE; addr < total_lowmem;
++	     addr += PPC_PIN_SIZE)
++		ppc44x_pin_tlb(addr + PAGE_OFFSET, addr);
+ 
+ 	return total_lowmem;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/platforms/85xx/mpc85xx_ads_common.c powerpc.git/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+--- linux-2.6.24/arch/ppc/platforms/85xx/mpc85xx_ads_common.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/platforms/85xx/mpc85xx_ads_common.c	2008-01-28 20:25:51.000000000 +0100
+@@ -42,8 +42,6 @@
+ 
+ #include <mm/mmu_decl.h>
+ 
+-#include <syslib/ppc85xx_rio.h>
+-
+ #include <platforms/85xx/mpc85xx_ads_common.h>
+ 
+ #ifndef CONFIG_PCI
+@@ -190,6 +188,7 @@
+ #endif /* CONFIG_PCI */
+ 
+ #ifdef CONFIG_RAPIDIO
++extern void mpc85xx_rio_setup(int law_start, int law_size);
+ void platform_rio_init(void)
+ {
+ 	/* 512MB RIO LAW at 0xc0000000 */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/platforms/85xx/stx_gp3.c powerpc.git/arch/ppc/platforms/85xx/stx_gp3.c
+--- linux-2.6.24/arch/ppc/platforms/85xx/stx_gp3.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/platforms/85xx/stx_gp3.c	2008-01-28 20:25:51.000000000 +0100
+@@ -50,12 +50,10 @@
+ #include <asm/irq.h>
+ #include <asm/immap_85xx.h>
+ #include <asm/cpm2.h>
+-#include <asm/mpc85xx.h>
+ #include <asm/ppc_sys.h>
+ 
+ #include <syslib/cpm2_pic.h>
+ #include <syslib/ppc85xx_common.h>
+-#include <syslib/ppc85xx_rio.h>
+ 
+ 
+ unsigned char __res[sizeof(bd_t)];
+@@ -271,6 +269,7 @@
+ #endif /* CONFIG_PCI */
+ 
+ #ifdef CONFIG_RAPIDIO
++extern void mpc85xx_rio_setup(int law_start, int law_size);
+ void
+ platform_rio_init(void)
+ {
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/platforms/85xx/tqm85xx.c powerpc.git/arch/ppc/platforms/85xx/tqm85xx.c
+--- linux-2.6.24/arch/ppc/platforms/85xx/tqm85xx.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/platforms/85xx/tqm85xx.c	2008-01-28 20:25:51.000000000 +0100
+@@ -54,7 +54,6 @@
+ #include <syslib/ppc85xx_setup.h>
+ #include <syslib/cpm2_pic.h>
+ #include <syslib/ppc85xx_common.h>
+-#include <syslib/ppc85xx_rio.h>
+ 
+ #ifndef CONFIG_PCI
+ unsigned long isa_io_base = 0;
+@@ -309,6 +308,7 @@
+ #endif /* CONFIG_PCI */
+ 
+ #ifdef CONFIG_RAPIDIO
++extern void mpc85xx_rio_setup(int law_start, int law_size);
+ void platform_rio_init(void)
+ {
+ 	/* 512MB RIO LAW at 0xc0000000 */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/platforms/ev64260.c powerpc.git/arch/ppc/platforms/ev64260.c
+--- linux-2.6.24/arch/ppc/platforms/ev64260.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/platforms/ev64260.c	2008-01-28 20:25:51.000000000 +0100
+@@ -336,7 +336,7 @@
+ #endif
+ 
+ 		if (early_serial_setup(&port) != 0)
+-			printk(KERN_WARNING "Early serial init of port 0"
++			printk(KERN_WARNING "Early serial init of port 0 "
+ 				"failed\n");
+ 
+ 		first_time = 0;
+@@ -388,7 +388,7 @@
+ 	ev64260_early_serial_map();
+ #endif
+ 
+-	printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc."
++	printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc. "
+ 		"(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE);
+ 
+ 	if (ppc_md.progress)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/platforms/prep_pci.c powerpc.git/arch/ppc/platforms/prep_pci.c
+--- linux-2.6.24/arch/ppc/platforms/prep_pci.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/platforms/prep_pci.c	2008-01-28 20:25:52.000000000 +0100
+@@ -1099,7 +1099,6 @@
+ 				pci_write_config_byte(dev, 0x43, reg);
+ 			}
+ 		}
+-		pci_dev_put(dev);
+ 	}
+ 
+ 	if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/Makefile powerpc.git/arch/ppc/syslib/Makefile
+--- linux-2.6.24/arch/ppc/syslib/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/Makefile	2008-01-28 20:25:52.000000000 +0100
+@@ -93,7 +93,6 @@
+ ifeq ($(CONFIG_85xx),y)
+ obj-$(CONFIG_PCI)		+= pci_auto.o
+ endif
+-obj-$(CONFIG_RAPIDIO)		+= ppc85xx_rio.o
+ obj-$(CONFIG_83xx)		+= ppc83xx_setup.o ppc_sys.o \
+ 					mpc83xx_sys.o mpc83xx_devices.o ipic.o
+ ifeq ($(CONFIG_83xx),y)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/gt64260_pic.c powerpc.git/arch/ppc/syslib/gt64260_pic.c
+--- linux-2.6.24/arch/ppc/syslib/gt64260_pic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/gt64260_pic.c	2008-01-28 20:25:52.000000000 +0100
+@@ -35,7 +35,6 @@
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
+ #include <linux/signal.h>
+-#include <linux/stddef.h>
+ #include <linux/delay.h>
+ #include <linux/irq.h>
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/mpc52xx_pic.c powerpc.git/arch/ppc/syslib/mpc52xx_pic.c
+--- linux-2.6.24/arch/ppc/syslib/mpc52xx_pic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/mpc52xx_pic.c	2008-01-28 20:25:52.000000000 +0100
+@@ -20,7 +20,6 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
+ #include <linux/signal.h>
+-#include <linux/stddef.h>
+ #include <linux/delay.h>
+ #include <linux/irq.h>
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/mv64360_pic.c powerpc.git/arch/ppc/syslib/mv64360_pic.c
+--- linux-2.6.24/arch/ppc/syslib/mv64360_pic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/mv64360_pic.c	2008-01-28 20:25:52.000000000 +0100
+@@ -36,7 +36,6 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
+ #include <linux/signal.h>
+-#include <linux/stddef.h>
+ #include <linux/delay.h>
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/ocp.c powerpc.git/arch/ppc/syslib/ocp.c
+--- linux-2.6.24/arch/ppc/syslib/ocp.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/ocp.c	2008-01-28 20:25:52.000000000 +0100
+@@ -376,7 +376,7 @@
+ 
+ 	down_write(&ocp_devices_sem);
+ 	dev = __ocp_find_device(vendor, function, index);
+-	list_del((struct list_head *)dev);
++	list_del(&dev->link);
+ 	up_write(&ocp_devices_sem);
+ 
+ 	DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)... done.\n", vendor, function, index));
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/ppc83xx_setup.c powerpc.git/arch/ppc/syslib/ppc83xx_setup.c
+--- linux-2.6.24/arch/ppc/syslib/ppc83xx_setup.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/ppc83xx_setup.c	2008-01-28 20:25:52.000000000 +0100
+@@ -41,7 +41,6 @@
+ 
+ #include <syslib/ppc83xx_setup.h>
+ #if defined(CONFIG_PCI)
+-#include <asm/delay.h>
+ #include <syslib/ppc83xx_pci.h>
+ #endif
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/ppc85xx_rio.c powerpc.git/arch/ppc/syslib/ppc85xx_rio.c
+--- linux-2.6.24/arch/ppc/syslib/ppc85xx_rio.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/ppc85xx_rio.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,932 +0,0 @@
+-/*
+- * MPC85xx RapidIO support
+- *
+- * Copyright 2005 MontaVista Software, Inc.
+- * Matt Porter <mporter@kernel.crashing.org>
+- *
+- * This program is free software; you can redistribute  it and/or modify it
+- * under  the terms of  the GNU General  Public License as published by the
+- * Free Software Foundation;  either version 2 of the  License, or (at your
+- * option) any later version.
+- */
+-
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/types.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/interrupt.h>
+-#include <linux/rio.h>
+-#include <linux/rio_drv.h>
+-
+-#include <asm/io.h>
+-
+-#define RIO_REGS_BASE		(CCSRBAR + 0xc0000)
+-#define RIO_ATMU_REGS_OFFSET	0x10c00
+-#define RIO_MSG_REGS_OFFSET	0x11000
+-#define RIO_MAINT_WIN_SIZE	0x400000
+-#define RIO_DBELL_WIN_SIZE	0x1000
+-
+-#define RIO_MSG_OMR_MUI		0x00000002
+-#define RIO_MSG_OSR_TE		0x00000080
+-#define RIO_MSG_OSR_QOI		0x00000020
+-#define RIO_MSG_OSR_QFI		0x00000010
+-#define RIO_MSG_OSR_MUB		0x00000004
+-#define RIO_MSG_OSR_EOMI	0x00000002
+-#define RIO_MSG_OSR_QEI		0x00000001
+-
+-#define RIO_MSG_IMR_MI		0x00000002
+-#define RIO_MSG_ISR_TE		0x00000080
+-#define RIO_MSG_ISR_QFI		0x00000010
+-#define RIO_MSG_ISR_DIQI	0x00000001
+-
+-#define RIO_MSG_DESC_SIZE	32
+-#define RIO_MSG_BUFFER_SIZE	4096
+-#define RIO_MIN_TX_RING_SIZE	2
+-#define RIO_MAX_TX_RING_SIZE	2048
+-#define RIO_MIN_RX_RING_SIZE	2
+-#define RIO_MAX_RX_RING_SIZE	2048
+-
+-#define DOORBELL_DMR_DI		0x00000002
+-#define DOORBELL_DSR_TE		0x00000080
+-#define DOORBELL_DSR_QFI	0x00000010
+-#define DOORBELL_DSR_DIQI	0x00000001
+-#define DOORBELL_TID_OFFSET	0x03
+-#define DOORBELL_SID_OFFSET	0x05
+-#define DOORBELL_INFO_OFFSET	0x06
+-
+-#define DOORBELL_MESSAGE_SIZE	0x08
+-#define DBELL_SID(x)		(*(u8 *)(x + DOORBELL_SID_OFFSET))
+-#define DBELL_TID(x)		(*(u8 *)(x + DOORBELL_TID_OFFSET))
+-#define DBELL_INF(x)		(*(u16 *)(x + DOORBELL_INFO_OFFSET))
+-
+-struct rio_atmu_regs {
+-	u32 rowtar;
+-	u32 pad1;
+-	u32 rowbar;
+-	u32 pad2;
+-	u32 rowar;
+-	u32 pad3[3];
+-};
+-
+-struct rio_msg_regs {
+-	u32 omr;
+-	u32 osr;
+-	u32 pad1;
+-	u32 odqdpar;
+-	u32 pad2;
+-	u32 osar;
+-	u32 odpr;
+-	u32 odatr;
+-	u32 odcr;
+-	u32 pad3;
+-	u32 odqepar;
+-	u32 pad4[13];
+-	u32 imr;
+-	u32 isr;
+-	u32 pad5;
+-	u32 ifqdpar;
+-	u32 pad6;
+-	u32 ifqepar;
+-	u32 pad7[250];
+-	u32 dmr;
+-	u32 dsr;
+-	u32 pad8;
+-	u32 dqdpar;
+-	u32 pad9;
+-	u32 dqepar;
+-	u32 pad10[26];
+-	u32 pwmr;
+-	u32 pwsr;
+-	u32 pad11;
+-	u32 pwqbar;
+-};
+-
+-struct rio_tx_desc {
+-	u32 res1;
+-	u32 saddr;
+-	u32 dport;
+-	u32 dattr;
+-	u32 res2;
+-	u32 res3;
+-	u32 dwcnt;
+-	u32 res4;
+-};
+-
+-static u32 regs_win;
+-static struct rio_atmu_regs *atmu_regs;
+-static struct rio_atmu_regs *maint_atmu_regs;
+-static struct rio_atmu_regs *dbell_atmu_regs;
+-static u32 dbell_win;
+-static u32 maint_win;
+-static struct rio_msg_regs *msg_regs;
+-
+-static struct rio_dbell_ring {
+-	void *virt;
+-	dma_addr_t phys;
+-} dbell_ring;
+-
+-static struct rio_msg_tx_ring {
+-	void *virt;
+-	dma_addr_t phys;
+-	void *virt_buffer[RIO_MAX_TX_RING_SIZE];
+-	dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE];
+-	int tx_slot;
+-	int size;
+-	void *dev_id;
+-} msg_tx_ring;
+-
+-static struct rio_msg_rx_ring {
+-	void *virt;
+-	dma_addr_t phys;
+-	void *virt_buffer[RIO_MAX_RX_RING_SIZE];
+-	int rx_slot;
+-	int size;
+-	void *dev_id;
+-} msg_rx_ring;
+-
+-/**
+- * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
+- * @index: ID of RapidIO interface
+- * @destid: Destination ID of target device
+- * @data: 16-bit info field of RapidIO doorbell message
+- *
+- * Sends a MPC85xx doorbell message. Returns %0 on success or
+- * %-EINVAL on failure.
+- */
+-static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
+-{
+-	pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
+-		 index, destid, data);
+-	out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
+-	out_be16((void *)(dbell_win), data);
+-
+-	return 0;
+-}
+-
+-/**
+- * mpc85xx_local_config_read - Generate a MPC85xx local config space read
+- * @index: ID of RapdiIO interface
+- * @offset: Offset into configuration space
+- * @len: Length (in bytes) of the maintenance transaction
+- * @data: Value to be read into
+- *
+- * Generates a MPC85xx local configuration space read. Returns %0 on
+- * success or %-EINVAL on failure.
+- */
+-static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
+-{
+-	pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
+-		 offset);
+-	*data = in_be32((void *)(regs_win + offset));
+-
+-	return 0;
+-}
+-
+-/**
+- * mpc85xx_local_config_write - Generate a MPC85xx local config space write
+- * @index: ID of RapdiIO interface
+- * @offset: Offset into configuration space
+- * @len: Length (in bytes) of the maintenance transaction
+- * @data: Value to be written
+- *
+- * Generates a MPC85xx local configuration space write. Returns %0 on
+- * success or %-EINVAL on failure.
+- */
+-static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
+-{
+-	pr_debug
+-	    ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
+-	     index, offset, data);
+-	out_be32((void *)(regs_win + offset), data);
+-
+-	return 0;
+-}
+-
+-/**
+- * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
+- * @index: ID of RapdiIO interface
+- * @destid: Destination ID of transaction
+- * @hopcount: Number of hops to target device
+- * @offset: Offset into configuration space
+- * @len: Length (in bytes) of the maintenance transaction
+- * @val: Location to be read into
+- *
+- * Generates a MPC85xx read maintenance transaction. Returns %0 on
+- * success or %-EINVAL on failure.
+- */
+-static int
+-mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
+-			u32 * val)
+-{
+-	u8 *data;
+-
+-	pr_debug
+-	    ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
+-	     index, destid, hopcount, offset, len);
+-	out_be32((void *)&maint_atmu_regs->rowtar,
+-		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+-
+-	data = (u8 *) maint_win + offset;
+-	switch (len) {
+-	case 1:
+-		*val = in_8((u8 *) data);
+-		break;
+-	case 2:
+-		*val = in_be16((u16 *) data);
+-		break;
+-	default:
+-		*val = in_be32((u32 *) data);
+-		break;
+-	}
+-
+-	return 0;
+-}
+-
+-/**
+- * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
+- * @index: ID of RapdiIO interface
+- * @destid: Destination ID of transaction
+- * @hopcount: Number of hops to target device
+- * @offset: Offset into configuration space
+- * @len: Length (in bytes) of the maintenance transaction
+- * @val: Value to be written
+- *
+- * Generates an MPC85xx write maintenance transaction. Returns %0 on
+- * success or %-EINVAL on failure.
+- */
+-static int
+-mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
+-			 int len, u32 val)
+-{
+-	u8 *data;
+-	pr_debug
+-	    ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
+-	     index, destid, hopcount, offset, len, val);
+-	out_be32((void *)&maint_atmu_regs->rowtar,
+-		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+-
+-	data = (u8 *) maint_win + offset;
+-	switch (len) {
+-	case 1:
+-		out_8((u8 *) data, val);
+-		break;
+-	case 2:
+-		out_be16((u16 *) data, val);
+-		break;
+-	default:
+-		out_be32((u32 *) data, val);
+-		break;
+-	}
+-
+-	return 0;
+-}
+-
+-/**
+- * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
+- * @mport: Master port with outbound message queue
+- * @rdev: Target of outbound message
+- * @mbox: Outbound mailbox
+- * @buffer: Message to add to outbound queue
+- * @len: Length of message
+- *
+- * Adds the @buffer message to the MPC85xx outbound message queue. Returns
+- * %0 on success or %-EINVAL on failure.
+- */
+-int
+-rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
+-			void *buffer, size_t len)
+-{
+-	u32 omr;
+-	struct rio_tx_desc *desc =
+-	    (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
+-	int ret = 0;
+-
+-	pr_debug
+-	    ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n",
+-	     rdev->destid, mbox, (int)buffer, len);
+-
+-	if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
+-		ret = -EINVAL;
+-		goto out;
+-	}
+-
+-	/* Copy and clear rest of buffer */
+-	memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
+-	if (len < (RIO_MAX_MSG_SIZE - 4))
+-		memset((void *)((u32) msg_tx_ring.
+-				virt_buffer[msg_tx_ring.tx_slot] + len), 0,
+-		       RIO_MAX_MSG_SIZE - len);
+-
+-	/* Set mbox field for message */
+-	desc->dport = mbox & 0x3;
+-
+-	/* Enable EOMI interrupt, set priority, and set destid */
+-	desc->dattr = 0x28000000 | (rdev->destid << 2);
+-
+-	/* Set transfer size aligned to next power of 2 (in double words) */
+-	desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
+-
+-	/* Set snooping and source buffer address */
+-	desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
+-
+-	/* Increment enqueue pointer */
+-	omr = in_be32((void *)&msg_regs->omr);
+-	out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
+-
+-	/* Go to next descriptor */
+-	if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
+-		msg_tx_ring.tx_slot = 0;
+-
+-      out:
+-	return ret;
+-}
+-
+-EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
+-
+-/**
+- * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
+- * @irq: Linux interrupt number
+- * @dev_instance: Pointer to interrupt-specific data
+- *
+- * Handles outbound message interrupts. Executes a register outbound
+- * mailbox event handler and acks the interrupt occurrence.
+- */
+-static irqreturn_t
+-mpc85xx_rio_tx_handler(int irq, void *dev_instance)
+-{
+-	int osr;
+-	struct rio_mport *port = (struct rio_mport *)dev_instance;
+-
+-	osr = in_be32((void *)&msg_regs->osr);
+-
+-	if (osr & RIO_MSG_OSR_TE) {
+-		pr_info("RIO: outbound message transmission error\n");
+-		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
+-		goto out;
+-	}
+-
+-	if (osr & RIO_MSG_OSR_QOI) {
+-		pr_info("RIO: outbound message queue overflow\n");
+-		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
+-		goto out;
+-	}
+-
+-	if (osr & RIO_MSG_OSR_EOMI) {
+-		u32 dqp = in_be32((void *)&msg_regs->odqdpar);
+-		int slot = (dqp - msg_tx_ring.phys) >> 5;
+-		port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot);
+-
+-		/* Ack the end-of-message interrupt */
+-		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
+-	}
+-
+-      out:
+-	return IRQ_HANDLED;
+-}
+-
+-/**
+- * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox
+- * @mport: Master port implementing the outbound message unit
+- * @dev_id: Device specific pointer to pass on event
+- * @mbox: Mailbox to open
+- * @entries: Number of entries in the outbound mailbox ring
+- *
+- * Initializes buffer ring, request the outbound message interrupt,
+- * and enables the outbound message unit. Returns %0 on success and
+- * %-EINVAL or %-ENOMEM on failure.
+- */
+-int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
+-{
+-	int i, j, rc = 0;
+-
+-	if ((entries < RIO_MIN_TX_RING_SIZE) ||
+-	    (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
+-		rc = -EINVAL;
+-		goto out;
+-	}
+-
+-	/* Initialize shadow copy ring */
+-	msg_tx_ring.dev_id = dev_id;
+-	msg_tx_ring.size = entries;
+-
+-	for (i = 0; i < msg_tx_ring.size; i++) {
+-		if (!
+-		    (msg_tx_ring.virt_buffer[i] =
+-		     dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+-					&msg_tx_ring.phys_buffer[i],
+-					GFP_KERNEL))) {
+-			rc = -ENOMEM;
+-			for (j = 0; j < msg_tx_ring.size; j++)
+-				if (msg_tx_ring.virt_buffer[j])
+-					dma_free_coherent(NULL,
+-							  RIO_MSG_BUFFER_SIZE,
+-							  msg_tx_ring.
+-							  virt_buffer[j],
+-							  msg_tx_ring.
+-							  phys_buffer[j]);
+-			goto out;
+-		}
+-	}
+-
+-	/* Initialize outbound message descriptor ring */
+-	if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
+-						    msg_tx_ring.size *
+-						    RIO_MSG_DESC_SIZE,
+-						    &msg_tx_ring.phys,
+-						    GFP_KERNEL))) {
+-		rc = -ENOMEM;
+-		goto out_dma;
+-	}
+-	memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
+-	msg_tx_ring.tx_slot = 0;
+-
+-	/* Point dequeue/enqueue pointers at first entry in ring */
+-	out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
+-	out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
+-
+-	/* Configure for snooping */
+-	out_be32((void *)&msg_regs->osar, 0x00000004);
+-
+-	/* Clear interrupt status */
+-	out_be32((void *)&msg_regs->osr, 0x000000b3);
+-
+-	/* Hook up outbound message handler */
+-	if ((rc =
+-	     request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
+-			 "msg_tx", (void *)mport)) < 0)
+-		goto out_irq;
+-
+-	/*
+-	 * Configure outbound message unit
+-	 *      Snooping
+-	 *      Interrupts (all enabled, except QEIE)
+-	 *      Chaining mode
+-	 *      Disable
+-	 */
+-	out_be32((void *)&msg_regs->omr, 0x00100220);
+-
+-	/* Set number of entries */
+-	out_be32((void *)&msg_regs->omr,
+-		 in_be32((void *)&msg_regs->omr) |
+-		 ((get_bitmask_order(entries) - 2) << 12));
+-
+-	/* Now enable the unit */
+-	out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
+-
+-      out:
+-	return rc;
+-
+-      out_irq:
+-	dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+-			  msg_tx_ring.virt, msg_tx_ring.phys);
+-
+-      out_dma:
+-	for (i = 0; i < msg_tx_ring.size; i++)
+-		dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+-				  msg_tx_ring.virt_buffer[i],
+-				  msg_tx_ring.phys_buffer[i]);
+-
+-	return rc;
+-}
+-
+-/**
+- * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox
+- * @mport: Master port implementing the outbound message unit
+- * @mbox: Mailbox to close
+- *
+- * Disables the outbound message unit, free all buffers, and
+- * frees the outbound message interrupt.
+- */
+-void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
+-{
+-	/* Disable inbound message unit */
+-	out_be32((void *)&msg_regs->omr, 0);
+-
+-	/* Free ring */
+-	dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+-			  msg_tx_ring.virt, msg_tx_ring.phys);
+-
+-	/* Free interrupt */
+-	free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
+-}
+-
+-/**
+- * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
+- * @irq: Linux interrupt number
+- * @dev_instance: Pointer to interrupt-specific data
+- *
+- * Handles inbound message interrupts. Executes a registered inbound
+- * mailbox event handler and acks the interrupt occurrence.
+- */
+-static irqreturn_t
+-mpc85xx_rio_rx_handler(int irq, void *dev_instance)
+-{
+-	int isr;
+-	struct rio_mport *port = (struct rio_mport *)dev_instance;
+-
+-	isr = in_be32((void *)&msg_regs->isr);
+-
+-	if (isr & RIO_MSG_ISR_TE) {
+-		pr_info("RIO: inbound message reception error\n");
+-		out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
+-		goto out;
+-	}
+-
+-	/* XXX Need to check/dispatch until queue empty */
+-	if (isr & RIO_MSG_ISR_DIQI) {
+-		/*
+-		 * We implement *only* mailbox 0, but can receive messages
+-		 * for any mailbox/letter to that mailbox destination. So,
+-		 * make the callback with an unknown/invalid mailbox number
+-		 * argument.
+-		 */
+-		port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1);
+-
+-		/* Ack the queueing interrupt */
+-		out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
+-	}
+-
+-      out:
+-	return IRQ_HANDLED;
+-}
+-
+-/**
+- * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox
+- * @mport: Master port implementing the inbound message unit
+- * @dev_id: Device specific pointer to pass on event
+- * @mbox: Mailbox to open
+- * @entries: Number of entries in the inbound mailbox ring
+- *
+- * Initializes buffer ring, request the inbound message interrupt,
+- * and enables the inbound message unit. Returns %0 on success
+- * and %-EINVAL or %-ENOMEM on failure.
+- */
+-int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
+-{
+-	int i, rc = 0;
+-
+-	if ((entries < RIO_MIN_RX_RING_SIZE) ||
+-	    (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
+-		rc = -EINVAL;
+-		goto out;
+-	}
+-
+-	/* Initialize client buffer ring */
+-	msg_rx_ring.dev_id = dev_id;
+-	msg_rx_ring.size = entries;
+-	msg_rx_ring.rx_slot = 0;
+-	for (i = 0; i < msg_rx_ring.size; i++)
+-		msg_rx_ring.virt_buffer[i] = NULL;
+-
+-	/* Initialize inbound message ring */
+-	if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
+-						    msg_rx_ring.size *
+-						    RIO_MAX_MSG_SIZE,
+-						    &msg_rx_ring.phys,
+-						    GFP_KERNEL))) {
+-		rc = -ENOMEM;
+-		goto out;
+-	}
+-
+-	/* Point dequeue/enqueue pointers at first entry in ring */
+-	out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
+-	out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
+-
+-	/* Clear interrupt status */
+-	out_be32((void *)&msg_regs->isr, 0x00000091);
+-
+-	/* Hook up inbound message handler */
+-	if ((rc =
+-	     request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
+-			 "msg_rx", (void *)mport)) < 0) {
+-		dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+-				  msg_tx_ring.virt_buffer[i],
+-				  msg_tx_ring.phys_buffer[i]);
+-		goto out;
+-	}
+-
+-	/*
+-	 * Configure inbound message unit:
+-	 *      Snooping
+-	 *      4KB max message size
+-	 *      Unmask all interrupt sources
+-	 *      Disable
+-	 */
+-	out_be32((void *)&msg_regs->imr, 0x001b0060);
+-
+-	/* Set number of queue entries */
+-	out_be32((void *)&msg_regs->imr,
+-		 in_be32((void *)&msg_regs->imr) |
+-		 ((get_bitmask_order(entries) - 2) << 12));
+-
+-	/* Now enable the unit */
+-	out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
+-
+-      out:
+-	return rc;
+-}
+-
+-/**
+- * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox
+- * @mport: Master port implementing the inbound message unit
+- * @mbox: Mailbox to close
+- *
+- * Disables the inbound message unit, free all buffers, and
+- * frees the inbound message interrupt.
+- */
+-void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
+-{
+-	/* Disable inbound message unit */
+-	out_be32((void *)&msg_regs->imr, 0);
+-
+-	/* Free ring */
+-	dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
+-			  msg_rx_ring.virt, msg_rx_ring.phys);
+-
+-	/* Free interrupt */
+-	free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
+-}
+-
+-/**
+- * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
+- * @mport: Master port implementing the inbound message unit
+- * @mbox: Inbound mailbox number
+- * @buf: Buffer to add to inbound queue
+- *
+- * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
+- * %0 on success or %-EINVAL on failure.
+- */
+-int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
+-{
+-	int rc = 0;
+-
+-	pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
+-		 msg_rx_ring.rx_slot);
+-
+-	if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
+-		printk(KERN_ERR
+-		       "RIO: error adding inbound buffer %d, buffer exists\n",
+-		       msg_rx_ring.rx_slot);
+-		rc = -EINVAL;
+-		goto out;
+-	}
+-
+-	msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
+-	if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
+-		msg_rx_ring.rx_slot = 0;
+-
+-      out:
+-	return rc;
+-}
+-
+-EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
+-
+-/**
+- * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit
+- * @mport: Master port implementing the inbound message unit
+- * @mbox: Inbound mailbox number
+- *
+- * Gets the next available inbound message from the inbound message queue.
+- * A pointer to the message is returned on success or NULL on failure.
+- */
+-void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
+-{
+-	u32 imr;
+-	u32 phys_buf, virt_buf;
+-	void *buf = NULL;
+-	int buf_idx;
+-
+-	phys_buf = in_be32((void *)&msg_regs->ifqdpar);
+-
+-	/* If no more messages, then bail out */
+-	if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
+-		goto out2;
+-
+-	virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
+-	buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
+-	buf = msg_rx_ring.virt_buffer[buf_idx];
+-
+-	if (!buf) {
+-		printk(KERN_ERR
+-		       "RIO: inbound message copy failed, no buffers\n");
+-		goto out1;
+-	}
+-
+-	/* Copy max message size, caller is expected to allocate that big */
+-	memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
+-
+-	/* Clear the available buffer */
+-	msg_rx_ring.virt_buffer[buf_idx] = NULL;
+-
+-      out1:
+-	imr = in_be32((void *)&msg_regs->imr);
+-	out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
+-
+-      out2:
+-	return buf;
+-}
+-
+-EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
+-
+-/**
+- * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
+- * @irq: Linux interrupt number
+- * @dev_instance: Pointer to interrupt-specific data
+- *
+- * Handles doorbell interrupts. Parses a list of registered
+- * doorbell event handlers and executes a matching event handler.
+- */
+-static irqreturn_t
+-mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
+-{
+-	int dsr;
+-	struct rio_mport *port = (struct rio_mport *)dev_instance;
+-
+-	dsr = in_be32((void *)&msg_regs->dsr);
+-
+-	if (dsr & DOORBELL_DSR_TE) {
+-		pr_info("RIO: doorbell reception error\n");
+-		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
+-		goto out;
+-	}
+-
+-	if (dsr & DOORBELL_DSR_QFI) {
+-		pr_info("RIO: doorbell queue full\n");
+-		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
+-		goto out;
+-	}
+-
+-	/* XXX Need to check/dispatch until queue empty */
+-	if (dsr & DOORBELL_DSR_DIQI) {
+-		u32 dmsg =
+-		    (u32) dbell_ring.virt +
+-		    (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
+-		u32 dmr;
+-		struct rio_dbell *dbell;
+-		int found = 0;
+-
+-		pr_debug
+-		    ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n",
+-		     DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
+-
+-		list_for_each_entry(dbell, &port->dbells, node) {
+-			if ((dbell->res->start <= DBELL_INF(dmsg)) &&
+-			    (dbell->res->end >= DBELL_INF(dmsg))) {
+-				found = 1;
+-				break;
+-			}
+-		}
+-		if (found) {
+-			dbell->dinb(port, dbell->dev_id, DBELL_SID(dmsg), DBELL_TID(dmsg),
+-				    DBELL_INF(dmsg));
+-		} else {
+-			pr_debug
+-			    ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
+-			     DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
+-		}
+-		dmr = in_be32((void *)&msg_regs->dmr);
+-		out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
+-		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
+-	}
+-
+-      out:
+-	return IRQ_HANDLED;
+-}
+-
+-/**
+- * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
+- * @mport: Master port implementing the inbound doorbell unit
+- *
+- * Initializes doorbell unit hardware and inbound DMA buffer
+- * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
+- * or %-ENOMEM on failure.
+- */
+-static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
+-{
+-	int rc = 0;
+-
+-	/* Map outbound doorbell window immediately after maintenance window */
+-	if (!(dbell_win =
+-	      (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
+-			    RIO_DBELL_WIN_SIZE))) {
+-		printk(KERN_ERR
+-		       "RIO: unable to map outbound doorbell window\n");
+-		rc = -ENOMEM;
+-		goto out;
+-	}
+-
+-	/* Initialize inbound doorbells */
+-	if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
+-						   512 * DOORBELL_MESSAGE_SIZE,
+-						   &dbell_ring.phys,
+-						   GFP_KERNEL))) {
+-		printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
+-		rc = -ENOMEM;
+-		iounmap((void *)dbell_win);
+-		goto out;
+-	}
+-
+-	/* Point dequeue/enqueue pointers at first entry in ring */
+-	out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
+-	out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
+-
+-	/* Clear interrupt status */
+-	out_be32((void *)&msg_regs->dsr, 0x00000091);
+-
+-	/* Hook up doorbell handler */
+-	if ((rc =
+-	     request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
+-			 "dbell_rx", (void *)mport) < 0)) {
+-		iounmap((void *)dbell_win);
+-		dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
+-				  dbell_ring.virt, dbell_ring.phys);
+-		printk(KERN_ERR
+-		       "MPC85xx RIO: unable to request inbound doorbell irq");
+-		goto out;
+-	}
+-
+-	/* Configure doorbells for snooping, 512 entries, and enable */
+-	out_be32((void *)&msg_regs->dmr, 0x00108161);
+-
+-      out:
+-	return rc;
+-}
+-
+-static char *cmdline = NULL;
+-
+-static int mpc85xx_rio_get_hdid(int index)
+-{
+-	/* XXX Need to parse multiple entries in some format */
+-	if (!cmdline)
+-		return -1;
+-
+-	return simple_strtol(cmdline, NULL, 0);
+-}
+-
+-static int mpc85xx_rio_get_cmdline(char *s)
+-{
+-	if (!s)
+-		return 0;
+-
+-	cmdline = s;
+-	return 1;
+-}
+-
+-__setup("riohdid=", mpc85xx_rio_get_cmdline);
+-
+-/**
+- * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
+- * @law_start: Starting physical address of RapidIO LAW
+- * @law_size: Size of RapidIO LAW
+- *
+- * Initializes MPC85xx RapidIO hardware interface, configures
+- * master port with system-specific info, and registers the
+- * master port with the RapidIO subsystem.
+- */
+-void mpc85xx_rio_setup(int law_start, int law_size)
+-{
+-	struct rio_ops *ops;
+-	struct rio_mport *port;
+-
+-	ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
+-	ops->lcread = mpc85xx_local_config_read;
+-	ops->lcwrite = mpc85xx_local_config_write;
+-	ops->cread = mpc85xx_rio_config_read;
+-	ops->cwrite = mpc85xx_rio_config_write;
+-	ops->dsend = mpc85xx_rio_doorbell_send;
+-
+-	port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
+-	port->id = 0;
+-	port->index = 0;
+-	INIT_LIST_HEAD(&port->dbells);
+-	port->iores.start = law_start;
+-	port->iores.end = law_start + law_size;
+-	port->iores.flags = IORESOURCE_MEM;
+-
+-	rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
+-	rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
+-	rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
+-	strcpy(port->name, "RIO0 mport");
+-
+-	port->ops = ops;
+-	port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
+-
+-	rio_register_mport(port);
+-
+-	regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
+-	atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
+-	maint_atmu_regs = atmu_regs + 1;
+-	dbell_atmu_regs = atmu_regs + 2;
+-	msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
+-
+-	/* Configure maintenance transaction window */
+-	out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
+-	out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
+-
+-	maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
+-
+-	/* Configure outbound doorbell window */
+-	out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
+-	out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
+-	mpc85xx_rio_doorbell_init(port);
+-}
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/ppc85xx_rio.h powerpc.git/arch/ppc/syslib/ppc85xx_rio.h
+--- linux-2.6.24/arch/ppc/syslib/ppc85xx_rio.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/ppc85xx_rio.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,20 +0,0 @@
+-/*
+- * MPC85xx RapidIO definitions
+- *
+- * Copyright 2005 MontaVista Software, Inc.
+- * Matt Porter <mporter@kernel.crashing.org>
+- *
+- * This program is free software; you can redistribute  it and/or modify it
+- * under  the terms of  the GNU General  Public License as published by the
+- * Free Software Foundation;  either version 2 of the  License, or (at your
+- * option) any later version.
+- */
+-
+-#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
+-#define __PPC_SYSLIB_PPC85XX_RIO_H
+-
+-#include <linux/init.h>
+-
+-extern void mpc85xx_rio_setup(int law_start, int law_size);
+-
+-#endif				/* __PPC_SYSLIB_PPC85XX_RIO_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/ppc8xx_pic.c powerpc.git/arch/ppc/syslib/ppc8xx_pic.c
+--- linux-2.6.24/arch/ppc/syslib/ppc8xx_pic.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/ppc8xx_pic.c	2008-01-28 20:25:52.000000000 +0100
+@@ -16,7 +16,7 @@
+  * the only interrupt controller.  Some boards, like the MBX and
+  * Sandpoint have the 8259 as a secondary controller.  Depending
+  * upon the processor type, the internal controller can have as
+- * few as 16 interrups or as many as 64.  We could use  the
++ * few as 16 interrupts or as many as 64.  We could use  the
+  * "clear_bit()" and "set_bit()" functions like other platforms,
+  * but they are overkill for us.
+  */
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/syslib/ppc_sys.c powerpc.git/arch/ppc/syslib/ppc_sys.c
+--- linux-2.6.24/arch/ppc/syslib/ppc_sys.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/syslib/ppc_sys.c	2008-01-28 20:25:52.000000000 +0100
+@@ -185,7 +185,7 @@
+  */
+ 
+ /*
+-   Here we'll replace .name pointers with fixed-lenght strings
++   Here we'll replace .name pointers with fixed-length strings
+    Hereby, this should be called *before* any func stuff triggeded.
+  */
+ void ppc_sys_device_initfunc(void)
+diff -x .git -x .gitignore -Nur linux-2.6.24/arch/ppc/xmon/start.c powerpc.git/arch/ppc/xmon/start.c
+--- linux-2.6.24/arch/ppc/xmon/start.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/arch/ppc/xmon/start.c	2008-01-28 20:25:52.000000000 +0100
+@@ -10,7 +10,6 @@
+ #include <linux/sysrq.h>
+ #include <linux/bitops.h>
+ #include <asm/xmon.h>
+-#include <asm/machdep.h>
+ #include <asm/errno.h>
+ #include <asm/processor.h>
+ #include <asm/delay.h>
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/ata/Kconfig powerpc.git/drivers/ata/Kconfig
+--- linux-2.6.24/drivers/ata/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/ata/Kconfig	2008-01-28 20:25:59.000000000 +0100
+@@ -607,13 +607,23 @@
+ 
+ config PATA_PLATFORM
+ 	tristate "Generic platform device PATA support"
+-	depends on EMBEDDED || ARCH_RPC
++	depends on EMBEDDED || ARCH_RPC || PPC
+ 	help
+ 	  This option enables support for generic directly connected ATA
+ 	  devices commonly found on embedded systems.
+ 
+ 	  If unsure, say N.
+ 
++config PATA_OF_PLATFORM
++	tristate "OpenFirmware platform device PATA support"
++	depends on PATA_PLATFORM && PPC_OF
++	help
++	  This option enables support for generic directly connected ATA
++	  devices commonly found on embedded systems with OpenFirmware
++	  bindings.
++
++	  If unsure, say N.
++
+ config PATA_ICSIDE
+ 	tristate "Acorn ICS PATA support"
+ 	depends on ARM && ARCH_ACORN
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/ata/Makefile powerpc.git/drivers/ata/Makefile
+--- linux-2.6.24/drivers/ata/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/ata/Makefile	2008-01-28 20:25:59.000000000 +0100
+@@ -67,6 +67,7 @@
+ obj-$(CONFIG_PATA_SCC)		+= pata_scc.o
+ obj-$(CONFIG_PATA_BF54X)	+= pata_bf54x.o
+ obj-$(CONFIG_PATA_PLATFORM)	+= pata_platform.o
++obj-$(CONFIG_PATA_OF_PLATFORM)	+= pata_of_platform.o
+ obj-$(CONFIG_PATA_ICSIDE)	+= pata_icside.o
+ # Should be last but two libata driver
+ obj-$(CONFIG_PATA_ACPI)		+= pata_acpi.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/ata/pata_of_platform.c powerpc.git/drivers/ata/pata_of_platform.c
+--- linux-2.6.24/drivers/ata/pata_of_platform.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/drivers/ata/pata_of_platform.c	2008-01-28 20:25:59.000000000 +0100
+@@ -0,0 +1,114 @@
++/*
++ * OF-platform PATA driver
++ *
++ * Copyright (c) 2007  MontaVista Software, Inc.
++ *                     Anton Vorontsov <avorontsov@ru.mvista.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License (Version 2) as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/pata_platform.h>
++
++static int __devinit pata_of_platform_probe(struct of_device *ofdev,
++					    const struct of_device_id *match)
++{
++	int ret;
++	struct device_node *dn = ofdev->node;
++	struct resource io_res;
++	struct resource ctl_res;
++	struct resource irq_res;
++	unsigned int reg_shift = 0;
++	int pio_mode = 0;
++	int pio_mask;
++	const u32 *prop;
++
++	ret = of_address_to_resource(dn, 0, &io_res);
++	if (ret) {
++		dev_err(&ofdev->dev, "can't get IO address from "
++			"device tree\n");
++		return -EINVAL;
++	}
++
++	if (of_device_is_compatible(dn, "electra-ide")) {
++		/* Altstatus is really at offset 0x3f6 from the primary window
++		 * on electra-ide. Adjust ctl_res and io_res accordingly.
++		 */
++		ctl_res = io_res;
++		ctl_res.start = ctl_res.start+0x3f6;
++		io_res.end = ctl_res.start-1;
++	} else {
++		ret = of_address_to_resource(dn, 1, &ctl_res);
++		if (ret) {
++			dev_err(&ofdev->dev, "can't get CTL address from "
++				"device tree\n");
++			return -EINVAL;
++		}
++	}
++
++	ret = of_irq_to_resource(dn, 0, &irq_res);
++	if (ret == NO_IRQ)
++		irq_res.start = irq_res.end = -1;
++	else
++		irq_res.flags = 0;
++
++	prop = of_get_property(dn, "reg-shift", NULL);
++	if (prop)
++		reg_shift = *prop;
++
++	prop = of_get_property(dn, "pio-mode", NULL);
++	if (prop) {
++		pio_mode = *prop;
++		if (pio_mode > 6) {
++			dev_err(&ofdev->dev, "invalid pio-mode\n");
++			return -EINVAL;
++		}
++	} else {
++		dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n");
++	}
++
++	pio_mask = 1 << pio_mode;
++	pio_mask |= (1 << pio_mode) - 1;
++
++	return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, &irq_res,
++				     reg_shift, pio_mask);
++}
++
++static int __devexit pata_of_platform_remove(struct of_device *ofdev)
++{
++	return __pata_platform_remove(&ofdev->dev);
++}
++
++static struct of_device_id pata_of_platform_match[] = {
++	{ .compatible = "ata-generic", },
++	{ .compatible = "electra-ide", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, pata_of_platform_match);
++
++static struct of_platform_driver pata_of_platform_driver = {
++	.name		= "pata_of_platform",
++	.match_table	= pata_of_platform_match,
++	.probe		= pata_of_platform_probe,
++	.remove		= __devexit_p(pata_of_platform_remove),
++};
++
++static int __init pata_of_platform_init(void)
++{
++	return of_register_platform_driver(&pata_of_platform_driver);
++}
++module_init(pata_of_platform_init);
++
++static void __exit pata_of_platform_exit(void)
++{
++	of_unregister_platform_driver(&pata_of_platform_driver);
++}
++module_exit(pata_of_platform_exit);
++
++MODULE_DESCRIPTION("OF-platform PATA driver");
++MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
++MODULE_LICENSE("GPL");
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/ata/pata_platform.c powerpc.git/drivers/ata/pata_platform.c
+--- linux-2.6.24/drivers/ata/pata_platform.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/ata/pata_platform.c	2008-01-28 20:25:59.000000000 +0100
+@@ -93,14 +93,9 @@
+ };
+ 
+ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
+-				     struct pata_platform_info *info)
++				     unsigned int shift)
+ {
+-	unsigned int shift = 0;
+-
+ 	/* Fixup the port shift for platforms that need it */
+-	if (info && info->ioport_shift)
+-		shift = info->ioport_shift;
+-
+ 	ioaddr->data_addr	= ioaddr->cmd_addr + (ATA_REG_DATA    << shift);
+ 	ioaddr->error_addr	= ioaddr->cmd_addr + (ATA_REG_ERR     << shift);
+ 	ioaddr->feature_addr	= ioaddr->cmd_addr + (ATA_REG_FEATURE << shift);
+@@ -114,8 +109,13 @@
+ }
+ 
+ /**
+- *	pata_platform_probe		-	attach a platform interface
+- *	@pdev: platform device
++ *	__pata_platform_probe		-	attach a platform interface
++ *	@dev: device
++ *	@io_res: Resource representing I/O base
++ *	@ctl_res: Resource representing CTL base
++ *	@irq_res: Resource representing IRQ and its flags
++ *	@ioport_shift: I/O port shift
++ *	@__pio_mask: PIO mask
+  *
+  *	Register a platform bus IDE interface. Such interfaces are PIO and we
+  *	assume do not support IRQ sharing.
+@@ -135,42 +135,18 @@
+  *
+  *	If no IRQ resource is present, PIO polling mode is used instead.
+  */
+-static int __devinit pata_platform_probe(struct platform_device *pdev)
++int __devinit __pata_platform_probe(struct device *dev,
++				    struct resource *io_res,
++				    struct resource *ctl_res,
++				    struct resource *irq_res,
++				    unsigned int ioport_shift,
++				    int __pio_mask)
+ {
+-	struct resource *io_res, *ctl_res;
+ 	struct ata_host *host;
+ 	struct ata_port *ap;
+-	struct pata_platform_info *pp_info;
+ 	unsigned int mmio;
+-	int irq;
+-
+-	/*
+-	 * Simple resource validation ..
+-	 */
+-	if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) {
+-		dev_err(&pdev->dev, "invalid number of resources\n");
+-		return -EINVAL;
+-	}
+-
+-	/*
+-	 * Get the I/O base first
+-	 */
+-	io_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+-	if (io_res == NULL) {
+-		io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-		if (unlikely(io_res == NULL))
+-			return -EINVAL;
+-	}
+-
+-	/*
+-	 * Then the CTL base
+-	 */
+-	ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
+-	if (ctl_res == NULL) {
+-		ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+-		if (unlikely(ctl_res == NULL))
+-			return -EINVAL;
+-	}
++	int irq = 0;
++	int irq_flags = 0;
+ 
+ 	/*
+ 	 * Check for MMIO
+@@ -181,20 +157,21 @@
+ 	/*
+ 	 * And the IRQ
+ 	 */
+-	irq = platform_get_irq(pdev, 0);
+-	if (irq < 0)
+-		irq = 0;	/* no irq */
++	if (irq_res && irq_res->start > 0) {
++		irq = irq_res->start;
++		irq_flags = irq_res->flags;
++	}
+ 
+ 	/*
+ 	 * Now that that's out of the way, wire up the port..
+ 	 */
+-	host = ata_host_alloc(&pdev->dev, 1);
++	host = ata_host_alloc(dev, 1);
+ 	if (!host)
+ 		return -ENOMEM;
+ 	ap = host->ports[0];
+ 
+ 	ap->ops = &pata_platform_port_ops;
+-	ap->pio_mask = pio_mask;
++	ap->pio_mask = __pio_mask;
+ 	ap->flags |= ATA_FLAG_SLAVE_POSS;
+ 
+ 	/*
+@@ -209,25 +186,24 @@
+ 	 * Handle the MMIO case
+ 	 */
+ 	if (mmio) {
+-		ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
++		ap->ioaddr.cmd_addr = devm_ioremap(dev, io_res->start,
+ 				io_res->end - io_res->start + 1);
+-		ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
++		ap->ioaddr.ctl_addr = devm_ioremap(dev, ctl_res->start,
+ 				ctl_res->end - ctl_res->start + 1);
+ 	} else {
+-		ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
++		ap->ioaddr.cmd_addr = devm_ioport_map(dev, io_res->start,
+ 				io_res->end - io_res->start + 1);
+-		ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
++		ap->ioaddr.ctl_addr = devm_ioport_map(dev, ctl_res->start,
+ 				ctl_res->end - ctl_res->start + 1);
+ 	}
+ 	if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) {
+-		dev_err(&pdev->dev, "failed to map IO/CTL base\n");
++		dev_err(dev, "failed to map IO/CTL base\n");
+ 		return -ENOMEM;
+ 	}
+ 
+ 	ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
+ 
+-	pp_info = pdev->dev.platform_data;
+-	pata_platform_setup_port(&ap->ioaddr, pp_info);
++	pata_platform_setup_port(&ap->ioaddr, ioport_shift);
+ 
+ 	ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport",
+ 		      (unsigned long long)io_res->start,
+@@ -235,26 +211,78 @@
+ 
+ 	/* activate */
+ 	return ata_host_activate(host, irq, irq ? ata_interrupt : NULL,
+-				 pp_info ? pp_info->irq_flags : 0,
+-				 &pata_platform_sht);
++				 irq_flags, &pata_platform_sht);
+ }
++EXPORT_SYMBOL_GPL(__pata_platform_probe);
+ 
+ /**
+- *	pata_platform_remove	-	unplug a platform interface
+- *	@pdev: platform device
++ *	__pata_platform_remove		-	unplug a platform interface
++ *	@dev: device
+  *
+  *	A platform bus ATA device has been unplugged. Perform the needed
+  *	cleanup. Also called on module unload for any active devices.
+  */
+-static int __devexit pata_platform_remove(struct platform_device *pdev)
++int __devexit __pata_platform_remove(struct device *dev)
+ {
+-	struct device *dev = &pdev->dev;
+ 	struct ata_host *host = dev_get_drvdata(dev);
+ 
+ 	ata_host_detach(host);
+ 
+ 	return 0;
+ }
++EXPORT_SYMBOL_GPL(__pata_platform_remove);
++
++static int __devinit pata_platform_probe(struct platform_device *pdev)
++{
++	struct resource *io_res;
++	struct resource *ctl_res;
++	struct resource *irq_res;
++	struct pata_platform_info *pp_info = pdev->dev.platform_data;
++
++	/*
++	 * Simple resource validation ..
++	 */
++	if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) {
++		dev_err(&pdev->dev, "invalid number of resources\n");
++		return -EINVAL;
++	}
++
++	/*
++	 * Get the I/O base first
++	 */
++	io_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
++	if (io_res == NULL) {
++		io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++		if (unlikely(io_res == NULL))
++			return -EINVAL;
++	}
++
++	/*
++	 * Then the CTL base
++	 */
++	ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
++	if (ctl_res == NULL) {
++		ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++		if (unlikely(ctl_res == NULL))
++			return -EINVAL;
++	}
++
++	/*
++	 * And the IRQ
++	 */
++	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++	if (irq_res)
++		irq_res->flags = pp_info ? pp_info->irq_flags : 0;
++
++	return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res,
++				     pp_info ? pp_info->ioport_shift : 0,
++				     pio_mask);
++}
++
++static int __devexit pata_platform_remove(struct platform_device *pdev)
++{
++	return __pata_platform_remove(&pdev->dev);
++}
+ 
+ static struct platform_driver pata_platform_driver = {
+ 	.probe		= pata_platform_probe,
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/char/hw_random/Kconfig powerpc.git/drivers/char/hw_random/Kconfig
+--- linux-2.6.24/drivers/char/hw_random/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/char/hw_random/Kconfig	2008-01-28 20:25:59.000000000 +0100
+@@ -98,7 +98,7 @@
+ 	default HW_RANDOM
+ 	---help---
+ 	  This driver provides kernel-side support for the Random Number
+-	  Generator hardware found on PA6T-1682M processor.
++	  Generator hardware found on PA Semi PWRficient SoCs.
+ 
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called pasemi-rng.
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/char/hw_random/pasemi-rng.c powerpc.git/drivers/char/hw_random/pasemi-rng.c
+--- linux-2.6.24/drivers/char/hw_random/pasemi-rng.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/char/hw_random/pasemi-rng.c	2008-01-28 20:25:59.000000000 +0100
+@@ -126,10 +126,9 @@
+ }
+ 
+ static struct of_device_id rng_match[] = {
+-	{
+-		.compatible      = "1682m-rng",
+-	},
+-	{},
++	{ .compatible      = "1682m-rng", },
++	{ .compatible      = "pasemi,pwrficient-rng", },
++	{ },
+ };
+ 
+ static struct of_platform_driver rng_driver = {
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/edac/pasemi_edac.c powerpc.git/drivers/edac/pasemi_edac.c
+--- linux-2.6.24/drivers/edac/pasemi_edac.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/edac/pasemi_edac.c	2008-01-28 20:26:00.000000000 +0100
+@@ -225,7 +225,7 @@
+ 		EDAC_FLAG_NONE;
+ 	mci->mod_name = MODULE_NAME;
+ 	mci->dev_name = pci_name(pdev);
+-	mci->ctl_name = "pasemi,1682m-mc";
++	mci->ctl_name = "pasemi,pwrficient-mc";
+ 	mci->edac_check = pasemi_edac_check;
+ 	mci->ctl_page_to_phys = NULL;
+ 	pci_read_config_dword(pdev, MCCFG_SCRUB, &scrub);
+@@ -297,4 +297,4 @@
+ 
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>");
+-MODULE_DESCRIPTION("MC support for PA Semi PA6T-1682M memory controller");
++MODULE_DESCRIPTION("MC support for PA Semi PWRficient memory controller");
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/macintosh/adb.c powerpc.git/drivers/macintosh/adb.c
+--- linux-2.6.24/drivers/macintosh/adb.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/macintosh/adb.c	2008-01-28 20:26:08.000000000 +0100
+@@ -35,6 +35,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/completion.h>
+ #include <linux/device.h>
++#include <linux/kthread.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/semaphore.h>
+@@ -82,21 +83,11 @@
+ BLOCKING_NOTIFIER_HEAD(adb_client_list);
+ static int adb_got_sleep;
+ static int adb_inited;
+-static pid_t adb_probe_task_pid;
+ static DECLARE_MUTEX(adb_probe_mutex);
+-static struct completion adb_probe_task_comp;
+ static int sleepy_trackpad;
+ static int autopoll_devs;
+ int __adb_probe_sync;
+ 
+-#ifdef CONFIG_PM_SLEEP
+-static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
+-static struct pmu_sleep_notifier adb_sleep_notifier = {
+-	adb_notify_sleep,
+-	SLEEP_LEVEL_ADB,
+-};
+-#endif
+-
+ static int adb_scan_bus(void);
+ static int do_adb_reset_bus(void);
+ static void adbdev_init(void);
+@@ -134,16 +125,6 @@
+ }
+ #endif
+ 
+-
+-static __inline__ void adb_wait_ms(unsigned int ms)
+-{
+-	if (current->pid && adb_probe_task_pid &&
+-	  adb_probe_task_pid == current->pid)
+-		msleep(ms);
+-	else
+-		mdelay(ms);
+-}
+-
+ static int adb_scan_bus(void)
+ {
+ 	int i, highFree=0, noMovement;
+@@ -248,13 +229,10 @@
+ static int
+ adb_probe_task(void *x)
+ {
+-	strcpy(current->comm, "kadbprobe");
+-
+ 	printk(KERN_INFO "adb: starting probe task...\n");
+ 	do_adb_reset_bus();
+ 	printk(KERN_INFO "adb: finished probe task...\n");
+ 
+-	adb_probe_task_pid = 0;
+ 	up(&adb_probe_mutex);
+ 
+ 	return 0;
+@@ -263,7 +241,7 @@
+ static void
+ __adb_probe_task(struct work_struct *bullshit)
+ {
+-	adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL);
++	kthread_run(adb_probe_task, NULL, "kadbprobe");
+ }
+ 
+ static DECLARE_WORK(adb_reset_work, __adb_probe_task);
+@@ -281,6 +259,36 @@
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_PM
++/*
++ * notify clients before sleep
++ */
++static int adb_suspend(struct platform_device *dev, pm_message_t state)
++{
++	adb_got_sleep = 1;
++	/* We need to get a lock on the probe thread */
++	down(&adb_probe_mutex);
++	/* Stop autopoll */
++	if (adb_controller->autopoll)
++		adb_controller->autopoll(0);
++	blocking_notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
++
++	return 0;
++}
++
++/*
++ * reset bus after sleep
++ */
++static int adb_resume(struct platform_device *dev)
++{
++	adb_got_sleep = 0;
++	up(&adb_probe_mutex);
++	adb_reset_bus();
++
++	return 0;
++}
++#endif /* CONFIG_PM */
++
+ int __init adb_init(void)
+ {
+ 	struct adb_driver *driver;
+@@ -313,15 +321,12 @@
+ 		printk(KERN_WARNING "Warning: no ADB interface detected\n");
+ 		adb_controller = NULL;
+ 	} else {
+-#ifdef CONFIG_PM_SLEEP
+-		pmu_register_sleep_notifier(&adb_sleep_notifier);
+-#endif /* CONFIG_PM */
+ #ifdef CONFIG_PPC
+ 		if (machine_is_compatible("AAPL,PowerBook1998") ||
+ 			machine_is_compatible("PowerBook1,1"))
+ 			sleepy_trackpad = 1;
+ #endif /* CONFIG_PPC */
+-		init_completion(&adb_probe_task_comp);
++
+ 		adbdev_init();
+ 		adb_reset_bus();
+ 	}
+@@ -330,33 +335,6 @@
+ 
+ __initcall(adb_init);
+ 
+-#ifdef CONFIG_PM
+-/*
+- * notify clients before sleep and reset bus afterwards
+- */
+-void
+-adb_notify_sleep(struct pmu_sleep_notifier *self, int when)
+-{
+-	switch (when) {
+-	case PBOOK_SLEEP_REQUEST:
+-		adb_got_sleep = 1;
+-		/* We need to get a lock on the probe thread */
+-		down(&adb_probe_mutex);
+-		/* Stop autopoll */
+-		if (adb_controller->autopoll)
+-			adb_controller->autopoll(0);
+-		blocking_notifier_call_chain(&adb_client_list,
+-			ADB_MSG_POWERDOWN, NULL);
+-		break;
+-	case PBOOK_WAKE:
+-		adb_got_sleep = 0;
+-		up(&adb_probe_mutex);
+-		adb_reset_bus();
+-		break;
+-	}
+-}
+-#endif /* CONFIG_PM */
+-
+ static int
+ do_adb_reset_bus(void)
+ {
+@@ -373,7 +351,7 @@
+ 
+ 	if (sleepy_trackpad) {
+ 		/* Let the trackpad settle down */
+-		adb_wait_ms(500);
++		msleep(500);
+ 	}
+ 
+ 	down(&adb_handler_sem);
+@@ -389,7 +367,7 @@
+ 
+ 	if (sleepy_trackpad) {
+ 		/* Let the trackpad settle down */
+-		adb_wait_ms(1500);
++		msleep(1500);
+ 	}
+ 
+ 	if (!ret) {
+@@ -413,41 +391,27 @@
+ 	adb_controller->poll();
+ }
+ 
+-static void
+-adb_probe_wakeup(struct adb_request *req)
++static void adb_sync_req_done(struct adb_request *req)
+ {
+-	complete(&adb_probe_task_comp);
+-}
++	struct completion *comp = req->arg;
+ 
+-/* Static request used during probe */
+-static struct adb_request adb_sreq;
+-static unsigned long adb_sreq_lock; // Use semaphore ! */ 
++	complete(comp);
++}
+ 
+ int
+ adb_request(struct adb_request *req, void (*done)(struct adb_request *),
+ 	    int flags, int nbytes, ...)
+ {
+ 	va_list list;
+-	int i, use_sreq;
++	int i;
+ 	int rc;
++	struct completion comp;
+ 
+ 	if ((adb_controller == NULL) || (adb_controller->send_request == NULL))
+ 		return -ENXIO;
+ 	if (nbytes < 1)
+ 		return -EINVAL;
+-	if (req == NULL && (flags & ADBREQ_NOSEND))
+-		return -EINVAL;
+-	
+-	if (req == NULL) {
+-		if (test_and_set_bit(0,&adb_sreq_lock)) {
+-			printk("adb.c: Warning: contention on static request !\n");
+-			return -EPERM;
+-		}
+-		req = &adb_sreq;
+-		flags |= ADBREQ_SYNC;
+-		use_sreq = 1;
+-	} else
+-		use_sreq = 0;
++
+ 	req->nbytes = nbytes+1;
+ 	req->done = done;
+ 	req->reply_expected = flags & ADBREQ_REPLY;
+@@ -460,25 +424,18 @@
+ 	if (flags & ADBREQ_NOSEND)
+ 		return 0;
+ 
+-	/* Synchronous requests send from the probe thread cause it to
+-	 * block. Beware that the "done" callback will be overriden !
+-	 */
+-	if ((flags & ADBREQ_SYNC) &&
+-	    (current->pid && adb_probe_task_pid &&
+-	    adb_probe_task_pid == current->pid)) {
+-		req->done = adb_probe_wakeup;
+-		rc = adb_controller->send_request(req, 0);
+-		if (rc || req->complete)
+-			goto bail;
+-		wait_for_completion(&adb_probe_task_comp);
+-		rc = 0;
+-		goto bail;
+-	}
+-
+-	rc = adb_controller->send_request(req, flags & ADBREQ_SYNC);
+-bail:
+-	if (use_sreq)
+-		clear_bit(0, &adb_sreq_lock);
++	/* Synchronous requests block using an on-stack completion */
++	if (flags & ADBREQ_SYNC) {
++		WARN_ON(done);
++		req->done = adb_sync_req_done;
++		req->arg = &comp;
++		init_completion(&comp);
++	}
++
++	rc = adb_controller->send_request(req, 0);
++
++	if ((flags & ADBREQ_SYNC) && !rc && !req->complete)
++		wait_for_completion(&comp);
+ 
+ 	return rc;
+ }
+@@ -864,7 +821,29 @@
+ 	.release	= adb_release,
+ };
+ 
+-static void
++static struct platform_driver adb_pfdrv = {
++	.driver = {
++		.name = "adb",
++	},
++#ifdef CONFIG_PM
++	.suspend = adb_suspend,
++	.resume = adb_resume,
++#endif
++};
++
++static struct platform_device adb_pfdev = {
++	.name = "adb",
++};
++
++static int __init
++adb_dummy_probe(struct platform_device *dev)
++{
++	if (dev == &adb_pfdev)
++		return 0;
++	return -ENODEV;
++}
++
++static void __init
+ adbdev_init(void)
+ {
+ 	if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
+@@ -876,4 +855,7 @@
+ 	if (IS_ERR(adb_dev_class))
+ 		return;
+ 	class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
++
++	platform_device_register(&adb_pfdev);
++	platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/macintosh/mediabay.c powerpc.git/drivers/macintosh/mediabay.c
+--- linux-2.6.24/drivers/macintosh/mediabay.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/macintosh/mediabay.c	2008-01-28 20:26:08.000000000 +0100
+@@ -20,6 +20,7 @@
+ #include <linux/stddef.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
++#include <linux/kthread.h>
+ #include <asm/prom.h>
+ #include <asm/pgtable.h>
+ #include <asm/io.h>
+@@ -35,7 +36,6 @@
+ 
+ 
+ #define MB_DEBUG
+-#define MB_IGNORE_SIGNALS
+ 
+ #ifdef MB_DEBUG
+ #define MBDBG(fmt, arg...)	printk(KERN_INFO fmt , ## arg)
+@@ -622,12 +622,7 @@
+ {
+ 	int	i;
+ 
+-	strcpy(current->comm, "media-bay");
+-#ifdef MB_IGNORE_SIGNALS
+-	sigfillset(&current->blocked);
+-#endif
+-
+-	for (;;) {
++	while (!kthread_should_stop()) {
+ 		for (i = 0; i < media_bay_count; ++i) {
+ 			down(&media_bays[i].lock);
+ 			if (!media_bays[i].sleeping)
+@@ -636,9 +631,8 @@
+ 		}
+ 
+ 		msleep_interruptible(MB_POLL_DELAY);
+-		if (signal_pending(current))
+-			return 0;
+ 	}
++	return 0;
+ }
+ 
+ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match)
+@@ -699,7 +693,7 @@
+ 
+ 	/* Startup kernel thread */
+ 	if (i == 0)
+-		kernel_thread(media_bay_task, NULL, CLONE_KERNEL);
++		kthread_run(media_bay_task, NULL, "media-bay");
+ 
+ 	return 0;
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/macintosh/therm_adt746x.c powerpc.git/drivers/macintosh/therm_adt746x.c
+--- linux-2.6.24/drivers/macintosh/therm_adt746x.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/macintosh/therm_adt746x.c	2008-01-28 20:26:08.000000000 +0100
+@@ -553,6 +553,7 @@
+ 	struct device_node* np;
+ 	const u32 *prop;
+ 	int i = 0, offset = 0;
++	int err;
+ 	
+ 	np = of_find_node_by_name(NULL, "fan");
+ 	if (!np)
+@@ -612,17 +613,20 @@
+ 		return -ENODEV;
+ 	}
+ 	
+-	device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
+-	device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
+-	device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
+-	device_create_file(&of_dev->dev, &dev_attr_sensor2_limit);
+-	device_create_file(&of_dev->dev, &dev_attr_sensor1_location);
+-	device_create_file(&of_dev->dev, &dev_attr_sensor2_location);
+-	device_create_file(&of_dev->dev, &dev_attr_limit_adjust);
+-	device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed);
+-	device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
++	err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
++	err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
++	err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
++	err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_limit);
++	err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_location);
++	err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_location);
++	err |= device_create_file(&of_dev->dev, &dev_attr_limit_adjust);
++	err |= device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed);
++	err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
+ 	if(therm_type == ADT7460)
+-		device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
++		err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
++	if (err)
++		printk(KERN_WARNING
++			"Failed to create tempertaure attribute file(s).\n");
+ 
+ #ifndef CONFIG_I2C_POWERMAC
+ 	request_module("i2c-powermac");
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/macintosh/therm_pm72.c powerpc.git/drivers/macintosh/therm_pm72.c
+--- linux-2.6.24/drivers/macintosh/therm_pm72.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/macintosh/therm_pm72.c	2008-01-28 20:26:08.000000000 +0100
+@@ -121,6 +121,7 @@
+ #include <linux/reboot.h>
+ #include <linux/kmod.h>
+ #include <linux/i2c.h>
++#include <linux/kthread.h>
+ #include <asm/prom.h>
+ #include <asm/machdep.h>
+ #include <asm/io.h>
+@@ -161,7 +162,7 @@
+ static int				state;
+ static int				cpu_count;
+ static int				cpu_pid_type;
+-static pid_t				ctrl_task;
++static struct task_struct		*ctrl_task;
+ static struct completion		ctrl_complete;
+ static int				critical_state;
+ static int				rackmac;
+@@ -1156,6 +1157,8 @@
+  */
+ static int init_cpu_state(struct cpu_pid_state *state, int index)
+ {
++	int err;
++
+ 	state->index = index;
+ 	state->first = 1;
+ 	state->rpm = (cpu_pid_type == CPU_PID_TYPE_RACKMAC) ? 4000 : 1000;
+@@ -1181,18 +1184,21 @@
+ 	DBG("CPU %d Using %d power history entries\n", index, state->count_power);
+ 
+ 	if (index == 0) {
+-		device_create_file(&of_dev->dev, &dev_attr_cpu0_temperature);
+-		device_create_file(&of_dev->dev, &dev_attr_cpu0_voltage);
+-		device_create_file(&of_dev->dev, &dev_attr_cpu0_current);
+-		device_create_file(&of_dev->dev, &dev_attr_cpu0_exhaust_fan_rpm);
+-		device_create_file(&of_dev->dev, &dev_attr_cpu0_intake_fan_rpm);
++		err = device_create_file(&of_dev->dev, &dev_attr_cpu0_temperature);
++		err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_voltage);
++		err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_current);
++		err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_exhaust_fan_rpm);
++		err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_intake_fan_rpm);
+ 	} else {
+-		device_create_file(&of_dev->dev, &dev_attr_cpu1_temperature);
+-		device_create_file(&of_dev->dev, &dev_attr_cpu1_voltage);
+-		device_create_file(&of_dev->dev, &dev_attr_cpu1_current);
+-		device_create_file(&of_dev->dev, &dev_attr_cpu1_exhaust_fan_rpm);
+-		device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm);
+-	}
++		err = device_create_file(&of_dev->dev, &dev_attr_cpu1_temperature);
++		err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_voltage);
++		err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_current);
++		err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_exhaust_fan_rpm);
++		err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm);
++	}
++	if (err)
++		printk(KERN_WARNING "Failed to create some of the atribute"
++			"files for CPU %d\n", index);
+ 
+ 	return 0;
+  fail:
+@@ -1328,6 +1334,7 @@
+ {
+ 	struct device_node *u3;
+ 	int u3h = 1; /* conservative by default */
++	int err;
+ 
+ 	/*
+ 	 * There are different PID params for machines with U3 and machines
+@@ -1379,8 +1386,11 @@
+ 	if (state->monitor == NULL)
+ 		return -ENODEV;
+ 
+-	device_create_file(&of_dev->dev, &dev_attr_backside_temperature);
+-	device_create_file(&of_dev->dev, &dev_attr_backside_fan_pwm);
++	err = device_create_file(&of_dev->dev, &dev_attr_backside_temperature);
++	err |= device_create_file(&of_dev->dev, &dev_attr_backside_fan_pwm);
++	if (err)
++		printk(KERN_WARNING "Failed to create attribute file(s)"
++			" for backside fan\n");
+ 
+ 	return 0;
+ }
+@@ -1491,6 +1501,8 @@
+  */
+ static int init_drives_state(struct drives_pid_state *state)
+ {
++	int err;
++
+ 	state->ticks = 1;
+ 	state->first = 1;
+ 	state->rpm = 1000;
+@@ -1499,8 +1511,11 @@
+ 	if (state->monitor == NULL)
+ 		return -ENODEV;
+ 
+-	device_create_file(&of_dev->dev, &dev_attr_drives_temperature);
+-	device_create_file(&of_dev->dev, &dev_attr_drives_fan_rpm);
++	err = device_create_file(&of_dev->dev, &dev_attr_drives_temperature);
++	err |= device_create_file(&of_dev->dev, &dev_attr_drives_fan_rpm);
++	if (err)
++		printk(KERN_WARNING "Failed to create attribute file(s)"
++			" for drives bay fan\n");
+ 
+ 	return 0;
+ }
+@@ -1621,7 +1636,9 @@
+ 	if (state->monitor == NULL)
+ 		return -ENODEV;
+ 
+-       	device_create_file(&of_dev->dev, &dev_attr_dimms_temperature);
++	if (device_create_file(&of_dev->dev, &dev_attr_dimms_temperature))
++		printk(KERN_WARNING "Failed to create attribute file"
++			" for DIMM temperature\n");
+ 
+ 	return 0;
+ }
+@@ -1731,6 +1748,8 @@
+  */
+ static int init_slots_state(struct slots_pid_state *state)
+ {
++	int err;
++
+ 	state->ticks = 1;
+ 	state->first = 1;
+ 	state->pwm = 50;
+@@ -1739,8 +1758,11 @@
+ 	if (state->monitor == NULL)
+ 		return -ENODEV;
+ 
+-	device_create_file(&of_dev->dev, &dev_attr_slots_temperature);
+-	device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm);
++	err = device_create_file(&of_dev->dev, &dev_attr_slots_temperature);
++	err |= device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm);
++	if (err)
++		printk(KERN_WARNING "Failed to create attribute file(s)"
++			" for slots bay fan\n");
+ 
+ 	return 0;
+ }
+@@ -1779,8 +1801,6 @@
+  */
+ static int main_control_loop(void *x)
+ {
+-	daemonize("kfand");
+-
+ 	DBG("main_control_loop started\n");
+ 
+ 	down(&driver_lock);
+@@ -1956,7 +1976,7 @@
+ {
+ 	init_completion(&ctrl_complete);
+ 
+-	ctrl_task = kernel_thread(main_control_loop, NULL, SIGCHLD | CLONE_KERNEL);
++	ctrl_task = kthread_run(main_control_loop, NULL, "kfand");
+ }
+ 
+ /*
+@@ -1964,7 +1984,7 @@
+  */
+ static void stop_control_loops(void)
+ {
+-	if (ctrl_task != 0)
++	if (ctrl_task)
+ 		wait_for_completion(&ctrl_complete);
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/macintosh/therm_windtunnel.c powerpc.git/drivers/macintosh/therm_windtunnel.c
+--- linux-2.6.24/drivers/macintosh/therm_windtunnel.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/macintosh/therm_windtunnel.c	2008-01-28 20:26:08.000000000 +0100
+@@ -36,6 +36,7 @@
+ #include <linux/i2c.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
++#include <linux/kthread.h>
+ 
+ #include <asm/prom.h>
+ #include <asm/machdep.h>
+@@ -61,8 +62,7 @@
+ 
+ static struct {
+ 	volatile int		running;
+-	struct completion	completion;
+-	pid_t			poll_task;
++	struct task_struct	*poll_task;
+ 	
+ 	struct semaphore 	lock;
+ 	struct of_device	*of_dev;
+@@ -223,6 +223,7 @@
+ setup_hardware( void )
+ {
+ 	int val;
++	int err;
+ 
+ 	/* save registers (if we unload the module) */
+ 	x.r0 = read_reg( x.fan, 0x00, 1 );
+@@ -265,8 +266,11 @@
+ 	x.upind = -1;
+ 	/* tune_fan( fan_up_table[x.upind].fan_setting ); */
+ 
+-	device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature );
+-	device_create_file( &x.of_dev->dev, &dev_attr_case_temperature );
++	err = device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature );
++	err |= device_create_file( &x.of_dev->dev, &dev_attr_case_temperature );
++	if (err)
++		printk(KERN_WARNING
++			"Failed to create temperature attribute file(s).\n");
+ }
+ 
+ static void
+@@ -282,27 +286,27 @@
+ 	write_reg( x.fan, 0x00, x.r0, 1 );
+ }
+ 
+-static int
+-control_loop( void *dummy )
++static int control_loop(void *dummy)
+ {
+-	daemonize("g4fand");
+-
+-	down( &x.lock );
++	down(&x.lock);
+ 	setup_hardware();
++	up(&x.lock);
+ 
+-	while( x.running ) {
+-		up( &x.lock );
+-
++	for (;;) {
+ 		msleep_interruptible(8000);
+-		
+-		down( &x.lock );
++		if (kthread_should_stop())
++			break;
++
++		down(&x.lock);
+ 		poll_temp();
++		up(&x.lock);
+ 	}
+ 
++	down(&x.lock);
+ 	restore_regs();
+-	up( &x.lock );
++	up(&x.lock);
+ 
+-	complete_and_exit( &x.completion, 0 );
++	return 0;
+ }
+ 
+ 
+@@ -322,8 +326,7 @@
+ 		ret = i2c_probe( adapter, &addr_data, &do_probe );
+ 		if( x.thermostat && x.fan ) {
+ 			x.running = 1;
+-			init_completion( &x.completion );
+-			x.poll_task = kernel_thread( control_loop, NULL, SIGCHLD | CLONE_KERNEL );
++			x.poll_task = kthread_run(control_loop, NULL, "g4fand");
+ 		}
+ 	}
+ 	return ret;
+@@ -339,7 +342,8 @@
+ 	else {
+ 		if( x.running ) {
+ 			x.running = 0;
+-			wait_for_completion( &x.completion );
++			kthread_stop(x.poll_task);
++			x.poll_task = NULL;
+ 		}
+ 		if( client == x.thermostat )
+ 			x.thermostat = NULL;
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/macintosh/via-pmu-backlight.c powerpc.git/drivers/macintosh/via-pmu-backlight.c
+--- linux-2.6.24/drivers/macintosh/via-pmu-backlight.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/macintosh/via-pmu-backlight.c	2008-01-28 20:26:08.000000000 +0100
+@@ -22,7 +22,7 @@
+ 
+ static void pmu_backlight_init_curve(u8 off, u8 min, u8 max)
+ {
+-	unsigned int i, flat, count, range = (max - min);
++	int i, flat, count, range = (max - min);
+ 
+ 	bl_curve[0] = off;
+ 
+@@ -68,17 +68,11 @@
+ 	return pmulevel;
+ }
+ 
+-static int pmu_backlight_update_status(struct backlight_device *bd)
++static int __pmu_backlight_update_status(struct backlight_device *bd)
+ {
+ 	struct adb_request req;
+-	unsigned long flags;
+ 	int level = bd->props.brightness;
+ 
+-	spin_lock_irqsave(&pmu_backlight_lock, flags);
+-
+-	/* Don't update brightness when sleeping */
+-	if (sleeping)
+-		goto out;
+ 
+ 	if (bd->props.power != FB_BLANK_UNBLANK ||
+ 	    bd->props.fb_blank != FB_BLANK_UNBLANK)
+@@ -99,12 +93,23 @@
+ 		pmu_wait_complete(&req);
+ 	}
+ 
+-out:
+-	spin_unlock_irqrestore(&pmu_backlight_lock, flags);
+-
+ 	return 0;
+ }
+ 
++static int pmu_backlight_update_status(struct backlight_device *bd)
++{
++	unsigned long flags;
++	int rc = 0;
++
++	spin_lock_irqsave(&pmu_backlight_lock, flags);
++	/* Don't update brightness when sleeping */
++	if (!sleeping)
++		rc = __pmu_backlight_update_status(bd);
++	spin_unlock_irqrestore(&pmu_backlight_lock, flags);
++	return rc;
++}
++
++
+ static int pmu_backlight_get_brightness(struct backlight_device *bd)
+ {
+ 	return bd->props.brightness;
+@@ -123,6 +128,16 @@
+ 
+ 	spin_lock_irqsave(&pmu_backlight_lock, flags);
+ 	sleeping = sleep;
++	if (pmac_backlight) {
++		if (sleep) {
++			struct adb_request req;
++
++			pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
++				    PMU_POW_BACKLIGHT | PMU_POW_OFF);
++			pmu_wait_complete(&req);
++		} else
++			__pmu_backlight_update_status(pmac_backlight);
++	}
+ 	spin_unlock_irqrestore(&pmu_backlight_lock, flags);
+ }
+ #endif /* CONFIG_PM */
+@@ -148,8 +163,8 @@
+ 
+ 	bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data);
+ 	if (IS_ERR(bd)) {
+-		printk("pmubl: Backlight registration failed\n");
+-		goto error;
++		printk(KERN_ERR "PMU Backlight registration failed\n");
++		return;
+ 	}
+ 	bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+ 	pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
+@@ -171,10 +186,5 @@
+ 	bd->props.power = FB_BLANK_UNBLANK;
+ 	backlight_update_status(bd);
+ 
+-	printk("pmubl: Backlight initialized (%s)\n", name);
+-
+-	return;
+-
+-error:
+-	return;
++	printk(KERN_INFO "PMU Backlight initialized (%s)\n", name);
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/macintosh/via-pmu.c powerpc.git/drivers/macintosh/via-pmu.c
+--- linux-2.6.24/drivers/macintosh/via-pmu.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/macintosh/via-pmu.c	2008-01-28 20:26:08.000000000 +0100
+@@ -10,13 +10,11 @@
+  *
+  * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi.
+  * Copyright (C) 2001-2002 Benjamin Herrenschmidt
++ * Copyright (C) 2006-2007 Johannes Berg
+  *
+  * THIS DRIVER IS BECOMING A TOTAL MESS !
+  *  - Cleanup atomically disabling reply to PMU events after
+  *    a sleep or a freq. switch
+- *  - Move sleep code out of here to pmac_pm, merge into new
+- *    common PM infrastructure
+- *  - Save/Restore PCI space properly
+  *
+  */
+ #include <stdarg.h>
+@@ -33,7 +31,6 @@
+ #include <linux/adb.h>
+ #include <linux/pmu.h>
+ #include <linux/cuda.h>
+-#include <linux/smp_lock.h>
+ #include <linux/module.h>
+ #include <linux/spinlock.h>
+ #include <linux/pm.h>
+@@ -65,9 +62,7 @@
+ #include "via-pmu-event.h"
+ 
+ /* Some compile options */
+-#undef SUSPEND_USES_PMU
+-#define DEBUG_SLEEP
+-#undef HACKED_PCI_SAVE
++#undef DEBUG_SLEEP
+ 
+ /* Misc minor number allocated for /dev/pmu */
+ #define PMU_MINOR		154
+@@ -152,12 +147,9 @@
+ static u8 pmu_intr_mask;
+ static int pmu_version;
+ static int drop_interrupts;
+-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
++#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+ static int option_lid_wakeup = 1;
+-#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */
+-#if (defined(CONFIG_PM_SLEEP)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY)
+-static int sleep_in_progress;
+-#endif
++#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
+ static unsigned long async_req_locks;
+ static unsigned int pmu_irq_stats[11];
+ 
+@@ -177,7 +169,6 @@
+ 
+ int __fake_sleep;
+ int asleep;
+-BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
+ 
+ #ifdef CONFIG_ADB
+ static int adb_dev_map;
+@@ -224,7 +215,7 @@
+ 
+ #ifdef DEBUG_SLEEP
+ int pmu_polled_request(struct adb_request *req);
+-int pmu_wink(struct adb_request *req);
++void pmu_blink(int n);
+ #endif
+ 
+ /*
+@@ -875,7 +866,7 @@
+ {
+ 	char *p = page;
+ 
+-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
++#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+ 	if (pmu_kind == PMU_KEYLARGO_BASED &&
+ 	    pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
+ 		p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup);
+@@ -916,7 +907,7 @@
+ 	*(val++) = 0;
+ 	while(*val == ' ')
+ 		val++;
+-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
++#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+ 	if (pmu_kind == PMU_KEYLARGO_BASED &&
+ 	    pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
+ 		if (!strcmp(label, "lid_wakeup"))
+@@ -1256,9 +1247,7 @@
+ pmu_suspend(void)
+ {
+ 	unsigned long flags;
+-#ifdef SUSPEND_USES_PMU
+-	struct adb_request *req;
+-#endif
++
+ 	if (!via)
+ 		return;
+ 	
+@@ -1276,17 +1265,10 @@
+ 		via_pmu_interrupt(0, NULL);
+ 		spin_lock_irqsave(&pmu_lock, flags);
+ 		if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) {
+-#ifdef SUSPEND_USES_PMU
+-			pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
+-			spin_unlock_irqrestore(&pmu_lock, flags);
+-			while(!req.complete)
+-				pmu_poll();
+-#else /* SUSPEND_USES_PMU */
+ 			if (gpio_irq >= 0)
+ 				disable_irq_nosync(gpio_irq);
+ 			out_8(&via[IER], CB1_INT | IER_CLR);
+ 			spin_unlock_irqrestore(&pmu_lock, flags);
+-#endif /* SUSPEND_USES_PMU */
+ 			break;
+ 		}
+ 	} while (1);
+@@ -1307,18 +1289,11 @@
+ 		return;
+ 	}
+ 	adb_int_pending = 1;
+-#ifdef SUSPEND_USES_PMU
+-	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
+-	spin_unlock_irqrestore(&pmu_lock, flags);
+-	while(!req.complete)
+-		pmu_poll();
+-#else /* SUSPEND_USES_PMU */
+ 	if (gpio_irq >= 0)
+ 		enable_irq(gpio_irq);
+ 	out_8(&via[IER], CB1_INT | IER_SET);
+ 	spin_unlock_irqrestore(&pmu_lock, flags);
+ 	pmu_poll();
+-#endif /* SUSPEND_USES_PMU */
+ }
+ 
+ /* Interrupt data could be the result data from an ADB cmd */
+@@ -1738,228 +1713,7 @@
+ 	return via != 0;
+ }
+ 
+-#ifdef CONFIG_PM_SLEEP
+-
+-static LIST_HEAD(sleep_notifiers);
+-
+-int
+-pmu_register_sleep_notifier(struct pmu_sleep_notifier *n)
+-{
+-	struct list_head *list;
+-	struct pmu_sleep_notifier *notifier;
+-
+-	for (list = sleep_notifiers.next; list != &sleep_notifiers;
+-	     list = list->next) {
+-		notifier = list_entry(list, struct pmu_sleep_notifier, list);
+-		if (n->priority > notifier->priority)
+-			break;
+-	}
+-	__list_add(&n->list, list->prev, list);
+-	return 0;
+-}
+-EXPORT_SYMBOL(pmu_register_sleep_notifier);
+-
+-int
+-pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
+-{
+-	if (n->list.next == 0)
+-		return -ENOENT;
+-	list_del(&n->list);
+-	n->list.next = NULL;
+-	return 0;
+-}
+-EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
+-#endif /* CONFIG_PM_SLEEP */
+-
+-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
+-
+-/* Sleep is broadcast last-to-first */
+-static void broadcast_sleep(int when)
+-{
+-	struct list_head *list;
+-	struct pmu_sleep_notifier *notifier;
+-
+-	for (list = sleep_notifiers.prev; list != &sleep_notifiers;
+-	     list = list->prev) {
+-		notifier = list_entry(list, struct pmu_sleep_notifier, list);
+-		notifier->notifier_call(notifier, when);
+-	}
+-}
+-
+-/* Wake is broadcast first-to-last */
+-static void broadcast_wake(void)
+-{
+-	struct list_head *list;
+-	struct pmu_sleep_notifier *notifier;
+-
+-	for (list = sleep_notifiers.next; list != &sleep_notifiers;
+-	     list = list->next) {
+-		notifier = list_entry(list, struct pmu_sleep_notifier, list);
+-		notifier->notifier_call(notifier, PBOOK_WAKE);
+-	}
+-}
+-
+-/*
+- * This struct is used to store config register values for
+- * PCI devices which may get powered off when we sleep.
+- */
+-static struct pci_save {
+-#ifndef HACKED_PCI_SAVE
+-	u16	command;
+-	u16	cache_lat;
+-	u16	intr;
+-	u32	rom_address;
+-#else
+-	u32	config[16];
+-#endif	
+-} *pbook_pci_saves;
+-static int pbook_npci_saves;
+-
+-static void
+-pbook_alloc_pci_save(void)
+-{
+-	int npci;
+-	struct pci_dev *pd = NULL;
+-
+-	npci = 0;
+-	while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
+-		++npci;
+-	}
+-	if (npci == 0)
+-		return;
+-	pbook_pci_saves = (struct pci_save *)
+-		kmalloc(npci * sizeof(struct pci_save), GFP_KERNEL);
+-	pbook_npci_saves = npci;
+-}
+-
+-static void
+-pbook_free_pci_save(void)
+-{
+-	if (pbook_pci_saves == NULL)
+-		return;
+-	kfree(pbook_pci_saves);
+-	pbook_pci_saves = NULL;
+-	pbook_npci_saves = 0;
+-}
+-
+-static void
+-pbook_pci_save(void)
+-{
+-	struct pci_save *ps = pbook_pci_saves;
+-	struct pci_dev *pd = NULL;
+-	int npci = pbook_npci_saves;
+-	
+-	if (ps == NULL)
+-		return;
+-
+-	while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
+-		if (npci-- == 0) {
+-			pci_dev_put(pd);
+-			return;
+-		}
+-#ifndef HACKED_PCI_SAVE
+-		pci_read_config_word(pd, PCI_COMMAND, &ps->command);
+-		pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
+-		pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr);
+-		pci_read_config_dword(pd, PCI_ROM_ADDRESS, &ps->rom_address);
+-#else
+-		int i;
+-		for (i=1;i<16;i++)
+-			pci_read_config_dword(pd, i<<4, &ps->config[i]);
+-#endif
+-		++ps;
+-	}
+-}
+-
+-/* For this to work, we must take care of a few things: If gmac was enabled
+- * during boot, it will be in the pci dev list. If it's disabled at this point
+- * (and it will probably be), then you can't access it's config space.
+- */
+-static void
+-pbook_pci_restore(void)
+-{
+-	u16 cmd;
+-	struct pci_save *ps = pbook_pci_saves - 1;
+-	struct pci_dev *pd = NULL;
+-	int npci = pbook_npci_saves;
+-	int j;
+-
+-	while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
+-#ifdef HACKED_PCI_SAVE
+-		int i;
+-		if (npci-- == 0) {
+-			pci_dev_put(pd);
+-			return;
+-		}
+-		ps++;
+-		for (i=2;i<16;i++)
+-			pci_write_config_dword(pd, i<<4, ps->config[i]);
+-		pci_write_config_dword(pd, 4, ps->config[1]);
+-#else
+-		if (npci-- == 0)
+-			return;
+-		ps++;
+-		if (ps->command == 0)
+-			continue;
+-		pci_read_config_word(pd, PCI_COMMAND, &cmd);
+-		if ((ps->command & ~cmd) == 0)
+-			continue;
+-		switch (pd->hdr_type) {
+-		case PCI_HEADER_TYPE_NORMAL:
+-			for (j = 0; j < 6; ++j)
+-				pci_write_config_dword(pd,
+-					PCI_BASE_ADDRESS_0 + j*4,
+-					pd->resource[j].start);
+-			pci_write_config_dword(pd, PCI_ROM_ADDRESS,
+-				ps->rom_address);
+-			pci_write_config_word(pd, PCI_CACHE_LINE_SIZE,
+-				ps->cache_lat);
+-			pci_write_config_word(pd, PCI_INTERRUPT_LINE,
+-				ps->intr);
+-			pci_write_config_word(pd, PCI_COMMAND, ps->command);
+-			break;
+-		}
+-#endif	
+-	}
+-}
+-
+-#ifdef DEBUG_SLEEP
+-/* N.B. This doesn't work on the 3400 */
+-void 
+-pmu_blink(int n)
+-{
+-	struct adb_request req;
+-
+-	memset(&req, 0, sizeof(req));
+-
+-	for (; n > 0; --n) {
+-		req.nbytes = 4;
+-		req.done = NULL;
+-		req.data[0] = 0xee;
+-		req.data[1] = 4;
+-		req.data[2] = 0;
+-		req.data[3] = 1;
+-		req.reply[0] = ADB_RET_OK;
+-		req.reply_len = 1;
+-		req.reply_expected = 0;
+-		pmu_polled_request(&req);
+-		mdelay(50);
+-		req.nbytes = 4;
+-		req.done = NULL;
+-		req.data[0] = 0xee;
+-		req.data[1] = 4;
+-		req.data[2] = 0;
+-		req.data[3] = 0;
+-		req.reply[0] = ADB_RET_OK;
+-		req.reply_len = 1;
+-		req.reply_expected = 0;
+-		pmu_polled_request(&req);
+-		mdelay(50);
+-	}
+-	mdelay(50);
+-}
+-#endif
+-
++#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+ /*
+  * Put the powerbook to sleep.
+  */
+@@ -1994,134 +1748,6 @@
+ 	out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
+ }
+ 
+-extern void pmu_backlight_set_sleep(int sleep);
+-
+-static int
+-pmac_suspend_devices(void)
+-{
+-	int ret;
+-
+-	pm_prepare_console();
+-	
+-	/* Notify old-style device drivers */
+-	broadcast_sleep(PBOOK_SLEEP_REQUEST);
+-
+-	/* Sync the disks. */
+-	/* XXX It would be nice to have some way to ensure that
+-	 * nobody is dirtying any new buffers while we wait. That
+-	 * could be achieved using the refrigerator for processes
+-	 * that swsusp uses
+-	 */
+-	sys_sync();
+-
+-	broadcast_sleep(PBOOK_SLEEP_NOW);
+-
+-	/* Send suspend call to devices, hold the device core's dpm_sem */
+-	ret = device_suspend(PMSG_SUSPEND);
+-	if (ret) {
+-		broadcast_wake();
+-		printk(KERN_ERR "Driver sleep failed\n");
+-		return -EBUSY;
+-	}
+-
+-#ifdef CONFIG_PMAC_BACKLIGHT
+-	/* Tell backlight code not to muck around with the chip anymore */
+-	pmu_backlight_set_sleep(1);
+-#endif
+-
+-	/* Call platform functions marked "on sleep" */
+-	pmac_pfunc_i2c_suspend();
+-	pmac_pfunc_base_suspend();
+-
+-	/* Stop preemption */
+-	preempt_disable();
+-
+-	/* Make sure the decrementer won't interrupt us */
+-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+-	/* Make sure any pending DEC interrupt occurring while we did
+-	 * the above didn't re-enable the DEC */
+-	mb();
+-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+-
+-	/* We can now disable MSR_EE. This code of course works properly only
+-	 * on UP machines... For SMP, if we ever implement sleep, we'll have to
+-	 * stop the "other" CPUs way before we do all that stuff.
+-	 */
+-	local_irq_disable();
+-
+-	/* Broadcast power down irq
+-	 * This isn't that useful in most cases (only directly wired devices can
+-	 * use this but still... This will take care of sysdev's as well, so
+-	 * we exit from here with local irqs disabled and PIC off.
+-	 */
+-	ret = device_power_down(PMSG_SUSPEND);
+-	if (ret) {
+-		wakeup_decrementer();
+-		local_irq_enable();
+-		preempt_enable();
+-		device_resume();
+-		broadcast_wake();
+-		printk(KERN_ERR "Driver powerdown failed\n");
+-		return -EBUSY;
+-	}
+-
+-	/* Wait for completion of async requests */
+-	while (!batt_req.complete)
+-		pmu_poll();
+-
+-	/* Giveup the lazy FPU & vec so we don't have to back them
+-	 * up from the low level code
+-	 */
+-	enable_kernel_fp();
+-
+-#ifdef CONFIG_ALTIVEC
+-	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+-		enable_kernel_altivec();
+-#endif /* CONFIG_ALTIVEC */
+-
+-	return 0;
+-}
+-
+-static int
+-pmac_wakeup_devices(void)
+-{
+-	mdelay(100);
+-
+-#ifdef CONFIG_PMAC_BACKLIGHT
+-	/* Tell backlight code it can use the chip again */
+-	pmu_backlight_set_sleep(0);
+-#endif
+-
+-	/* Power back up system devices (including the PIC) */
+-	device_power_up();
+-
+-	/* Force a poll of ADB interrupts */
+-	adb_int_pending = 1;
+-	via_pmu_interrupt(0, NULL);
+-
+-	/* Restart jiffies & scheduling */
+-	wakeup_decrementer();
+-
+-	/* Re-enable local CPU interrupts */
+-	local_irq_enable();
+-	mdelay(10);
+-	preempt_enable();
+-
+-	/* Call platform functions marked "on wake" */
+-	pmac_pfunc_base_resume();
+-	pmac_pfunc_i2c_resume();
+-
+-	/* Resume devices */
+-	device_resume();
+-
+-	/* Notify old style drivers */
+-	broadcast_wake();
+-
+-	pm_restore_console();
+-
+-	return 0;
+-}
+-
+ #define	GRACKLE_PM	(1<<7)
+ #define GRACKLE_DOZE	(1<<5)
+ #define	GRACKLE_NAP	(1<<4)
+@@ -2132,19 +1758,12 @@
+ 	unsigned long save_l2cr;
+ 	unsigned short pmcr1;
+ 	struct adb_request req;
+-	int ret;
+ 	struct pci_dev *grackle;
+ 
+ 	grackle = pci_get_bus_and_slot(0, 0);
+ 	if (!grackle)
+ 		return -ENODEV;
+ 
+-	ret = pmac_suspend_devices();
+-	if (ret) {
+-		printk(KERN_ERR "Sleep rejected by devices\n");
+-		return ret;
+-	}
+-	
+ 	/* Turn off various things. Darwin does some retry tests here... */
+ 	pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE);
+ 	pmu_wait_complete(&req);
+@@ -2207,8 +1826,6 @@
+ 			PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY);
+ 	pmu_wait_complete(&req);
+ 
+-	pmac_wakeup_devices();
+-
+ 	return 0;
+ }
+ 
+@@ -2218,7 +1835,6 @@
+ 	unsigned long save_l2cr;
+ 	unsigned long save_l3cr;
+ 	struct adb_request req;
+-	int ret;
+ 	
+ 	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) {
+ 		printk(KERN_ERR "Sleep mode not supported on this machine\n");
+@@ -2228,12 +1844,6 @@
+ 	if (num_online_cpus() > 1 || cpu_is_offline(0))
+ 		return -EAGAIN;
+ 
+-	ret = pmac_suspend_devices();
+-	if (ret) {
+-		printk(KERN_ERR "Sleep rejected by devices\n");
+-		return ret;
+-	}
+-
+ 	/* Stop environment and ADB interrupts */
+ 	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
+ 	pmu_wait_complete(&req);
+@@ -2304,45 +1914,33 @@
+ 	/* Restore LPJ, cpufreq will adjust the cpu frequency */
+ 	loops_per_jiffy /= 2;
+ 
+-	pmac_wakeup_devices();
+-
+ 	return 0;
+ }
+ 
+ #define PB3400_MEM_CTRL		0xf8000000
+ #define PB3400_MEM_CTRL_SLEEP	0x70
+ 
+-static int
+-powerbook_sleep_3400(void)
++static void __iomem *pb3400_mem_ctrl;
++
++static void powerbook_sleep_init_3400(void)
+ {
+-	int ret, i, x;
++	/* map in the memory controller registers */
++	pb3400_mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100);
++	if (pb3400_mem_ctrl == NULL)
++		printk(KERN_WARNING "ioremap failed: sleep won't be possible");
++}
++
++static int powerbook_sleep_3400(void)
++{
++	int i, x;
+ 	unsigned int hid0;
+-	unsigned long p;
++	unsigned long msr;
+ 	struct adb_request sleep_req;
+-	void __iomem *mem_ctrl;
+ 	unsigned int __iomem *mem_ctrl_sleep;
+ 
+-	/* first map in the memory controller registers */
+-	mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100);
+-	if (mem_ctrl == NULL) {
+-		printk("powerbook_sleep_3400: ioremap failed\n");
++	if (pb3400_mem_ctrl == NULL)
+ 		return -ENOMEM;
+-	}
+-	mem_ctrl_sleep = mem_ctrl + PB3400_MEM_CTRL_SLEEP;
+-
+-	/* Allocate room for PCI save */
+-	pbook_alloc_pci_save();
+-
+-	ret = pmac_suspend_devices();
+-	if (ret) {
+-		pbook_free_pci_save();
+-		iounmap(mem_ctrl);
+-		printk(KERN_ERR "Sleep rejected by devices\n");
+-		return ret;
+-	}
+-
+-	/* Save the state of PCI config space for some slots */
+-	pbook_pci_save();
++	mem_ctrl_sleep = pb3400_mem_ctrl + PB3400_MEM_CTRL_SLEEP;
+ 
+ 	/* Set the memory controller to keep the memory refreshed
+ 	   while we're asleep */
+@@ -2357,41 +1955,34 @@
+ 
+ 	/* Ask the PMU to put us to sleep */
+ 	pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
+-	while (!sleep_req.complete)
+-		mb();
++	pmu_wait_complete(&sleep_req);
++	pmu_unlock();
+ 
+-	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,1);
++	pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 1);
+ 
+-	/* displacement-flush the L2 cache - necessary? */
+-	for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000)
+-		i = *(volatile int *)p;
+ 	asleep = 1;
+ 
+ 	/* Put the CPU into sleep mode */
+ 	hid0 = mfspr(SPRN_HID0);
+ 	hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
+ 	mtspr(SPRN_HID0, hid0);
+-	mtmsr(mfmsr() | MSR_POW | MSR_EE);
+-	udelay(10);
++	local_irq_enable();
++	msr = mfmsr() | MSR_POW;
++	while (asleep) {
++		mb();
++		mtmsr(msr);
++		isync();
++	}
++	local_irq_disable();
+ 
+ 	/* OK, we're awake again, start restoring things */
+ 	out_be32(mem_ctrl_sleep, 0x3f);
+-	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,0);
+-	pbook_pci_restore();
+-	pmu_unlock();
+-
+-	/* wait for the PMU interrupt sequence to complete */
+-	while (asleep)
+-		mb();
+-
+-	pmac_wakeup_devices();
+-	pbook_free_pci_save();
+-	iounmap(mem_ctrl);
++	pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 0);
+ 
+ 	return 0;
+ }
+ 
+-#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */
++#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
+ 
+ /*
+  * Support for /dev/pmu device
+@@ -2548,7 +2139,6 @@
+ 	struct pmu_private *pp = file->private_data;
+ 	unsigned long flags;
+ 
+-	lock_kernel();
+ 	if (pp != 0) {
+ 		file->private_data = NULL;
+ 		spin_lock_irqsave(&all_pvt_lock, flags);
+@@ -2562,10 +2152,96 @@
+ 
+ 		kfree(pp);
+ 	}
+-	unlock_kernel();
+ 	return 0;
+ }
+ 
++#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
++static void pmac_suspend_disable_irqs(void)
++{
++	/* Call platform functions marked "on sleep" */
++	pmac_pfunc_i2c_suspend();
++	pmac_pfunc_base_suspend();
++}
++
++static int powerbook_sleep(suspend_state_t state)
++{
++	int error = 0;
++
++	/* Wait for completion of async requests */
++	while (!batt_req.complete)
++		pmu_poll();
++
++	/* Giveup the lazy FPU & vec so we don't have to back them
++	 * up from the low level code
++	 */
++	enable_kernel_fp();
++
++#ifdef CONFIG_ALTIVEC
++	if (cpu_has_feature(CPU_FTR_ALTIVEC))
++		enable_kernel_altivec();
++#endif /* CONFIG_ALTIVEC */
++
++	switch (pmu_kind) {
++	case PMU_OHARE_BASED:
++		error = powerbook_sleep_3400();
++		break;
++	case PMU_HEATHROW_BASED:
++	case PMU_PADDINGTON_BASED:
++		error = powerbook_sleep_grackle();
++		break;
++	case PMU_KEYLARGO_BASED:
++		error = powerbook_sleep_Core99();
++		break;
++	default:
++		return -ENOSYS;
++	}
++
++	if (error)
++		return error;
++
++	mdelay(100);
++
++	return 0;
++}
++
++static void pmac_suspend_enable_irqs(void)
++{
++	/* Force a poll of ADB interrupts */
++	adb_int_pending = 1;
++	via_pmu_interrupt(0, NULL);
++
++	mdelay(10);
++
++	/* Call platform functions marked "on wake" */
++	pmac_pfunc_base_resume();
++	pmac_pfunc_i2c_resume();
++}
++
++static int pmu_sleep_valid(suspend_state_t state)
++{
++	return state == PM_SUSPEND_MEM
++		&& (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0);
++}
++
++static struct platform_suspend_ops pmu_pm_ops = {
++	.enter = powerbook_sleep,
++	.valid = pmu_sleep_valid,
++};
++
++static int register_pmu_pm_ops(void)
++{
++	if (pmu_kind == PMU_OHARE_BASED)
++		powerbook_sleep_init_3400();
++	ppc_md.suspend_disable_irqs = pmac_suspend_disable_irqs;
++	ppc_md.suspend_enable_irqs = pmac_suspend_enable_irqs;
++	suspend_set_ops(&pmu_pm_ops);
++
++	return 0;
++}
++
++device_initcall(register_pmu_pm_ops);
++#endif
++
+ static int
+ pmu_ioctl(struct inode * inode, struct file *filp,
+ 		     u_int cmd, u_long arg)
+@@ -2574,35 +2250,15 @@
+ 	int error = -EINVAL;
+ 
+ 	switch (cmd) {
+-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
+ 	case PMU_IOC_SLEEP:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EACCES;
+-		if (sleep_in_progress)
+-			return -EBUSY;
+-		sleep_in_progress = 1;
+-		switch (pmu_kind) {
+-		case PMU_OHARE_BASED:
+-			error = powerbook_sleep_3400();
+-			break;
+-		case PMU_HEATHROW_BASED:
+-		case PMU_PADDINGTON_BASED:
+-			error = powerbook_sleep_grackle();
+-			break;
+-		case PMU_KEYLARGO_BASED:
+-			error = powerbook_sleep_Core99();
+-			break;
+-		default:
+-			error = -ENOSYS;
+-		}
+-		sleep_in_progress = 0;
+-		break;
++		return pm_suspend(PM_SUSPEND_MEM);
+ 	case PMU_IOC_CAN_SLEEP:
+-		if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0)
++		if (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) < 0)
+ 			return put_user(0, argp);
+ 		else
+ 			return put_user(1, argp);
+-#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */
+ 
+ #ifdef CONFIG_PMAC_BACKLIGHT_LEGACY
+ 	/* Compatibility ioctl's for backlight */
+@@ -2610,9 +2266,6 @@
+ 	{
+ 		int brightness;
+ 
+-		if (sleep_in_progress)
+-			return -EBUSY;
+-
+ 		brightness = pmac_backlight_get_legacy_brightness();
+ 		if (brightness < 0)
+ 			return brightness;
+@@ -2624,9 +2277,6 @@
+ 	{
+ 		int brightness;
+ 
+-		if (sleep_in_progress)
+-			return -EBUSY;
+-
+ 		error = get_user(brightness, argp);
+ 		if (error)
+ 			return error;
+@@ -2751,15 +2401,43 @@
+ 	local_irq_restore(flags);
+ 	return 0;
+ }
+-#endif /* DEBUG_SLEEP */
+ 
++/* N.B. This doesn't work on the 3400 */
++void pmu_blink(int n)
++{
++	struct adb_request req;
+ 
+-/* FIXME: This is a temporary set of callbacks to enable us
+- * to do suspend-to-disk.
+- */
++	memset(&req, 0, sizeof(req));
+ 
+-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
++	for (; n > 0; --n) {
++		req.nbytes = 4;
++		req.done = NULL;
++		req.data[0] = 0xee;
++		req.data[1] = 4;
++		req.data[2] = 0;
++		req.data[3] = 1;
++		req.reply[0] = ADB_RET_OK;
++		req.reply_len = 1;
++		req.reply_expected = 0;
++		pmu_polled_request(&req);
++		mdelay(50);
++		req.nbytes = 4;
++		req.done = NULL;
++		req.data[0] = 0xee;
++		req.data[1] = 4;
++		req.data[2] = 0;
++		req.data[3] = 0;
++		req.reply[0] = ADB_RET_OK;
++		req.reply_len = 1;
++		req.reply_expected = 0;
++		pmu_polled_request(&req);
++		mdelay(50);
++	}
++	mdelay(50);
++}
++#endif /* DEBUG_SLEEP */
+ 
++#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+ int pmu_sys_suspended;
+ 
+ static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
+@@ -2767,10 +2445,15 @@
+ 	if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended)
+ 		return 0;
+ 
+-	/* Suspend PMU event interrupts */
++	/* Suspend PMU event interrupts */\
+ 	pmu_suspend();
+-
+ 	pmu_sys_suspended = 1;
++
++#ifdef CONFIG_PMAC_BACKLIGHT
++	/* Tell backlight code not to muck around with the chip anymore */
++	pmu_backlight_set_sleep(1);
++#endif
++
+ 	return 0;
+ }
+ 
+@@ -2785,15 +2468,18 @@
+ 	pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
+ 	pmu_wait_complete(&req);
+ 
++#ifdef CONFIG_PMAC_BACKLIGHT
++	/* Tell backlight code it can use the chip again */
++	pmu_backlight_set_sleep(0);
++#endif
+ 	/* Resume PMU event interrupts */
+ 	pmu_resume();
+-
+ 	pmu_sys_suspended = 0;
+ 
+ 	return 0;
+ }
+ 
+-#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */
++#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
+ 
+ static struct sysdev_class pmu_sysclass = {
+ 	set_kset_name("pmu"),
+@@ -2804,10 +2490,10 @@
+ };
+ 
+ static struct sysdev_driver driver_pmu = {
+-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
++#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+ 	.suspend	= &pmu_sys_suspend,
+ 	.resume		= &pmu_sys_resume,
+-#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */
++#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
+ };
+ 
+ static int __init init_pmu_sysfs(void)
+@@ -2842,10 +2528,10 @@
+ EXPORT_SYMBOL(pmu_suspend);
+ EXPORT_SYMBOL(pmu_resume);
+ EXPORT_SYMBOL(pmu_unlock);
+-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
++#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+ EXPORT_SYMBOL(pmu_enable_irled);
+ EXPORT_SYMBOL(pmu_battery_count);
+ EXPORT_SYMBOL(pmu_batteries);
+ EXPORT_SYMBOL(pmu_power_flags);
+-#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */
++#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/net/fs_enet/fs_enet-main.c powerpc.git/drivers/net/fs_enet/fs_enet-main.c
+--- linux-2.6.24/drivers/net/fs_enet/fs_enet-main.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/net/fs_enet/fs_enet-main.c	2008-01-28 20:26:12.000000000 +0100
+@@ -1178,8 +1178,15 @@
+ 	struct device_node *phynode, *mdionode;
+ 	struct resource res;
+ 	int ret = 0, len;
++	const u32 *data;
++
++	data  = of_get_property(np, "fixed-link", NULL);
++	if (data) {
++		snprintf(fpi->bus_id, 16, PHY_ID_FMT, 0, *data);
++		return 0;
++	}
+ 
+-	const u32 *data = of_get_property(np, "phy-handle", &len);
++	data = of_get_property(np, "phy-handle", &len);
+ 	if (!data || len != 4)
+ 		return -EINVAL;
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/net/fs_enet/mac-fcc.c powerpc.git/drivers/net/fs_enet/mac-fcc.c
+--- linux-2.6.24/drivers/net/fs_enet/mac-fcc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/net/fs_enet/mac-fcc.c	2008-01-28 20:26:12.000000000 +0100
+@@ -81,16 +81,8 @@
+ static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op)
+ {
+ 	const struct fs_platform_info *fpi = fep->fpi;
+-	int i;
+ 
+-	W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG);
+-	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
+-		if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
+-			return 0;
+-
+-	printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+-	       __FUNCTION__);
+-	return 1;
++	return cpm_command(fpi->cp_command, op);
+ }
+ 
+ static int do_pd_setup(struct fs_enet_private *fep)
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/net/fs_enet/mac-scc.c powerpc.git/drivers/net/fs_enet/mac-scc.c
+--- linux-2.6.24/drivers/net/fs_enet/mac-scc.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/net/fs_enet/mac-scc.c	2008-01-28 20:26:12.000000000 +0100
+@@ -89,21 +89,12 @@
+  * Delay to wait for SCC reset command to complete (in us)
+  */
+ #define SCC_RESET_DELAY		50
+-#define MAX_CR_CMD_LOOPS	10000
+ 
+ static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
+ {
+ 	const struct fs_platform_info *fpi = fep->fpi;
+-	int i;
+ 
+-	W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8));
+-	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
+-		if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
+-			return 0;
+-
+-	printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+-		__FUNCTION__);
+-	return 1;
++	return cpm_command(fpi->cp_command, op);
+ }
+ 
+ static int do_pd_setup(struct fs_enet_private *fep)
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/net/ibm_newemac/core.c powerpc.git/drivers/net/ibm_newemac/core.c
+--- linux-2.6.24/drivers/net/ibm_newemac/core.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/net/ibm_newemac/core.c	2008-01-28 20:26:12.000000000 +0100
+@@ -37,6 +37,7 @@
+ #include <linux/mii.h>
+ #include <linux/bitops.h>
+ #include <linux/workqueue.h>
++#include <linux/of.h>
+ 
+ #include <asm/processor.h>
+ #include <asm/io.h>
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/net/phy/Kconfig powerpc.git/drivers/net/phy/Kconfig
+--- linux-2.6.24/drivers/net/phy/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/net/phy/Kconfig	2008-01-28 20:26:14.000000000 +0100
+@@ -61,34 +61,12 @@
+ 	  Currently supports the IP175C PHY.
+ 
+ config FIXED_PHY
+-	tristate "Drivers for PHY emulation on fixed speed/link"
++	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
+ 	---help---
+-	  Adds the driver to PHY layer to cover the boards that do not have any PHY bound,
+-	  but with the ability to manipulate the speed/link in software. The relevant MII
+-	  speed/duplex parameters could be effectively handled in a user-specified function.
+-	  Currently tested with mpc866ads.
++	  Adds the platform "fixed" MDIO Bus to cover the boards that use
++	  PHYs that are not connected to the real MDIO bus.
+ 
+-config FIXED_MII_10_FDX
+-	bool "Emulation for 10M Fdx fixed PHY behavior"
+-	depends on FIXED_PHY
+-
+-config FIXED_MII_100_FDX
+-	bool "Emulation for 100M Fdx fixed PHY behavior"
+-	depends on FIXED_PHY
+-
+-config FIXED_MII_1000_FDX
+-	bool "Emulation for 1000M Fdx fixed PHY behavior"
+-	depends on FIXED_PHY
+-
+-config FIXED_MII_AMNT
+-        int "Number of emulated PHYs to allocate "
+-        depends on FIXED_PHY
+-        default "1"
+-        ---help---
+-        Sometimes it is required to have several independent emulated
+-        PHYs on the bus (in case of multi-eth but phy-less HW for instance).
+-        This control will have specified number allocated for each fixed
+-        PHY type enabled.
++	  Currently tested with mpc866ads and mpc8349e-mitx.
+ 
+ config MDIO_BITBANG
+ 	tristate "Support for bitbanged MDIO buses"
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/net/phy/fixed.c powerpc.git/drivers/net/phy/fixed.c
+--- linux-2.6.24/drivers/net/phy/fixed.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/net/phy/fixed.c	2008-01-28 20:26:14.000000000 +0100
+@@ -1,362 +1,253 @@
+ /*
+- * drivers/net/phy/fixed.c
++ * Fixed MDIO bus (MDIO bus emulation with fixed PHYs)
+  *
+- * Driver for fixed PHYs, when transceiver is able to operate in one fixed mode.
++ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
++ *         Anton Vorontsov <avorontsov@ru.mvista.com>
+  *
+- * Author: Vitaly Bordug
+- *
+- * Copyright (c) 2006 MontaVista Software, Inc.
++ * Copyright (c) 2006-2007 MontaVista Software, 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.
+- *
+  */
++
+ #include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/errno.h>
+-#include <linux/unistd.h>
+-#include <linux/slab.h>
+-#include <linux/interrupt.h>
+-#include <linux/init.h>
+-#include <linux/delay.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/spinlock.h>
+-#include <linux/mm.h>
+ #include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/list.h>
+ #include <linux/mii.h>
+-#include <linux/ethtool.h>
+ #include <linux/phy.h>
+ #include <linux/phy_fixed.h>
+ 
+-#include <asm/io.h>
+-#include <asm/irq.h>
+-#include <asm/uaccess.h>
+-
+-/* we need to track the allocated pointers in order to free them on exit */
+-static struct fixed_info *fixed_phy_ptrs[CONFIG_FIXED_MII_AMNT*MAX_PHY_AMNT];
+-
+-/*-----------------------------------------------------------------------------
+- *  If something weird is required to be done with link/speed,
+- * network driver is able to assign a function to implement this.
+- * May be useful for PHY's that need to be software-driven.
+- *-----------------------------------------------------------------------------*/
+-int fixed_mdio_set_link_update(struct phy_device *phydev,
+-			       int (*link_update) (struct net_device *,
+-						   struct fixed_phy_status *))
+-{
+-	struct fixed_info *fixed;
+-
+-	if (link_update == NULL)
+-		return -EINVAL;
++#define MII_REGS_NUM 29
+ 
+-	if (phydev) {
+-		if (phydev->bus) {
+-			fixed = phydev->bus->priv;
+-			fixed->link_update = link_update;
+-			return 0;
+-		}
+-	}
+-	return -EINVAL;
+-}
+-
+-EXPORT_SYMBOL(fixed_mdio_set_link_update);
++struct fixed_mdio_bus {
++	int irqs[PHY_MAX_ADDR];
++	struct mii_bus mii_bus;
++	struct list_head phys;
++};
+ 
+-struct fixed_info *fixed_mdio_get_phydev (int phydev_ind)
+-{
+-	if (phydev_ind >= MAX_PHY_AMNT)
+-		return NULL;
+-	return fixed_phy_ptrs[phydev_ind];
+-}
++struct fixed_phy {
++	int id;
++	u16 regs[MII_REGS_NUM];
++	struct phy_device *phydev;
++	struct fixed_phy_status status;
++	int (*link_update)(struct net_device *, struct fixed_phy_status *);
++	struct list_head node;
++};
+ 
+-EXPORT_SYMBOL(fixed_mdio_get_phydev);
++static struct platform_device *pdev;
++static struct fixed_mdio_bus platform_fmb = {
++	.phys = LIST_HEAD_INIT(platform_fmb.phys),
++};
+ 
+-/*-----------------------------------------------------------------------------
+- *  This is used for updating internal mii regs from the status
+- *-----------------------------------------------------------------------------*/
+-#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX)
+-static int fixed_mdio_update_regs(struct fixed_info *fixed)
++static int fixed_phy_update_regs(struct fixed_phy *fp)
+ {
+-	u16 *regs = fixed->regs;
+-	u16 bmsr = 0;
++	u16 bmsr = BMSR_ANEGCAPABLE;
+ 	u16 bmcr = 0;
++	u16 lpagb = 0;
++	u16 lpa = 0;
+ 
+-	if (!regs) {
+-		printk(KERN_ERR "%s: regs not set up", __FUNCTION__);
+-		return -EINVAL;
+-	}
+-
+-	if (fixed->phy_status.link)
+-		bmsr |= BMSR_LSTATUS;
+-
+-	if (fixed->phy_status.duplex) {
++	if (fp->status.duplex) {
+ 		bmcr |= BMCR_FULLDPLX;
+ 
+-		switch (fixed->phy_status.speed) {
++		switch (fp->status.speed) {
++		case 1000:
++			bmsr |= BMSR_ESTATEN;
++			bmcr |= BMCR_SPEED1000;
++			lpagb |= LPA_1000FULL;
++			break;
+ 		case 100:
+ 			bmsr |= BMSR_100FULL;
+ 			bmcr |= BMCR_SPEED100;
++			lpa |= LPA_100FULL;
+ 			break;
+-
+ 		case 10:
+ 			bmsr |= BMSR_10FULL;
++			lpa |= LPA_10FULL;
+ 			break;
++		default:
++			printk(KERN_WARNING "fixed phy: unknown speed\n");
++			return -EINVAL;
+ 		}
+ 	} else {
+-		switch (fixed->phy_status.speed) {
++		switch (fp->status.speed) {
++		case 1000:
++			bmsr |= BMSR_ESTATEN;
++			bmcr |= BMCR_SPEED1000;
++			lpagb |= LPA_1000HALF;
++			break;
+ 		case 100:
+ 			bmsr |= BMSR_100HALF;
+ 			bmcr |= BMCR_SPEED100;
++			lpa |= LPA_100HALF;
+ 			break;
+-
+ 		case 10:
+-			bmsr |= BMSR_100HALF;
++			bmsr |= BMSR_10HALF;
++			lpa |= LPA_10HALF;
+ 			break;
++		default:
++			printk(KERN_WARNING "fixed phy: unknown speed\n");
++			return -EINVAL;
+ 		}
+ 	}
+ 
+-	regs[MII_BMCR] = bmcr;
+-	regs[MII_BMSR] = bmsr | 0x800;	/*we are always capable of 10 hdx */
++	if (fp->status.link)
++		bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
++
++	if (fp->status.pause)
++		lpa |= LPA_PAUSE_CAP;
++
++	if (fp->status.asym_pause)
++		lpa |= LPA_PAUSE_ASYM;
++
++	fp->regs[MII_PHYSID1] = fp->id >> 16;
++	fp->regs[MII_PHYSID2] = fp->id;
++
++	fp->regs[MII_BMSR] = bmsr;
++	fp->regs[MII_BMCR] = bmcr;
++	fp->regs[MII_LPA] = lpa;
++	fp->regs[MII_STAT1000] = lpagb;
+ 
+ 	return 0;
+ }
+ 
+-static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location)
++static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num)
+ {
+-	struct fixed_info *fixed = bus->priv;
++	struct fixed_mdio_bus *fmb = container_of(bus, struct fixed_mdio_bus,
++						  mii_bus);
++	struct fixed_phy *fp;
+ 
+-	/* if user has registered link update callback, use it */
+-	if (fixed->phydev)
+-		if (fixed->phydev->attached_dev) {
+-			if (fixed->link_update) {
+-				fixed->link_update(fixed->phydev->attached_dev,
+-						   &fixed->phy_status);
+-				fixed_mdio_update_regs(fixed);
++	if (reg_num >= MII_REGS_NUM)
++		return -1;
++
++	list_for_each_entry(fp, &fmb->phys, node) {
++		if (fp->id == phy_id) {
++			/* Issue callback if user registered it. */
++			if (fp->link_update) {
++				fp->link_update(fp->phydev->attached_dev,
++						&fp->status);
++				fixed_phy_update_regs(fp);
+ 			}
++			return fp->regs[reg_num];
+ 		}
++	}
+ 
+-	if ((unsigned int)location >= fixed->regs_num)
+-		return -1;
+-	return fixed->regs[location];
++	return 0xFFFF;
+ }
+ 
+-static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location,
+-			   u16 val)
++static int fixed_mdio_write(struct mii_bus *bus, int phy_id, int reg_num,
++			    u16 val)
+ {
+-	/* do nothing for now */
+ 	return 0;
+ }
+ 
+-static int fixed_mii_reset(struct mii_bus *bus)
++/*
++ * If something weird is required to be done with link/speed,
++ * network driver is able to assign a function to implement this.
++ * May be useful for PHY's that need to be software-driven.
++ */
++int fixed_phy_set_link_update(struct phy_device *phydev,
++			      int (*link_update)(struct net_device *,
++						 struct fixed_phy_status *))
+ {
+-	/*nothing here - no way/need to reset it */
+-	return 0;
+-}
+-#endif
++	struct fixed_mdio_bus *fmb = &platform_fmb;
++	struct fixed_phy *fp;
+ 
+-static int fixed_config_aneg(struct phy_device *phydev)
+-{
+-	/* :TODO:03/13/2006 09:45:37 PM::
+-	   The full autoneg funcionality can be emulated,
+-	   but no need to have anything here for now
+-	 */
+-	return 0;
+-}
++	if (!link_update || !phydev || !phydev->bus)
++		return -EINVAL;
+ 
+-/*-----------------------------------------------------------------------------
+- * the manual bind will do the magic - with phy_id_mask == 0
+- * match will never return true...
+- *-----------------------------------------------------------------------------*/
+-static struct phy_driver fixed_mdio_driver = {
+-	.name = "Fixed PHY",
+-#ifdef CONFIG_FIXED_MII_1000_FDX
+-	.features = PHY_GBIT_FEATURES,
+-#else
+-	.features = PHY_BASIC_FEATURES,
+-#endif
+-	.config_aneg = fixed_config_aneg,
+-	.read_status = genphy_read_status,
+-	.driver = { .owner = THIS_MODULE, },
+-};
++	list_for_each_entry(fp, &fmb->phys, node) {
++		if (fp->id == phydev->phy_id) {
++			fp->link_update = link_update;
++			fp->phydev = phydev;
++			return 0;
++		}
++	}
+ 
+-static void fixed_mdio_release(struct device *dev)
+-{
+-	struct phy_device *phydev = container_of(dev, struct phy_device, dev);
+-	struct mii_bus *bus = phydev->bus;
+-	struct fixed_info *fixed = bus->priv;
+-
+-	kfree(phydev);
+-	kfree(bus->dev);
+-	kfree(bus);
+-	kfree(fixed->regs);
+-	kfree(fixed);
++	return -ENOENT;
+ }
++EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
+ 
+-/*-----------------------------------------------------------------------------
+- *  This func is used to create all the necessary stuff, bind
+- * the fixed phy driver and register all it on the mdio_bus_type.
+- * speed is either 10 or 100 or 1000, duplex is boolean.
+- * number is used to create multiple fixed PHYs, so that several devices can
+- * utilize them simultaneously.
+- *
+- * The device on mdio bus will look like [bus_id]:[phy_id],
+- * bus_id = number
+- * phy_id = speed+duplex.
+- *-----------------------------------------------------------------------------*/
+-#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX)
+-struct fixed_info *fixed_mdio_register_device(
+-	int bus_id, int speed, int duplex, u8 phy_id)
++int fixed_phy_add(unsigned int irq, int phy_id,
++		  struct fixed_phy_status *status)
+ {
+-	struct mii_bus *new_bus;
+-	struct fixed_info *fixed;
+-	struct phy_device *phydev;
+-	int err;
++	int ret;
++	struct fixed_mdio_bus *fmb = &platform_fmb;
++	struct fixed_phy *fp;
+ 
+-	struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL);
++	fp = kzalloc(sizeof(*fp), GFP_KERNEL);
++	if (!fp)
++		return -ENOMEM;
+ 
+-	if (dev == NULL)
+-		goto err_dev_alloc;
++	memset(fp->regs, 0xFF,  sizeof(fp->regs[0]) * MII_REGS_NUM);
+ 
+-	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
++	fmb->irqs[phy_id] = irq;
+ 
+-	if (new_bus == NULL)
+-		goto err_bus_alloc;
+-
+-	fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL);
+-
+-	if (fixed == NULL)
+-		goto err_fixed_alloc;
+-
+-	fixed->regs = kzalloc(MII_REGS_NUM * sizeof(int), GFP_KERNEL);
+-	if (NULL == fixed->regs)
+-		goto err_fixed_regs_alloc;
+-
+-	fixed->regs_num = MII_REGS_NUM;
+-	fixed->phy_status.speed = speed;
+-	fixed->phy_status.duplex = duplex;
+-	fixed->phy_status.link = 1;
+-
+-	new_bus->name = "Fixed MII Bus";
+-	new_bus->read = &fixed_mii_read;
+-	new_bus->write = &fixed_mii_write;
+-	new_bus->reset = &fixed_mii_reset;
+-	/*set up workspace */
+-	fixed_mdio_update_regs(fixed);
+-	new_bus->priv = fixed;
+-
+-	new_bus->dev = dev;
+-	dev_set_drvdata(dev, new_bus);
+-
+-	/* create phy_device and register it on the mdio bus */
+-	phydev = phy_device_create(new_bus, 0, 0);
+-	if (phydev == NULL)
+-		goto err_phy_dev_create;
+-
+-	/*
+-	 * Put the phydev pointer into the fixed pack so that bus read/write
+-	 * code could be able to access for instance attached netdev. Well it
+-	 * doesn't have to do so, only in case of utilizing user-specified
+-	 * link-update...
+-	 */
+-
+-	fixed->phydev = phydev;
+-	phydev->speed = speed;
+-	phydev->duplex = duplex;
+-
+-	phydev->irq = PHY_IGNORE_INTERRUPT;
+-	phydev->dev.bus = &mdio_bus_type;
+-
+-	snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
+-		 PHY_ID_FMT, bus_id, phy_id);
+-
+-	phydev->bus = new_bus;
+-
+-	phydev->dev.driver = &fixed_mdio_driver.driver;
+-	phydev->dev.release = fixed_mdio_release;
+-	err = phydev->dev.driver->probe(&phydev->dev);
+-	if (err < 0) {
+-		printk(KERN_ERR "Phy %s: problems with fixed driver\n",
+-		       phydev->dev.bus_id);
+-		goto err_out;
+-	}
+-	err = device_register(&phydev->dev);
+-	if (err) {
+-		printk(KERN_ERR "Phy %s failed to register\n",
+-		       phydev->dev.bus_id);
+-		goto err_out;
+-	}
+-	//phydev->state = PHY_RUNNING; /* make phy go up quick, but in 10Mbit/HDX
+-	return fixed;
++	fp->id = phy_id;
++	fp->status = *status;
+ 
+-err_out:
+-	kfree(phydev);
+-err_phy_dev_create:
+-	kfree(fixed->regs);
+-err_fixed_regs_alloc:
+-	kfree(fixed);
+-err_fixed_alloc:
+-	kfree(new_bus);
+-err_bus_alloc:
+-	kfree(dev);
+-err_dev_alloc:
++	ret = fixed_phy_update_regs(fp);
++	if (ret)
++		goto err_regs;
+ 
+-	return NULL;
++	list_add_tail(&fp->node, &fmb->phys);
+ 
+-}
+-#endif
++	return 0;
+ 
+-MODULE_DESCRIPTION("Fixed PHY device & driver for PAL");
+-MODULE_AUTHOR("Vitaly Bordug");
+-MODULE_LICENSE("GPL");
++err_regs:
++	kfree(fp);
++	return ret;
++}
++EXPORT_SYMBOL_GPL(fixed_phy_add);
+ 
+-static int __init fixed_init(void)
++static int __init fixed_mdio_bus_init(void)
+ {
+-	int cnt = 0;
+-	int i;
+-/* register on the bus... Not expected to be matched
+- * with anything there...
+- *
+- */
+-	phy_driver_register(&fixed_mdio_driver);
++	struct fixed_mdio_bus *fmb = &platform_fmb;
++	int ret;
+ 
+-/* We will create several mdio devices here, and will bound the upper
+- * driver to them.
+- *
+- * Then the external software can lookup the phy bus by searching
+- * for 0:101, to be connected to the virtual 100M Fdx phy.
+- *
+- * In case several virtual PHYs required, the bus_id will be in form
+- * [num]:[duplex]+[speed], which make it able even to define
+- * driver-specific link control callback, if for instance PHY is
+- * completely SW-driven.
+- */
+-	for (i=1; i <= CONFIG_FIXED_MII_AMNT; i++) {
+-#ifdef CONFIG_FIXED_MII_1000_FDX
+-		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(0, 1000, 1, i);
+-#endif
+-#ifdef CONFIG_FIXED_MII_100_FDX
+-		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(1, 100, 1, i);
+-#endif
+-#ifdef CONFIG_FIXED_MII_10_FDX
+-		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(2, 10, 1, i);
+-#endif
++	pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
++	if (!pdev) {
++		ret = -ENOMEM;
++		goto err_pdev;
+ 	}
+ 
++	fmb->mii_bus.id = 0;
++	fmb->mii_bus.name = "Fixed MDIO Bus";
++	fmb->mii_bus.dev = &pdev->dev;
++	fmb->mii_bus.read = &fixed_mdio_read;
++	fmb->mii_bus.write = &fixed_mdio_write;
++	fmb->mii_bus.irq = fmb->irqs;
++
++	ret = mdiobus_register(&fmb->mii_bus);
++	if (ret)
++		goto err_mdiobus_reg;
++
+ 	return 0;
++
++err_mdiobus_reg:
++	platform_device_unregister(pdev);
++err_pdev:
++	return ret;
+ }
++module_init(fixed_mdio_bus_init);
+ 
+-static void __exit fixed_exit(void)
++static void __exit fixed_mdio_bus_exit(void)
+ {
+-	int i;
++	struct fixed_mdio_bus *fmb = &platform_fmb;
++	struct fixed_phy *fp;
+ 
+-	phy_driver_unregister(&fixed_mdio_driver);
+-	for (i=0; i < MAX_PHY_AMNT; i++)
+-		if ( fixed_phy_ptrs[i] )
+-			device_unregister(&fixed_phy_ptrs[i]->phydev->dev);
++	mdiobus_unregister(&fmb->mii_bus);
++	platform_device_unregister(pdev);
++
++	list_for_each_entry(fp, &fmb->phys, node) {
++		list_del(&fp->node);
++		kfree(fp);
++	}
+ }
++module_exit(fixed_mdio_bus_exit);
+ 
+-module_init(fixed_init);
+-module_exit(fixed_exit);
++MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)");
++MODULE_AUTHOR("Vitaly Bordug");
++MODULE_LICENSE("GPL");
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/net/ps3_gelic_net.c powerpc.git/drivers/net/ps3_gelic_net.c
+--- linux-2.6.24/drivers/net/ps3_gelic_net.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/net/ps3_gelic_net.c	2008-01-28 20:26:14.000000000 +0100
+@@ -58,11 +58,11 @@
+ {
+ 	return &card->dev->core;
+ }
+-static inline unsigned int bus_id(struct gelic_net_card *card)
++static inline u64 bus_id(struct gelic_net_card *card)
+ {
+ 	return card->dev->bus_id;
+ }
+-static inline unsigned int dev_id(struct gelic_net_card *card)
++static inline u64 dev_id(struct gelic_net_card *card)
+ {
+ 	return card->dev->dev_id;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/net/ucc_geth.c powerpc.git/drivers/net/ucc_geth.c
+--- linux-2.6.24/drivers/net/ucc_geth.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/net/ucc_geth.c	2008-01-28 20:26:14.000000000 +0100
+@@ -3822,6 +3822,7 @@
+ 	int err, ucc_num, max_speed = 0;
+ 	const phandle *ph;
+ 	const unsigned int *prop;
++	const char *sprop;
+ 	const void *mac_addr;
+ 	phy_interface_t phy_interface;
+ 	static const int enet_to_speed[] = {
+@@ -3854,10 +3855,56 @@
+ 
+ 	ug_info->uf_info.ucc_num = ucc_num;
+ 
+-	prop = of_get_property(np, "rx-clock", NULL);
+-	ug_info->uf_info.rx_clock = *prop;
+-	prop = of_get_property(np, "tx-clock", NULL);
+-	ug_info->uf_info.tx_clock = *prop;
++	sprop = of_get_property(np, "rx-clock-name", NULL);
++	if (sprop) {
++		ug_info->uf_info.rx_clock = qe_clock_source(sprop);
++		if ((ug_info->uf_info.rx_clock < QE_CLK_NONE) ||
++		    (ug_info->uf_info.rx_clock > QE_CLK24)) {
++			printk(KERN_ERR
++				"ucc_geth: invalid rx-clock-name property\n");
++			return -EINVAL;
++		}
++	} else {
++		prop = of_get_property(np, "rx-clock", NULL);
++		if (!prop) {
++			/* If both rx-clock-name and rx-clock are missing,
++			   we want to tell people to use rx-clock-name. */
++			printk(KERN_ERR
++				"ucc_geth: missing rx-clock-name property\n");
++			return -EINVAL;
++		}
++		if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
++			printk(KERN_ERR
++				"ucc_geth: invalid rx-clock propperty\n");
++			return -EINVAL;
++		}
++		ug_info->uf_info.rx_clock = *prop;
++	}
++
++	sprop = of_get_property(np, "tx-clock-name", NULL);
++	if (sprop) {
++		ug_info->uf_info.tx_clock = qe_clock_source(sprop);
++		if ((ug_info->uf_info.tx_clock < QE_CLK_NONE) ||
++		    (ug_info->uf_info.tx_clock > QE_CLK24)) {
++			printk(KERN_ERR
++				"ucc_geth: invalid tx-clock-name property\n");
++			return -EINVAL;
++		}
++	} else {
++		prop = of_get_property(np, "rx-clock", NULL);
++		if (!prop) {
++			printk(KERN_ERR
++				"ucc_geth: mising tx-clock-name property\n");
++			return -EINVAL;
++		}
++		if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
++			printk(KERN_ERR
++				"ucc_geth: invalid tx-clock property\n");
++			return -EINVAL;
++		}
++		ug_info->uf_info.tx_clock = *prop;
++	}
++
+ 	err = of_address_to_resource(np, 0, &res);
+ 	if (err)
+ 		return -EINVAL;
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/of/base.c powerpc.git/drivers/of/base.c
+--- linux-2.6.24/drivers/of/base.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/of/base.c	2008-01-28 20:26:17.000000000 +0100
+@@ -273,3 +273,61 @@
+ 	return np;
+ }
+ EXPORT_SYMBOL(of_find_compatible_node);
++
++/**
++ * of_match_node - Tell if an device_node has a matching of_match structure
++ *	@matches:	array of of device match structures to search in
++ *	@node:		the of device structure to match against
++ *
++ *	Low level utility function used by device matching.
++ */
++const struct of_device_id *of_match_node(const struct of_device_id *matches,
++					 const struct device_node *node)
++{
++	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
++		int match = 1;
++		if (matches->name[0])
++			match &= node->name
++				&& !strcmp(matches->name, node->name);
++		if (matches->type[0])
++			match &= node->type
++				&& !strcmp(matches->type, node->type);
++		if (matches->compatible[0])
++			match &= of_device_is_compatible(node,
++						matches->compatible);
++		if (match)
++			return matches;
++		matches++;
++	}
++	return NULL;
++}
++EXPORT_SYMBOL(of_match_node);
++
++/**
++ *	of_find_matching_node - Find a node based on an of_device_id match
++ *				table.
++ *	@from:		The node to start searching from or NULL, the node
++ *			you pass will not be searched, only the next one
++ *			will; typically, you pass what the previous call
++ *			returned. of_node_put() will be called on it
++ *	@matches:	array of of device match structures to search in
++ *
++ *	Returns a node pointer with refcount incremented, use
++ *	of_node_put() on it when done.
++ */
++struct device_node *of_find_matching_node(struct device_node *from,
++					  const struct of_device_id *matches)
++{
++	struct device_node *np;
++
++	read_lock(&devtree_lock);
++	np = from ? from->allnext : allnodes;
++	for (; np; np = np->allnext) {
++		if (of_match_node(matches, np) && of_node_get(np))
++			break;
++	}
++	of_node_put(from);
++	read_unlock(&devtree_lock);
++	return np;
++}
++EXPORT_SYMBOL(of_find_matching_node);
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/of/device.c powerpc.git/drivers/of/device.c
+--- linux-2.6.24/drivers/of/device.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/of/device.c	2008-01-28 20:26:17.000000000 +0100
+@@ -10,35 +10,6 @@
+ #include <asm/errno.h>
+ 
+ /**
+- * of_match_node - Tell if an device_node has a matching of_match structure
+- * @ids: array of of device match structures to search in
+- * @node: the of device structure to match against
+- *
+- * Low level utility function used by device matching.
+- */
+-const struct of_device_id *of_match_node(const struct of_device_id *matches,
+-					 const struct device_node *node)
+-{
+-	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
+-		int match = 1;
+-		if (matches->name[0])
+-			match &= node->name
+-				&& !strcmp(matches->name, node->name);
+-		if (matches->type[0])
+-			match &= node->type
+-				&& !strcmp(matches->type, node->type);
+-		if (matches->compatible[0])
+-			match &= of_device_is_compatible(node,
+-						matches->compatible);
+-		if (match)
+-			return matches;
+-		matches++;
+-	}
+-	return NULL;
+-}
+-EXPORT_SYMBOL(of_match_node);
+-
+-/**
+  * of_match_device - Tell if an of_device structure has a matching
+  * of_match structure
+  * @ids: array of of device match structures to search in
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/ps3/Makefile powerpc.git/drivers/ps3/Makefile
+--- linux-2.6.24/drivers/ps3/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/ps3/Makefile	2008-01-28 20:26:18.000000000 +0100
+@@ -4,3 +4,4 @@
+ obj-$(CONFIG_PPC_PS3) += sys-manager-core.o
+ obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o
+ obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o
++obj-$(CONFIG_PS3_LPM) += ps3-lpm.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/ps3/ps3-lpm.c powerpc.git/drivers/ps3/ps3-lpm.c
+--- linux-2.6.24/drivers/ps3/ps3-lpm.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/drivers/ps3/ps3-lpm.c	2008-01-28 20:26:18.000000000 +0100
+@@ -0,0 +1,1248 @@
++/*
++ * PS3 Logical Performance Monitor.
++ *
++ *  Copyright (C) 2007 Sony Computer Entertainment Inc.
++ *  Copyright 2007 Sony Corp.
++ *
++ *  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; version 2 of the License.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/uaccess.h>
++#include <asm/ps3.h>
++#include <asm/lv1call.h>
++#include <asm/cell-pmu.h>
++
++
++/* BOOKMARK tag macros */
++#define PS3_PM_BOOKMARK_START                    0x8000000000000000ULL
++#define PS3_PM_BOOKMARK_STOP                     0x4000000000000000ULL
++#define PS3_PM_BOOKMARK_TAG_KERNEL               0x1000000000000000ULL
++#define PS3_PM_BOOKMARK_TAG_USER                 0x3000000000000000ULL
++#define PS3_PM_BOOKMARK_TAG_MASK_HI              0xF000000000000000ULL
++#define PS3_PM_BOOKMARK_TAG_MASK_LO              0x0F00000000000000ULL
++
++/* CBE PM CONTROL register macros */
++#define PS3_PM_CONTROL_PPU_TH0_BOOKMARK          0x00001000
++#define PS3_PM_CONTROL_PPU_TH1_BOOKMARK          0x00000800
++#define PS3_PM_CONTROL_PPU_COUNT_MODE_MASK       0x000C0000
++#define PS3_PM_CONTROL_PPU_COUNT_MODE_PROBLEM    0x00080000
++#define PS3_WRITE_PM_MASK                        0xFFFFFFFFFFFFFFFFULL
++
++/* CBE PM START STOP register macros */
++#define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START 0x02000000
++#define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START 0x01000000
++#define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP  0x00020000
++#define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP  0x00010000
++#define PS3_PM_START_STOP_START_MASK             0xFF000000
++#define PS3_PM_START_STOP_STOP_MASK              0x00FF0000
++
++/* CBE PM COUNTER register macres */
++#define PS3_PM_COUNTER_MASK_HI                   0xFFFFFFFF00000000ULL
++#define PS3_PM_COUNTER_MASK_LO                   0x00000000FFFFFFFFULL
++
++/* BASE SIGNAL GROUP NUMBER macros */
++#define PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER  0
++#define PM_ISLAND2_SIGNAL_GROUP_NUMBER1      6
++#define PM_ISLAND2_SIGNAL_GROUP_NUMBER2      7
++#define PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER  7
++#define PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER  15
++#define PM_SPU_TRIGGER_SIGNAL_GROUP_NUMBER   17
++#define PM_SPU_EVENT_SIGNAL_GROUP_NUMBER     18
++#define PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER  18
++#define PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER  24
++#define PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER  49
++#define PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER  52
++#define PM_SIG_GROUP_SPU                     41
++#define PM_SIG_GROUP_SPU_TRIGGER             42
++#define PM_SIG_GROUP_SPU_EVENT               43
++#define PM_SIG_GROUP_MFC_MAX                 60
++
++/**
++ * struct ps3_lpm_shadow_regs - Performance monitor shadow registers.
++ *
++ * @pm_control: Shadow of the processor's pm_control register.
++ * @pm_start_stop: Shadow of the processor's pm_start_stop register.
++ * @pm_interval: Shadow of the processor's pm_interval register.
++ * @group_control: Shadow of the processor's group_control register.
++ * @debug_bus_control: Shadow of the processor's debug_bus_control register.
++ *
++ * The logical performance monitor provides a write-only interface to
++ * these processor registers.  These shadow variables cache the processor
++ * register values for reading.
++ *
++ * The initial value of the shadow registers at lpm creation is
++ * PS3_LPM_SHADOW_REG_INIT.
++ */
++
++struct ps3_lpm_shadow_regs {
++	u64 pm_control;
++	u64 pm_start_stop;
++	u64 pm_interval;
++	u64 group_control;
++	u64 debug_bus_control;
++};
++
++#define PS3_LPM_SHADOW_REG_INIT 0xFFFFFFFF00000000ULL
++
++/**
++ * struct ps3_lpm_priv - Private lpm device data.
++ *
++ * @open: An atomic variable indicating the lpm driver has been opened.
++ * @rights: The lpm rigths granted by the system policy module.  A logical
++ *  OR of enum ps3_lpm_rights.
++ * @node_id: The node id of a BE prosessor whose performance monitor this
++ *  lpar has the right to use.
++ * @pu_id: The lv1 id of the logical PU.
++ * @lpm_id: The lv1 id of this lpm instance.
++ * @outlet_id: The outlet created by lv1 for this lpm instance.
++ * @tb_count: The number of bytes of data held in the lv1 trace buffer.
++ * @tb_cache: Kernel buffer to receive the data from the lv1 trace buffer.
++ *  Must be 128 byte aligned.
++ * @tb_cache_size: Size of the kernel @tb_cache buffer.  Must be 128 byte
++ *  aligned.
++ * @tb_cache_internal: An unaligned buffer allocated by this driver to be
++ *  used for the trace buffer cache when ps3_lpm_open() is called with a
++ *  NULL tb_cache argument.  Otherwise unused.
++ * @shadow: Processor register shadow of type struct ps3_lpm_shadow_regs.
++ * @sbd: The struct ps3_system_bus_device attached to this driver.
++ *
++ * The trace buffer is a buffer allocated and used internally to the lv1
++ * hypervisor to collect trace data.  The trace buffer cache is a guest
++ * buffer that accepts the trace data from the trace buffer.
++ */
++
++struct ps3_lpm_priv {
++	atomic_t open;
++	u64 rights;
++	u64 node_id;
++	u64 pu_id;
++	u64 lpm_id;
++	u64 outlet_id;
++	u64 tb_count;
++	void *tb_cache;
++	u64 tb_cache_size;
++	void *tb_cache_internal;
++	struct ps3_lpm_shadow_regs shadow;
++	struct ps3_system_bus_device *sbd;
++};
++
++enum {
++	PS3_LPM_DEFAULT_TB_CACHE_SIZE = 0x4000,
++};
++
++/**
++ * lpm_priv - Static instance of the lpm data.
++ *
++ * Since the exported routines don't support the notion of a device
++ * instance we need to hold the instance in this static variable
++ * and then only allow at most one instance at a time to be created.
++ */
++
++static struct ps3_lpm_priv *lpm_priv;
++
++static struct device *sbd_core(void)
++{
++	BUG_ON(!lpm_priv || !lpm_priv->sbd);
++	return &lpm_priv->sbd->core;
++}
++
++/**
++ * use_start_stop_bookmark - Enable the PPU bookmark trace.
++ *
++ * And it enables PPU bookmark triggers ONLY if the other triggers are not set.
++ * The start/stop bookmarks are inserted at ps3_enable_pm() and ps3_disable_pm()
++ * to start/stop LPM.
++ *
++ * Used to get good quality of the performance counter.
++ */
++
++enum {use_start_stop_bookmark = 1,};
++
++void ps3_set_bookmark(u64 bookmark)
++{
++	/*
++	 * As per the PPE book IV, to avoid bookmark loss there must
++	 * not be a traced branch within 10 cycles of setting the
++	 * SPRN_BKMK register.  The actual text is unclear if 'within'
++	 * includes cycles before the call.
++	 */
++
++	asm volatile("or 29, 29, 29;"); /* db10cyc */
++	mtspr(SPRN_BKMK, bookmark);
++	asm volatile("or 29, 29, 29;"); /* db10cyc */
++}
++EXPORT_SYMBOL_GPL(ps3_set_bookmark);
++
++void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id)
++{
++	u64 bookmark;
++
++	bookmark = (get_tb() & 0x00000000FFFFFFFFULL) |
++		PS3_PM_BOOKMARK_TAG_KERNEL;
++	bookmark = ((tag << 56) & PS3_PM_BOOKMARK_TAG_MASK_LO) |
++		(incident << 48) | (th_id << 32) | bookmark;
++	ps3_set_bookmark(bookmark);
++}
++EXPORT_SYMBOL_GPL(ps3_set_pm_bookmark);
++
++/**
++ * ps3_read_phys_ctr - Read physical counter registers.
++ *
++ * Each physical counter can act as one 32 bit counter or as two 16 bit
++ * counters.
++ */
++
++u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr)
++{
++	int result;
++	u64 counter0415;
++	u64 counter2637;
++
++	if (phys_ctr >= NR_PHYS_CTRS) {
++		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
++			__LINE__, phys_ctr);
++		return 0;
++	}
++
++	result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415,
++				     &counter2637);
++	if (result) {
++		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
++			"phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr,
++			ps3_result(result));
++		return 0;
++	}
++
++	switch (phys_ctr) {
++	case 0:
++		return counter0415 >> 32;
++	case 1:
++		return counter0415 & PS3_PM_COUNTER_MASK_LO;
++	case 2:
++		return counter2637 >> 32;
++	case 3:
++		return counter2637 & PS3_PM_COUNTER_MASK_LO;
++	default:
++		BUG();
++	}
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ps3_read_phys_ctr);
++
++/**
++ * ps3_write_phys_ctr - Write physical counter registers.
++ *
++ * Each physical counter can act as one 32 bit counter or as two 16 bit
++ * counters.
++ */
++
++void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val)
++{
++	u64 counter0415;
++	u64 counter0415_mask;
++	u64 counter2637;
++	u64 counter2637_mask;
++	int result;
++
++	if (phys_ctr >= NR_PHYS_CTRS) {
++		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
++			__LINE__, phys_ctr);
++		return;
++	}
++
++	switch (phys_ctr) {
++	case 0:
++		counter0415 = (u64)val << 32;
++		counter0415_mask = PS3_PM_COUNTER_MASK_HI;
++		counter2637 = 0x0;
++		counter2637_mask = 0x0;
++		break;
++	case 1:
++		counter0415 = (u64)val;
++		counter0415_mask = PS3_PM_COUNTER_MASK_LO;
++		counter2637 = 0x0;
++		counter2637_mask = 0x0;
++		break;
++	case 2:
++		counter0415 = 0x0;
++		counter0415_mask = 0x0;
++		counter2637 = (u64)val << 32;
++		counter2637_mask = PS3_PM_COUNTER_MASK_HI;
++		break;
++	case 3:
++		counter0415 = 0x0;
++		counter0415_mask = 0x0;
++		counter2637 = (u64)val;
++		counter2637_mask = PS3_PM_COUNTER_MASK_LO;
++		break;
++	default:
++		BUG();
++	}
++
++	result = lv1_set_lpm_counter(lpm_priv->lpm_id,
++				     counter0415, counter0415_mask,
++				     counter2637, counter2637_mask,
++				     &counter0415, &counter2637);
++	if (result)
++		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
++			"phys_ctr %u, val %u, %s\n", __func__, __LINE__,
++			phys_ctr, val, ps3_result(result));
++}
++EXPORT_SYMBOL_GPL(ps3_write_phys_ctr);
++
++/**
++ * ps3_read_ctr - Read counter.
++ *
++ * Read 16 or 32 bits depending on the current size of the counter.
++ * Counters 4, 5, 6 & 7 are always 16 bit.
++ */
++
++u32 ps3_read_ctr(u32 cpu, u32 ctr)
++{
++	u32 val;
++	u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1);
++
++	val = ps3_read_phys_ctr(cpu, phys_ctr);
++
++	if (ps3_get_ctr_size(cpu, phys_ctr) == 16)
++		val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff);
++
++	return val;
++}
++EXPORT_SYMBOL_GPL(ps3_read_ctr);
++
++/**
++ * ps3_write_ctr - Write counter.
++ *
++ * Write 16 or 32 bits depending on the current size of the counter.
++ * Counters 4, 5, 6 & 7 are always 16 bit.
++ */
++
++void ps3_write_ctr(u32 cpu, u32 ctr, u32 val)
++{
++	u32 phys_ctr;
++	u32 phys_val;
++
++	phys_ctr = ctr & (NR_PHYS_CTRS - 1);
++
++	if (ps3_get_ctr_size(cpu, phys_ctr) == 16) {
++		phys_val = ps3_read_phys_ctr(cpu, phys_ctr);
++
++		if (ctr < NR_PHYS_CTRS)
++			val = (val << 16) | (phys_val & 0xffff);
++		else
++			val = (val & 0xffff) | (phys_val & 0xffff0000);
++	}
++
++	ps3_write_phys_ctr(cpu, phys_ctr, val);
++}
++EXPORT_SYMBOL_GPL(ps3_write_ctr);
++
++/**
++ * ps3_read_pm07_control - Read counter control registers.
++ *
++ * Each logical counter has a corresponding control register.
++ */
++
++u32 ps3_read_pm07_control(u32 cpu, u32 ctr)
++{
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ps3_read_pm07_control);
++
++/**
++ * ps3_write_pm07_control - Write counter control registers.
++ *
++ * Each logical counter has a corresponding control register.
++ */
++
++void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val)
++{
++	int result;
++	static const u64 mask = 0xFFFFFFFFFFFFFFFFULL;
++	u64 old_value;
++
++	if (ctr >= NR_CTRS) {
++		dev_dbg(sbd_core(), "%s:%u: ctr too big: %u\n", __func__,
++			__LINE__, ctr);
++		return;
++	}
++
++	result = lv1_set_lpm_counter_control(lpm_priv->lpm_id, ctr, val, mask,
++					     &old_value);
++	if (result)
++		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter_control "
++			"failed: ctr %u, %s\n", __func__, __LINE__, ctr,
++			ps3_result(result));
++}
++EXPORT_SYMBOL_GPL(ps3_write_pm07_control);
++
++/**
++ * ps3_read_pm - Read Other LPM control registers.
++ */
++
++u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg)
++{
++	int result = 0;
++	u64 val = 0;
++
++	switch (reg) {
++	case pm_control:
++		return lpm_priv->shadow.pm_control;
++	case trace_address:
++		return CBE_PM_TRACE_BUF_EMPTY;
++	case pm_start_stop:
++		return lpm_priv->shadow.pm_start_stop;
++	case pm_interval:
++		return lpm_priv->shadow.pm_interval;
++	case group_control:
++		return lpm_priv->shadow.group_control;
++	case debug_bus_control:
++		return lpm_priv->shadow.debug_bus_control;
++	case pm_status:
++		result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id,
++						      &val);
++		if (result) {
++			val = 0;
++			dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: "
++				"reg %u, %s\n", __func__, __LINE__, reg,
++				ps3_result(result));
++		}
++		return (u32)val;
++	case ext_tr_timer:
++		return 0;
++	default:
++		dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
++			__LINE__, reg);
++		BUG();
++		break;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ps3_read_pm);
++
++/**
++ * ps3_write_pm - Write Other LPM control registers.
++ */
++
++void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val)
++{
++	int result = 0;
++	u64 dummy;
++
++	switch (reg) {
++	case group_control:
++		if (val != lpm_priv->shadow.group_control)
++			result = lv1_set_lpm_group_control(lpm_priv->lpm_id,
++							   val,
++							   PS3_WRITE_PM_MASK,
++							   &dummy);
++		lpm_priv->shadow.group_control = val;
++		break;
++	case debug_bus_control:
++		if (val != lpm_priv->shadow.debug_bus_control)
++			result = lv1_set_lpm_debug_bus_control(lpm_priv->lpm_id,
++							      val,
++							      PS3_WRITE_PM_MASK,
++							      &dummy);
++		lpm_priv->shadow.debug_bus_control = val;
++		break;
++	case pm_control:
++		if (use_start_stop_bookmark)
++			val |= (PS3_PM_CONTROL_PPU_TH0_BOOKMARK |
++				PS3_PM_CONTROL_PPU_TH1_BOOKMARK);
++		if (val != lpm_priv->shadow.pm_control)
++			result = lv1_set_lpm_general_control(lpm_priv->lpm_id,
++							     val,
++							     PS3_WRITE_PM_MASK,
++							     0, 0, &dummy,
++							     &dummy);
++		lpm_priv->shadow.pm_control = val;
++		break;
++	case pm_interval:
++		if (val != lpm_priv->shadow.pm_interval)
++			result = lv1_set_lpm_interval(lpm_priv->lpm_id, val,
++						   PS3_WRITE_PM_MASK, &dummy);
++		lpm_priv->shadow.pm_interval = val;
++		break;
++	case pm_start_stop:
++		if (val != lpm_priv->shadow.pm_start_stop)
++			result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
++							     val,
++							     PS3_WRITE_PM_MASK,
++							     &dummy);
++		lpm_priv->shadow.pm_start_stop = val;
++		break;
++	case trace_address:
++	case ext_tr_timer:
++	case pm_status:
++		break;
++	default:
++		dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
++			__LINE__, reg);
++		BUG();
++		break;
++	}
++
++	if (result)
++		dev_err(sbd_core(), "%s:%u: lv1 set_control failed: "
++			"reg %u, %s\n", __func__, __LINE__, reg,
++			ps3_result(result));
++}
++EXPORT_SYMBOL_GPL(ps3_write_pm);
++
++/**
++ * ps3_get_ctr_size - Get the size of a physical counter.
++ *
++ * Returns either 16 or 32.
++ */
++
++u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr)
++{
++	u32 pm_ctrl;
++
++	if (phys_ctr >= NR_PHYS_CTRS) {
++		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
++			__LINE__, phys_ctr);
++		return 0;
++	}
++
++	pm_ctrl = ps3_read_pm(cpu, pm_control);
++	return (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32;
++}
++EXPORT_SYMBOL_GPL(ps3_get_ctr_size);
++
++/**
++ * ps3_set_ctr_size - Set the size of a physical counter to 16 or 32 bits.
++ */
++
++void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size)
++{
++	u32 pm_ctrl;
++
++	if (phys_ctr >= NR_PHYS_CTRS) {
++		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
++			__LINE__, phys_ctr);
++		return;
++	}
++
++	pm_ctrl = ps3_read_pm(cpu, pm_control);
++
++	switch (ctr_size) {
++	case 16:
++		pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr);
++		ps3_write_pm(cpu, pm_control, pm_ctrl);
++		break;
++
++	case 32:
++		pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr);
++		ps3_write_pm(cpu, pm_control, pm_ctrl);
++		break;
++	default:
++		BUG();
++	}
++}
++EXPORT_SYMBOL_GPL(ps3_set_ctr_size);
++
++static u64 pm_translate_signal_group_number_on_island2(u64 subgroup)
++{
++
++	if (subgroup == 2)
++		subgroup = 3;
++
++	if (subgroup <= 6)
++		return PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER + subgroup;
++	else if (subgroup == 7)
++		return PM_ISLAND2_SIGNAL_GROUP_NUMBER1;
++	else
++		return PM_ISLAND2_SIGNAL_GROUP_NUMBER2;
++}
++
++static u64 pm_translate_signal_group_number_on_island3(u64 subgroup)
++{
++
++	switch (subgroup) {
++	case 2:
++	case 3:
++	case 4:
++		subgroup += 2;
++		break;
++	case 5:
++		subgroup = 8;
++		break;
++	default:
++		break;
++	}
++	return PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER + subgroup;
++}
++
++static u64 pm_translate_signal_group_number_on_island4(u64 subgroup)
++{
++	return PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER + subgroup;
++}
++
++static u64 pm_translate_signal_group_number_on_island5(u64 subgroup)
++{
++
++	switch (subgroup) {
++	case 3:
++		subgroup = 4;
++		break;
++	case 4:
++		subgroup = 6;
++		break;
++	default:
++		break;
++	}
++	return PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER + subgroup;
++}
++
++static u64 pm_translate_signal_group_number_on_island6(u64 subgroup,
++						       u64 subsubgroup)
++{
++	switch (subgroup) {
++	case 3:
++	case 4:
++	case 5:
++		subgroup += 1;
++		break;
++	default:
++		break;
++	}
++
++	switch (subsubgroup) {
++	case 4:
++	case 5:
++	case 6:
++		subsubgroup += 2;
++		break;
++	case 7:
++	case 8:
++	case 9:
++	case 10:
++		subsubgroup += 4;
++		break;
++	case 11:
++	case 12:
++	case 13:
++		subsubgroup += 5;
++		break;
++	default:
++		break;
++	}
++
++	if (subgroup <= 5)
++		return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup);
++	else
++		return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup
++			+ subsubgroup - 1);
++}
++
++static u64 pm_translate_signal_group_number_on_island7(u64 subgroup)
++{
++	return PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER + subgroup;
++}
++
++static u64 pm_translate_signal_group_number_on_island8(u64 subgroup)
++{
++	return PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER + subgroup;
++}
++
++static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group)
++{
++	u64 island;
++	u64 subgroup;
++	u64 subsubgroup;
++
++	subgroup = 0;
++	subsubgroup = 0;
++	island = 0;
++	if (group < 1000) {
++		if (group < 100) {
++			if (20 <= group && group < 30) {
++				island = 2;
++				subgroup = group - 20;
++			} else if (30 <= group && group < 40) {
++				island = 3;
++				subgroup = group - 30;
++			} else if (40 <= group && group < 50) {
++				island = 4;
++				subgroup = group - 40;
++			} else if (50 <= group && group < 60) {
++				island = 5;
++				subgroup = group - 50;
++			} else if (60 <= group && group < 70) {
++				island = 6;
++				subgroup = group - 60;
++			} else if (70 <= group && group < 80) {
++				island = 7;
++				subgroup = group - 70;
++			} else if (80 <= group && group < 90) {
++				island = 8;
++				subgroup = group - 80;
++			}
++		} else if (200 <= group && group < 300) {
++			island = 2;
++			subgroup = group - 200;
++		} else if (600 <= group && group < 700) {
++			island = 6;
++			subgroup = 5;
++			subsubgroup = group - 650;
++		}
++	} else if (6000 <= group && group < 7000) {
++		island = 6;
++		subgroup = 5;
++		subsubgroup = group - 6500;
++	}
++
++	switch (island) {
++	case 2:
++		return pm_translate_signal_group_number_on_island2(subgroup);
++	case 3:
++		return pm_translate_signal_group_number_on_island3(subgroup);
++	case 4:
++		return pm_translate_signal_group_number_on_island4(subgroup);
++	case 5:
++		return pm_translate_signal_group_number_on_island5(subgroup);
++	case 6:
++		return pm_translate_signal_group_number_on_island6(subgroup,
++								   subsubgroup);
++	case 7:
++		return pm_translate_signal_group_number_on_island7(subgroup);
++	case 8:
++		return pm_translate_signal_group_number_on_island8(subgroup);
++	default:
++		dev_dbg(sbd_core(), "%s:%u: island not found: %lu\n", __func__,
++			__LINE__, group);
++		BUG();
++		break;
++	}
++	return 0;
++}
++
++static u64 pm_bus_word_to_ps3_lv1_bus_word(u8 word)
++{
++
++	switch (word) {
++	case 1:
++		return 0xF000;
++	case 2:
++		return 0x0F00;
++	case 4:
++		return 0x00F0;
++	case 8:
++	default:
++		return 0x000F;
++	}
++}
++
++static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select,
++			    u64 signal_select, u64 attr1, u64 attr2, u64 attr3)
++{
++	int ret;
++
++	ret = lv1_set_lpm_signal(lpm_priv->lpm_id, lv1_signal_group, bus_select,
++				 signal_select, attr1, attr2, attr3);
++	if (ret)
++		dev_err(sbd_core(),
++			"%s:%u: error:%d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
++			__func__, __LINE__, ret, lv1_signal_group, bus_select,
++			signal_select, attr1, attr2, attr3);
++
++	return ret;
++}
++
++int ps3_set_signal(u64 signal_group, u8 signal_bit, u16 sub_unit,
++		   u8 bus_word)
++{
++	int ret;
++	u64 lv1_signal_group;
++	u64 bus_select;
++	u64 signal_select;
++	u64 attr1, attr2, attr3;
++
++	if (signal_group == 0)
++		return __ps3_set_signal(0, 0, 0, 0, 0, 0);
++
++	lv1_signal_group =
++		pm_signal_group_to_ps3_lv1_signal_group(signal_group);
++	bus_select = pm_bus_word_to_ps3_lv1_bus_word(bus_word);
++
++	switch (signal_group) {
++	case PM_SIG_GROUP_SPU_TRIGGER:
++		signal_select = 1;
++		signal_select = signal_select << (63 - signal_bit);
++		break;
++	case PM_SIG_GROUP_SPU_EVENT:
++		signal_select = 1;
++		signal_select = (signal_select << (63 - signal_bit)) | 0x3;
++		break;
++	default:
++		signal_select = 0;
++		break;
++	}
++
++	/*
++	 * 0: physical object.
++	 * 1: logical object.
++	 * This parameter is only used for the PPE and SPE signals.
++	 */
++	attr1 = 1;
++
++	/*
++	 * This parameter is used to specify the target physical/logical
++	 * PPE/SPE object.
++	 */
++	if (PM_SIG_GROUP_SPU <= signal_group &&
++		signal_group < PM_SIG_GROUP_MFC_MAX)
++		attr2 = sub_unit;
++	else
++		attr2 = lpm_priv->pu_id;
++
++	/*
++	 * This parameter is only used for setting the SPE signal.
++	 */
++	attr3 = 0;
++
++	ret = __ps3_set_signal(lv1_signal_group, bus_select, signal_select,
++			       attr1, attr2, attr3);
++	if (ret)
++		dev_err(sbd_core(), "%s:%u: __ps3_set_signal failed: %d\n",
++			__func__, __LINE__, ret);
++
++	return ret;
++}
++EXPORT_SYMBOL_GPL(ps3_set_signal);
++
++u32 ps3_get_hw_thread_id(int cpu)
++{
++	return get_hard_smp_processor_id(cpu);
++}
++EXPORT_SYMBOL_GPL(ps3_get_hw_thread_id);
++
++/**
++ * ps3_enable_pm - Enable the entire performance monitoring unit.
++ *
++ * When we enable the LPM, all pending writes to counters get committed.
++ */
++
++void ps3_enable_pm(u32 cpu)
++{
++	int result;
++	u64 tmp;
++	int insert_bookmark = 0;
++
++	lpm_priv->tb_count = 0;
++
++	if (use_start_stop_bookmark) {
++		if (!(lpm_priv->shadow.pm_start_stop &
++			(PS3_PM_START_STOP_START_MASK
++			| PS3_PM_START_STOP_STOP_MASK))) {
++			result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
++				(PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START |
++				PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START |
++				PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP |
++				PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP),
++				0xFFFFFFFFFFFFFFFFULL, &tmp);
++
++			if (result)
++				dev_err(sbd_core(), "%s:%u: "
++					"lv1_set_lpm_trigger_control failed: "
++					"%s\n", __func__, __LINE__,
++					ps3_result(result));
++
++			insert_bookmark = !result;
++		}
++	}
++
++	result = lv1_start_lpm(lpm_priv->lpm_id);
++
++	if (result)
++		dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n",
++			__func__, __LINE__, ps3_result(result));
++
++	if (use_start_stop_bookmark && !result && insert_bookmark)
++		ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START);
++}
++EXPORT_SYMBOL_GPL(ps3_enable_pm);
++
++/**
++ * ps3_disable_pm - Disable the entire performance monitoring unit.
++ */
++
++void ps3_disable_pm(u32 cpu)
++{
++	int result;
++	u64 tmp;
++
++	ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_STOP);
++
++	result = lv1_stop_lpm(lpm_priv->lpm_id, &tmp);
++
++	if (result) {
++		if(result != LV1_WRONG_STATE)
++			dev_err(sbd_core(), "%s:%u: lv1_stop_lpm failed: %s\n",
++				__func__, __LINE__, ps3_result(result));
++		return;
++	}
++
++	lpm_priv->tb_count = tmp;
++
++	dev_dbg(sbd_core(), "%s:%u: tb_count %lu (%lxh)\n", __func__, __LINE__,
++		lpm_priv->tb_count, lpm_priv->tb_count);
++}
++EXPORT_SYMBOL_GPL(ps3_disable_pm);
++
++/**
++ * ps3_lpm_copy_tb - Copy data from the trace buffer to a kernel buffer.
++ * @offset: Offset in bytes from the start of the trace buffer.
++ * @buf: Copy destination.
++ * @count: Maximum count of bytes to copy.
++ * @bytes_copied: Pointer to a variable that will recieve the number of
++ *  bytes copied to @buf.
++ *
++ * On error @buf will contain any successfully copied trace buffer data
++ * and bytes_copied will be set to the number of bytes successfully copied.
++ */
++
++int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count,
++		    unsigned long *bytes_copied)
++{
++	int result;
++
++	*bytes_copied = 0;
++
++	if (!lpm_priv->tb_cache)
++		return -EPERM;
++
++	if (offset >= lpm_priv->tb_count)
++		return 0;
++
++	count = min(count, lpm_priv->tb_count - offset);
++
++	while (*bytes_copied < count) {
++		const unsigned long request = count - *bytes_copied;
++		u64 tmp;
++
++		result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
++						   request, &tmp);
++		if (result) {
++			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
++				__func__, __LINE__, request, offset);
++
++			dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
++				"failed: %s\n", __func__, __LINE__,
++				ps3_result(result));
++			return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
++		}
++
++		memcpy(buf, lpm_priv->tb_cache, tmp);
++		buf += tmp;
++		*bytes_copied += tmp;
++		offset += tmp;
++	}
++	dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
++		*bytes_copied);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb);
++
++/**
++ * ps3_lpm_copy_tb_to_user - Copy data from the trace buffer to a user buffer.
++ * @offset: Offset in bytes from the start of the trace buffer.
++ * @buf: A __user copy destination.
++ * @count: Maximum count of bytes to copy.
++ * @bytes_copied: Pointer to a variable that will recieve the number of
++ *  bytes copied to @buf.
++ *
++ * On error @buf will contain any successfully copied trace buffer data
++ * and bytes_copied will be set to the number of bytes successfully copied.
++ */
++
++int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
++			    unsigned long count, unsigned long *bytes_copied)
++{
++	int result;
++
++	*bytes_copied = 0;
++
++	if (!lpm_priv->tb_cache)
++		return -EPERM;
++
++	if (offset >= lpm_priv->tb_count)
++		return 0;
++
++	count = min(count, lpm_priv->tb_count - offset);
++
++	while (*bytes_copied < count) {
++		const unsigned long request = count - *bytes_copied;
++		u64 tmp;
++
++		result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
++						   request, &tmp);
++		if (result) {
++			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
++				__func__, __LINE__, request, offset);
++			dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
++				"failed: %s\n", __func__, __LINE__,
++				ps3_result(result));
++			return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
++		}
++
++		result = copy_to_user(buf, lpm_priv->tb_cache, tmp);
++
++		if (result) {
++			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%p\n",
++				__func__, __LINE__, tmp, buf);
++			dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n",
++				__func__, __LINE__, result);
++			return -EFAULT;
++		}
++
++		buf += tmp;
++		*bytes_copied += tmp;
++		offset += tmp;
++	}
++	dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
++		*bytes_copied);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb_to_user);
++
++/**
++ * ps3_get_and_clear_pm_interrupts -
++ *
++ * Clearing interrupts for the entire performance monitoring unit.
++ * Reading pm_status clears the interrupt bits.
++ */
++
++u32 ps3_get_and_clear_pm_interrupts(u32 cpu)
++{
++	return ps3_read_pm(cpu, pm_status);
++}
++EXPORT_SYMBOL_GPL(ps3_get_and_clear_pm_interrupts);
++
++/**
++ * ps3_enable_pm_interrupts -
++ *
++ * Enabling interrupts for the entire performance monitoring unit.
++ * Enables the interrupt bits in the pm_status register.
++ */
++
++void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask)
++{
++	if (mask)
++		ps3_write_pm(cpu, pm_status, mask);
++}
++EXPORT_SYMBOL_GPL(ps3_enable_pm_interrupts);
++
++/**
++ * ps3_enable_pm_interrupts -
++ *
++ * Disabling interrupts for the entire performance monitoring unit.
++ */
++
++void ps3_disable_pm_interrupts(u32 cpu)
++{
++	ps3_get_and_clear_pm_interrupts(cpu);
++	ps3_write_pm(cpu, pm_status, 0);
++}
++EXPORT_SYMBOL_GPL(ps3_disable_pm_interrupts);
++
++/**
++ * ps3_lpm_open - Open the logical performance monitor device.
++ * @tb_type: Specifies the type of trace buffer lv1 sould use for this lpm
++ *  instance, specified by one of enum ps3_lpm_tb_type.
++ * @tb_cache: Optional user supplied buffer to use as the trace buffer cache.
++ *  If NULL, the driver will allocate and manage an internal buffer.
++ *  Unused when when @tb_type is PS3_LPM_TB_TYPE_NONE.
++ * @tb_cache_size: The size in bytes of the user supplied @tb_cache buffer.
++ *  Unused when @tb_cache is NULL or @tb_type is PS3_LPM_TB_TYPE_NONE.
++ */
++
++int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
++	u64 tb_cache_size)
++{
++	int result;
++	u64 tb_size;
++
++	BUG_ON(!lpm_priv);
++	BUG_ON(tb_type != PS3_LPM_TB_TYPE_NONE
++		&& tb_type != PS3_LPM_TB_TYPE_INTERNAL);
++
++	if (tb_type == PS3_LPM_TB_TYPE_NONE && tb_cache)
++		dev_dbg(sbd_core(), "%s:%u: bad in vals\n", __func__, __LINE__);
++
++	if (!atomic_add_unless(&lpm_priv->open, 1, 1)) {
++		dev_dbg(sbd_core(), "%s:%u: busy\n", __func__, __LINE__);
++		return -EBUSY;
++	}
++
++	/* Note tb_cache needs 128 byte alignment. */
++
++	if (tb_type == PS3_LPM_TB_TYPE_NONE) {
++		lpm_priv->tb_cache_size = 0;
++		lpm_priv->tb_cache_internal = NULL;
++		lpm_priv->tb_cache = NULL;
++	} else if (tb_cache) {
++		if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128)
++			|| tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) {
++			dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n",
++				__func__, __LINE__);
++			result = -EINVAL;
++			goto fail_align;
++		}
++		lpm_priv->tb_cache_size = tb_cache_size;
++		lpm_priv->tb_cache_internal = NULL;
++		lpm_priv->tb_cache = tb_cache;
++	} else {
++		lpm_priv->tb_cache_size = PS3_LPM_DEFAULT_TB_CACHE_SIZE;
++		lpm_priv->tb_cache_internal = kzalloc(
++			lpm_priv->tb_cache_size + 127, GFP_KERNEL);
++		if (!lpm_priv->tb_cache_internal) {
++			dev_err(sbd_core(), "%s:%u: alloc internal tb_cache "
++				"failed\n", __func__, __LINE__);
++			result = -ENOMEM;
++			goto fail_malloc;
++		}
++		lpm_priv->tb_cache = (void *)_ALIGN_UP(
++			(unsigned long)lpm_priv->tb_cache_internal, 128);
++	}
++
++	result = lv1_construct_lpm(lpm_priv->node_id, tb_type, 0, 0,
++				ps3_mm_phys_to_lpar(__pa(lpm_priv->tb_cache)),
++				lpm_priv->tb_cache_size, &lpm_priv->lpm_id,
++				&lpm_priv->outlet_id, &tb_size);
++
++	if (result) {
++		dev_err(sbd_core(), "%s:%u: lv1_construct_lpm failed: %s\n",
++			__func__, __LINE__, ps3_result(result));
++		result = -EINVAL;
++		goto fail_construct;
++	}
++
++	lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT;
++	lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT;
++	lpm_priv->shadow.pm_interval = PS3_LPM_SHADOW_REG_INIT;
++	lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT;
++	lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT;
++
++	dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, "
++		"tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id,
++		lpm_priv->outlet_id, tb_size);
++
++	return 0;
++
++fail_construct:
++	kfree(lpm_priv->tb_cache_internal);
++	lpm_priv->tb_cache_internal = NULL;
++fail_malloc:
++fail_align:
++	atomic_dec(&lpm_priv->open);
++	return result;
++}
++EXPORT_SYMBOL_GPL(ps3_lpm_open);
++
++/**
++ * ps3_lpm_close - Close the lpm device.
++ *
++ */
++
++int ps3_lpm_close(void)
++{
++	dev_dbg(sbd_core(), "%s:%u\n", __func__, __LINE__);
++
++	lv1_destruct_lpm(lpm_priv->lpm_id);
++	lpm_priv->lpm_id = 0;
++
++	kfree(lpm_priv->tb_cache_internal);
++	lpm_priv->tb_cache_internal = NULL;
++
++	atomic_dec(&lpm_priv->open);
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ps3_lpm_close);
++
++static int __devinit ps3_lpm_probe(struct ps3_system_bus_device *dev)
++{
++	dev_dbg(&dev->core, " -> %s:%u\n", __func__, __LINE__);
++
++	if (lpm_priv) {
++		dev_info(&dev->core, "%s:%u: called twice\n",
++			__func__, __LINE__);
++		return -EBUSY;
++	}
++
++	lpm_priv = kzalloc(sizeof(*lpm_priv), GFP_KERNEL);
++
++	if (!lpm_priv)
++		return -ENOMEM;
++
++	lpm_priv->sbd = dev;
++	lpm_priv->node_id = dev->lpm.node_id;
++	lpm_priv->pu_id = dev->lpm.pu_id;
++	lpm_priv->rights = dev->lpm.rights;
++
++	dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__);
++
++	return 0;
++}
++
++static int ps3_lpm_remove(struct ps3_system_bus_device *dev)
++{
++	dev_dbg(&dev->core, " -> %s:%u:\n", __func__, __LINE__);
++
++	ps3_lpm_close();
++
++	kfree(lpm_priv);
++	lpm_priv = NULL;
++
++	dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__);
++	return 0;
++}
++
++static struct ps3_system_bus_driver ps3_lpm_driver = {
++	.match_id = PS3_MATCH_ID_LPM,
++	.core.name	= "ps3-lpm",
++	.core.owner	= THIS_MODULE,
++	.probe		= ps3_lpm_probe,
++	.remove		= ps3_lpm_remove,
++	.shutdown	= ps3_lpm_remove,
++};
++
++static int __init ps3_lpm_init(void)
++{
++	pr_debug("%s:%d:\n", __func__, __LINE__);
++	return ps3_system_bus_driver_register(&ps3_lpm_driver);
++}
++
++static void __exit ps3_lpm_exit(void)
++{
++	pr_debug("%s:%d:\n", __func__, __LINE__);
++	ps3_system_bus_driver_unregister(&ps3_lpm_driver);
++}
++
++module_init(ps3_lpm_init);
++module_exit(ps3_lpm_exit);
++
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("PS3 Logical Performance Monitor Driver");
++MODULE_AUTHOR("Sony Corporation");
++MODULE_ALIAS(PS3_MODULE_ALIAS_LPM);
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/ps3/ps3-sys-manager.c powerpc.git/drivers/ps3/ps3-sys-manager.c
+--- linux-2.6.24/drivers/ps3/ps3-sys-manager.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/ps3/ps3-sys-manager.c	2008-01-28 20:26:18.000000000 +0100
+@@ -452,7 +452,7 @@
+ 	case PS3_SM_EVENT_THERMAL_ALERT:
+ 		dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n",
+ 			__func__, __LINE__, event.value);
+-		printk(KERN_INFO "PS3 Thermal Alert Zone %u\n", event.value);
++		pr_info("PS3 Thermal Alert Zone %u\n", event.value);
+ 		break;
+ 	case PS3_SM_EVENT_THERMAL_CLEARED:
+ 		dev_dbg(&dev->core, "%s:%d: THERMAL_CLEARED (zone %u)\n",
+@@ -488,7 +488,7 @@
+ 	result = ps3_vuart_read(dev, &cmd, sizeof(cmd));
+ 	BUG_ON(result && "need to retry here");
+ 
+-	if(result)
++	if (result)
+ 		return result;
+ 
+ 	if (cmd.version != 1) {
+@@ -521,7 +521,7 @@
+ 	result = ps3_vuart_read(dev, &header,
+ 		sizeof(struct ps3_sys_manager_header));
+ 
+-	if(result)
++	if (result)
+ 		return result;
+ 
+ 	if (header.version != 1) {
+@@ -589,9 +589,9 @@
+ 		PS3_SM_WAKE_DEFAULT);
+ 	ps3_sys_manager_send_request_shutdown(dev);
+ 
+-	printk(KERN_EMERG "System Halted, OK to turn off power\n");
++	pr_emerg("System Halted, OK to turn off power\n");
+ 
+-	while(1)
++	while (1)
+ 		ps3_sys_manager_handle_msg(dev);
+ }
+ 
+@@ -626,9 +626,9 @@
+ 		PS3_SM_WAKE_DEFAULT);
+ 	ps3_sys_manager_send_request_shutdown(dev);
+ 
+-	printk(KERN_EMERG "System Halted, OK to turn off power\n");
++	pr_emerg("System Halted, OK to turn off power\n");
+ 
+-	while(1)
++	while (1)
+ 		ps3_sys_manager_handle_msg(dev);
+ }
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/ps3/ps3-vuart.c powerpc.git/drivers/ps3/ps3-vuart.c
+--- linux-2.6.24/drivers/ps3/ps3-vuart.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/ps3/ps3-vuart.c	2008-01-28 20:26:18.000000000 +0100
+@@ -108,18 +108,18 @@
+ struct ports_bmp {
+ 	u64 status;
+ 	u64 unused[3];
+-} __attribute__ ((aligned (32)));
++} __attribute__((aligned(32)));
+ 
+ #define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__)
+ static void __maybe_unused _dump_ports_bmp(
+-	const struct ports_bmp* bmp, const char* func, int line)
++	const struct ports_bmp *bmp, const char *func, int line)
+ {
+ 	pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status);
+ }
+ 
+ #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__)
+ static void __maybe_unused _dump_port_params(unsigned int port_number,
+-	const char* func, int line)
++	const char *func, int line)
+ {
+ #if defined(DEBUG)
+ 	static const char *strings[] = {
+@@ -363,7 +363,7 @@
+  */
+ 
+ static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev,
+-	const void* buf, unsigned int bytes, unsigned long *bytes_written)
++	const void *buf, unsigned int bytes, unsigned long *bytes_written)
+ {
+ 	int result;
+ 	struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+@@ -431,7 +431,7 @@
+ 	int result;
+ 	struct ps3_vuart_port_priv *priv = to_port_priv(dev);
+ 	u64 bytes_waiting;
+-	void* tmp;
++	void *tmp;
+ 
+ 	result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting);
+ 
+@@ -526,9 +526,8 @@
+ 
+ 	lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);
+ 
+-	if (!lb) {
++	if (!lb)
+ 		return -ENOMEM;
+-	}
+ 
+ 	memcpy(lb->data, buf, bytes);
+ 	lb->head = lb->data;
+@@ -878,7 +877,7 @@
+ struct vuart_bus_priv {
+ 	struct ports_bmp *bmp;
+ 	unsigned int virq;
+-	struct semaphore probe_mutex;
++	struct mutex probe_mutex;
+ 	int use_count;
+ 	struct ps3_system_bus_device *devices[PORT_COUNT];
+ } static vuart_bus_priv;
+@@ -926,9 +925,8 @@
+ 
+ 	BUG_ON(vuart_bus_priv.use_count > 2);
+ 
+-	if (vuart_bus_priv.use_count != 1) {
++	if (vuart_bus_priv.use_count != 1)
+ 		return 0;
+-	}
+ 
+ 	BUG_ON(vuart_bus_priv.bmp);
+ 
+@@ -1017,7 +1015,7 @@
+ 		return -EINVAL;
+ 	}
+ 
+-	down(&vuart_bus_priv.probe_mutex);
++	mutex_lock(&vuart_bus_priv.probe_mutex);
+ 
+ 	result = ps3_vuart_bus_interrupt_get();
+ 
+@@ -1077,7 +1075,7 @@
+ 		goto fail_probe;
+ 	}
+ 
+-	up(&vuart_bus_priv.probe_mutex);
++	mutex_unlock(&vuart_bus_priv.probe_mutex);
+ 
+ 	return result;
+ 
+@@ -1090,7 +1088,7 @@
+ fail_busy:
+ 	ps3_vuart_bus_interrupt_put();
+ fail_setup_interrupt:
+-	up(&vuart_bus_priv.probe_mutex);
++	mutex_unlock(&vuart_bus_priv.probe_mutex);
+ 	dev_dbg(&dev->core, "%s:%d: failed\n", __func__, __LINE__);
+ 	return result;
+ }
+@@ -1129,7 +1127,7 @@
+ 
+ 	BUG_ON(!dev);
+ 
+-	down(&vuart_bus_priv.probe_mutex);
++	mutex_lock(&vuart_bus_priv.probe_mutex);
+ 
+ 	dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
+ 		dev->match_id);
+@@ -1137,7 +1135,7 @@
+ 	if (!dev->core.driver) {
+ 		dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
+ 			__LINE__);
+-		up(&vuart_bus_priv.probe_mutex);
++		mutex_unlock(&vuart_bus_priv.probe_mutex);
+ 		return 0;
+ 	}
+ 
+@@ -1160,7 +1158,7 @@
+ 	priv = NULL;
+ 
+ 	dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
+-	up(&vuart_bus_priv.probe_mutex);
++	mutex_unlock(&vuart_bus_priv.probe_mutex);
+ 	return 0;
+ }
+ 
+@@ -1180,7 +1178,7 @@
+ 
+ 	BUG_ON(!dev);
+ 
+-	down(&vuart_bus_priv.probe_mutex);
++	mutex_lock(&vuart_bus_priv.probe_mutex);
+ 
+ 	dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
+ 		dev->match_id);
+@@ -1188,7 +1186,7 @@
+ 	if (!dev->core.driver) {
+ 		dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
+ 			__LINE__);
+-		up(&vuart_bus_priv.probe_mutex);
++		mutex_unlock(&vuart_bus_priv.probe_mutex);
+ 		return 0;
+ 	}
+ 
+@@ -1212,7 +1210,7 @@
+ 
+ 	dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
+ 
+-	up(&vuart_bus_priv.probe_mutex);
++	mutex_unlock(&vuart_bus_priv.probe_mutex);
+ 	return 0;
+ }
+ 
+@@ -1223,7 +1221,7 @@
+ 	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+ 		return -ENODEV;
+ 
+-	init_MUTEX(&vuart_bus_priv.probe_mutex);
++	mutex_init(&vuart_bus_priv.probe_mutex);
+ 
+ 	return 0;
+ }
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/serial/Kconfig powerpc.git/drivers/serial/Kconfig
+--- linux-2.6.24/drivers/serial/Kconfig	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/serial/Kconfig	2008-01-28 20:26:19.000000000 +0100
+@@ -1284,4 +1284,14 @@
+ 	  Currently, only 8250 compatible ports are supported, but
+ 	  others can easily be added.
+ 
++config SERIAL_QE
++	tristate "Freescale QUICC Engine serial port support"
++	depends on QUICC_ENGINE
++	select SERIAL_CORE
++	select FW_LOADER
++	default n
++	help
++	  This driver supports the QE serial ports on Freescale embedded
++	  PowerPC that contain a QUICC Engine.
++
+ endmenu
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/serial/Makefile powerpc.git/drivers/serial/Makefile
+--- linux-2.6.24/drivers/serial/Makefile	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/serial/Makefile	2008-01-28 20:26:19.000000000 +0100
+@@ -64,3 +64,4 @@
+ obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
+ obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
+ obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
++obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/serial/cpm_uart/cpm_uart_cpm1.c powerpc.git/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+--- linux-2.6.24/drivers/serial/cpm_uart/cpm_uart_cpm1.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/serial/cpm_uart/cpm_uart_cpm1.c	2008-01-28 20:26:19.000000000 +0100
+@@ -52,11 +52,7 @@
+ #ifdef CONFIG_PPC_CPM_NEW_BINDING
+ void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
+ {
+-	u16 __iomem *cpcr = &cpmp->cp_cpcr;
+-
+-	out_be16(cpcr, port->command | (cmd << 8) | CPM_CR_FLG);
+-	while (in_be16(cpcr) & CPM_CR_FLG)
+-		;
++	cpm_command(port->command, cmd);
+ }
+ #else
+ void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/serial/cpm_uart/cpm_uart_cpm2.c powerpc.git/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+--- linux-2.6.24/drivers/serial/cpm_uart/cpm_uart_cpm2.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/serial/cpm_uart/cpm_uart_cpm2.c	2008-01-28 20:26:19.000000000 +0100
+@@ -52,13 +52,7 @@
+ #ifdef CONFIG_PPC_CPM_NEW_BINDING
+ void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
+ {
+-	cpm_cpm2_t __iomem *cp = cpm2_map(im_cpm);
+-
+-	out_be32(&cp->cp_cpcr, port->command | cmd | CPM_CR_FLG);
+-	while (in_be32(&cp->cp_cpcr) & CPM_CR_FLG)
+-		;
+-
+-	cpm2_unmap(cp);
++	cpm_command(port->command, cmd);
+ }
+ #else
+ void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
+@@ -171,9 +165,9 @@
+ 	 * really has to get out of the driver so boards can
+ 	 * be supported in a sane fashion.
+ 	 */
++	volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+ #ifndef CONFIG_STX_GP3
+ 	volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+-	volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+ 
+ 	io->iop_pparb |= 0x008b0000;
+ 	io->iop_pdirb |= 0x00880000;
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/serial/mpc52xx_uart.c powerpc.git/drivers/serial/mpc52xx_uart.c
+--- linux-2.6.24/drivers/serial/mpc52xx_uart.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/serial/mpc52xx_uart.c	2008-01-28 20:26:19.000000000 +0100
+@@ -36,7 +36,7 @@
+  * DCD. However, the pin multiplexing aren't changed and should be set either
+  * by the bootloader or in the platform init code.
+  *
+- * The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2,
++ * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2,
+  * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and
+  * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly
+  * fpr the console code : without this 1:1 mapping, at early boot time, when we
+@@ -68,11 +68,12 @@
+ #include <linux/sysrq.h>
+ #include <linux/console.h>
+ 
+-#include <asm/delay.h>
+-#include <asm/io.h>
++#include <linux/delay.h>
++#include <linux/io.h>
+ 
+ #if defined(CONFIG_PPC_MERGE)
+-#include <asm/of_platform.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
+ #else
+ #include <linux/platform_device.h>
+ #endif
+@@ -111,16 +112,18 @@
+ #endif
+ 
+ #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase))
++#define FIFO(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
+ 
+ 
+ /* Forward declaration of the interruption handling routine */
+-static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id);
++static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id);
+ 
+ 
+ /* Simple macro to test if a port is console or not. This one is taken
+  * for serial_core.c and maybe should be moved to serial_core.h ? */
+ #ifdef CONFIG_SERIAL_CORE_CONSOLE
+-#define uart_console(port)	((port)->cons && (port)->cons->index == (port)->line)
++#define uart_console(port) \
++	((port)->cons && (port)->cons->index == (port)->line)
+ #else
+ #define uart_console(port)	(0)
+ #endif
+@@ -162,7 +165,7 @@
+ {
+ 	/* port->lock taken by caller */
+ 	port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY;
+-	out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
++	out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
+ }
+ 
+ static void
+@@ -170,7 +173,7 @@
+ {
+ 	/* port->lock taken by caller */
+ 	port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
+-	out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
++	out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
+ }
+ 
+ static void
+@@ -184,7 +187,7 @@
+ 		/* Make sure tx interrupts are on */
+ 		/* Truly necessary ??? They should be anyway */
+ 		port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
+-		out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
++		out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
+ 	}
+ 
+ 	spin_unlock_irqrestore(&port->lock, flags);
+@@ -195,7 +198,7 @@
+ {
+ 	/* port->lock taken by caller */
+ 	port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY;
+-	out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
++	out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
+ }
+ 
+ static void
+@@ -210,10 +213,10 @@
+ 	unsigned long flags;
+ 	spin_lock_irqsave(&port->lock, flags);
+ 
+-	if ( ctl == -1 )
+-		out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK);
++	if (ctl == -1)
++		out_8(&PSC(port)->command, MPC52xx_PSC_START_BRK);
+ 	else
+-		out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK);
++		out_8(&PSC(port)->command, MPC52xx_PSC_STOP_BRK);
+ 
+ 	spin_unlock_irqrestore(&port->lock, flags);
+ }
+@@ -222,6 +225,7 @@
+ mpc52xx_uart_startup(struct uart_port *port)
+ {
+ 	struct mpc52xx_psc __iomem *psc = PSC(port);
++	struct mpc52xx_psc_fifo __iomem *fifo = FIFO(port);
+ 	int ret;
+ 
+ 	/* Request IRQ */
+@@ -231,23 +235,23 @@
+ 		return ret;
+ 
+ 	/* Reset/activate the port, clear and enable interrupts */
+-	out_8(&psc->command,MPC52xx_PSC_RST_RX);
+-	out_8(&psc->command,MPC52xx_PSC_RST_TX);
++	out_8(&psc->command, MPC52xx_PSC_RST_RX);
++	out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ 
+-	out_be32(&psc->sicr,0);	/* UART mode DCD ignored */
++	out_be32(&psc->sicr, 0);	/* UART mode DCD ignored */
+ 
+ 	out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */
+ 
+-	out_8(&psc->rfcntl, 0x00);
+-	out_be16(&psc->rfalarm, 0x1ff);
+-	out_8(&psc->tfcntl, 0x07);
+-	out_be16(&psc->tfalarm, 0x80);
++	out_8(&fifo->rfcntl, 0x00);
++	out_be16(&fifo->rfalarm, 0x1ff);
++	out_8(&fifo->tfcntl, 0x07);
++	out_be16(&fifo->tfalarm, 0x80);
+ 
+ 	port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
+-	out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
++	out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+ 
+-	out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);
+-	out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);
++	out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
++	out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
+ 
+ 	return 0;
+ }
+@@ -258,12 +262,12 @@
+ 	struct mpc52xx_psc __iomem *psc = PSC(port);
+ 
+ 	/* Shut down the port.  Leave TX active if on a console port */
+-	out_8(&psc->command,MPC52xx_PSC_RST_RX);
++	out_8(&psc->command, MPC52xx_PSC_RST_RX);
+ 	if (!uart_console(port))
+-		out_8(&psc->command,MPC52xx_PSC_RST_TX);
++		out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ 
+ 	port->read_status_mask = 0;
+-	out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
++	out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+ 
+ 	/* Release interrupt */
+ 	free_irq(port->irq, port);
+@@ -271,7 +275,7 @@
+ 
+ static void
+ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
+-                         struct ktermios *old)
++			 struct ktermios *old)
+ {
+ 	struct mpc52xx_psc __iomem *psc = PSC(port);
+ 	unsigned long flags;
+@@ -283,14 +287,14 @@
+ 	mr1 = 0;
+ 
+ 	switch (new->c_cflag & CSIZE) {
+-		case CS5:	mr1 |= MPC52xx_PSC_MODE_5_BITS;
+-				break;
+-		case CS6:	mr1 |= MPC52xx_PSC_MODE_6_BITS;
+-				break;
+-		case CS7:	mr1 |= MPC52xx_PSC_MODE_7_BITS;
+-				break;
+-		case CS8:
+-		default:	mr1 |= MPC52xx_PSC_MODE_8_BITS;
++	case CS5:	mr1 |= MPC52xx_PSC_MODE_5_BITS;
++		break;
++	case CS6:	mr1 |= MPC52xx_PSC_MODE_6_BITS;
++		break;
++	case CS7:	mr1 |= MPC52xx_PSC_MODE_7_BITS;
++		break;
++	case CS8:
++	default:	mr1 |= MPC52xx_PSC_MODE_8_BITS;
+ 	}
+ 
+ 	if (new->c_cflag & PARENB) {
+@@ -332,24 +336,24 @@
+ 		udelay(1);
+ 
+ 	if (!j)
+-		printk(	KERN_ERR "mpc52xx_uart.c: "
++		printk(KERN_ERR "mpc52xx_uart.c: "
+ 			"Unable to flush RX & TX fifos in-time in set_termios."
+-			"Some chars may have been lost.\n" );
++			"Some chars may have been lost.\n");
+ 
+ 	/* Reset the TX & RX */
+-	out_8(&psc->command,MPC52xx_PSC_RST_RX);
+-	out_8(&psc->command,MPC52xx_PSC_RST_TX);
++	out_8(&psc->command, MPC52xx_PSC_RST_RX);
++	out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ 
+ 	/* Send new mode settings */
+-	out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1);
+-	out_8(&psc->mode,mr1);
+-	out_8(&psc->mode,mr2);
+-	out_8(&psc->ctur,ctr >> 8);
+-	out_8(&psc->ctlr,ctr & 0xff);
++	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
++	out_8(&psc->mode, mr1);
++	out_8(&psc->mode, mr2);
++	out_8(&psc->ctur, ctr >> 8);
++	out_8(&psc->ctlr, ctr & 0xff);
+ 
+ 	/* Reenable TX & RX */
+-	out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);
+-	out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);
++	out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
++	out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
+ 
+ 	/* We're all set, release the lock */
+ 	spin_unlock_irqrestore(&port->lock, flags);
+@@ -364,7 +368,8 @@
+ static void
+ mpc52xx_uart_release_port(struct uart_port *port)
+ {
+-	if (port->flags & UPF_IOREMAP) { /* remapped by us ? */
++	/* remapped by us ? */
++	if (port->flags & UPF_IOREMAP) {
+ 		iounmap(port->membase);
+ 		port->membase = NULL;
+ 	}
+@@ -379,7 +384,7 @@
+ 
+ 	if (port->flags & UPF_IOREMAP) /* Need to remap ? */
+ 		port->membase = ioremap(port->mapbase,
+-		                        sizeof(struct mpc52xx_psc));
++					sizeof(struct mpc52xx_psc));
+ 
+ 	if (!port->membase)
+ 		return -EINVAL;
+@@ -398,22 +403,22 @@
+ static void
+ mpc52xx_uart_config_port(struct uart_port *port, int flags)
+ {
+-	if ( (flags & UART_CONFIG_TYPE) &&
+-	     (mpc52xx_uart_request_port(port) == 0) )
+-	     	port->type = PORT_MPC52xx;
++	if ((flags & UART_CONFIG_TYPE)
++		&& (mpc52xx_uart_request_port(port) == 0))
++		port->type = PORT_MPC52xx;
+ }
+ 
+ static int
+ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
+ {
+-	if ( ser->type != PORT_UNKNOWN && ser->type != PORT_MPC52xx )
++	if (ser->type != PORT_UNKNOWN && ser->type != PORT_MPC52xx)
+ 		return -EINVAL;
+ 
+-	if ( (ser->irq != port->irq) ||
+-	     (ser->io_type != SERIAL_IO_MEM) ||
+-	     (ser->baud_base != port->uartclk)  ||
+-	     (ser->iomem_base != (void*)port->mapbase) ||
+-	     (ser->hub6 != 0 ) )
++	if ((ser->irq != port->irq) ||
++	    (ser->io_type != SERIAL_IO_MEM) ||
++	    (ser->baud_base != port->uartclk)  ||
++	    (ser->iomem_base != (void *)port->mapbase) ||
++	    (ser->hub6 != 0))
+ 		return -EINVAL;
+ 
+ 	return 0;
+@@ -455,8 +460,8 @@
+ 	unsigned short status;
+ 
+ 	/* While we can read, do so ! */
+-	while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) &
+-	        MPC52xx_PSC_SR_RXRDY) {
++	while ((status = in_be16(&PSC(port)->mpc52xx_psc_status)) &
++		MPC52xx_PSC_SR_RXRDY) {
+ 
+ 		/* Get the char */
+ 		ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8);
+@@ -474,9 +479,9 @@
+ 		flag = TTY_NORMAL;
+ 		port->icount.rx++;
+ 
+-		if ( status & (MPC52xx_PSC_SR_PE |
+-		               MPC52xx_PSC_SR_FE |
+-		               MPC52xx_PSC_SR_RB) ) {
++		if (status & (MPC52xx_PSC_SR_PE |
++			      MPC52xx_PSC_SR_FE |
++			      MPC52xx_PSC_SR_RB)) {
+ 
+ 			if (status & MPC52xx_PSC_SR_RB) {
+ 				flag = TTY_BREAK;
+@@ -487,7 +492,7 @@
+ 				flag = TTY_FRAME;
+ 
+ 			/* Clear error condition */
+-			out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT);
++			out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT);
+ 
+ 		}
+ 		tty_insert_flip_char(tty, ch, flag);
+@@ -568,16 +573,16 @@
+ 
+ 		/* Do we need to receive chars ? */
+ 		/* For this RX interrupts must be on and some chars waiting */
+-		if ( status & MPC52xx_PSC_IMR_RXRDY )
++		if (status & MPC52xx_PSC_IMR_RXRDY)
+ 			keepgoing |= mpc52xx_uart_int_rx_chars(port);
+ 
+ 		/* Do we need to send chars ? */
+ 		/* For this, TX must be ready and TX interrupt enabled */
+-		if ( status & MPC52xx_PSC_IMR_TXRDY )
++		if (status & MPC52xx_PSC_IMR_TXRDY)
+ 			keepgoing |= mpc52xx_uart_int_tx_chars(port);
+ 
+ 		/* Limit number of iteration */
+-		if ( !(--pass) )
++		if (!(--pass))
+ 			keepgoing = 0;
+ 
+ 	} while (keepgoing);
+@@ -596,7 +601,7 @@
+ 
+ static void __init
+ mpc52xx_console_get_options(struct uart_port *port,
+-                            int *baud, int *parity, int *bits, int *flow)
++			    int *baud, int *parity, int *bits, int *flow)
+ {
+ 	struct mpc52xx_psc __iomem *psc = PSC(port);
+ 	unsigned char mr1;
+@@ -604,7 +609,7 @@
+ 	pr_debug("mpc52xx_console_get_options(port=%p)\n", port);
+ 
+ 	/* Read the mode registers */
+-	out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1);
++	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
+ 	mr1 = in_8(&psc->mode);
+ 
+ 	/* CT{U,L}R are write-only ! */
+@@ -616,11 +621,18 @@
+ 
+ 	/* Parse them */
+ 	switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) {
+-		case MPC52xx_PSC_MODE_5_BITS:	*bits = 5; break;
+-		case MPC52xx_PSC_MODE_6_BITS:	*bits = 6; break;
+-		case MPC52xx_PSC_MODE_7_BITS:	*bits = 7; break;
+-		case MPC52xx_PSC_MODE_8_BITS:
+-		default:			*bits = 8;
++	case MPC52xx_PSC_MODE_5_BITS:
++		*bits = 5;
++		break;
++	case MPC52xx_PSC_MODE_6_BITS:
++		*bits = 6;
++		break;
++	case MPC52xx_PSC_MODE_7_BITS:
++		*bits = 7;
++		break;
++	case MPC52xx_PSC_MODE_8_BITS:
++	default:
++		*bits = 8;
+ 	}
+ 
+ 	if (mr1 & MPC52xx_PSC_MODE_PARNONE)
+@@ -657,7 +669,7 @@
+ 		/* Wait the TX buffer to be empty */
+ 		j = 20000;	/* Maximum wait */
+ 		while (!(in_be16(&psc->mpc52xx_psc_status) &
+-		         MPC52xx_PSC_SR_TXEMP) && --j)
++			 MPC52xx_PSC_SR_TXEMP) && --j)
+ 			udelay(1);
+ 	}
+ 
+@@ -730,16 +742,18 @@
+ 	}
+ 
+ 	pr_debug("Console on ttyPSC%x is %s\n",
+-	         co->index, mpc52xx_uart_nodes[co->index]->full_name);
++		 co->index, mpc52xx_uart_nodes[co->index]->full_name);
+ 
+ 	/* Fetch register locations */
+-	if ((ret = of_address_to_resource(np, 0, &res)) != 0) {
++	ret = of_address_to_resource(np, 0, &res);
++	if (ret) {
+ 		pr_debug("Could not get resources for PSC%x\n", co->index);
+ 		return ret;
+ 	}
+ 
+ 	/* Search for bus-frequency property in this node or a parent */
+-	if ((ipb_freq = mpc52xx_find_ipb_freq(np)) == 0) {
++	ipb_freq = mpc52xx_find_ipb_freq(np);
++	if (ipb_freq == 0) {
+ 		pr_debug("Could not find IPB bus frequency!\n");
+ 		return -EINVAL;
+ 	}
+@@ -757,7 +771,8 @@
+ 		return -EINVAL;
+ 
+ 	pr_debug("mpc52xx-psc uart at %p, mapped to %p, irq=%x, freq=%i\n",
+-	         (void*)port->mapbase, port->membase, port->irq, port->uartclk);
++		 (void *)port->mapbase, port->membase,
++		 port->irq, port->uartclk);
+ 
+ 	/* Setup the port parameters accoding to options */
+ 	if (options)
+@@ -766,7 +781,7 @@
+ 		mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow);
+ 
+ 	pr_debug("Setting console parameters: %i %i%c1 flow=%c\n",
+-	         baud, bits, parity, flow);
++		 baud, bits, parity, flow);
+ 
+ 	return uart_set_options(port, co, baud, parity, bits, flow);
+ }
+@@ -781,7 +796,7 @@
+ 	.device	= uart_console_device,
+ 	.setup	= mpc52xx_console_setup,
+ 	.flags	= CON_PRINTBUFFER,
+-	.index	= -1,	/* Specified on the cmdline (e.g. console=ttyPSC0 ) */
++	.index	= -1,	/* Specified on the cmdline (e.g. console=ttyPSC0) */
+ 	.data	= &mpc52xx_uart_driver,
+ };
+ 
+@@ -809,7 +824,6 @@
+ /* ======================================================================== */
+ 
+ static struct uart_driver mpc52xx_uart_driver = {
+-	.owner		= THIS_MODULE,
+ 	.driver_name	= "mpc52xx_psc_uart",
+ 	.dev_name	= "ttyPSC",
+ 	.major		= SERIAL_PSC_MAJOR,
+@@ -837,7 +851,7 @@
+ 	if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
+ 		return -EINVAL;
+ 
+-	if (!mpc52xx_match_psc_function(idx,"uart"))
++	if (!mpc52xx_match_psc_function(idx, "uart"))
+ 		return -ENODEV;
+ 
+ 	/* Init the port structure */
+@@ -848,13 +862,13 @@
+ 	port->fifosize	= 512;
+ 	port->iotype	= UPIO_MEM;
+ 	port->flags	= UPF_BOOT_AUTOCONF |
+-			  ( uart_console(port) ? 0 : UPF_IOREMAP );
++			  (uart_console(port) ? 0 : UPF_IOREMAP);
+ 	port->line	= idx;
+ 	port->ops	= &mpc52xx_uart_ops;
+ 	port->dev	= &dev->dev;
+ 
+ 	/* Search for IRQ and mapbase */
+-	for (i=0 ; i<dev->num_resources ; i++, res++) {
++	for (i = 0 ; i < dev->num_resources ; i++, res++) {
+ 		if (res->flags & IORESOURCE_MEM)
+ 			port->mapbase = res->start;
+ 		else if (res->flags & IORESOURCE_IRQ)
+@@ -866,7 +880,7 @@
+ 	/* Add the port to the uart sub-system */
+ 	ret = uart_add_one_port(&mpc52xx_uart_driver, port);
+ 	if (!ret)
+-		platform_set_drvdata(dev, (void*)port);
++		platform_set_drvdata(dev, (void *)port);
+ 
+ 	return ret;
+ }
+@@ -917,6 +931,7 @@
+ 	.resume		= mpc52xx_uart_resume,
+ #endif
+ 	.driver		= {
++		.owner	= THIS_MODULE,
+ 		.name	= "mpc52xx-psc",
+ 	},
+ };
+@@ -946,10 +961,11 @@
+ 	if (idx >= MPC52xx_PSC_MAXNUM)
+ 		return -EINVAL;
+ 	pr_debug("Found %s assigned to ttyPSC%x\n",
+-	         mpc52xx_uart_nodes[idx]->full_name, idx);
++		 mpc52xx_uart_nodes[idx]->full_name, idx);
+ 
+ 	/* Search for bus-frequency property in this node or a parent */
+-	if ((ipb_freq = mpc52xx_find_ipb_freq(op->node)) == 0) {
++	ipb_freq = mpc52xx_find_ipb_freq(op->node);
++	if (ipb_freq == 0) {
+ 		dev_dbg(&op->dev, "Could not find IPB bus frequency!\n");
+ 		return -EINVAL;
+ 	}
+@@ -962,22 +978,23 @@
+ 	port->fifosize	= 512;
+ 	port->iotype	= UPIO_MEM;
+ 	port->flags	= UPF_BOOT_AUTOCONF |
+-			  ( uart_console(port) ? 0 : UPF_IOREMAP );
++			  (uart_console(port) ? 0 : UPF_IOREMAP);
+ 	port->line	= idx;
+ 	port->ops	= &mpc52xx_uart_ops;
+ 	port->dev	= &op->dev;
+ 
+ 	/* Search for IRQ and mapbase */
+-	if ((ret = of_address_to_resource(op->node, 0, &res)) != 0)
++	ret = of_address_to_resource(op->node, 0, &res);
++	if (ret)
+ 		return ret;
+ 
+ 	port->mapbase = res.start;
+ 	port->irq = irq_of_parse_and_map(op->node, 0);
+ 
+ 	dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n",
+-	        (void*)port->mapbase, port->irq, port->uartclk);
++		(void *)port->mapbase, port->irq, port->uartclk);
+ 
+-	if ((port->irq==NO_IRQ) || !port->mapbase) {
++	if ((port->irq == NO_IRQ) || !port->mapbase) {
+ 		printk(KERN_ERR "Could not allocate resources for PSC\n");
+ 		return -EINVAL;
+ 	}
+@@ -985,7 +1002,7 @@
+ 	/* Add the port to the uart sub-system */
+ 	ret = uart_add_one_port(&mpc52xx_uart_driver, port);
+ 	if (!ret)
+-		dev_set_drvdata(&op->dev, (void*)port);
++		dev_set_drvdata(&op->dev, (void *)port);
+ 
+ 	return ret;
+ }
+@@ -1048,6 +1065,7 @@
+ 	if (idx < 0)
+ 		return; /* No free slot; abort */
+ 
++	of_node_get(np);
+ 	/* If the slot is already occupied, then swap slots */
+ 	if (mpc52xx_uart_nodes[idx] && (free_idx != -1))
+ 		mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx];
+@@ -1057,7 +1075,7 @@
+ static void
+ mpc52xx_uart_of_enumerate(void)
+ {
+-	static int enum_done = 0;
++	static int enum_done;
+ 	struct device_node *np;
+ 	const unsigned int *devno;
+ 	int i;
+@@ -1071,7 +1089,7 @@
+ 
+ 		/* Is a particular device number requested? */
+ 		devno = of_get_property(np, "port-number", NULL);
+-		mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1);
++		mpc52xx_uart_of_assign(np, devno ? *devno : -1);
+ 	}
+ 
+ 	enum_done = 1;
+@@ -1079,15 +1097,13 @@
+ 	for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {
+ 		if (mpc52xx_uart_nodes[i])
+ 			pr_debug("%s assigned to ttyPSC%x\n",
+-			         mpc52xx_uart_nodes[i]->full_name, i);
++				 mpc52xx_uart_nodes[i]->full_name, i);
+ 	}
+ }
+ 
+ MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match);
+ 
+ static struct of_platform_driver mpc52xx_uart_of_driver = {
+-	.owner		= THIS_MODULE,
+-	.name		= "mpc52xx-psc-uart",
+ 	.match_table	= mpc52xx_uart_of_match,
+ 	.probe		= mpc52xx_uart_of_probe,
+ 	.remove		= mpc52xx_uart_of_remove,
+@@ -1113,7 +1129,8 @@
+ 
+ 	printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n");
+ 
+-	if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) {
++	ret = uart_register_driver(&mpc52xx_uart_driver);
++	if (ret) {
+ 		printk(KERN_ERR "%s: uart_register_driver failed (%i)\n",
+ 		       __FILE__, ret);
+ 		return ret;
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/serial/uartlite.c powerpc.git/drivers/serial/uartlite.c
+--- linux-2.6.24/drivers/serial/uartlite.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/serial/uartlite.c	2008-01-28 20:26:19.000000000 +0100
+@@ -539,7 +539,7 @@
+  *
+  * @dev: pointer to device structure
+  */
+-static int __devinit ulite_release(struct device *dev)
++static int __devexit ulite_release(struct device *dev)
+ {
+ 	struct uart_port *port = dev_get_drvdata(dev);
+ 	int rc = 0;
+@@ -572,14 +572,14 @@
+ 	return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start);
+ }
+ 
+-static int ulite_remove(struct platform_device *pdev)
++static int __devexit ulite_remove(struct platform_device *pdev)
+ {
+ 	return ulite_release(&pdev->dev);
+ }
+ 
+ static struct platform_driver ulite_platform_driver = {
+ 	.probe	= ulite_probe,
+-	.remove	= ulite_remove,
++	.remove	= __devexit_p(ulite_remove),
+ 	.driver	= {
+ 		   .owner = THIS_MODULE,
+ 		   .name  = "uartlite",
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/serial/ucc_uart.c powerpc.git/drivers/serial/ucc_uart.c
+--- linux-2.6.24/drivers/serial/ucc_uart.c	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/drivers/serial/ucc_uart.c	2008-01-28 20:26:20.000000000 +0100
+@@ -0,0 +1,1514 @@
++/*
++ * Freescale QUICC Engine UART device driver
++ *
++ * Author: Timur Tabi <timur@freescale.com>
++ *
++ * Copyright 2007 Freescale Semiconductor, Inc.  This file is licensed under
++ * the terms of the GNU General Public License version 2.  This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ *
++ * This driver adds support for UART devices via Freescale's QUICC Engine
++ * found on some Freescale SOCs.
++ *
++ * If Soft-UART support is needed but not already present, then this driver
++ * will request and upload the "Soft-UART" microcode upon probe.  The
++ * filename of the microcode should be fsl_qe_ucode_uart_X_YZ.bin, where "X"
++ * is the name of the SOC (e.g. 8323), and YZ is the revision of the SOC,
++ * (e.g. "11" for 1.1).
++ */
++
++#include <linux/module.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#include <linux/io.h>
++#include <linux/of_platform.h>
++#include <linux/dma-mapping.h>
++
++#include <linux/fs_uart_pd.h>
++#include <asm/ucc_slow.h>
++
++#include <linux/firmware.h>
++#include <asm/reg.h>
++
++/*
++ * The GUMR flag for Soft UART.  This would normally be defined in qe.h,
++ * but Soft-UART is a hack and we want to keep everything related to it in
++ * this file.
++ */
++#define UCC_SLOW_GUMR_H_SUART   	0x00004000      /* Soft-UART */
++
++/*
++ * soft_uart is 1 if we need to use Soft-UART mode
++ */
++static int soft_uart;
++/*
++ * firmware_loaded is 1 if the firmware has been loaded, 0 otherwise.
++ */
++static int firmware_loaded;
++
++/* Enable this macro to configure all serial ports in internal loopback
++   mode */
++/* #define LOOPBACK */
++
++/* The major and minor device numbers are defined in
++ * http://www.lanana.org/docs/device-list/devices-2.6+.txt.  For the QE
++ * UART, we have major number 204 and minor numbers 46 - 49, which are the
++ * same as for the CPM2.  This decision was made because no Freescale part
++ * has both a CPM and a QE.
++ */
++#define SERIAL_QE_MAJOR 204
++#define SERIAL_QE_MINOR 46
++
++/* Since we only have minor numbers 46 - 49, there is a hard limit of 4 ports */
++#define UCC_MAX_UART    4
++
++/* The number of buffer descriptors for receiving characters. */
++#define RX_NUM_FIFO     4
++
++/* The number of buffer descriptors for transmitting characters. */
++#define TX_NUM_FIFO     4
++
++/* The maximum size of the character buffer for a single RX BD. */
++#define RX_BUF_SIZE     32
++
++/* The maximum size of the character buffer for a single TX BD. */
++#define TX_BUF_SIZE     32
++
++/*
++ * The number of jiffies to wait after receiving a close command before the
++ * device is actually closed.  This allows the last few characters to be
++ * sent over the wire.
++ */
++#define UCC_WAIT_CLOSING 100
++
++struct ucc_uart_pram {
++	struct ucc_slow_pram common;
++	u8 res1[8];     	/* reserved */
++	__be16 maxidl;  	/* Maximum idle chars */
++	__be16 idlc;    	/* temp idle counter */
++	__be16 brkcr;   	/* Break count register */
++	__be16 parec;   	/* receive parity error counter */
++	__be16 frmec;   	/* receive framing error counter */
++	__be16 nosec;   	/* receive noise counter */
++	__be16 brkec;   	/* receive break condition counter */
++	__be16 brkln;   	/* last received break length */
++	__be16 uaddr[2];	/* UART address character 1 & 2 */
++	__be16 rtemp;   	/* Temp storage */
++	__be16 toseq;   	/* Transmit out of sequence char */
++	__be16 cchars[8];       /* control characters 1-8 */
++	__be16 rccm;    	/* receive control character mask */
++	__be16 rccr;    	/* receive control character register */
++	__be16 rlbc;    	/* receive last break character */
++	__be16 res2;    	/* reserved */
++	__be32 res3;    	/* reserved, should be cleared */
++	u8 res4;		/* reserved, should be cleared */
++	u8 res5[3];     	/* reserved, should be cleared */
++	__be32 res6;    	/* reserved, should be cleared */
++	__be32 res7;    	/* reserved, should be cleared */
++	__be32 res8;    	/* reserved, should be cleared */
++	__be32 res9;    	/* reserved, should be cleared */
++	__be32 res10;   	/* reserved, should be cleared */
++	__be32 res11;   	/* reserved, should be cleared */
++	__be32 res12;   	/* reserved, should be cleared */
++	__be32 res13;   	/* reserved, should be cleared */
++/* The rest is for Soft-UART only */
++	__be16 supsmr;  	/* 0x90, Shadow UPSMR */
++	__be16 res92;   	/* 0x92, reserved, initialize to 0 */
++	__be32 rx_state;	/* 0x94, RX state, initialize to 0 */
++	__be32 rx_cnt;  	/* 0x98, RX count, initialize to 0 */
++	u8 rx_length;   	/* 0x9C, Char length, set to 1+CL+PEN+1+SL */
++	u8 rx_bitmark;  	/* 0x9D, reserved, initialize to 0 */
++	u8 rx_temp_dlst_qe;     /* 0x9E, reserved, initialize to 0 */
++	u8 res14[0xBC - 0x9F];  /* reserved */
++	__be32 dump_ptr;	/* 0xBC, Dump pointer */
++	__be32 rx_frame_rem;    /* 0xC0, reserved, initialize to 0 */
++	u8 rx_frame_rem_size;   /* 0xC4, reserved, initialize to 0 */
++	u8 tx_mode;     	/* 0xC5, mode, 0=AHDLC, 1=UART */
++	__be16 tx_state;	/* 0xC6, TX state */
++	u8 res15[0xD0 - 0xC8];  /* reserved */
++	__be32 resD0;   	/* 0xD0, reserved, initialize to 0 */
++	u8 resD4;       	/* 0xD4, reserved, initialize to 0 */
++	__be16 resD5;   	/* 0xD5, reserved, initialize to 0 */
++} __attribute__ ((packed));
++
++/* SUPSMR definitions, for Soft-UART only */
++#define UCC_UART_SUPSMR_SL      	0x8000
++#define UCC_UART_SUPSMR_RPM_MASK	0x6000
++#define UCC_UART_SUPSMR_RPM_ODD 	0x0000
++#define UCC_UART_SUPSMR_RPM_LOW 	0x2000
++#define UCC_UART_SUPSMR_RPM_EVEN	0x4000
++#define UCC_UART_SUPSMR_RPM_HIGH	0x6000
++#define UCC_UART_SUPSMR_PEN     	0x1000
++#define UCC_UART_SUPSMR_TPM_MASK	0x0C00
++#define UCC_UART_SUPSMR_TPM_ODD 	0x0000
++#define UCC_UART_SUPSMR_TPM_LOW 	0x0400
++#define UCC_UART_SUPSMR_TPM_EVEN	0x0800
++#define UCC_UART_SUPSMR_TPM_HIGH	0x0C00
++#define UCC_UART_SUPSMR_FRZ     	0x0100
++#define UCC_UART_SUPSMR_UM_MASK 	0x00c0
++#define UCC_UART_SUPSMR_UM_NORMAL       0x0000
++#define UCC_UART_SUPSMR_UM_MAN_MULTI    0x0040
++#define UCC_UART_SUPSMR_UM_AUTO_MULTI   0x00c0
++#define UCC_UART_SUPSMR_CL_MASK 	0x0030
++#define UCC_UART_SUPSMR_CL_8    	0x0030
++#define UCC_UART_SUPSMR_CL_7    	0x0020
++#define UCC_UART_SUPSMR_CL_6    	0x0010
++#define UCC_UART_SUPSMR_CL_5    	0x0000
++
++#define UCC_UART_TX_STATE_AHDLC 	0x00
++#define UCC_UART_TX_STATE_UART  	0x01
++#define UCC_UART_TX_STATE_X1    	0x00
++#define UCC_UART_TX_STATE_X16   	0x80
++
++#define UCC_UART_PRAM_ALIGNMENT 0x100
++
++#define UCC_UART_SIZE_OF_BD     UCC_SLOW_SIZE_OF_BD
++#define NUM_CONTROL_CHARS       8
++
++/* Private per-port data structure */
++struct uart_qe_port {
++	struct uart_port port;
++	struct ucc_slow __iomem *uccp;
++	struct ucc_uart_pram __iomem *uccup;
++	struct ucc_slow_info us_info;
++	struct ucc_slow_private *us_private;
++	struct device_node *np;
++	unsigned int ucc_num;   /* First ucc is 0, not 1 */
++
++	u16 rx_nrfifos;
++	u16 rx_fifosize;
++	u16 tx_nrfifos;
++	u16 tx_fifosize;
++	int wait_closing;
++	u32 flags;
++	struct qe_bd *rx_bd_base;
++	struct qe_bd *rx_cur;
++	struct qe_bd *tx_bd_base;
++	struct qe_bd *tx_cur;
++	unsigned char *tx_buf;
++	unsigned char *rx_buf;
++	void *bd_virt;  	/* virtual address of the BD buffers */
++	dma_addr_t bd_dma_addr; /* bus address of the BD buffers */
++	unsigned int bd_size;   /* size of BD buffer space */
++};
++
++static struct uart_driver ucc_uart_driver = {
++	.owner  	= THIS_MODULE,
++	.driver_name    = "serial",
++	.dev_name       = "ttyQE",
++	.major  	= SERIAL_QE_MAJOR,
++	.minor  	= SERIAL_QE_MINOR,
++	.nr     	= UCC_MAX_UART,
++};
++
++/*
++ * Virtual to physical address translation.
++ *
++ * Given the virtual address for a character buffer, this function returns
++ * the physical (DMA) equivalent.
++ */
++static inline dma_addr_t cpu2qe_addr(void *addr, struct uart_qe_port *qe_port)
++{
++	if (likely((addr >= qe_port->bd_virt)) &&
++	    (addr < (qe_port->bd_virt + qe_port->bd_size)))
++		return qe_port->bd_dma_addr + (addr - qe_port->bd_virt);
++
++	/* something nasty happened */
++	printk(KERN_ERR "%s: addr=%p\n", __FUNCTION__, addr);
++	BUG();
++	return 0;
++}
++
++/*
++ * Physical to virtual address translation.
++ *
++ * Given the physical (DMA) address for a character buffer, this function
++ * returns the virtual equivalent.
++ */
++static inline void *qe2cpu_addr(dma_addr_t addr, struct uart_qe_port *qe_port)
++{
++	/* sanity check */
++	if (likely((addr >= qe_port->bd_dma_addr) &&
++		   (addr < (qe_port->bd_dma_addr + qe_port->bd_size))))
++		return qe_port->bd_virt + (addr - qe_port->bd_dma_addr);
++
++	/* something nasty happened */
++	printk(KERN_ERR "%s: addr=%x\n", __FUNCTION__, addr);
++	BUG();
++	return NULL;
++}
++
++/*
++ * Return 1 if the QE is done transmitting all buffers for this port
++ *
++ * This function scans each BD in sequence.  If we find a BD that is not
++ * ready (READY=1), then we return 0 indicating that the QE is still sending
++ * data.  If we reach the last BD (WRAP=1), then we know we've scanned
++ * the entire list, and all BDs are done.
++ */
++static unsigned int qe_uart_tx_empty(struct uart_port *port)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++	struct qe_bd *bdp = qe_port->tx_bd_base;
++
++	while (1) {
++		if (in_be16(&bdp->status) & BD_SC_READY)
++			/* This BD is not done, so return "not done" */
++			return 0;
++
++		if (in_be16(&bdp->status) & BD_SC_WRAP)
++			/*
++			 * This BD is done and it's the last one, so return
++			 * "done"
++			 */
++			return 1;
++
++		bdp++;
++	};
++}
++
++/*
++ * Set the modem control lines
++ *
++ * Although the QE can control the modem control lines (e.g. CTS), we
++ * don't need that support. This function must exist, however, otherwise
++ * the kernel will panic.
++ */
++void qe_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++}
++
++/*
++ * Get the current modem control line status
++ *
++ * Although the QE can control the modem control lines (e.g. CTS), this
++ * driver currently doesn't support that, so we always return Carrier
++ * Detect, Data Set Ready, and Clear To Send.
++ */
++static unsigned int qe_uart_get_mctrl(struct uart_port *port)
++{
++	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
++}
++
++/*
++ * Disable the transmit interrupt.
++ *
++ * Although this function is called "stop_tx", it does not actually stop
++ * transmission of data.  Instead, it tells the QE to not generate an
++ * interrupt when the UCC is finished sending characters.
++ */
++static void qe_uart_stop_tx(struct uart_port *port)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++
++	clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX);
++}
++
++/*
++ * Transmit as many characters to the HW as possible.
++ *
++ * This function will attempt to stuff of all the characters from the
++ * kernel's transmit buffer into TX BDs.
++ *
++ * A return value of non-zero indicates that it sucessfully stuffed all
++ * characters from the kernel buffer.
++ *
++ * A return value of zero indicates that there are still characters in the
++ * kernel's buffer that have not been transmitted, but there are no more BDs
++ * available.  This function should be called again after a BD has been made
++ * available.
++ */
++static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
++{
++	struct qe_bd *bdp;
++	unsigned char *p;
++	unsigned int count;
++	struct uart_port *port = &qe_port->port;
++	struct circ_buf *xmit = &port->info->xmit;
++
++	bdp = qe_port->rx_cur;
++
++	/* Handle xon/xoff */
++	if (port->x_char) {
++		/* Pick next descriptor and fill from buffer */
++		bdp = qe_port->tx_cur;
++
++		p = qe2cpu_addr(bdp->buf, qe_port);
++
++		*p++ = port->x_char;
++		out_be16(&bdp->length, 1);
++		setbits16(&bdp->status, BD_SC_READY);
++		/* Get next BD. */
++		if (in_be16(&bdp->status) & BD_SC_WRAP)
++			bdp = qe_port->tx_bd_base;
++		else
++			bdp++;
++		qe_port->tx_cur = bdp;
++
++		port->icount.tx++;
++		port->x_char = 0;
++		return 1;
++	}
++
++	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
++		qe_uart_stop_tx(port);
++		return 0;
++	}
++
++	/* Pick next descriptor and fill from buffer */
++	bdp = qe_port->tx_cur;
++
++	while (!(in_be16(&bdp->status) & BD_SC_READY) &&
++	       (xmit->tail != xmit->head)) {
++		count = 0;
++		p = qe2cpu_addr(bdp->buf, qe_port);
++		while (count < qe_port->tx_fifosize) {
++			*p++ = xmit->buf[xmit->tail];
++			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
++			port->icount.tx++;
++			count++;
++			if (xmit->head == xmit->tail)
++				break;
++		}
++
++		out_be16(&bdp->length, count);
++		setbits16(&bdp->status, BD_SC_READY);
++
++		/* Get next BD. */
++		if (in_be16(&bdp->status) & BD_SC_WRAP)
++			bdp = qe_port->tx_bd_base;
++		else
++			bdp++;
++	}
++	qe_port->tx_cur = bdp;
++
++	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++		uart_write_wakeup(port);
++
++	if (uart_circ_empty(xmit)) {
++		/* The kernel buffer is empty, so turn off TX interrupts.  We
++		   don't need to be told when the QE is finished transmitting
++		   the data. */
++		qe_uart_stop_tx(port);
++		return 0;
++	}
++
++	return 1;
++}
++
++/*
++ * Start transmitting data
++ *
++ * This function will start transmitting any available data, if the port
++ * isn't already transmitting data.
++ */
++static void qe_uart_start_tx(struct uart_port *port)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++
++	/* If we currently are transmitting, then just return */
++	if (in_be16(&qe_port->uccp->uccm) & UCC_UART_UCCE_TX)
++		return;
++
++	/* Otherwise, pump the port and start transmission */
++	if (qe_uart_tx_pump(qe_port))
++		setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX);
++}
++
++/*
++ * Stop transmitting data
++ */
++static void qe_uart_stop_rx(struct uart_port *port)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++
++	clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX);
++}
++
++/*
++ * Enable status change interrupts
++ *
++ * We don't support status change interrupts, but we need to define this
++ * function otherwise the kernel will panic.
++ */
++static void qe_uart_enable_ms(struct uart_port *port)
++{
++}
++
++/* Start or stop sending  break signal
++ *
++ * This function controls the sending of a break signal.  If break_state=1,
++ * then we start sending a break signal.  If break_state=0, then we stop
++ * sending the break signal.
++ */
++static void qe_uart_break_ctl(struct uart_port *port, int break_state)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++
++	if (break_state)
++		ucc_slow_stop_tx(qe_port->us_private);
++	else
++		ucc_slow_restart_tx(qe_port->us_private);
++}
++
++/* ISR helper function for receiving character.
++ *
++ * This function is called by the ISR to handling receiving characters
++ */
++static void qe_uart_int_rx(struct uart_qe_port *qe_port)
++{
++	int i;
++	unsigned char ch, *cp;
++	struct uart_port *port = &qe_port->port;
++	struct tty_struct *tty = port->info->tty;
++	struct qe_bd *bdp;
++	u16 status;
++	unsigned int flg;
++
++	/* Just loop through the closed BDs and copy the characters into
++	 * the buffer.
++	 */
++	bdp = qe_port->rx_cur;
++	while (1) {
++		status = in_be16(&bdp->status);
++
++		/* If this one is empty, then we assume we've read them all */
++		if (status & BD_SC_EMPTY)
++			break;
++
++		/* get number of characters, and check space in RX buffer */
++		i = in_be16(&bdp->length);
++
++		/* If we don't have enough room in RX buffer for the entire BD,
++		 * then we try later, which will be the next RX interrupt.
++		 */
++		if (tty_buffer_request_room(tty, i) < i) {
++			dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n");
++			return;
++		}
++
++		/* get pointer */
++		cp = qe2cpu_addr(bdp->buf, qe_port);
++
++		/* loop through the buffer */
++		while (i-- > 0) {
++			ch = *cp++;
++			port->icount.rx++;
++			flg = TTY_NORMAL;
++
++			if (!i && status &
++			    (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV))
++				goto handle_error;
++			if (uart_handle_sysrq_char(port, ch))
++				continue;
++
++error_return:
++			tty_insert_flip_char(tty, ch, flg);
++
++		}
++
++		/* This BD is ready to be used again. Clear status. get next */
++		clrsetbits_be16(&bdp->status, BD_SC_BR | BD_SC_FR | BD_SC_PR |
++			BD_SC_OV | BD_SC_ID, BD_SC_EMPTY);
++		if (in_be16(&bdp->status) & BD_SC_WRAP)
++			bdp = qe_port->rx_bd_base;
++		else
++			bdp++;
++
++	}
++
++	/* Write back buffer pointer */
++	qe_port->rx_cur = bdp;
++
++	/* Activate BH processing */
++	tty_flip_buffer_push(tty);
++
++	return;
++
++	/* Error processing */
++
++handle_error:
++	/* Statistics */
++	if (status & BD_SC_BR)
++		port->icount.brk++;
++	if (status & BD_SC_PR)
++		port->icount.parity++;
++	if (status & BD_SC_FR)
++		port->icount.frame++;
++	if (status & BD_SC_OV)
++		port->icount.overrun++;
++
++	/* Mask out ignored conditions */
++	status &= port->read_status_mask;
++
++	/* Handle the remaining ones */
++	if (status & BD_SC_BR)
++		flg = TTY_BREAK;
++	else if (status & BD_SC_PR)
++		flg = TTY_PARITY;
++	else if (status & BD_SC_FR)
++		flg = TTY_FRAME;
++
++	/* Overrun does not affect the current character ! */
++	if (status & BD_SC_OV)
++		tty_insert_flip_char(tty, 0, TTY_OVERRUN);
++#ifdef SUPPORT_SYSRQ
++	port->sysrq = 0;
++#endif
++	goto error_return;
++}
++
++/* Interrupt handler
++ *
++ * This interrupt handler is called after a BD is processed.
++ */
++static irqreturn_t qe_uart_int(int irq, void *data)
++{
++	struct uart_qe_port *qe_port = (struct uart_qe_port *) data;
++	struct ucc_slow __iomem *uccp = qe_port->uccp;
++	u16 events;
++
++	/* Clear the interrupts */
++	events = in_be16(&uccp->ucce);
++	out_be16(&uccp->ucce, events);
++
++	if (events & UCC_UART_UCCE_BRKE)
++		uart_handle_break(&qe_port->port);
++
++	if (events & UCC_UART_UCCE_RX)
++		qe_uart_int_rx(qe_port);
++
++	if (events & UCC_UART_UCCE_TX)
++		qe_uart_tx_pump(qe_port);
++
++	return events ? IRQ_HANDLED : IRQ_NONE;
++}
++
++/* Initialize buffer descriptors
++ *
++ * This function initializes all of the RX and TX buffer descriptors.
++ */
++static void qe_uart_initbd(struct uart_qe_port *qe_port)
++{
++	int i;
++	void *bd_virt;
++	struct qe_bd *bdp;
++
++	/* Set the physical address of the host memory buffers in the buffer
++	 * descriptors, and the virtual address for us to work with.
++	 */
++	bd_virt = qe_port->bd_virt;
++	bdp = qe_port->rx_bd_base;
++	qe_port->rx_cur = qe_port->rx_bd_base;
++	for (i = 0; i < (qe_port->rx_nrfifos - 1); i++) {
++		out_be16(&bdp->status, BD_SC_EMPTY | BD_SC_INTRPT);
++		out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
++		out_be16(&bdp->length, 0);
++		bd_virt += qe_port->rx_fifosize;
++		bdp++;
++	}
++
++	/* */
++	out_be16(&bdp->status, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT);
++	out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
++	out_be16(&bdp->length, 0);
++
++	/* Set the physical address of the host memory
++	 * buffers in the buffer descriptors, and the
++	 * virtual address for us to work with.
++	 */
++	bd_virt = qe_port->bd_virt +
++		L1_CACHE_ALIGN(qe_port->rx_nrfifos * qe_port->rx_fifosize);
++	qe_port->tx_cur = qe_port->tx_bd_base;
++	bdp = qe_port->tx_bd_base;
++	for (i = 0; i < (qe_port->tx_nrfifos - 1); i++) {
++		out_be16(&bdp->status, BD_SC_INTRPT);
++		out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
++		out_be16(&bdp->length, 0);
++		bd_virt += qe_port->tx_fifosize;
++		bdp++;
++	}
++
++	/* Loopback requires the preamble bit to be set on the first TX BD */
++#ifdef LOOPBACK
++	setbits16(&qe_port->tx_cur->status, BD_SC_P);
++#endif
++
++	out_be16(&bdp->status, BD_SC_WRAP | BD_SC_INTRPT);
++	out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
++	out_be16(&bdp->length, 0);
++}
++
++/*
++ * Initialize a UCC for UART.
++ *
++ * This function configures a given UCC to be used as a UART device. Basic
++ * UCC initialization is handled in qe_uart_request_port().  This function
++ * does all the UART-specific stuff.
++ */
++static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
++{
++	u32 cecr_subblock;
++	struct ucc_slow __iomem *uccp = qe_port->uccp;
++	struct ucc_uart_pram *uccup = qe_port->uccup;
++
++	unsigned int i;
++
++	/* First, disable TX and RX in the UCC */
++	ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX);
++
++	/* Program the UCC UART parameter RAM */
++	out_8(&uccup->common.rbmr, UCC_BMR_GBL | UCC_BMR_BO_BE);
++	out_8(&uccup->common.tbmr, UCC_BMR_GBL | UCC_BMR_BO_BE);
++	out_be16(&uccup->common.mrblr, qe_port->rx_fifosize);
++	out_be16(&uccup->maxidl, 0x10);
++	out_be16(&uccup->brkcr, 1);
++	out_be16(&uccup->parec, 0);
++	out_be16(&uccup->frmec, 0);
++	out_be16(&uccup->nosec, 0);
++	out_be16(&uccup->brkec, 0);
++	out_be16(&uccup->uaddr[0], 0);
++	out_be16(&uccup->uaddr[1], 0);
++	out_be16(&uccup->toseq, 0);
++	for (i = 0; i < 8; i++)
++		out_be16(&uccup->cchars[i], 0xC000);
++	out_be16(&uccup->rccm, 0xc0ff);
++
++	/* Configure the GUMR registers for UART */
++	if (soft_uart)
++		/* Soft-UART requires a 1X multiplier for TX */
++		clrsetbits_be32(&uccp->gumr_l,
++			UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
++			UCC_SLOW_GUMR_L_RDCR_MASK,
++			UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 |
++			UCC_SLOW_GUMR_L_RDCR_16);
++	else
++		clrsetbits_be32(&uccp->gumr_l,
++			UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
++			UCC_SLOW_GUMR_L_RDCR_MASK,
++			UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 |
++			UCC_SLOW_GUMR_L_RDCR_16);
++
++	clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW,
++		UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX);
++
++#ifdef LOOPBACK
++	clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK,
++		UCC_SLOW_GUMR_L_DIAG_LOOP);
++	clrsetbits_be32(&uccp->gumr_h,
++		UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_RSYN,
++		UCC_SLOW_GUMR_H_CDS);
++#endif
++
++	/* Enable rx interrupts  and clear all pending events.  */
++	out_be16(&uccp->uccm, 0);
++	out_be16(&uccp->ucce, 0xffff);
++	out_be16(&uccp->udsr, 0x7e7e);
++
++	/* Initialize UPSMR */
++	out_be16(&uccp->upsmr, 0);
++
++	if (soft_uart) {
++		out_be16(&uccup->supsmr, 0x30);
++		out_be16(&uccup->res92, 0);
++		out_be32(&uccup->rx_state, 0);
++		out_be32(&uccup->rx_cnt, 0);
++		out_8(&uccup->rx_bitmark, 0);
++		out_8(&uccup->rx_length, 10);
++		out_be32(&uccup->dump_ptr, 0x4000);
++		out_8(&uccup->rx_temp_dlst_qe, 0);
++		out_be32(&uccup->rx_frame_rem, 0);
++		out_8(&uccup->rx_frame_rem_size, 0);
++		/* Soft-UART requires TX to be 1X */
++		out_8(&uccup->tx_mode,
++			UCC_UART_TX_STATE_UART | UCC_UART_TX_STATE_X1);
++		out_be16(&uccup->tx_state, 0);
++		out_8(&uccup->resD4, 0);
++		out_be16(&uccup->resD5, 0);
++
++		/* Set UART mode.
++		 * Enable receive and transmit.
++		 */
++
++		/* From the microcode errata:
++		 * 1.GUMR_L register, set mode=0010 (QMC).
++		 * 2.Set GUMR_H[17] bit. (UART/AHDLC mode).
++		 * 3.Set GUMR_H[19:20] (Transparent mode)
++		 * 4.Clear GUMR_H[26] (RFW)
++		 * ...
++		 * 6.Receiver must use 16x over sampling
++		 */
++		clrsetbits_be32(&uccp->gumr_l,
++			UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
++			UCC_SLOW_GUMR_L_RDCR_MASK,
++			UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_16 |
++			UCC_SLOW_GUMR_L_RDCR_16);
++
++		clrsetbits_be32(&uccp->gumr_h,
++			UCC_SLOW_GUMR_H_RFW | UCC_SLOW_GUMR_H_RSYN,
++			UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX |
++			UCC_SLOW_GUMR_H_TTX | UCC_SLOW_GUMR_H_TFL);
++
++#ifdef LOOPBACK
++		clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK,
++				UCC_SLOW_GUMR_L_DIAG_LOOP);
++		clrbits32(&uccp->gumr_h, UCC_SLOW_GUMR_H_CTSP |
++			  UCC_SLOW_GUMR_H_CDS);
++#endif
++
++		cecr_subblock = ucc_slow_get_qe_cr_subblock(qe_port->ucc_num);
++		qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
++			QE_CR_PROTOCOL_UNSPECIFIED, 0);
++	}
++}
++
++/*
++ * Initialize the port.
++ */
++static int qe_uart_startup(struct uart_port *port)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++	int ret;
++
++	/*
++	 * If we're using Soft-UART mode, then we need to make sure the
++	 * firmware has been uploaded first.
++	 */
++	if (soft_uart && !firmware_loaded) {
++		dev_err(port->dev, "Soft-UART firmware not uploaded\n");
++		return -ENODEV;
++	}
++
++	qe_uart_initbd(qe_port);
++	qe_uart_init_ucc(qe_port);
++
++	/* Install interrupt handler. */
++	ret = request_irq(port->irq, qe_uart_int, IRQF_SHARED, "ucc-uart",
++		qe_port);
++	if (ret) {
++		dev_err(port->dev, "could not claim IRQ %u\n", port->irq);
++		return ret;
++	}
++
++	/* Startup rx-int */
++	setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX);
++	ucc_slow_enable(qe_port->us_private, COMM_DIR_RX_AND_TX);
++
++	return 0;
++}
++
++/*
++ * Shutdown the port.
++ */
++static void qe_uart_shutdown(struct uart_port *port)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++	struct ucc_slow __iomem *uccp = qe_port->uccp;
++	unsigned int timeout = 20;
++
++	/* Disable RX and TX */
++
++	/* Wait for all the BDs marked sent */
++	while (!qe_uart_tx_empty(port)) {
++		if (!--timeout) {
++			dev_warn(port->dev, "shutdown timeout\n");
++			break;
++		}
++		set_current_state(TASK_UNINTERRUPTIBLE);
++		schedule_timeout(2);
++	}
++
++	if (qe_port->wait_closing) {
++		/* Wait a bit longer */
++		set_current_state(TASK_UNINTERRUPTIBLE);
++		schedule_timeout(qe_port->wait_closing);
++	}
++
++	/* Stop uarts */
++	ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX);
++	clrbits16(&uccp->uccm, UCC_UART_UCCE_TX | UCC_UART_UCCE_RX);
++
++	/* Shut them really down and reinit buffer descriptors */
++	ucc_slow_graceful_stop_tx(qe_port->us_private);
++	qe_uart_initbd(qe_port);
++
++	free_irq(port->irq, qe_port);
++}
++
++/*
++ * Set the serial port parameters.
++ */
++static void qe_uart_set_termios(struct uart_port *port,
++				struct ktermios *termios, struct ktermios *old)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++	struct ucc_slow __iomem *uccp = qe_port->uccp;
++	unsigned int baud;
++	unsigned long flags;
++	u16 upsmr = in_be16(&uccp->upsmr);
++	struct ucc_uart_pram __iomem *uccup = qe_port->uccup;
++	u16 supsmr = in_be16(&uccup->supsmr);
++	u8 char_length = 2; /* 1 + CL + PEN + 1 + SL */
++
++	/* Character length programmed into the mode register is the
++	 * sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
++	 * 1 or 2 stop bits, minus 1.
++	 * The value 'bits' counts this for us.
++	 */
++
++	/* byte size */
++	upsmr &= UCC_UART_UPSMR_CL_MASK;
++	supsmr &= UCC_UART_SUPSMR_CL_MASK;
++
++	switch (termios->c_cflag & CSIZE) {
++	case CS5:
++		upsmr |= UCC_UART_UPSMR_CL_5;
++		supsmr |= UCC_UART_SUPSMR_CL_5;
++		char_length += 5;
++		break;
++	case CS6:
++		upsmr |= UCC_UART_UPSMR_CL_6;
++		supsmr |= UCC_UART_SUPSMR_CL_6;
++		char_length += 6;
++		break;
++	case CS7:
++		upsmr |= UCC_UART_UPSMR_CL_7;
++		supsmr |= UCC_UART_SUPSMR_CL_7;
++		char_length += 7;
++		break;
++	default:	/* case CS8 */
++		upsmr |= UCC_UART_UPSMR_CL_8;
++		supsmr |= UCC_UART_SUPSMR_CL_8;
++		char_length += 8;
++		break;
++	}
++
++	/* If CSTOPB is set, we want two stop bits */
++	if (termios->c_cflag & CSTOPB) {
++		upsmr |= UCC_UART_UPSMR_SL;
++		supsmr |= UCC_UART_SUPSMR_SL;
++		char_length++;  /* + SL */
++	}
++
++	if (termios->c_cflag & PARENB) {
++		upsmr |= UCC_UART_UPSMR_PEN;
++		supsmr |= UCC_UART_SUPSMR_PEN;
++		char_length++;  /* + PEN */
++
++		if (!(termios->c_cflag & PARODD)) {
++			upsmr &= ~(UCC_UART_UPSMR_RPM_MASK |
++				   UCC_UART_UPSMR_TPM_MASK);
++			upsmr |= UCC_UART_UPSMR_RPM_EVEN |
++				UCC_UART_UPSMR_TPM_EVEN;
++			supsmr &= ~(UCC_UART_SUPSMR_RPM_MASK |
++				    UCC_UART_SUPSMR_TPM_MASK);
++			supsmr |= UCC_UART_SUPSMR_RPM_EVEN |
++				UCC_UART_SUPSMR_TPM_EVEN;
++		}
++	}
++
++	/*
++	 * Set up parity check flag
++	 */
++	port->read_status_mask = BD_SC_EMPTY | BD_SC_OV;
++	if (termios->c_iflag & INPCK)
++		port->read_status_mask |= BD_SC_FR | BD_SC_PR;
++	if (termios->c_iflag & (BRKINT | PARMRK))
++		port->read_status_mask |= BD_SC_BR;
++
++	/*
++	 * Characters to ignore
++	 */
++	port->ignore_status_mask = 0;
++	if (termios->c_iflag & IGNPAR)
++		port->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
++	if (termios->c_iflag & IGNBRK) {
++		port->ignore_status_mask |= BD_SC_BR;
++		/*
++		 * If we're ignore parity and break indicators, ignore
++		 * overruns too.  (For real raw support).
++		 */
++		if (termios->c_iflag & IGNPAR)
++			port->ignore_status_mask |= BD_SC_OV;
++	}
++	/*
++	 * !!! ignore all characters if CREAD is not set
++	 */
++	if ((termios->c_cflag & CREAD) == 0)
++		port->read_status_mask &= ~BD_SC_EMPTY;
++
++	baud = uart_get_baud_rate(port, termios, old, 0, 115200);
++
++	/* Do we really need a spinlock here? */
++	spin_lock_irqsave(&port->lock, flags);
++
++	out_be16(&uccp->upsmr, upsmr);
++	if (soft_uart) {
++		out_be16(&uccup->supsmr, supsmr);
++		out_8(&uccup->rx_length, char_length);
++
++		/* Soft-UART requires a 1X multiplier for TX */
++		qe_setbrg(qe_port->us_info.rx_clock, baud, 16);
++		qe_setbrg(qe_port->us_info.tx_clock, baud, 1);
++	} else {
++		qe_setbrg(qe_port->us_info.rx_clock, baud, 16);
++		qe_setbrg(qe_port->us_info.tx_clock, baud, 16);
++	}
++
++	spin_unlock_irqrestore(&port->lock, flags);
++}
++
++/*
++ * Return a pointer to a string that describes what kind of port this is.
++ */
++static const char *qe_uart_type(struct uart_port *port)
++{
++	return "QE";
++}
++
++/*
++ * Allocate any memory and I/O resources required by the port.
++ */
++static int qe_uart_request_port(struct uart_port *port)
++{
++	int ret;
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++	struct ucc_slow_info *us_info = &qe_port->us_info;
++	struct ucc_slow_private *uccs;
++	unsigned int rx_size, tx_size;
++	void *bd_virt;
++	dma_addr_t bd_dma_addr = 0;
++
++	ret = ucc_slow_init(us_info, &uccs);
++	if (ret) {
++		dev_err(port->dev, "could not initialize UCC%u\n",
++		       qe_port->ucc_num);
++		return ret;
++	}
++
++	qe_port->us_private = uccs;
++	qe_port->uccp = uccs->us_regs;
++	qe_port->uccup = (struct ucc_uart_pram *) uccs->us_pram;
++	qe_port->rx_bd_base = uccs->rx_bd;
++	qe_port->tx_bd_base = uccs->tx_bd;
++
++	/*
++	 * Allocate the transmit and receive data buffers.
++	 */
++
++	rx_size = L1_CACHE_ALIGN(qe_port->rx_nrfifos * qe_port->rx_fifosize);
++	tx_size = L1_CACHE_ALIGN(qe_port->tx_nrfifos * qe_port->tx_fifosize);
++
++	bd_virt = dma_alloc_coherent(NULL, rx_size + tx_size, &bd_dma_addr,
++		GFP_KERNEL);
++	if (!bd_virt) {
++		dev_err(port->dev, "could not allocate buffer descriptors\n");
++		return -ENOMEM;
++	}
++
++	qe_port->bd_virt = bd_virt;
++	qe_port->bd_dma_addr = bd_dma_addr;
++	qe_port->bd_size = rx_size + tx_size;
++
++	qe_port->rx_buf = bd_virt;
++	qe_port->tx_buf = qe_port->rx_buf + rx_size;
++
++	return 0;
++}
++
++/*
++ * Configure the port.
++ *
++ * We say we're a CPM-type port because that's mostly true.  Once the device
++ * is configured, this driver operates almost identically to the CPM serial
++ * driver.
++ */
++static void qe_uart_config_port(struct uart_port *port, int flags)
++{
++	if (flags & UART_CONFIG_TYPE) {
++		port->type = PORT_CPM;
++		qe_uart_request_port(port);
++	}
++}
++
++/*
++ * Release any memory and I/O resources that were allocated in
++ * qe_uart_request_port().
++ */
++static void qe_uart_release_port(struct uart_port *port)
++{
++	struct uart_qe_port *qe_port =
++		container_of(port, struct uart_qe_port, port);
++	struct ucc_slow_private *uccs = qe_port->us_private;
++
++	dma_free_coherent(NULL, qe_port->bd_size, qe_port->bd_virt,
++			  qe_port->bd_dma_addr);
++
++	ucc_slow_free(uccs);
++}
++
++/*
++ * Verify that the data in serial_struct is suitable for this device.
++ */
++static int qe_uart_verify_port(struct uart_port *port,
++			       struct serial_struct *ser)
++{
++	if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM)
++		return -EINVAL;
++
++	if (ser->irq < 0 || ser->irq >= NR_IRQS)
++		return -EINVAL;
++
++	if (ser->baud_base < 9600)
++		return -EINVAL;
++
++	return 0;
++}
++/* UART operations
++ *
++ * Details on these functions can be found in Documentation/serial/driver
++ */
++static struct uart_ops qe_uart_pops = {
++	.tx_empty       = qe_uart_tx_empty,
++	.set_mctrl      = qe_uart_set_mctrl,
++	.get_mctrl      = qe_uart_get_mctrl,
++	.stop_tx	= qe_uart_stop_tx,
++	.start_tx       = qe_uart_start_tx,
++	.stop_rx	= qe_uart_stop_rx,
++	.enable_ms      = qe_uart_enable_ms,
++	.break_ctl      = qe_uart_break_ctl,
++	.startup	= qe_uart_startup,
++	.shutdown       = qe_uart_shutdown,
++	.set_termios    = qe_uart_set_termios,
++	.type   	= qe_uart_type,
++	.release_port   = qe_uart_release_port,
++	.request_port   = qe_uart_request_port,
++	.config_port    = qe_uart_config_port,
++	.verify_port    = qe_uart_verify_port,
++};
++
++/*
++ * Obtain the SOC model number and revision level
++ *
++ * This function parses the device tree to obtain the SOC model.  It then
++ * reads the SVR register to the revision.
++ *
++ * The device tree stores the SOC model two different ways.
++ *
++ * The new way is:
++ *
++ *      	cpu@0 {
++ *      		compatible = "PowerPC,8323";
++ *      		device_type = "cpu";
++ *      		...
++ *
++ *
++ * The old way is:
++ *      	 PowerPC,8323@0 {
++ *      		device_type = "cpu";
++ *      		...
++ *
++ * This code first checks the new way, and then the old way.
++ */
++static unsigned int soc_info(unsigned int *rev_h, unsigned int *rev_l)
++{
++	struct device_node *np;
++	const char *soc_string;
++	unsigned int svr;
++	unsigned int soc;
++
++	/* Find the CPU node */
++	np = of_find_node_by_type(NULL, "cpu");
++	if (!np)
++		return 0;
++	/* Find the compatible property */
++	soc_string = of_get_property(np, "compatible", NULL);
++	if (!soc_string)
++		/* No compatible property, so try the name. */
++		soc_string = np->name;
++
++	/* Extract the SOC number from the "PowerPC," string */
++	if ((sscanf(soc_string, "PowerPC,%u", &soc) != 1) || !soc)
++		return 0;
++
++	/* Get the revision from the SVR */
++	svr = mfspr(SPRN_SVR);
++	*rev_h = (svr >> 4) & 0xf;
++	*rev_l = svr & 0xf;
++
++	return soc;
++}
++
++/*
++ * requst_firmware_nowait() callback function
++ *
++ * This function is called by the kernel when a firmware is made available,
++ * or if it times out waiting for the firmware.
++ */
++static void uart_firmware_cont(const struct firmware *fw, void *context)
++{
++	struct qe_firmware *firmware;
++	struct device *dev = context;
++	int ret;
++
++	if (!fw) {
++		dev_err(dev, "firmware not found\n");
++		return;
++	}
++
++	firmware = (struct qe_firmware *) fw->data;
++
++	if (firmware->header.length != fw->size) {
++		dev_err(dev, "invalid firmware\n");
++		return;
++	}
++
++	ret = qe_upload_firmware(firmware);
++	if (ret) {
++		dev_err(dev, "could not load firmware\n");
++		return;
++	}
++
++	firmware_loaded = 1;
++}
++
++static int ucc_uart_probe(struct of_device *ofdev,
++	const struct of_device_id *match)
++{
++	struct device_node *np = ofdev->node;
++	const unsigned int *iprop;      /* Integer OF properties */
++	const char *sprop;      /* String OF properties */
++	struct uart_qe_port *qe_port = NULL;
++	struct resource res;
++	int ret;
++
++	/*
++	 * Determine if we need Soft-UART mode
++	 */
++	if (of_find_property(np, "soft-uart", NULL)) {
++		dev_dbg(&ofdev->dev, "using Soft-UART mode\n");
++		soft_uart = 1;
++	}
++
++	/*
++	 * If we are using Soft-UART, determine if we need to upload the
++	 * firmware, too.
++	 */
++	if (soft_uart) {
++		struct qe_firmware_info *qe_fw_info;
++
++		qe_fw_info = qe_get_firmware_info();
++
++		/* Check if the firmware has been uploaded. */
++		if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) {
++			firmware_loaded = 1;
++		} else {
++			char filename[32];
++			unsigned int soc;
++			unsigned int rev_h;
++			unsigned int rev_l;
++
++			soc = soc_info(&rev_h, &rev_l);
++			if (!soc) {
++				dev_err(&ofdev->dev, "unknown CPU model\n");
++				return -ENXIO;
++			}
++			sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin",
++				soc, rev_h, rev_l);
++
++			dev_info(&ofdev->dev, "waiting for firmware %s\n",
++				filename);
++
++			/*
++			 * We call request_firmware_nowait instead of
++			 * request_firmware so that the driver can load and
++			 * initialize the ports without holding up the rest of
++			 * the kernel.  If hotplug support is enabled in the
++			 * kernel, then we use it.
++			 */
++			ret = request_firmware_nowait(THIS_MODULE,
++				FW_ACTION_HOTPLUG, filename, &ofdev->dev,
++				&ofdev->dev, uart_firmware_cont);
++			if (ret) {
++				dev_err(&ofdev->dev,
++					"could not load firmware %s\n",
++					filename);
++				return ret;
++			}
++		}
++	}
++
++	qe_port = kzalloc(sizeof(struct uart_qe_port), GFP_KERNEL);
++	if (!qe_port) {
++		dev_err(&ofdev->dev, "can't allocate QE port structure\n");
++		return -ENOMEM;
++	}
++
++	/* Search for IRQ and mapbase */
++	ret = of_address_to_resource(np, 0, &res);
++	if (ret) {
++		dev_err(&ofdev->dev, "missing 'reg' property in device tree\n");
++		kfree(qe_port);
++		return ret;
++	}
++	if (!res.start) {
++		dev_err(&ofdev->dev, "invalid 'reg' property in device tree\n");
++		kfree(qe_port);
++		return -EINVAL;
++	}
++	qe_port->port.mapbase = res.start;
++
++	/* Get the UCC number (device ID) */
++	/* UCCs are numbered 1-7 */
++	iprop = of_get_property(np, "device-id", NULL);
++	if (!iprop || (*iprop < 1) || (*iprop > UCC_MAX_NUM)) {
++		dev_err(&ofdev->dev,
++			"missing or invalid UCC specified in device tree\n");
++		kfree(qe_port);
++		return -ENODEV;
++	}
++	qe_port->ucc_num = *iprop - 1;
++
++	/*
++	 * In the future, we should not require the BRG to be specified in the
++	 * device tree.  If no clock-source is specified, then just pick a BRG
++	 * to use.  This requires a new QE library function that manages BRG
++	 * assignments.
++	 */
++
++	sprop = of_get_property(np, "rx-clock-name", NULL);
++	if (!sprop) {
++		dev_err(&ofdev->dev, "missing rx-clock-name in device tree\n");
++		kfree(qe_port);
++		return -ENODEV;
++	}
++
++	qe_port->us_info.rx_clock = qe_clock_source(sprop);
++	if ((qe_port->us_info.rx_clock < QE_BRG1) ||
++	    (qe_port->us_info.rx_clock > QE_BRG16)) {
++		dev_err(&ofdev->dev, "rx-clock-name must be a BRG for UART\n");
++		kfree(qe_port);
++		return -ENODEV;
++	}
++
++#ifdef LOOPBACK
++	/* In internal loopback mode, TX and RX must use the same clock */
++	qe_port->us_info.tx_clock = qe_port->us_info.rx_clock;
++#else
++	sprop = of_get_property(np, "tx-clock-name", NULL);
++	if (!sprop) {
++		dev_err(&ofdev->dev, "missing tx-clock-name in device tree\n");
++		kfree(qe_port);
++		return -ENODEV;
++	}
++	qe_port->us_info.tx_clock = qe_clock_source(sprop);
++#endif
++	if ((qe_port->us_info.tx_clock < QE_BRG1) ||
++	    (qe_port->us_info.tx_clock > QE_BRG16)) {
++		dev_err(&ofdev->dev, "tx-clock-name must be a BRG for UART\n");
++		kfree(qe_port);
++		return -ENODEV;
++	}
++
++	/* Get the port number, numbered 0-3 */
++	iprop = of_get_property(np, "port-number", NULL);
++	if (!iprop) {
++		dev_err(&ofdev->dev, "missing port-number in device tree\n");
++		kfree(qe_port);
++		return -EINVAL;
++	}
++	qe_port->port.line = *iprop;
++	if (qe_port->port.line >= UCC_MAX_UART) {
++		dev_err(&ofdev->dev, "port-number must be 0-%u\n",
++			UCC_MAX_UART - 1);
++		kfree(qe_port);
++		return -EINVAL;
++	}
++
++	qe_port->port.irq = irq_of_parse_and_map(np, 0);
++	if (qe_port->port.irq == NO_IRQ) {
++		dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n",
++		       qe_port->ucc_num + 1);
++		kfree(qe_port);
++		return -EINVAL;
++	}
++
++	/*
++	 * Newer device trees have an "fsl,qe" compatible property for the QE
++	 * node, but we still need to support older device trees.
++	 */
++	np = of_find_compatible_node(NULL, NULL, "fsl,qe");
++	if (!np) {
++		np = of_find_node_by_type(NULL, "qe");
++		if (!np) {
++			dev_err(&ofdev->dev, "could not find 'qe' node\n");
++			kfree(qe_port);
++			return -EINVAL;
++		}
++	}
++
++	iprop = of_get_property(np, "brg-frequency", NULL);
++	if (!iprop) {
++		dev_err(&ofdev->dev,
++		       "missing brg-frequency in device tree\n");
++		kfree(qe_port);
++		return -EINVAL;
++	}
++
++	if (*iprop)
++		qe_port->port.uartclk = *iprop;
++	else {
++		/*
++		 * Older versions of U-Boot do not initialize the brg-frequency
++		 * property, so in this case we assume the BRG frequency is
++		 * half the QE bus frequency.
++		 */
++		iprop = of_get_property(np, "bus-frequency", NULL);
++		if (!iprop) {
++			dev_err(&ofdev->dev,
++				"missing QE bus-frequency in device tree\n");
++			kfree(qe_port);
++			return -EINVAL;
++		}
++		if (*iprop)
++			qe_port->port.uartclk = *iprop / 2;
++		else {
++			dev_err(&ofdev->dev,
++				"invalid QE bus-frequency in device tree\n");
++			kfree(qe_port);
++			return -EINVAL;
++		}
++	}
++
++	spin_lock_init(&qe_port->port.lock);
++	qe_port->np = np;
++	qe_port->port.dev = &ofdev->dev;
++	qe_port->port.ops = &qe_uart_pops;
++	qe_port->port.iotype = UPIO_MEM;
++
++	qe_port->tx_nrfifos = TX_NUM_FIFO;
++	qe_port->tx_fifosize = TX_BUF_SIZE;
++	qe_port->rx_nrfifos = RX_NUM_FIFO;
++	qe_port->rx_fifosize = RX_BUF_SIZE;
++
++	qe_port->wait_closing = UCC_WAIT_CLOSING;
++	qe_port->port.fifosize = 512;
++	qe_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
++
++	qe_port->us_info.ucc_num = qe_port->ucc_num;
++	qe_port->us_info.regs = (phys_addr_t) res.start;
++	qe_port->us_info.irq = qe_port->port.irq;
++
++	qe_port->us_info.rx_bd_ring_len = qe_port->rx_nrfifos;
++	qe_port->us_info.tx_bd_ring_len = qe_port->tx_nrfifos;
++
++	/* Make sure ucc_slow_init() initializes both TX and RX */
++	qe_port->us_info.init_tx = 1;
++	qe_port->us_info.init_rx = 1;
++
++	/* Add the port to the uart sub-system.  This will cause
++	 * qe_uart_config_port() to be called, so the us_info structure must
++	 * be initialized.
++	 */
++	ret = uart_add_one_port(&ucc_uart_driver, &qe_port->port);
++	if (ret) {
++		dev_err(&ofdev->dev, "could not add /dev/ttyQE%u\n",
++		       qe_port->port.line);
++		kfree(qe_port);
++		return ret;
++	}
++
++	dev_set_drvdata(&ofdev->dev, qe_port);
++
++	dev_info(&ofdev->dev, "UCC%u assigned to /dev/ttyQE%u\n",
++		qe_port->ucc_num + 1, qe_port->port.line);
++
++	/* Display the mknod command for this device */
++	dev_dbg(&ofdev->dev, "mknod command is 'mknod /dev/ttyQE%u c %u %u'\n",
++	       qe_port->port.line, SERIAL_QE_MAJOR,
++	       SERIAL_QE_MINOR + qe_port->port.line);
++
++	return 0;
++}
++
++static int ucc_uart_remove(struct of_device *ofdev)
++{
++	struct uart_qe_port *qe_port = dev_get_drvdata(&ofdev->dev);
++
++	dev_info(&ofdev->dev, "removing /dev/ttyQE%u\n", qe_port->port.line);
++
++	uart_remove_one_port(&ucc_uart_driver, &qe_port->port);
++
++	dev_set_drvdata(&ofdev->dev, NULL);
++	kfree(qe_port);
++
++	return 0;
++}
++
++static struct of_device_id ucc_uart_match[] = {
++	{
++		.type = "serial",
++		.compatible = "ucc_uart",
++	},
++	{},
++};
++MODULE_DEVICE_TABLE(of, ucc_uart_match);
++
++static struct of_platform_driver ucc_uart_of_driver = {
++	.owner  	= THIS_MODULE,
++	.name   	= "ucc_uart",
++	.match_table    = ucc_uart_match,
++	.probe  	= ucc_uart_probe,
++	.remove 	= ucc_uart_remove,
++};
++
++static int __init ucc_uart_init(void)
++{
++	int ret;
++
++	printk(KERN_INFO "Freescale QUICC Engine UART device driver\n");
++#ifdef LOOPBACK
++	printk(KERN_INFO "ucc-uart: Using loopback mode\n");
++#endif
++
++	ret = uart_register_driver(&ucc_uart_driver);
++	if (ret) {
++		printk(KERN_ERR "ucc-uart: could not register UART driver\n");
++		return ret;
++	}
++
++	ret = of_register_platform_driver(&ucc_uart_of_driver);
++	if (ret)
++		printk(KERN_ERR
++		       "ucc-uart: could not register platform driver\n");
++
++	return ret;
++}
++
++static void __exit ucc_uart_exit(void)
++{
++	printk(KERN_INFO
++	       "Freescale QUICC Engine UART device driver unloading\n");
++
++	of_unregister_platform_driver(&ucc_uart_of_driver);
++	uart_unregister_driver(&ucc_uart_driver);
++}
++
++module_init(ucc_uart_init);
++module_exit(ucc_uart_exit);
++
++MODULE_DESCRIPTION("Freescale QUICC Engine (QE) UART");
++MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_QE_MAJOR);
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/drivers/spi/mpc52xx_psc_spi.c powerpc.git/drivers/spi/mpc52xx_psc_spi.c
+--- linux-2.6.24/drivers/spi/mpc52xx_psc_spi.c	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/drivers/spi/mpc52xx_psc_spi.c	2008-01-28 20:26:20.000000000 +0100
+@@ -330,6 +330,7 @@
+ 
+ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
+ {
++	struct device_node *np;
+ 	struct mpc52xx_cdm __iomem *cdm;
+ 	struct mpc52xx_gpio __iomem *gpio;
+ 	struct mpc52xx_psc __iomem *psc = mps->psc;
+@@ -338,8 +339,12 @@
+ 	int ret = 0;
+ 
+ #if defined(CONFIG_PPC_MERGE)
+-	cdm = mpc52xx_find_and_map("mpc5200-cdm");
+-	gpio = mpc52xx_find_and_map("mpc5200-gpio");
++	np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm");
++	cdm = of_iomap(np, 0);
++	of_node_put(np);
++	np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio");
++	gpio = of_iomap(np, 0);
++	of_node_put(np);
+ #else
+ 	cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
+ 	gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
+diff -x .git -x .gitignore -Nur linux-2.6.24/fs/openpromfs/inode.c powerpc.git/fs/openpromfs/inode.c
+--- linux-2.6.24/fs/openpromfs/inode.c	2008-01-28 20:50:11.000000000 +0100
++++ powerpc.git/fs/openpromfs/inode.c	2008-01-28 20:26:31.000000000 +0100
+@@ -131,7 +131,7 @@
+ 	/* Nothing to do */
+ }
+ 
+-static const struct seq_operations property_op = {
++static struct seq_operations property_op = {
+ 	.start		= property_start,
+ 	.next		= property_next,
+ 	.stop		= property_stop,
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/8xx_immap.h powerpc.git/include/asm-powerpc/8xx_immap.h
+--- linux-2.6.24/include/asm-powerpc/8xx_immap.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/8xx_immap.h	2008-01-28 20:26:42.000000000 +0100
+@@ -123,7 +123,7 @@
+ #define OR_G5LA		0x00000400	/* Output #GPL5 on #GPL_A5		*/
+ #define OR_G5LS		0x00000200	/* Drive #GPL high on falling edge of...*/
+ #define OR_BI		0x00000100	/* Burst inhibit			*/
+-#define OR_SCY_MSK	0x000000f0	/* Cycle Lenght in Clocks		*/
++#define OR_SCY_MSK	0x000000f0	/* Cycle Length in Clocks		*/
+ #define OR_SCY_0_CLK	0x00000000	/* 0 clock cycles wait states		*/
+ #define OR_SCY_1_CLK	0x00000010	/* 1 clock cycles wait states		*/
+ #define OR_SCY_2_CLK	0x00000020	/* 2 clock cycles wait states		*/
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/commproc.h powerpc.git/include/asm-powerpc/commproc.h
+--- linux-2.6.24/include/asm-powerpc/commproc.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/commproc.h	2008-01-28 20:26:42.000000000 +0100
+@@ -693,7 +693,7 @@
+ #define	CICR_SCC_SCC3		((uint)0x00200000)	/* SCC3 @ SCCc */
+ #define	CICR_SCB_SCC2		((uint)0x00040000)	/* SCC2 @ SCCb */
+ #define	CICR_SCA_SCC1		((uint)0x00000000)	/* SCC1 @ SCCa */
+-#define CICR_IRL_MASK		((uint)0x0000e000)	/* Core interrrupt */
++#define CICR_IRL_MASK		((uint)0x0000e000)	/* Core interrupt */
+ #define CICR_HP_MASK		((uint)0x00001f00)	/* Hi-pri int. */
+ #define CICR_IEN		((uint)0x00000080)	/* Int. enable */
+ #define CICR_SPS		((uint)0x00000001)	/* SCC Spread */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/cpm.h powerpc.git/include/asm-powerpc/cpm.h
+--- linux-2.6.24/include/asm-powerpc/cpm.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/cpm.h	2008-01-28 20:26:42.000000000 +0100
+@@ -10,5 +10,6 @@
+ unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
+ void __iomem *cpm_muram_addr(unsigned long offset);
+ dma_addr_t cpm_muram_dma(void __iomem *addr);
++int cpm_command(u32 command, u8 opcode);
+ 
+ #endif
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/cputable.h powerpc.git/include/asm-powerpc/cputable.h
+--- linux-2.6.24/include/asm-powerpc/cputable.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/cputable.h	2008-01-28 20:26:42.000000000 +0100
+@@ -57,6 +57,14 @@
+ 	PPC_PMC_PA6T = 2,
+ };
+ 
++struct pt_regs;
++
++extern int machine_check_generic(struct pt_regs *regs);
++extern int machine_check_4xx(struct pt_regs *regs);
++extern int machine_check_440A(struct pt_regs *regs);
++extern int machine_check_e500(struct pt_regs *regs);
++extern int machine_check_e200(struct pt_regs *regs);
++
+ /* NOTE WELL: Update identify_cpu() if fields are added or removed! */
+ struct cpu_spec {
+ 	/* CPU is matched via (PVR & pvr_mask) == pvr_value */
+@@ -97,6 +105,11 @@
+ 
+ 	/* Name of processor class, for the ELF AT_PLATFORM entry */
+ 	char		*platform;
++
++	/* Processor specific machine check handling. Return negative
++	 * if the error is fatal, 1 if it was fully recovered and 0 to
++	 * pass up (not CPU originated) */
++	int		(*machine_check)(struct pt_regs *regs);
+ };
+ 
+ extern struct cpu_spec		*cur_cpu_spec;
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/cputhreads.h powerpc.git/include/asm-powerpc/cputhreads.h
+--- linux-2.6.24/include/asm-powerpc/cputhreads.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/include/asm-powerpc/cputhreads.h	2008-01-28 20:26:42.000000000 +0100
+@@ -0,0 +1,71 @@
++#ifndef _ASM_POWERPC_CPUTHREADS_H
++#define _ASM_POWERPC_CPUTHREADS_H
++
++#include <linux/cpumask.h>
++
++/*
++ * Mapping of threads to cores
++ */
++
++#ifdef CONFIG_SMP
++extern int threads_per_core;
++extern int threads_shift;
++extern cpumask_t threads_core_mask;
++#else
++#define threads_per_core	1
++#define threads_shift		0
++#define threads_core_mask	(CPU_MASK_CPU0)
++#endif
++
++/* cpu_thread_mask_to_cores - Return a cpumask of one per cores
++ *                            hit by the argument
++ *
++ * @threads:	a cpumask of threads
++ *
++ * This function returns a cpumask which will have one "cpu" (or thread)
++ * bit set for each core that has at least one thread set in the argument.
++ *
++ * This can typically be used for things like IPI for tlb invalidations
++ * since those need to be done only once per core/TLB
++ */
++static inline cpumask_t cpu_thread_mask_to_cores(cpumask_t threads)
++{
++	cpumask_t	tmp, res;
++	int		i;
++
++	res = CPU_MASK_NONE;
++	for (i = 0; i < NR_CPUS; i += threads_per_core) {
++		cpus_shift_right(tmp, threads_core_mask, i);
++		if (cpus_intersects(threads, tmp))
++			cpu_set(i, res);
++	}
++	return res;
++}
++
++static inline int cpu_nr_cores(void)
++{
++	return NR_CPUS >> threads_shift;
++}
++
++static inline cpumask_t cpu_online_cores_map(void)
++{
++	return cpu_thread_mask_to_cores(cpu_online_map);
++}
++
++static inline int cpu_thread_to_core(int cpu)
++{
++	return cpu >> threads_shift;
++}
++
++static inline int cpu_thread_in_core(int cpu)
++{
++	return cpu & (threads_per_core - 1);
++}
++
++static inline int cpu_first_thread_in_core(int cpu)
++{
++	return cpu & ~(threads_per_core - 1);
++}
++
++#endif /* _ASM_POWERPC_CPUTHREADS_H */
++
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/dcr-native.h powerpc.git/include/asm-powerpc/dcr-native.h
+--- linux-2.6.24/include/asm-powerpc/dcr-native.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/dcr-native.h	2008-01-28 20:26:42.000000000 +0100
+@@ -22,6 +22,8 @@
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+ 
++#include <linux/spinlock.h>
++
+ typedef struct {
+ 	unsigned int base;
+ } dcr_host_t;
+@@ -55,20 +57,28 @@
+ } while (0)
+ 
+ /* R/W of indirect DCRs make use of standard naming conventions for DCRs */
+-#define mfdcri(base, reg)			\
+-({						\
+-	mtdcr(base ## _CFGADDR, base ## _ ## reg);	\
+-	mfdcr(base ## _CFGDATA);			\
++extern spinlock_t dcr_ind_lock;
++
++#define mfdcri(base, reg)				\
++({							\
++	unsigned long flags; 				\
++	unsigned int val;				\
++	spin_lock_irqsave(&dcr_ind_lock, flags);	\
++	mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg);	\
++	val = mfdcr(DCRN_ ## base ## _CONFIG_DATA);	\
++	spin_unlock_irqrestore(&dcr_ind_lock, flags);	\
++	val;						\
+ })
+ 
+-#define mtdcri(base, reg, data)			\
+-do {						\
+-	mtdcr(base ## _CFGADDR, base ## _ ## reg);	\
+-	mtdcr(base ## _CFGDATA, data);		\
++#define mtdcri(base, reg, data)				\
++do {							\
++	unsigned long flags; 				\
++	spin_lock_irqsave(&dcr_ind_lock, flags);	\
++	mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg);	\
++	mtdcr(DCRN_ ## base ## _CONFIG_DATA, data);	\
++	spin_unlock_irqrestore(&dcr_ind_lock, flags);	\
+ } while (0)
+ 
+ #endif /* __ASSEMBLY__ */
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_POWERPC_DCR_NATIVE_H */
+-
+-
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/dcr-regs.h powerpc.git/include/asm-powerpc/dcr-regs.h
+--- linux-2.6.24/include/asm-powerpc/dcr-regs.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/include/asm-powerpc/dcr-regs.h	2008-01-28 20:26:42.000000000 +0100
+@@ -0,0 +1,71 @@
++/*
++ * Common DCR / SDR / CPR register definitions used on various IBM/AMCC
++ * 4xx processors
++ *
++ *    Copyright 2007 Benjamin Herrenschmidt, IBM Corp
++ *                   <benh@kernel.crashing.org>
++ *
++ * Mostly lifted from asm-ppc/ibm4xx.h by
++ *
++ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
++ *
++ */
++
++#ifndef __DCR_REGS_H__
++#define __DCR_REGS_H__
++
++/*
++ * Most DCRs used for controlling devices such as the MAL, DMA engine,
++ * etc... are obtained for the device tree.
++ *
++ * The definitions in this files are fixed DCRs and indirect DCRs that
++ * are commonly used outside of specific drivers or refer to core
++ * common registers that may occasionally have to be tweaked outside
++ * of the driver main register set
++ */
++
++/* CPRs (440GX and 440SP/440SPe) */
++#define DCRN_CPR0_CONFIG_ADDR	0xc
++#define DCRN_CPR0_CONFIG_DATA	0xd
++
++/* SDRs (440GX and 440SP/440SPe) */
++#define DCRN_SDR0_CONFIG_ADDR 	0xe
++#define DCRN_SDR0_CONFIG_DATA	0xf
++
++#define SDR0_PFC0		0x4100
++#define SDR0_PFC1		0x4101
++#define SDR0_PFC1_EPS		0x1c00000
++#define SDR0_PFC1_EPS_SHIFT	22
++#define SDR0_PFC1_RMII		0x02000000
++#define SDR0_MFR		0x4300
++#define SDR0_MFR_TAH0 		0x80000000  	/* TAHOE0 Enable */
++#define SDR0_MFR_TAH1 		0x40000000  	/* TAHOE1 Enable */
++#define SDR0_MFR_PCM  		0x10000000  	/* PPC440GP irq compat mode */
++#define SDR0_MFR_ECS  		0x08000000  	/* EMAC int clk */
++#define SDR0_MFR_T0TXFL		0x00080000
++#define SDR0_MFR_T0TXFH		0x00040000
++#define SDR0_MFR_T1TXFL		0x00020000
++#define SDR0_MFR_T1TXFH		0x00010000
++#define SDR0_MFR_E0TXFL		0x00008000
++#define SDR0_MFR_E0TXFH		0x00004000
++#define SDR0_MFR_E0RXFL		0x00002000
++#define SDR0_MFR_E0RXFH		0x00001000
++#define SDR0_MFR_E1TXFL		0x00000800
++#define SDR0_MFR_E1TXFH		0x00000400
++#define SDR0_MFR_E1RXFL		0x00000200
++#define SDR0_MFR_E1RXFH		0x00000100
++#define SDR0_MFR_E2TXFL		0x00000080
++#define SDR0_MFR_E2TXFH		0x00000040
++#define SDR0_MFR_E2RXFL		0x00000020
++#define SDR0_MFR_E2RXFH		0x00000010
++#define SDR0_MFR_E3TXFL		0x00000008
++#define SDR0_MFR_E3TXFH		0x00000004
++#define SDR0_MFR_E3RXFL		0x00000002
++#define SDR0_MFR_E3RXFH		0x00000001
++#define SDR0_UART0		0x0120
++#define SDR0_UART1		0x0121
++#define SDR0_UART2		0x0122
++#define SDR0_UART3		0x0123
++#define SDR0_CUST0		0x4000
++
++#endif /* __DCR_REGS_H__ */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/dma-mapping.h powerpc.git/include/asm-powerpc/dma-mapping.h
+--- linux-2.6.24/include/asm-powerpc/dma-mapping.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/dma-mapping.h	2008-01-28 20:26:42.000000000 +0100
+@@ -87,6 +87,9 @@
+ 	return dma_ops->dma_supported(dev, mask);
+ }
+ 
++/* We have our own implementation of pci_set_dma_mask() */
++#define HAVE_ARCH_PCI_SET_DMA_MASK
++
+ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
+ {
+ 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+@@ -186,8 +189,6 @@
+ extern struct dma_mapping_ops dma_iommu_ops;
+ extern struct dma_mapping_ops dma_direct_ops;
+ 
+-extern unsigned long dma_direct_offset;
+-
+ #else /* CONFIG_PPC64 */
+ 
+ #define dma_supported(dev, mask)	(1)
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/firmware.h powerpc.git/include/asm-powerpc/firmware.h
+--- linux-2.6.24/include/asm-powerpc/firmware.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/firmware.h	2008-01-28 20:26:42.000000000 +0100
+@@ -64,7 +64,7 @@
+ 	FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
+ 	FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
+ 	FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT,
+-	FW_FEATURE_CELLEB_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_BEAT,
++	FW_FEATURE_CELLEB_ALWAYS = 0,
+ 	FW_FEATURE_NATIVE_POSSIBLE = 0,
+ 	FW_FEATURE_NATIVE_ALWAYS = 0,
+ 	FW_FEATURE_POSSIBLE =
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/immap_86xx.h powerpc.git/include/asm-powerpc/immap_86xx.h
+--- linux-2.6.24/include/asm-powerpc/immap_86xx.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/immap_86xx.h	2008-01-28 20:26:42.000000000 +0100
+@@ -89,14 +89,14 @@
+  * them.
+  *
+  * guts: Pointer to GUTS structure
+- * co: The DMA controller (1 or 2)
++ * co: The DMA controller (0 or 1)
+  * ch: The channel on the DMA controller (0, 1, 2, or 3)
+  * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx)
+  */
+ static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
+ 	unsigned int co, unsigned int ch, unsigned int device)
+ {
+-	unsigned int shift = 16 + (8 * (2 - co) + 2 * (3 - ch));
++	unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
+ 
+ 	clrsetbits_be32(&guts->dmacr, 3 << shift, device << shift);
+ }
+@@ -118,6 +118,27 @@
+ #define CCSR_GUTS_PMUXCR_DMA1_0		0x00000002
+ #define CCSR_GUTS_PMUXCR_DMA1_3		0x00000001
+ 
++/*
++ * Set the DMA external control bits in the GUTS
++ *
++ * The DMA external control bits in the PMUXCR are only meaningful for
++ * channels 0 and 3.  Any other channels are ignored.
++ *
++ * guts: Pointer to GUTS structure
++ * co: The DMA controller (0 or 1)
++ * ch: The channel on the DMA controller (0, 1, 2, or 3)
++ * value: the new value for the bit (0 or 1)
++ */
++static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
++	unsigned int co, unsigned int ch, unsigned int value)
++{
++	if ((ch == 0) || (ch == 3)) {
++		unsigned int shift = 2 * (co + 1) - (ch & 1) - 1;
++
++		clrsetbits_be32(&guts->pmuxcr, 1 << shift, value << shift);
++	}
++}
++
+ #define CCSR_GUTS_CLKDVDR_PXCKEN	0x80000000
+ #define CCSR_GUTS_CLKDVDR_SSICKEN	0x20000000
+ #define CCSR_GUTS_CLKDVDR_PXCKINV	0x10000000
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/immap_qe.h powerpc.git/include/asm-powerpc/immap_qe.h
+--- linux-2.6.24/include/asm-powerpc/immap_qe.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/immap_qe.h	2008-01-28 20:26:42.000000000 +0100
+@@ -393,9 +393,39 @@
+ 	u8	res2[0x48];
+ } __attribute__ ((packed));
+ 
+-/* RISC Special Registers (Trap and Breakpoint) */
++/*
++ * RISC Special Registers (Trap and Breakpoint).  These are described in
++ * the QE Developer's Handbook.
++ */
+ struct rsp {
+-	u32	reg[0x40];	/* 64 32-bit registers */
++	__be32 tibcr[16];	/* Trap/instruction breakpoint control regs */
++	u8 res0[64];
++	__be32 ibcr0;
++	__be32 ibs0;
++	__be32 ibcnr0;
++	u8 res1[4];
++	__be32 ibcr1;
++	__be32 ibs1;
++	__be32 ibcnr1;
++	__be32 npcr;
++	__be32 dbcr;
++	__be32 dbar;
++	__be32 dbamr;
++	__be32 dbsr;
++	__be32 dbcnr;
++	u8 res2[12];
++	__be32 dbdr_h;
++	__be32 dbdr_l;
++	__be32 dbdmr_h;
++	__be32 dbdmr_l;
++	__be32 bsr;
++	__be32 bor;
++	__be32 bior;
++	u8 res3[4];
++	__be32 iatr[4];
++	__be32 eccr;		/* Exception control configuration register */
++	__be32 eicr;
++	u8 res4[0x100-0xf8];
+ } __attribute__ ((packed));
+ 
+ struct qe_immap {
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/io.h powerpc.git/include/asm-powerpc/io.h
+--- linux-2.6.24/include/asm-powerpc/io.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/io.h	2008-01-28 20:26:42.000000000 +0100
+@@ -50,15 +50,16 @@
+ #define PCI_DRAM_OFFSET	pci_dram_offset
+ #else
+ #define _IO_BASE	pci_io_base
+-#define _ISA_MEM_BASE	0
++#define _ISA_MEM_BASE	isa_mem_base
+ #define PCI_DRAM_OFFSET	0
+ #endif
+ 
+ extern unsigned long isa_io_base;
+-extern unsigned long isa_mem_base;
+ extern unsigned long pci_io_base;
+ extern unsigned long pci_dram_offset;
+ 
++extern resource_size_t isa_mem_base;
++
+ #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_INDIRECT_IO)
+ #error CONFIG_PPC_INDIRECT_IO is not yet supported on 32 bits
+ #endif
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/iommu.h powerpc.git/include/asm-powerpc/iommu.h
+--- linux-2.6.24/include/asm-powerpc/iommu.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/iommu.h	2008-01-28 20:26:42.000000000 +0100
+@@ -69,10 +69,9 @@
+ };
+ 
+ struct scatterlist;
+-struct device_node;
+ 
+ /* Frees table for an individual device node */
+-extern void iommu_free_table(struct device_node *dn);
++extern void iommu_free_table(struct iommu_table *tbl, const char *node_name);
+ 
+ /* Initializes an iommu_table based in values set in the passed-in
+  * structure
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/ipic.h powerpc.git/include/asm-powerpc/ipic.h
+--- linux-2.6.24/include/asm-powerpc/ipic.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/ipic.h	2008-01-28 20:26:42.000000000 +0100
+@@ -20,11 +20,13 @@
+ 
+ /* Flags when we init the IPIC */
+ #define IPIC_SPREADMODE_GRP_A	0x00000001
+-#define IPIC_SPREADMODE_GRP_D	0x00000002
+-#define IPIC_SPREADMODE_MIX_A	0x00000004
+-#define IPIC_SPREADMODE_MIX_B	0x00000008
+-#define IPIC_DISABLE_MCP_OUT	0x00000010
+-#define IPIC_IRQ0_MCP		0x00000020
++#define IPIC_SPREADMODE_GRP_B	0x00000002
++#define IPIC_SPREADMODE_GRP_C	0x00000004
++#define IPIC_SPREADMODE_GRP_D	0x00000008
++#define IPIC_SPREADMODE_MIX_A	0x00000010
++#define IPIC_SPREADMODE_MIX_B	0x00000020
++#define IPIC_DISABLE_MCP_OUT	0x00000040
++#define IPIC_IRQ0_MCP		0x00000080
+ 
+ /* IPIC registers offsets */
+ #define IPIC_SICFR	0x00	/* System Global Interrupt Configuration Register */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/iseries/hv_lp_event.h powerpc.git/include/asm-powerpc/iseries/hv_lp_event.h
+--- linux-2.6.24/include/asm-powerpc/iseries/hv_lp_event.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/iseries/hv_lp_event.h	2008-01-28 20:26:42.000000000 +0100
+@@ -78,7 +78,7 @@
+ 
+ /*
+  * Close an Lp Event Path for a type and partition
+- * returns 0 on sucess
++ * returns 0 on success
+  */
+ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/kexec.h powerpc.git/include/asm-powerpc/kexec.h
+--- linux-2.6.24/include/asm-powerpc/kexec.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/kexec.h	2008-01-28 20:26:42.000000000 +0100
+@@ -123,6 +123,9 @@
+ extern void default_machine_kexec(struct kimage *image);
+ extern int default_machine_kexec_prepare(struct kimage *image);
+ extern void default_machine_crash_shutdown(struct pt_regs *regs);
++typedef void (*crash_shutdown_t)(void);
++extern int crash_shutdown_register(crash_shutdown_t handler);
++extern int crash_shutdown_unregister(crash_shutdown_t handler);
+ 
+ extern void machine_kexec_simple(struct kimage *image);
+ extern void crash_kexec_secondary(struct pt_regs *regs);
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/lmb.h powerpc.git/include/asm-powerpc/lmb.h
+--- linux-2.6.24/include/asm-powerpc/lmb.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/lmb.h	2008-01-28 20:26:42.000000000 +0100
+@@ -51,6 +51,7 @@
+ extern unsigned long __init lmb_phys_mem_size(void);
+ extern unsigned long __init lmb_end_of_DRAM(void);
+ extern void __init lmb_enforce_memory_limit(unsigned long memory_limit);
++extern int __init lmb_is_reserved(unsigned long addr);
+ 
+ extern void lmb_dump_all(void);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/machdep.h powerpc.git/include/asm-powerpc/machdep.h
+--- linux-2.6.24/include/asm-powerpc/machdep.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/machdep.h	2008-01-28 20:26:42.000000000 +0100
+@@ -204,6 +204,13 @@
+ 	/*
+ 	 * optional PCI "hooks"
+ 	 */
++	/* Called in indirect_* to avoid touching devices */
++	int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);
++
++	/* Called at then very end of pcibios_init() */
++	void (*pcibios_after_init)(void);
++
++#endif /* CONFIG_PPC32 */
+ 
+ 	/* Called after PPC generic resource fixup to perform
+ 	   machine specific fixups */
+@@ -212,18 +219,9 @@
+ 	/* Called for each PCI bus in the system when it's probed */
+ 	void (*pcibios_fixup_bus)(struct pci_bus *);
+ 
+-	/* Called when pci_enable_device() is called (initial=0) or
+-	 * when a device with no assigned resource is found (initial=1).
+-	 * Returns 0 to allow assignment/enabling of the device. */
+-	int  (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
+-
+-	/* Called in indirect_* to avoid touching devices */
+-	int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);
+-
+-	/* Called at then very end of pcibios_init() */
+-	void (*pcibios_after_init)(void);
+-
+-#endif /* CONFIG_PPC32 */
++	/* Called when pci_enable_device() is called. Returns 0 to
++	 * allow assignment/enabling of the device. */
++	int  (*pcibios_enable_device_hook)(struct pci_dev *);
+ 
+ 	/* Called to shutdown machine specific hardware not already controlled
+ 	 * by other drivers.
+@@ -253,6 +251,16 @@
+ 	 */
+ 	void (*machine_kexec)(struct kimage *image);
+ #endif /* CONFIG_KEXEC */
++
++#ifdef CONFIG_SUSPEND
++	/* These are called to disable and enable, respectively, IRQs when
++	 * entering a suspend state.  If NULL, then the generic versions
++	 * will be called.  The generic versions disable/enable the
++	 * decrementer along with interrupts.
++	 */
++	void (*suspend_disable_irqs)(void);
++	void (*suspend_enable_irqs)(void);
++#endif
+ };
+ 
+ extern void power4_idle(void);
+@@ -326,5 +334,31 @@
+ 		ppc_md.log_error(buf, err_type, fatal);
+ }
+ 
++#define __define_machine_initcall(mach,level,fn,id) \
++	static int __init __machine_initcall_##mach##_##fn(void) { \
++		if (machine_is(mach)) return fn(); \
++		return 0; \
++	} \
++	__define_initcall(level,__machine_initcall_##mach##_##fn,id);
++
++#define machine_core_initcall(mach,fn)		__define_machine_initcall(mach,"1",fn,1)
++#define machine_core_initcall_sync(mach,fn)	__define_machine_initcall(mach,"1s",fn,1s)
++#define machine_postcore_initcall(mach,fn)	__define_machine_initcall(mach,"2",fn,2)
++#define machine_postcore_initcall_sync(mach,fn)	__define_machine_initcall(mach,"2s",fn,2s)
++#define machine_arch_initcall(mach,fn)		__define_machine_initcall(mach,"3",fn,3)
++#define machine_arch_initcall_sync(mach,fn)	__define_machine_initcall(mach,"3s",fn,3s)
++#define machine_subsys_initcall(mach,fn)	__define_machine_initcall(mach,"4",fn,4)
++#define machine_subsys_initcall_sync(mach,fn)	__define_machine_initcall(mach,"4s",fn,4s)
++#define machine_fs_initcall(mach,fn)		__define_machine_initcall(mach,"5",fn,5)
++#define machine_fs_initcall_sync(mach,fn)	__define_machine_initcall(mach,"5s",fn,5s)
++#define machine_rootfs_initcall(mach,fn)	__define_machine_initcall(mach,"rootfs",fn,rootfs)
++#define machine_device_initcall(mach,fn)	__define_machine_initcall(mach,"6",fn,6)
++#define machine_device_initcall_sync(mach,fn)	__define_machine_initcall(mach,"6s",fn,6s)
++#define machine_late_initcall(mach,fn)		__define_machine_initcall(mach,"7",fn,7)
++#define machine_late_initcall_sync(mach,fn)	__define_machine_initcall(mach,"7s",fn,7s)
++
++void generic_suspend_disable_irqs(void);
++void generic_suspend_enable_irqs(void);
++
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_POWERPC_MACHDEP_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/mmu-hash64.h powerpc.git/include/asm-powerpc/mmu-hash64.h
+--- linux-2.6.24/include/asm-powerpc/mmu-hash64.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/mmu-hash64.h	2008-01-28 21:37:04.000000000 +0100
+@@ -80,7 +80,7 @@
+ #define HPTE_V_AVPN_SHIFT	7
+ #define HPTE_V_AVPN		ASM_CONST(0x3fffffffffffff80)
+ #define HPTE_V_AVPN_VAL(x)	(((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
+-#define HPTE_V_COMPARE(x,y)	(!(((x) ^ (y)) & 0xffffffffffffff80))
++#define HPTE_V_COMPARE(x,y)	(!(((x) ^ (y)) & 0xffffffffffffff80UL))
+ #define HPTE_V_BOLTED		ASM_CONST(0x0000000000000010)
+ #define HPTE_V_LOCK		ASM_CONST(0x0000000000000008)
+ #define HPTE_V_LARGE		ASM_CONST(0x0000000000000004)
+@@ -180,6 +180,7 @@
+ extern int mmu_io_psize;
+ extern int mmu_kernel_ssize;
+ extern int mmu_highuser_ssize;
++extern u16 mmu_slb_size;
+ 
+ /*
+  * If the processor supports 64k normal pages but not 64k cache
+@@ -277,6 +278,7 @@
+ extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
+ 			     unsigned long pstart, unsigned long mode,
+ 			     int psize, int ssize);
++extern void set_huge_psize(int psize);
+ 
+ extern void htab_initialize(void);
+ extern void htab_initialize_secondary(void);
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/mpc52xx.h powerpc.git/include/asm-powerpc/mpc52xx.h
+--- linux-2.6.24/include/asm-powerpc/mpc52xx.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/mpc52xx.h	2008-01-28 20:26:42.000000000 +0100
+@@ -248,8 +248,6 @@
+ 
+ #ifndef __ASSEMBLY__
+ 
+-extern void __iomem * mpc52xx_find_and_map(const char *);
+-extern void __iomem * mpc52xx_find_and_map_path(const char *path);
+ extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node);
+ extern void mpc5200_setup_xlb_arbiter(void);
+ extern void mpc52xx_declare_of_platform_devices(void);
+@@ -257,7 +255,12 @@
+ extern void mpc52xx_init_irq(void);
+ extern unsigned int mpc52xx_get_irq(void);
+ 
++#ifdef CONFIG_PCI
+ extern int __init mpc52xx_add_bridge(struct device_node *node);
++extern void __init mpc52xx_setup_pci(void);
++#else
++static inline void mpc52xx_setup_pci(void) { }
++#endif
+ 
+ extern void __init mpc52xx_map_wdt(void);
+ extern void mpc52xx_restart(char *cmd);
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/mpc52xx_psc.h powerpc.git/include/asm-powerpc/mpc52xx_psc.h
+--- linux-2.6.24/include/asm-powerpc/mpc52xx_psc.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/mpc52xx_psc.h	2008-01-28 20:26:42.000000000 +0100
+@@ -153,6 +153,9 @@
+ 	u8		reserved16[3];
+ 	u8		irfdr;		/* PSC + 0x54 */
+ 	u8		reserved17[3];
++};
++
++struct mpc52xx_psc_fifo {
+ 	u16		rfnum;		/* PSC + 0x58 */
+ 	u16		reserved18;
+ 	u16		tfnum;		/* PSC + 0x5c */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/mpc8260.h powerpc.git/include/asm-powerpc/mpc8260.h
+--- linux-2.6.24/include/asm-powerpc/mpc8260.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/mpc8260.h	2008-01-28 20:26:42.000000000 +0100
+@@ -8,6 +8,7 @@
+ #ifndef __ASM_POWERPC_MPC8260_H__
+ #define __ASM_POWERPC_MPC8260_H__
+ 
++#define MPC82XX_BCR_PLDP 0x00800000 /* Pipeline Maximum Depth */
+ 
+ #ifdef CONFIG_8260
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/mpic.h powerpc.git/include/asm-powerpc/mpic.h
+--- linux-2.6.24/include/asm-powerpc/mpic.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/mpic.h	2008-01-28 20:26:42.000000000 +0100
+@@ -22,7 +22,9 @@
+ #define MPIC_GREG_GLOBAL_CONF_0		0x00020
+ #define		MPIC_GREG_GCONF_RESET			0x80000000
+ #define		MPIC_GREG_GCONF_8259_PTHROU_DIS		0x20000000
++#define		MPIC_GREG_GCONF_NO_BIAS			0x10000000
+ #define		MPIC_GREG_GCONF_BASE_MASK		0x000fffff
++#define		MPIC_GREG_GCONF_MCK			0x08000000
+ #define MPIC_GREG_GLOBAL_CONF_1		0x00030
+ #define		MPIC_GREG_GLOBAL_CONF_1_SIE		0x08000000
+ #define		MPIC_GREG_GLOBAL_CONF_1_CLK_RATIO_MASK	0x70000000
+@@ -78,6 +80,7 @@
+ #define 	MPIC_CPU_WHOAMI_MASK			0x0000001f
+ #define MPIC_CPU_INTACK			0x000a0
+ #define MPIC_CPU_EOI			0x000b0
++#define MPIC_CPU_MCACK			0x000c0
+ 
+ /*
+  * Per-source registers
+@@ -141,6 +144,7 @@
+ #define TSI108_CPU_WHOAMI		0xffffffff
+ #define TSI108_CPU_INTACK		0x00004
+ #define TSI108_CPU_EOI			0x00008
++#define TSI108_CPU_MCACK		0x00004 /* Doesn't really exist here */
+ 
+ /*
+  * Per-source registers
+@@ -183,6 +187,7 @@
+ 	MPIC_IDX_CPU_WHOAMI,
+ 	MPIC_IDX_CPU_INTACK,
+ 	MPIC_IDX_CPU_EOI,
++	MPIC_IDX_CPU_MCACK,
+ 
+ 	MPIC_IDX_IRQ_BASE,
+ 	MPIC_IDX_IRQ_STRIDE,
+@@ -344,6 +349,10 @@
+ #define MPIC_USES_DCR			0x00000080
+ /* MPIC has 11-bit vector fields (or larger) */
+ #define MPIC_LARGE_VECTORS		0x00000100
++/* Enable delivery of prio 15 interrupts as MCK instead of EE */
++#define MPIC_ENABLE_MCK			0x00000200
++/* Disable bias among target selection, spread interrupts evenly */
++#define MPIC_NO_BIAS			0x00000400
+ 
+ /* MPIC HW modification ID */
+ #define MPIC_REGSET_MASK		0xf0000000
+@@ -447,10 +456,19 @@
+ /* Send a message (IPI) to a given target (cpu number or MSG_*) */
+ void smp_mpic_message_pass(int target, int msg);
+ 
++/* Unmask a specific virq */
++extern void mpic_unmask_irq(unsigned int irq);
++/* Mask a specific virq */
++extern void mpic_mask_irq(unsigned int irq);
++/* EOI a specific virq */
++extern void mpic_end_irq(unsigned int irq);
++
+ /* Fetch interrupt from a given mpic */
+ extern unsigned int mpic_get_one_irq(struct mpic *mpic);
+-/* This one gets to the primary mpic */
++/* This one gets from the primary mpic */
+ extern unsigned int mpic_get_irq(void);
++/* Fetch Machine Check interrupt from primary mpic */
++extern unsigned int mpic_get_mcirq(void);
+ 
+ /* Set the EPIC clock ratio */
+ void mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio);
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/nvram.h powerpc.git/include/asm-powerpc/nvram.h
+--- linux-2.6.24/include/asm-powerpc/nvram.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/nvram.h	2008-01-28 20:26:42.000000000 +0100
+@@ -10,6 +10,8 @@
+ #ifndef _ASM_POWERPC_NVRAM_H
+ #define _ASM_POWERPC_NVRAM_H
+ 
++#include <linux/errno.h>
++
+ #define NVRW_CNT 0x20
+ #define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */
+ #define NVRAM_BLOCK_LEN 16
+@@ -71,7 +73,16 @@
+ extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
+ 
+ extern int pSeries_nvram_init(void);
++
++#ifdef CONFIG_MMIO_NVRAM
+ extern int mmio_nvram_init(void);
++#else
++static inline int mmio_nvram_init(void)
++{
++	return -ENODEV;
++}
++#endif
++
+ #endif /* __KERNEL__ */
+ 
+ /* PowerMac specific nvram stuffs */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/of_platform.h powerpc.git/include/asm-powerpc/of_platform.h
+--- linux-2.6.24/include/asm-powerpc/of_platform.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/of_platform.h	2008-01-28 20:26:42.000000000 +0100
+@@ -15,8 +15,14 @@
+ #include <linux/of_platform.h>
+ 
+ /* Platform drivers register/unregister */
+-extern int of_register_platform_driver(struct of_platform_driver *drv);
+-extern void of_unregister_platform_driver(struct of_platform_driver *drv);
++static inline int of_register_platform_driver(struct of_platform_driver *drv)
++{
++	return of_register_driver(drv, &of_platform_bus_type);
++}
++static inline void of_unregister_platform_driver(struct of_platform_driver *drv)
++{
++	of_unregister_driver(drv);
++}
+ 
+ /* Platform devices and busses creation */
+ extern struct of_device *of_platform_device_create(struct device_node *np,
+@@ -26,9 +32,11 @@
+ #define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
+ 
+ extern int of_platform_bus_probe(struct device_node *root,
+-				 struct of_device_id *matches,
++				 const struct of_device_id *matches,
+ 				 struct device *parent);
+ 
+ extern struct of_device *of_find_device_by_phandle(phandle ph);
+ 
++extern void of_instantiate_rtc(void);
++
+ #endif	/* _ASM_POWERPC_OF_PLATFORM_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/pci-bridge.h powerpc.git/include/asm-powerpc/pci-bridge.h
+--- linux-2.6.24/include/asm-powerpc/pci-bridge.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/pci-bridge.h	2008-01-28 20:26:42.000000000 +0100
+@@ -1,15 +1,42 @@
+ #ifndef _ASM_POWERPC_PCI_BRIDGE_H
+ #define _ASM_POWERPC_PCI_BRIDGE_H
+ #ifdef __KERNEL__
+-
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
+ #include <linux/pci.h>
+ #include <linux/list.h>
+ #include <linux/ioport.h>
+ 
+-#ifndef CONFIG_PPC64
+-
+ struct device_node;
+-struct pci_controller;
++
++extern unsigned int ppc_pci_flags;
++enum {
++	/* Force re-assigning all resources (ignore firmware
++	 * setup completely)
++	 */
++	PPC_PCI_REASSIGN_ALL_RSRC	= 0x00000001,
++
++	/* Re-assign all bus numbers */
++	PPC_PCI_REASSIGN_ALL_BUS	= 0x00000002,
++
++	/* Do not try to assign, just use existing setup */
++	PPC_PCI_PROBE_ONLY		= 0x00000004,
++
++	/* Don't bother with ISA alignment unless the bridge has
++	 * ISA forwarding enabled
++	 */
++	PPC_PCI_CAN_SKIP_ISA_ALIGN	= 0x00000008,
++
++	/* Enable domain numbers in /proc */
++	PPC_PCI_ENABLE_PROC_DOMAINS	= 0x00000010,
++	/* ... except for domain 0 */
++	PPC_PCI_COMPAT_DOMAIN_0		= 0x00000020,
++};
++
+ 
+ /*
+  * Structure of a PCI controller (host bridge)
+@@ -17,26 +44,41 @@
+ struct pci_controller {
+ 	struct pci_bus *bus;
+ 	char is_dynamic;
+-	void *arch_data;
++#ifdef CONFIG_PPC64
++	int node;
++#endif
++	struct device_node *dn;
+ 	struct list_head list_node;
+ 	struct device *parent;
+ 
+ 	int first_busno;
+ 	int last_busno;
++#ifndef CONFIG_PPC64
+ 	int self_busno;
++#endif
+ 
+ 	void __iomem *io_base_virt;
++#ifdef CONFIG_PPC64
++	void *io_base_alloc;
++#endif
+ 	resource_size_t io_base_phys;
++#ifndef CONFIG_PPC64
++	resource_size_t pci_io_size;
++#endif
+ 
+ 	/* Some machines (PReP) have a non 1:1 mapping of
+ 	 * the PCI memory space in the CPU bus space
+ 	 */
+ 	resource_size_t pci_mem_offset;
++#ifdef CONFIG_PPC64
++	unsigned long pci_io_size;
++#endif
+ 
+ 	struct pci_ops *ops;
+-	volatile unsigned int __iomem *cfg_addr;
+-	volatile void __iomem *cfg_data;
++	unsigned int __iomem *cfg_addr;
++	void __iomem *cfg_data;
+ 
++#ifndef CONFIG_PPC64
+ 	/*
+ 	 * Used for variants of PCI indirect handling and possible quirks:
+ 	 *  SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
+@@ -51,21 +93,30 @@
+ 	 *   set.
+ 	 *  BIG_ENDIAN - cfg_addr is a big endian register
+ 	 */
+-#define PPC_INDIRECT_TYPE_SET_CFG_TYPE		(0x00000001)
+-#define PPC_INDIRECT_TYPE_EXT_REG		(0x00000002)
+-#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS	(0x00000004)
+-#define PPC_INDIRECT_TYPE_NO_PCIE_LINK		(0x00000008)
+-#define PPC_INDIRECT_TYPE_BIG_ENDIAN		(0x00000010)
++#define PPC_INDIRECT_TYPE_SET_CFG_TYPE		0x00000001
++#define PPC_INDIRECT_TYPE_EXT_REG		0x00000002
++#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS	0x00000004
++#define PPC_INDIRECT_TYPE_NO_PCIE_LINK		0x00000008
++#define PPC_INDIRECT_TYPE_BIG_ENDIAN		0x00000010
+ 	u32 indirect_type;
+-
++#endif	/* !CONFIG_PPC64 */
+ 	/* Currently, we limit ourselves to 1 IO range and 3 mem
+ 	 * ranges since the common pci_bus structure can't handle more
+ 	 */
+ 	struct resource	io_resource;
+ 	struct resource mem_resources[3];
+ 	int global_number;		/* PCI domain number */
++#ifdef CONFIG_PPC64
++	unsigned long buid;
++	unsigned long dma_window_base_cur;
++	unsigned long dma_window_size;
++
++	void *private_data;
++#endif	/* CONFIG_PPC64 */
+ };
+ 
++#ifndef CONFIG_PPC64
++
+ static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
+ {
+ 	return bus->sysdata;
+@@ -81,18 +132,18 @@
+ 
+ /* These are used for config access before all the PCI probing
+    has been done. */
+-int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn,
+-			   int where, u8 *val);
+-int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn,
+-			   int where, u16 *val);
+-int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn,
+-			    int where, u32 *val);
+-int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn,
+-			    int where, u8 val);
+-int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn,
+-			    int where, u16 val);
+-int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn,
+-			     int where, u32 val);
++extern int early_read_config_byte(struct pci_controller *hose, int bus,
++			int dev_fn, int where, u8 *val);
++extern int early_read_config_word(struct pci_controller *hose, int bus,
++			int dev_fn, int where, u16 *val);
++extern int early_read_config_dword(struct pci_controller *hose, int bus,
++			int dev_fn, int where, u32 *val);
++extern int early_write_config_byte(struct pci_controller *hose, int bus,
++			int dev_fn, int where, u8 val);
++extern int early_write_config_word(struct pci_controller *hose, int bus,
++			int dev_fn, int where, u16 val);
++extern int early_write_config_dword(struct pci_controller *hose, int bus,
++			int dev_fn, int where, u32 val);
+ 
+ extern int early_find_capability(struct pci_controller *hose, int bus,
+ 				 int dev_fn, int cap);
+@@ -101,87 +152,33 @@
+ 			       resource_size_t cfg_addr,
+ 			       resource_size_t cfg_data, u32 flags);
+ extern void setup_grackle(struct pci_controller *hose);
+-extern void __init update_bridge_resource(struct pci_dev *dev,
+-					  struct resource *res);
+-
+-#else
+-
+-
+-/*
+- * 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.
+- */
+-
+-/*
+- * Structure of a PCI controller (host bridge)
+- */
+-struct pci_controller {
+-	struct pci_bus *bus;
+-	char is_dynamic;
+-	int node;
+-	void *arch_data;
+-	struct list_head list_node;
+-	struct device *parent;
+-
+-	int first_busno;
+-	int last_busno;
+-
+-	void __iomem *io_base_virt;
+-	void *io_base_alloc;
+-	resource_size_t io_base_phys;
+-
+-	/* Some machines have a non 1:1 mapping of
+-	 * the PCI memory space in the CPU bus space
+-	 */
+-	resource_size_t pci_mem_offset;
+-	unsigned long pci_io_size;
+-
+-	struct pci_ops *ops;
+-	volatile unsigned int __iomem *cfg_addr;
+-	volatile void __iomem *cfg_data;
+-
+-	/* Currently, we limit ourselves to 1 IO range and 3 mem
+-	 * ranges since the common pci_bus structure can't handle more
+-	 */
+-	struct resource io_resource;
+-	struct resource mem_resources[3];
+-	int global_number;
+-	unsigned long buid;
+-	unsigned long dma_window_base_cur;
+-	unsigned long dma_window_size;
+-
+-	void *private_data;
+-};
++#else	/* CONFIG_PPC64 */
+ 
+ /*
+  * PCI stuff, for nodes representing PCI devices, pointed to
+  * by device_node->data.
+  */
+-struct pci_controller;
+ struct iommu_table;
+ 
+ struct pci_dn {
+ 	int	busno;			/* pci bus number */
+-	int	bussubno;		/* pci subordinate bus number */
+ 	int	devfn;			/* pci device and function number */
+-	int	class_code;		/* pci device class */
+ 
+ 	struct  pci_controller *phb;	/* for pci devices */
+ 	struct	iommu_table *iommu_table;	/* for phb's or bridges */
+-	struct	pci_dev *pcidev;	/* back-pointer to the pci device */
+ 	struct	device_node *node;	/* back-pointer to the device_node */
+ 
+ 	int	pci_ext_config_space;	/* for pci devices */
+ 
+ #ifdef CONFIG_EEH
++	struct	pci_dev *pcidev;	/* back-pointer to the pci device */
++	int	class_code;		/* pci device class */
+ 	int	eeh_mode;		/* See eeh.h for possible EEH_MODEs */
+ 	int	eeh_config_addr;
+ 	int	eeh_pe_config_addr; /* new-style partition endpoint address */
+-	int 	eeh_check_count;	/* # times driver ignored error */
+-	int 	eeh_freeze_count;	/* # times this device froze up. */
+-	int 	eeh_false_positives;	/* # times this device reported #ff's */
++	int	eeh_check_count;	/* # times driver ignored error */
++	int	eeh_freeze_count;	/* # times this device froze up. */
++	int	eeh_false_positives;	/* # times this device reported #ff's */
+ 	u32	config_space[16];	/* saved PCI config space */
+ #endif
+ };
+@@ -189,7 +186,7 @@
+ /* Get the pointer to a device_node's pci_dn */
+ #define PCI_DN(dn)	((struct pci_dn *) (dn)->data)
+ 
+-struct device_node *fetch_dev_dn(struct pci_dev *dev);
++extern struct device_node *fetch_dev_dn(struct pci_dev *dev);
+ 
+ /* Get a device_node from a pci_dev.  This code must be fast except
+  * in the case where the sysdata is incorrect and needs to be fixed
+@@ -227,14 +224,14 @@
+ }
+ 
+ /** Find the bus corresponding to the indicated device node */
+-struct pci_bus * pcibios_find_pci_bus(struct device_node *dn);
++extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn);
+ 
+ /** Remove all of the PCI devices under this bus */
+-void pcibios_remove_pci_devices(struct pci_bus *bus);
++extern void pcibios_remove_pci_devices(struct pci_bus *bus);
+ 
+ /** Discover new pci devices under this bus, and add them */
+-void pcibios_add_pci_devices(struct pci_bus * bus);
+-void pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus);
++extern void pcibios_add_pci_devices(struct pci_bus *bus);
++extern void pcibios_fixup_new_pci_devices(struct pci_bus *bus);
+ 
+ extern int pcibios_remove_root_bus(struct pci_controller *phb);
+ 
+@@ -270,20 +267,18 @@
+ #define PHB_SET_NODE(PHB, NODE)		((PHB)->node = -1)
+ #endif
+ 
+-#endif /* CONFIG_PPC64 */
++#endif	/* CONFIG_PPC64 */
+ 
+ /* Get the PCI host controller for an OF device */
+-extern struct pci_controller*
+-pci_find_hose_for_OF_device(struct device_node* node);
++extern struct pci_controller *pci_find_hose_for_OF_device(
++			struct device_node* node);
+ 
+ /* Fill up host controller resources from the OF node */
+-extern void
+-pci_process_bridge_OF_ranges(struct pci_controller *hose,
+-			   struct device_node *dev, int primary);
++extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
++			struct device_node *dev, int primary);
+ 
+ /* Allocate & free a PCI host bridge structure */
+-extern struct pci_controller *
+-pcibios_alloc_controller(struct device_node *dev);
++extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
+ extern void pcibios_free_controller(struct pci_controller *phb);
+ 
+ #ifdef CONFIG_PCI
+@@ -298,9 +293,7 @@
+ {
+ 	return 0;
+ }
+-#endif
+-
++#endif	/* CONFIG_PCI */
+ 
+-
+-#endif /* __KERNEL__ */
+-#endif
++#endif	/* __KERNEL__ */
++#endif	/* _ASM_POWERPC_PCI_BRIDGE_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/pci.h powerpc.git/include/asm-powerpc/pci.h
+--- linux-2.6.24/include/asm-powerpc/pci.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/pci.h	2008-01-28 20:26:42.000000000 +0100
+@@ -36,11 +36,10 @@
+ 
+ /*
+  * Set this to 1 if you want the kernel to re-assign all PCI
+- * bus numbers
++ * bus numbers (don't do that on ppc64 yet !)
+  */
+-extern int pci_assign_all_buses;
+-#define pcibios_assign_all_busses()	(pci_assign_all_buses)
+-
++#define pcibios_assign_all_busses()    	(ppc_pci_flags & \
++					 PPC_PCI_REASSIGN_ALL_BUS)
+ #define pcibios_scan_all_fns(a, b)	0
+ 
+ static inline void pcibios_set_master(struct pci_dev *dev)
+@@ -95,9 +94,6 @@
+ #define get_pci_dma_ops()	NULL
+ #endif
+ 
+-/* Decide whether to display the domain number in /proc */
+-extern int pci_proc_domain(struct pci_bus *bus);
+-
+ #else /* 32-bit */
+ 
+ #ifdef CONFIG_PCI
+@@ -109,17 +105,14 @@
+ 	*strategy_parameter = ~0UL;
+ }
+ #endif
+-
+-/* Set the name of the bus as it appears in /proc/bus/pci */
+-static inline int pci_proc_domain(struct pci_bus *bus)
+-{
+-	return 0;
+-}
+-
+ #endif /* CONFIG_PPC64 */
+ 
+ extern int pci_domain_nr(struct pci_bus *bus);
+ 
++/* Decide whether to display the domain number in /proc */
++extern int pci_proc_domain(struct pci_bus *bus);
++
++
+ struct vm_area_struct;
+ /* Map a range of PCI memory or I/O space for a device into user space */
+ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+@@ -199,13 +192,12 @@
+ 	return root;
+ }
+ 
+-extern void pcibios_fixup_device_resources(struct pci_dev *dev,
+-			struct pci_bus *bus);
+-
+ extern void pcibios_setup_new_device(struct pci_dev *dev);
+ 
+ extern void pcibios_claim_one_bus(struct pci_bus *b);
+ 
++extern void pcibios_resource_survey(void);
++
+ extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
+ 
+ extern struct pci_dev *of_create_pci_dev(struct device_node *node,
+@@ -229,5 +221,8 @@
+ 				 const struct resource *rsrc,
+ 				 resource_size_t *start, resource_size_t *end);
+ 
++extern void pcibios_do_bus_setup(struct pci_bus *bus);
++extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
++
+ #endif	/* __KERNEL__ */
+ #endif /* __ASM_POWERPC_PCI_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/ppc-pci.h powerpc.git/include/asm-powerpc/ppc-pci.h
+--- linux-2.6.24/include/asm-powerpc/ppc-pci.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/ppc-pci.h	2008-01-28 20:26:42.000000000 +0100
+@@ -22,7 +22,6 @@
+ 
+ 
+ extern struct list_head hose_list;
+-extern int global_phb_number;
+ 
+ extern void find_and_init_phbs(void);
+ 
+@@ -47,9 +46,6 @@
+ extern unsigned long get_phb_buid (struct device_node *);
+ extern int rtas_setup_phb(struct pci_controller *phb);
+ 
+-/* From iSeries PCI */
+-extern void iSeries_pcibios_init(void);
+-
+ extern unsigned long pci_probe_only;
+ 
+ /* ---- EEH internal-use-only related routines ---- */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/prom.h powerpc.git/include/asm-powerpc/prom.h
+--- linux-2.6.24/include/asm-powerpc/prom.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/prom.h	2008-01-28 20:26:42.000000000 +0100
+@@ -202,6 +202,10 @@
+  */
+ extern u64 of_translate_address(struct device_node *np, const u32 *addr);
+ 
++/* Translate a DMA address from device space to CPU space */
++extern u64 of_translate_dma_address(struct device_node *dev,
++				    const u32 *in_addr);
++
+ /* Extract an address from a device, returns the region size and
+  * the address space flags too. The PCI version uses a BAR number
+  * instead of an absolute index
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/ps3.h powerpc.git/include/asm-powerpc/ps3.h
+--- linux-2.6.24/include/asm-powerpc/ps3.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/ps3.h	2008-01-28 20:26:42.000000000 +0100
+@@ -24,6 +24,7 @@
+ #include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/device.h>
++#include "cell-pmu.h"
+ 
+ union ps3_firmware_version {
+ 	u64 raw;
+@@ -317,6 +318,7 @@
+ 	PS3_MATCH_ID_STOR_FLASH     = 8,
+ 	PS3_MATCH_ID_SOUND          = 9,
+ 	PS3_MATCH_ID_GRAPHICS       = 10,
++	PS3_MATCH_ID_LPM            = 11,
+ };
+ 
+ #define PS3_MODULE_ALIAS_EHCI           "ps3:1"
+@@ -329,11 +331,13 @@
+ #define PS3_MODULE_ALIAS_STOR_FLASH     "ps3:8"
+ #define PS3_MODULE_ALIAS_SOUND          "ps3:9"
+ #define PS3_MODULE_ALIAS_GRAPHICS       "ps3:10"
++#define PS3_MODULE_ALIAS_LPM            "ps3:11"
+ 
+ enum ps3_system_bus_device_type {
+ 	PS3_DEVICE_TYPE_IOC0 = 1,
+ 	PS3_DEVICE_TYPE_SB,
+ 	PS3_DEVICE_TYPE_VUART,
++	PS3_DEVICE_TYPE_LPM,
+ };
+ 
+ /**
+@@ -344,12 +348,17 @@
+ 	enum ps3_match_id match_id;
+ 	enum ps3_system_bus_device_type dev_type;
+ 
+-	unsigned int bus_id;              /* SB */
+-	unsigned int dev_id;              /* SB */
++	u64 bus_id;                       /* SB */
++	u64 dev_id;                       /* SB */
+ 	unsigned int interrupt_id;        /* SB */
+ 	struct ps3_dma_region *d_region;  /* SB, IOC0 */
+ 	struct ps3_mmio_region *m_region; /* SB, IOC0*/
+ 	unsigned int port_number;         /* VUART */
++	struct {                          /* LPM */
++		u64 node_id;
++		u64 pu_id;
++		u64 rights;
++	} lpm;
+ 
+ /*	struct iommu_table *iommu_table; -- waiting for BenH's cleanups */
+ 	struct device core;
+@@ -438,5 +447,66 @@
+ extern struct ps3_prealloc ps3fb_videomemory;
+ extern struct ps3_prealloc ps3flash_bounce_buffer;
+ 
++/* logical performance monitor */
++
++/**
++ * enum ps3_lpm_rights - Rigths granted by the system policy module.
++ *
++ * @PS3_LPM_RIGHTS_USE_LPM: The right to use the lpm.
++ * @PS3_LPM_RIGHTS_USE_TB: The right to use the internal trace buffer.
++ */
++
++enum ps3_lpm_rights {
++	PS3_LPM_RIGHTS_USE_LPM = 0x001,
++	PS3_LPM_RIGHTS_USE_TB = 0x100,
++};
++
++/**
++ * enum ps3_lpm_tb_type - Type of trace buffer lv1 should use.
++ *
++ * @PS3_LPM_TB_TYPE_NONE: Do not use a trace buffer.
++ * @PS3_LPM_RIGHTS_USE_TB: Use the lv1 internal trace buffer.  Must have
++ *  rights @PS3_LPM_RIGHTS_USE_TB.
++ */
++
++enum ps3_lpm_tb_type {
++	PS3_LPM_TB_TYPE_NONE = 0,
++	PS3_LPM_TB_TYPE_INTERNAL = 1,
++};
++
++int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
++	u64 tb_cache_size);
++int ps3_lpm_close(void);
++int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count,
++	unsigned long *bytes_copied);
++int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
++	unsigned long count, unsigned long *bytes_copied);
++void ps3_set_bookmark(u64 bookmark);
++void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id);
++int ps3_set_signal(u64 rtas_signal_group, u8 signal_bit, u16 sub_unit,
++	u8 bus_word);
++
++u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr);
++void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val);
++u32 ps3_read_ctr(u32 cpu, u32 ctr);
++void ps3_write_ctr(u32 cpu, u32 ctr, u32 val);
++
++u32 ps3_read_pm07_control(u32 cpu, u32 ctr);
++void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val);
++u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg);
++void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val);
++
++u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr);
++void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size);
++
++void ps3_enable_pm(u32 cpu);
++void ps3_disable_pm(u32 cpu);
++void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask);
++void ps3_disable_pm_interrupts(u32 cpu);
++
++u32 ps3_get_and_clear_pm_interrupts(u32 cpu);
++void ps3_sync_irq(int node);
++u32 ps3_get_hw_thread_id(int cpu);
++u64 ps3_get_spe_id(void *arg);
+ 
+ #endif
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/ptrace.h powerpc.git/include/asm-powerpc/ptrace.h
+--- linux-2.6.24/include/asm-powerpc/ptrace.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/ptrace.h	2008-01-28 20:26:42.000000000 +0100
+@@ -106,7 +106,8 @@
+  */
+ #define FULL_REGS(regs)		(((regs)->trap & 1) == 0)
+ #ifndef __powerpc64__
+-#define IS_CRITICAL_EXC(regs)	(((regs)->trap & 2) == 0)
++#define IS_CRITICAL_EXC(regs)	(((regs)->trap & 2) != 0)
++#define IS_MCHECK_EXC(regs)	(((regs)->trap & 4) != 0)
+ #endif /* ! __powerpc64__ */
+ #define TRAP(regs)		((regs)->trap & ~0xF)
+ #ifdef __powerpc64__
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/qe.h powerpc.git/include/asm-powerpc/qe.h
+--- linux-2.6.24/include/asm-powerpc/qe.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/qe.h	2008-01-28 20:26:42.000000000 +0100
+@@ -28,6 +28,52 @@
+ #define MEM_PART_SECONDARY	1
+ #define MEM_PART_MURAM		2
+ 
++/* Clocks and BRGs */
++enum qe_clock {
++	QE_CLK_NONE = 0,
++	QE_BRG1,		/* Baud Rate Generator 1 */
++	QE_BRG2,		/* Baud Rate Generator 2 */
++	QE_BRG3,		/* Baud Rate Generator 3 */
++	QE_BRG4,		/* Baud Rate Generator 4 */
++	QE_BRG5,		/* Baud Rate Generator 5 */
++	QE_BRG6,		/* Baud Rate Generator 6 */
++	QE_BRG7,		/* Baud Rate Generator 7 */
++	QE_BRG8,		/* Baud Rate Generator 8 */
++	QE_BRG9,		/* Baud Rate Generator 9 */
++	QE_BRG10,		/* Baud Rate Generator 10 */
++	QE_BRG11,		/* Baud Rate Generator 11 */
++	QE_BRG12,		/* Baud Rate Generator 12 */
++	QE_BRG13,		/* Baud Rate Generator 13 */
++	QE_BRG14,		/* Baud Rate Generator 14 */
++	QE_BRG15,		/* Baud Rate Generator 15 */
++	QE_BRG16,		/* Baud Rate Generator 16 */
++	QE_CLK1,		/* Clock 1 */
++	QE_CLK2,		/* Clock 2 */
++	QE_CLK3,		/* Clock 3 */
++	QE_CLK4,		/* Clock 4 */
++	QE_CLK5,		/* Clock 5 */
++	QE_CLK6,		/* Clock 6 */
++	QE_CLK7,		/* Clock 7 */
++	QE_CLK8,		/* Clock 8 */
++	QE_CLK9,		/* Clock 9 */
++	QE_CLK10,		/* Clock 10 */
++	QE_CLK11,		/* Clock 11 */
++	QE_CLK12,		/* Clock 12 */
++	QE_CLK13,		/* Clock 13 */
++	QE_CLK14,		/* Clock 14 */
++	QE_CLK15,		/* Clock 15 */
++	QE_CLK16,		/* Clock 16 */
++	QE_CLK17,		/* Clock 17 */
++	QE_CLK18,		/* Clock 18 */
++	QE_CLK19,		/* Clock 19 */
++	QE_CLK20,		/* Clock 20 */
++	QE_CLK21,		/* Clock 21 */
++	QE_CLK22,		/* Clock 22 */
++	QE_CLK23,		/* Clock 23 */
++	QE_CLK24,		/* Clock 24 */
++	QE_CLK_DUMMY
++};
++
+ /* Export QE common operations */
+ extern void qe_reset(void);
+ extern int par_io_init(struct device_node *np);
+@@ -38,7 +84,8 @@
+ 
+ /* QE internal API */
+ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
+-void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier);
++enum qe_clock qe_clock_source(const char *source);
++int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
+ int qe_get_snum(void);
+ void qe_put_snum(u8 snum);
+ unsigned long qe_muram_alloc(int size, int align);
+@@ -47,6 +94,58 @@
+ void qe_muram_dump(void);
+ void *qe_muram_addr(unsigned long offset);
+ 
++/* Structure that defines QE firmware binary files.
++ *
++ * See Documentation/powerpc/qe-firmware.txt for a description of these
++ * fields.
++ */
++struct qe_firmware {
++	struct qe_header {
++		__be32 length;  /* Length of the entire structure, in bytes */
++		u8 magic[3];    /* Set to { 'Q', 'E', 'F' } */
++		u8 version;     /* Version of this layout. First ver is '1' */
++	} header;
++	u8 id[62];      /* Null-terminated identifier string */
++	u8 split;	/* 0 = shared I-RAM, 1 = split I-RAM */
++	u8 count;       /* Number of microcode[] structures */
++	struct {
++		__be16 model;   	/* The SOC model  */
++		u8 major;       	/* The SOC revision major */
++		u8 minor;       	/* The SOC revision minor */
++	} __attribute__ ((packed)) soc;
++	u8 padding[4];			/* Reserved, for alignment */
++	__be64 extended_modes;		/* Extended modes */
++	__be32 vtraps[8];		/* Virtual trap addresses */
++	u8 reserved[4];			/* Reserved, for future expansion */
++	struct qe_microcode {
++		u8 id[32];      	/* Null-terminated identifier */
++		__be32 traps[16];       /* Trap addresses, 0 == ignore */
++		__be32 eccr;    	/* The value for the ECCR register */
++		__be32 iram_offset;     /* Offset into I-RAM for the code */
++		__be32 count;   	/* Number of 32-bit words of the code */
++		__be32 code_offset;     /* Offset of the actual microcode */
++		u8 major;       	/* The microcode version major */
++		u8 minor;       	/* The microcode version minor */
++		u8 revision;		/* The microcode version revision */
++		u8 padding;		/* Reserved, for alignment */
++		u8 reserved[4];		/* Reserved, for future expansion */
++	} __attribute__ ((packed)) microcode[1];
++	/* All microcode binaries should be located here */
++	/* CRC32 should be located here, after the microcode binaries */
++} __attribute__ ((packed));
++
++struct qe_firmware_info {
++	char id[64];		/* Firmware name */
++	u32 vtraps[8];		/* Virtual trap addresses */
++	u64 extended_modes;	/* Extended modes */
++};
++
++/* Upload a firmware to the QE */
++int qe_upload_firmware(const struct qe_firmware *firmware);
++
++/* Obtain information on the uploaded firmware */
++struct qe_firmware_info *qe_get_firmware_info(void);
++
+ /* Buffer descriptors */
+ struct qe_bd {
+ 	__be16 status;
+@@ -129,52 +228,6 @@
+ 	COMM_DIR_RX_AND_TX = 3
+ };
+ 
+-/* Clocks and BRGs */
+-enum qe_clock {
+-	QE_CLK_NONE = 0,
+-	QE_BRG1,		/* Baud Rate Generator 1 */
+-	QE_BRG2,		/* Baud Rate Generator 2 */
+-	QE_BRG3,		/* Baud Rate Generator 3 */
+-	QE_BRG4,		/* Baud Rate Generator 4 */
+-	QE_BRG5,		/* Baud Rate Generator 5 */
+-	QE_BRG6,		/* Baud Rate Generator 6 */
+-	QE_BRG7,		/* Baud Rate Generator 7 */
+-	QE_BRG8,		/* Baud Rate Generator 8 */
+-	QE_BRG9,		/* Baud Rate Generator 9 */
+-	QE_BRG10,		/* Baud Rate Generator 10 */
+-	QE_BRG11,		/* Baud Rate Generator 11 */
+-	QE_BRG12,		/* Baud Rate Generator 12 */
+-	QE_BRG13,		/* Baud Rate Generator 13 */
+-	QE_BRG14,		/* Baud Rate Generator 14 */
+-	QE_BRG15,		/* Baud Rate Generator 15 */
+-	QE_BRG16,		/* Baud Rate Generator 16 */
+-	QE_CLK1,		/* Clock 1 */
+-	QE_CLK2,		/* Clock 2 */
+-	QE_CLK3,		/* Clock 3 */
+-	QE_CLK4,		/* Clock 4 */
+-	QE_CLK5,		/* Clock 5 */
+-	QE_CLK6,		/* Clock 6 */
+-	QE_CLK7,		/* Clock 7 */
+-	QE_CLK8,		/* Clock 8 */
+-	QE_CLK9,		/* Clock 9 */
+-	QE_CLK10,		/* Clock 10 */
+-	QE_CLK11,		/* Clock 11 */
+-	QE_CLK12,		/* Clock 12 */
+-	QE_CLK13,		/* Clock 13 */
+-	QE_CLK14,		/* Clock 14 */
+-	QE_CLK15,		/* Clock 15 */
+-	QE_CLK16,		/* Clock 16 */
+-	QE_CLK17,		/* Clock 17 */
+-	QE_CLK18,		/* Clock 18 */
+-	QE_CLK19,		/* Clock 19 */
+-	QE_CLK20,		/* Clock 20 */
+-	QE_CLK21,		/* Clock 21 */
+-	QE_CLK22,		/* Clock 22 */
+-	QE_CLK23,		/* Clock 23 */
+-	QE_CLK24,		/* Clock 24 */
+-	QE_CLK_DUMMY,
+-};
+-
+ /* QE CMXUCR Registers.
+  * There are two UCCs represented in each of the four CMXUCR registers.
+  * These values are for the UCC in the LSBs
+@@ -328,6 +381,15 @@
+ 
+ #define QE_SDEBCR_BA_MASK	0x01FFFFFF
+ 
++/* Communication Processor */
++#define QE_CP_CERCR_MEE		0x8000	/* Multi-user RAM ECC enable */
++#define QE_CP_CERCR_IEE		0x4000	/* Instruction RAM ECC enable */
++#define QE_CP_CERCR_CIR		0x0800	/* Common instruction RAM */
++
++/* I-RAM */
++#define QE_IRAM_IADD_AIE	0x80000000	/* Auto Increment Enable */
++#define QE_IRAM_IADD_BADDR	0x00080000	/* Base Address */
++
+ /* UPC */
+ #define UPGCR_PROTOCOL	0x80000000	/* protocol ul2 or pl2 */
+ #define UPGCR_TMS	0x40000000	/* Transmit master/slave mode */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/reg.h powerpc.git/include/asm-powerpc/reg.h
+--- linux-2.6.24/include/asm-powerpc/reg.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/reg.h	2008-01-28 20:26:42.000000000 +0100
+@@ -553,6 +553,7 @@
+ #define SPRN_PA6T_BTCR	978	/* Breakpoint and Tagging Control Register */
+ #define SPRN_PA6T_IMAAT	979	/* Instruction Match Array Action Table */
+ #define SPRN_PA6T_PCCR	1019	/* Power Counter Control Register */
++#define SPRN_BKMK	1020	/* Cell Bookmark Register */
+ #define SPRN_PA6T_RPCCR	1021	/* Retire PC Trace Control Register */
+ 
+ 
+@@ -691,12 +692,6 @@
+ #define PV_BE		0x0070
+ #define PV_PA6T		0x0090
+ 
+-/*
+- * Number of entries in the SLB. If this ever changes we should handle
+- * it with a use a cpu feature fixup.
+- */
+-#define SLB_NUM_ENTRIES 64
+-
+ /* Macros for setting and retrieving special purpose registers */
+ #ifndef __ASSEMBLY__
+ #define mfmsr()		({unsigned long rval; \
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/reg_booke.h powerpc.git/include/asm-powerpc/reg_booke.h
+--- linux-2.6.24/include/asm-powerpc/reg_booke.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/reg_booke.h	2008-01-28 20:26:42.000000000 +0100
+@@ -123,16 +123,23 @@
+ #define SPRN_SPEFSCR	0x200	/* SPE & Embedded FP Status & Control */
+ #define SPRN_BBEAR	0x201	/* Branch Buffer Entry Address Register */
+ #define SPRN_BBTAR	0x202	/* Branch Buffer Target Address Register */
++#define SPRN_ATB	0x20E	/* Alternate Time Base */
++#define SPRN_ATBL	0x20E	/* Alternate Time Base Lower */
++#define SPRN_ATBU	0x20F	/* Alternate Time Base Upper */
+ #define SPRN_IVOR32	0x210	/* Interrupt Vector Offset Register 32 */
+ #define SPRN_IVOR33	0x211	/* Interrupt Vector Offset Register 33 */
+ #define SPRN_IVOR34	0x212	/* Interrupt Vector Offset Register 34 */
+ #define SPRN_IVOR35	0x213	/* Interrupt Vector Offset Register 35 */
++#define SPRN_IVOR36	0x214	/* Interrupt Vector Offset Register 36 */
++#define SPRN_IVOR37	0x215	/* Interrupt Vector Offset Register 37 */
+ #define SPRN_MCSRR0	0x23A	/* Machine Check Save and Restore Register 0 */
+ #define SPRN_MCSRR1	0x23B	/* Machine Check Save and Restore Register 1 */
+ #define SPRN_MCSR	0x23C	/* Machine Check Status Register */
+ #define SPRN_MCAR	0x23D	/* Machine Check Address Register */
+ #define SPRN_DSRR0	0x23E	/* Debug Save and Restore Register 0 */
+ #define SPRN_DSRR1	0x23F	/* Debug Save and Restore Register 1 */
++#define SPRN_SPRG8	0x25C	/* Special Purpose Register General 8 */
++#define SPRN_SPRG9	0x25D	/* Special Purpose Register General 9 */
+ #define SPRN_MAS0	0x270	/* MMU Assist Register 0 */
+ #define SPRN_MAS1	0x271	/* MMU Assist Register 1 */
+ #define SPRN_MAS2	0x272	/* MMU Assist Register 2 */
+@@ -140,15 +147,18 @@
+ #define SPRN_MAS4	0x274	/* MMU Assist Register 4 */
+ #define SPRN_MAS5	0x275	/* MMU Assist Register 5 */
+ #define SPRN_MAS6	0x276	/* MMU Assist Register 6 */
+-#define SPRN_MAS7	0x3b0	/* MMU Assist Register 7 */
+ #define SPRN_PID1	0x279	/* Process ID Register 1 */
+ #define SPRN_PID2	0x27A	/* Process ID Register 2 */
+ #define SPRN_TLB0CFG	0x2B0	/* TLB 0 Config Register */
+ #define SPRN_TLB1CFG	0x2B1	/* TLB 1 Config Register */
++#define SPRN_EPR	0x2BE	/* External Proxy Register */
+ #define SPRN_CCR1	0x378	/* Core Configuration Register 1 */
+ #define SPRN_ZPR	0x3B0	/* Zone Protection Register (40x) */
++#define SPRN_MAS7	0x3B0	/* MMU Assist Register 7 */
+ #define SPRN_MMUCR	0x3B2	/* MMU Control Register */
+ #define SPRN_CCR0	0x3B3	/* Core Configuration Register 0 */
++#define SPRN_EPLC	0x3B3	/* External Process ID Load Context */
++#define SPRN_EPSC	0x3B4	/* External Process ID Store Context */
+ #define SPRN_SGR	0x3B9	/* Storage Guarded Register */
+ #define SPRN_DCWR	0x3BA	/* Data Cache Write-thru Register */
+ #define SPRN_SLER	0x3BB	/* Little-endian real mode */
+@@ -159,6 +169,7 @@
+ #define SPRN_L1CSR0	0x3F2	/* L1 Cache Control and Status Register 0 */
+ #define SPRN_L1CSR1	0x3F3	/* L1 Cache Control and Status Register 1 */
+ #define SPRN_PIT	0x3DB	/* Programmable Interval Timer */
++#define SPRN_BUCSR	0x3F5	/* Branch Unit Control and Status */
+ #define SPRN_DCCR	0x3FA	/* Data Cache Cacheability Register */
+ #define SPRN_ICCR	0x3FB	/* Instruction Cache Cacheability Register */
+ #define SPRN_SVR	0x3FF	/* System Version Register */
+@@ -207,7 +218,6 @@
+ #define	CCR1_TCS	0x00000080 /* Timer Clock Select */
+ 
+ /* Bit definitions for the MCSR. */
+-#ifdef CONFIG_440A
+ #define MCSR_MCS	0x80000000 /* Machine Check Summary */
+ #define MCSR_IB		0x40000000 /* Instruction PLB Error */
+ #define MCSR_DRB	0x20000000 /* Data Read PLB Error */
+@@ -217,7 +227,7 @@
+ #define MCSR_DCSP	0x02000000 /* D-Cache Search Parity Error */
+ #define MCSR_DCFP	0x01000000 /* D-Cache Flush Parity Error */
+ #define MCSR_IMPE	0x00800000 /* Imprecise Machine Check Exception */
+-#endif
++
+ #ifdef CONFIG_E500
+ #define MCSR_MCP 	0x80000000UL /* Machine Check Input Pin */
+ #define MCSR_ICPERR 	0x40000000UL /* I-Cache Parity Error */
+@@ -293,7 +303,7 @@
+ #define ESR_IMCB	0x20000000	/* Instr. Machine Check - Bus error */
+ #define ESR_IMCT	0x10000000	/* Instr. Machine Check - Timeout */
+ #define ESR_PIL		0x08000000	/* Program Exception - Illegal */
+-#define ESR_PPR		0x04000000	/* Program Exception - Priveleged */
++#define ESR_PPR		0x04000000	/* Program Exception - Privileged */
+ #define ESR_PTR		0x02000000	/* Program Exception - Trap */
+ #define ESR_FP		0x01000000	/* Floating Point Operation */
+ #define ESR_DST		0x00800000	/* Storage Exception - Data miss */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/setjmp.h powerpc.git/include/asm-powerpc/setjmp.h
+--- linux-2.6.24/include/asm-powerpc/setjmp.h	1970-01-01 01:00:00.000000000 +0100
++++ powerpc.git/include/asm-powerpc/setjmp.h	2008-01-28 20:26:42.000000000 +0100
+@@ -0,0 +1,18 @@
++/*
++ * Copyright © 2008 Michael Neuling IBM Corporation
++ *
++ *      This program is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU General Public License
++ *      as published by the Free Software Foundation; either version
++ *      2 of the License, or (at your option) any later version.
++ *
++ */
++#ifndef _ASM_POWERPC_SETJMP_H
++#define _ASM_POWERPC_SETJMP_H
++
++#define JMP_BUF_LEN    23
++
++extern long setjmp(long *);
++extern void longjmp(long *, long);
++
++#endif /* _ASM_POWERPC_SETJMP_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/smu.h powerpc.git/include/asm-powerpc/smu.h
+--- linux-2.6.24/include/asm-powerpc/smu.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/smu.h	2008-01-28 20:26:42.000000000 +0100
+@@ -22,7 +22,7 @@
+  * Partition info commands
+  *
+  * These commands are used to retrieve the sdb-partition-XX datas from
+- * the SMU. The lenght is always 2. First byte is the subcommand code
++ * the SMU. The length is always 2. First byte is the subcommand code
+  * and second byte is the partition ID.
+  *
+  * The reply is 6 bytes:
+@@ -173,12 +173,12 @@
+  * Power supply control
+  *
+  * The "sub" command is an ASCII string in the data, the
+- * data lenght is that of the string.
++ * data length is that of the string.
+  *
+  * The VSLEW command can be used to get or set the voltage slewing.
+- *  - lenght 5 (only "VSLEW") : it returns "DONE" and 3 bytes of
++ *  - length 5 (only "VSLEW") : it returns "DONE" and 3 bytes of
+  *    reply at data offset 6, 7 and 8.
+- *  - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is
++ *  - length 8 ("VSLEWxyz") has 3 additional bytes appended, and is
+  *    used to set the voltage slewing point. The SMU replies with "DONE"
+  * I yet have to figure out their exact meaning of those 3 bytes in
+  * both cases. They seem to be:
+@@ -201,20 +201,90 @@
+  */
+ #define SMU_CMD_READ_ADC			0xd8
+ 
++
+ /* Misc commands
+  *
+  * This command seem to be a grab bag of various things
++ *
++ * Parameters:
++ *   1: subcommand
+  */
+ #define SMU_CMD_MISC_df_COMMAND			0xdf
+-#define   SMU_CMD_MISC_df_SET_DISPLAY_LIT	0x02 /* i: 1 byte */
++
++/*
++ * Sets "system ready" status
++ *
++ * I did not yet understand how it exactly works or what it does.
++ *
++ * Guessing from OF code, 0x02 activates the display backlight. Apple uses/used
++ * the same codebase for all OF versions. On PowerBooks, this command would
++ * enable the backlight. For the G5s, it only activates the front LED. However,
++ * don't take this for granted.
++ *
++ * Parameters:
++ *   2: status [0x00, 0x01 or 0x02]
++ */
++#define   SMU_CMD_MISC_df_SET_DISPLAY_LIT	0x02
++
++/*
++ * Sets mode of power switch.
++ *
++ * What this actually does is not yet known. Maybe it enables some interrupt.
++ *
++ * Parameters:
++ *   2: enable power switch? [0x00 or 0x01]
++ *   3 (optional): enable nmi? [0x00 or 0x01]
++ *
++ * Returns:
++ *   If parameter 2 is 0x00 and parameter 3 is not specified, returns wether
++ *   NMI is enabled. Otherwise unknown.
++ */
+ #define   SMU_CMD_MISC_df_NMI_OPTION		0x04
+ 
++/* Sets LED dimm offset.
++ *
++ * The front LED dimms itself during sleep. Its brightness (or, well, the PWM
++ * frequency) depends on current time. Therefore, the SMU needs to know the
++ * timezone.
++ *
++ * Parameters:
++ *   2-8: unknown (BCD coding)
++ */
++#define   SMU_CMD_MISC_df_DIMM_OFFSET		0x99
++
++
+ /*
+  * Version info commands
+  *
+- * I haven't quite tried to figure out how these work
++ * Parameters:
++ *   1 (optional): Specifies version part to retrieve
++ *
++ * Returns:
++ *   Version value
+  */
+ #define SMU_CMD_VERSION_COMMAND			0xea
++#define   SMU_VERSION_RUNNING			0x00
++#define   SMU_VERSION_BASE			0x01
++#define   SMU_VERSION_UPDATE			0x02
++
++
++/*
++ * Switches
++ *
++ * These are switches whose status seems to be known to the SMU.
++ *
++ * Parameters:
++ *   none
++ *
++ * Result:
++ *   Switch bits (ORed, see below)
++ */
++#define SMU_CMD_SWITCHES			0xdc
++
++/* Switches bits */
++#define SMU_SWITCH_CASE_CLOSED			0x01
++#define SMU_SWITCH_AC_POWER			0x04
++#define SMU_SWITCH_POWER_SWITCH			0x08
+ 
+ 
+ /*
+@@ -243,10 +313,64 @@
+  */
+ #define SMU_CMD_MISC_ee_COMMAND			0xee
+ #define   SMU_CMD_MISC_ee_GET_DATABLOCK_REC	0x02
+-#define	  SMU_CMD_MISC_ee_LEDS_CTRL		0x04 /* i: 00 (00,01) [00] */
++
++/* Retrieves currently used watts.
++ *
++ * Parameters:
++ *   1: 0x03 (Meaning unknown)
++ */
++#define   SMU_CMD_MISC_ee_GET_WATTS		0x03
++
++#define   SMU_CMD_MISC_ee_LEDS_CTRL		0x04 /* i: 00 (00,01) [00] */
+ #define   SMU_CMD_MISC_ee_GET_DATA		0x05 /* i: 00 , o: ?? */
+ 
+ 
++/*
++ * Power related commands
++ *
++ * Parameters:
++ *   1: subcommand
++ */
++#define SMU_CMD_POWER_EVENTS_COMMAND		0x8f
++
++/* SMU_POWER_EVENTS subcommands */
++enum {
++	SMU_PWR_GET_POWERUP_EVENTS      = 0x00,
++	SMU_PWR_SET_POWERUP_EVENTS      = 0x01,
++	SMU_PWR_CLR_POWERUP_EVENTS      = 0x02,
++	SMU_PWR_GET_WAKEUP_EVENTS       = 0x03,
++	SMU_PWR_SET_WAKEUP_EVENTS       = 0x04,
++	SMU_PWR_CLR_WAKEUP_EVENTS       = 0x05,
++
++	/*
++	 * Get last shutdown cause
++	 *
++	 * Returns:
++	 *   1 byte (signed char): Last shutdown cause. Exact meaning unknown.
++	 */
++	SMU_PWR_LAST_SHUTDOWN_CAUSE	= 0x07,
++
++	/*
++	 * Sets or gets server ID. Meaning or use is unknown.
++	 *
++	 * Parameters:
++	 *   2 (optional): Set server ID (1 byte)
++	 *
++	 * Returns:
++	 *   1 byte (server ID?)
++	 */
++	SMU_PWR_SERVER_ID		= 0x08,
++};
++
++/* Power events wakeup bits */
++enum {
++	SMU_PWR_WAKEUP_KEY              = 0x01, /* Wake on key press */
++	SMU_PWR_WAKEUP_AC_INSERT        = 0x02, /* Wake on AC adapter plug */
++	SMU_PWR_WAKEUP_AC_CHANGE        = 0x04,
++	SMU_PWR_WAKEUP_LID_OPEN         = 0x08,
++	SMU_PWR_WAKEUP_RING             = 0x10,
++};
++
+ 
+ /*
+  * - Kernel side interface -
+@@ -564,13 +688,13 @@
+ 
+ 	__u8		cmd;			/* SMU command byte */
+ 	__u8		pad[3];			/* padding */
+-	__u32		data_len;		/* Lenght of data following */
++	__u32		data_len;		/* Length of data following */
+ };
+ 
+ struct smu_user_reply_hdr
+ {
+ 	__u32		status;			/* Command status */
+-	__u32		reply_len;		/* Lenght of data follwing */
++	__u32		reply_len;		/* Length of data follwing */
+ };
+ 
+ #endif /*  _SMU_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/sparsemem.h powerpc.git/include/asm-powerpc/sparsemem.h
+--- linux-2.6.24/include/asm-powerpc/sparsemem.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/sparsemem.h	2008-01-28 20:26:42.000000000 +0100
+@@ -10,13 +10,8 @@
+  */
+ #define SECTION_SIZE_BITS       24
+ 
+-#if defined(CONFIG_PS3_USE_LPAR_ADDR)
+-#define MAX_PHYSADDR_BITS       47
+-#define MAX_PHYSMEM_BITS        47
+-#else
+ #define MAX_PHYSADDR_BITS       44
+ #define MAX_PHYSMEM_BITS        44
+-#endif
+ 
+ #ifdef CONFIG_MEMORY_HOTPLUG
+ extern void create_section_mapping(unsigned long start, unsigned long end);
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/spu.h powerpc.git/include/asm-powerpc/spu.h
+--- linux-2.6.24/include/asm-powerpc/spu.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/spu.h	2008-01-28 20:26:42.000000000 +0100
+@@ -104,6 +104,7 @@
+ 
+ struct spu_context;
+ struct spu_runqueue;
++struct spu_lscsa;
+ struct device_node;
+ 
+ enum spu_utilization_state {
+@@ -145,7 +146,6 @@
+ 	void (* ibox_callback)(struct spu *spu);
+ 	void (* stop_callback)(struct spu *spu);
+ 	void (* mfc_callback)(struct spu *spu);
+-	void (* dma_callback)(struct spu *spu, int type);
+ 
+ 	char irq_c0[8];
+ 	char irq_c1[8];
+@@ -196,10 +196,11 @@
+ extern struct cbe_spu_info cbe_spu_info[];
+ 
+ void spu_init_channels(struct spu *spu);
+-int spu_irq_class_0_bottom(struct spu *spu);
+-int spu_irq_class_1_bottom(struct spu *spu);
+ void spu_irq_setaffinity(struct spu *spu, int cpu);
+ 
++void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
++		void *code, int code_size);
++
+ #ifdef CONFIG_KEXEC
+ void crash_register_spus(struct list_head *list);
+ #else
+@@ -210,6 +211,7 @@
+ 
+ extern void spu_invalidate_slbs(struct spu *spu);
+ extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm);
++int spu_64k_pages_available(void);
+ 
+ /* Calls from the memory management to the SPU */
+ struct mm_struct;
+@@ -279,6 +281,8 @@
+ int spu_add_sysdev_attr_group(struct attribute_group *attrs);
+ void spu_remove_sysdev_attr_group(struct attribute_group *attrs);
+ 
++int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
++		unsigned long dsisr, unsigned *flt);
+ 
+ /*
+  * Notifier blocks:
+@@ -303,7 +307,7 @@
+ extern void do_notify_spus_active(void);
+ 
+ /*
+- * This defines the Local Store, Problem Area and Privlege Area of an SPU.
++ * This defines the Local Store, Problem Area and Privilege Area of an SPU.
+  */
+ 
+ union mfc_tag_size_class_cmd {
+@@ -524,8 +528,24 @@
+ #define CLASS2_ENABLE_SPU_STOP_INTR			0x2L
+ #define CLASS2_ENABLE_SPU_HALT_INTR			0x4L
+ #define CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR	0x8L
++#define CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR		0x10L
+ 	u8  pad_0x118_0x140[0x28];				/* 0x118 */
+ 	u64 int_stat_RW[3];					/* 0x140 */
++#define CLASS0_DMA_ALIGNMENT_INTR			0x1L
++#define CLASS0_INVALID_DMA_COMMAND_INTR			0x2L
++#define CLASS0_SPU_ERROR_INTR				0x4L
++#define CLASS0_INTR_MASK				0x7L
++#define CLASS1_SEGMENT_FAULT_INTR			0x1L
++#define CLASS1_STORAGE_FAULT_INTR			0x2L
++#define CLASS1_LS_COMPARE_SUSPEND_ON_GET_INTR		0x4L
++#define CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR		0x8L
++#define CLASS1_INTR_MASK				0xfL
++#define CLASS2_MAILBOX_INTR				0x1L
++#define CLASS2_SPU_STOP_INTR				0x2L
++#define CLASS2_SPU_HALT_INTR				0x4L
++#define CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR		0x8L
++#define CLASS2_MAILBOX_THRESHOLD_INTR			0x10L
++#define CLASS2_INTR_MASK				0x1fL
+ 	u8  pad_0x158_0x180[0x28];				/* 0x158 */
+ 	u64 int_route_RW;					/* 0x180 */
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/spu_csa.h powerpc.git/include/asm-powerpc/spu_csa.h
+--- linux-2.6.24/include/asm-powerpc/spu_csa.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/spu_csa.h	2008-01-28 20:26:42.000000000 +0100
+@@ -194,7 +194,7 @@
+ };
+ 
+ /*
+- * struct spu_priv2_collapsed - condensed priviliged 2 area, w/o pads.
++ * struct spu_priv2_collapsed - condensed privileged 2 area, w/o pads.
+  */
+ struct spu_priv2_collapsed {
+ 	u64 slb_index_W;
+@@ -254,20 +254,11 @@
+ 	u64 spu_chnldata_RW[32];
+ 	u32 spu_mailbox_data[4];
+ 	u32 pu_mailbox_data[1];
+-	u64 dar, dsisr;
++	u64 dar, dsisr, class_0_pending;
+ 	unsigned long suspend_time;
+ 	spinlock_t register_lock;
+ };
+ 
+-extern int spu_init_csa(struct spu_state *csa);
+-extern void spu_fini_csa(struct spu_state *csa);
+-extern int spu_save(struct spu_state *prev, struct spu *spu);
+-extern int spu_restore(struct spu_state *new, struct spu *spu);
+-extern int spu_switch(struct spu_state *prev, struct spu_state *new,
+-		      struct spu *spu);
+-extern int spu_alloc_lscsa(struct spu_state *csa);
+-extern void spu_free_lscsa(struct spu_state *csa);
+-
+ #endif /* !__SPU__ */
+ #endif /* __KERNEL__ */
+ #endif /* !__ASSEMBLY__ */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/spu_priv1.h powerpc.git/include/asm-powerpc/spu_priv1.h
+--- linux-2.6.24/include/asm-powerpc/spu_priv1.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/spu_priv1.h	2008-01-28 20:26:42.000000000 +0100
+@@ -24,6 +24,7 @@
+ #include <linux/types.h>
+ 
+ struct spu;
++struct spu_context;
+ 
+ /* access to priv1 registers */
+ 
+@@ -178,6 +179,8 @@
+ 	int (*enumerate_spus)(int (*fn)(void *data));
+ 	int (*create_spu)(struct spu *spu, void *data);
+ 	int (*destroy_spu)(struct spu *spu);
++	void (*enable_spu)(struct spu_context *ctx);
++	void (*disable_spu)(struct spu_context *ctx);
+ 	int (*init_affinity)(void);
+ };
+ 
+@@ -207,6 +210,18 @@
+ 	return spu_management_ops->init_affinity();
+ }
+ 
++static inline void
++spu_enable_spu (struct spu_context *ctx)
++{
++	spu_management_ops->enable_spu(ctx);
++}
++
++static inline void
++spu_disable_spu (struct spu_context *ctx)
++{
++	spu_management_ops->disable_spu(ctx);
++}
++
+ /*
+  * The declarations folowing are put here for convenience
+  * and only intended to be used by the platform setup code.
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/system.h powerpc.git/include/asm-powerpc/system.h
+--- linux-2.6.24/include/asm-powerpc/system.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/system.h	2008-01-28 20:26:42.000000000 +0100
+@@ -169,6 +169,8 @@
+ extern void bad_page_fault(struct pt_regs *, unsigned long, int);
+ extern int die(const char *, struct pt_regs *, long);
+ extern void _exception(int, struct pt_regs *, int, unsigned long);
++extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
++
+ #ifdef CONFIG_BOOKE_WDT
+ extern u32 booke_wdt_enabled;
+ extern u32 booke_wdt_period;
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-powerpc/udbg.h powerpc.git/include/asm-powerpc/udbg.h
+--- linux-2.6.24/include/asm-powerpc/udbg.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-powerpc/udbg.h	2008-01-28 20:26:42.000000000 +0100
+@@ -48,6 +48,7 @@
+ extern void __init udbg_init_debug_beat(void);
+ extern void __init udbg_init_btext(void);
+ extern void __init udbg_init_44x_as1(void);
++extern void __init udbg_init_40x_realmode(void);
+ extern void __init udbg_init_cpm(void);
+ 
+ #endif /* __KERNEL__ */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-ppc/8xx_immap.h powerpc.git/include/asm-ppc/8xx_immap.h
+--- linux-2.6.24/include/asm-ppc/8xx_immap.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-ppc/8xx_immap.h	2008-01-28 20:26:42.000000000 +0100
+@@ -123,7 +123,7 @@
+ #define OR_G5LA		0x00000400	/* Output #GPL5 on #GPL_A5		*/
+ #define OR_G5LS		0x00000200	/* Drive #GPL high on falling edge of...*/
+ #define OR_BI		0x00000100	/* Burst inhibit			*/
+-#define OR_SCY_MSK	0x000000f0	/* Cycle Lenght in Clocks		*/
++#define OR_SCY_MSK	0x000000f0	/* Cycle Length in Clocks		*/
+ #define OR_SCY_0_CLK	0x00000000	/* 0 clock cycles wait states		*/
+ #define OR_SCY_1_CLK	0x00000010	/* 1 clock cycles wait states		*/
+ #define OR_SCY_2_CLK	0x00000020	/* 2 clock cycles wait states		*/
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-ppc/commproc.h powerpc.git/include/asm-ppc/commproc.h
+--- linux-2.6.24/include/asm-ppc/commproc.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-ppc/commproc.h	2008-01-28 20:26:42.000000000 +0100
+@@ -681,7 +681,7 @@
+ #define	CICR_SCC_SCC3		((uint)0x00200000)	/* SCC3 @ SCCc */
+ #define	CICR_SCB_SCC2		((uint)0x00040000)	/* SCC2 @ SCCb */
+ #define	CICR_SCA_SCC1		((uint)0x00000000)	/* SCC1 @ SCCa */
+-#define CICR_IRL_MASK		((uint)0x0000e000)	/* Core interrrupt */
++#define CICR_IRL_MASK		((uint)0x0000e000)	/* Core interrupt */
+ #define CICR_HP_MASK		((uint)0x00001f00)	/* Hi-pri int. */
+ #define CICR_IEN		((uint)0x00000080)	/* Int. enable */
+ #define CICR_SPS		((uint)0x00000001)	/* SCC Spread */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-ppc/mmu.h powerpc.git/include/asm-ppc/mmu.h
+--- linux-2.6.24/include/asm-ppc/mmu.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-ppc/mmu.h	2008-01-28 20:26:43.000000000 +0100
+@@ -383,6 +383,12 @@
+ #define BOOKE_PAGESZ_256GB	14
+ #define BOOKE_PAGESZ_1TB	15
+ 
++#ifndef CONFIG_SERIAL_TEXT_DEBUG
++#define PPC44x_EARLY_TLBS	1
++#else
++#define PPC44x_EARLY_TLBS	2
++#endif
++
+ /*
+  * Freescale Book-E MMU support
+  */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-ppc/mpc52xx_psc.h powerpc.git/include/asm-ppc/mpc52xx_psc.h
+--- linux-2.6.24/include/asm-ppc/mpc52xx_psc.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-ppc/mpc52xx_psc.h	2008-01-28 20:26:43.000000000 +0100
+@@ -159,6 +159,9 @@
+ 	u8		reserved16[3];
+ 	u8		irfdr;		/* PSC + 0x54 */
+ 	u8		reserved17[3];
++};
++
++struct mpc52xx_psc_fifo {
+ 	u16		rfnum;		/* PSC + 0x58 */
+ 	u16		reserved18;
+ 	u16		tfnum;		/* PSC + 0x5c */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/asm-ppc/reg_booke.h powerpc.git/include/asm-ppc/reg_booke.h
+--- linux-2.6.24/include/asm-ppc/reg_booke.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/asm-ppc/reg_booke.h	2008-01-28 20:26:43.000000000 +0100
+@@ -207,7 +207,7 @@
+ #define	CCR1_TCS	0x00000080 /* Timer Clock Select */
+ 
+ /* Bit definitions for the MCSR. */
+-#ifdef CONFIG_440A
++#ifdef CONFIG_4xx
+ #define MCSR_MCS	0x80000000 /* Machine Check Summary */
+ #define MCSR_IB		0x40000000 /* Instruction PLB Error */
+ #define MCSR_DRB	0x20000000 /* Data Read PLB Error */
+@@ -283,7 +283,7 @@
+ #define ESR_IMCB	0x20000000	/* Instr. Machine Check - Bus error */
+ #define ESR_IMCT	0x10000000	/* Instr. Machine Check - Timeout */
+ #define ESR_PIL		0x08000000	/* Program Exception - Illegal */
+-#define ESR_PPR		0x04000000	/* Program Exception - Priveleged */
++#define ESR_PPR		0x04000000	/* Program Exception - Privileged */
+ #define ESR_PTR		0x02000000	/* Program Exception - Trap */
+ #define ESR_FP		0x01000000	/* Floating Point Operation */
+ #define ESR_DST		0x00800000	/* Storage Exception - Data miss */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/linux/of.h powerpc.git/include/linux/of.h
+--- linux-2.6.24/include/linux/of.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/linux/of.h	2008-01-28 20:26:44.000000000 +0100
+@@ -17,6 +17,7 @@
+  */
+ #include <linux/types.h>
+ #include <linux/bitops.h>
++#include <linux/mod_devicetable.h>
+ 
+ #include <asm/prom.h>
+ 
+@@ -41,11 +42,20 @@
+ #define for_each_compatible_node(dn, type, compatible) \
+ 	for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
+ 	     dn = of_find_compatible_node(dn, type, compatible))
++extern struct device_node *of_find_matching_node(struct device_node *from,
++	const struct of_device_id *matches);
++#define for_each_matching_node(dn, matches) \
++	for (dn = of_find_matching_node(NULL, matches); dn; \
++	     dn = of_find_matching_node(dn, matches))
+ extern struct device_node *of_find_node_by_path(const char *path);
+ extern struct device_node *of_find_node_by_phandle(phandle handle);
+ extern struct device_node *of_get_parent(const struct device_node *node);
+ extern struct device_node *of_get_next_child(const struct device_node *node,
+ 					     struct device_node *prev);
++#define for_each_child_of_node(parent, child) \
++	for (child = of_get_next_child(parent, NULL); child != NULL; \
++	     child = of_get_next_child(parent, child))
++
+ extern struct property *of_find_property(const struct device_node *np,
+ 					 const char *name,
+ 					 int *lenp);
+@@ -56,5 +66,7 @@
+ 				int *lenp);
+ extern int of_n_addr_cells(struct device_node *np);
+ extern int of_n_size_cells(struct device_node *np);
++extern const struct of_device_id *of_match_node(
++	const struct of_device_id *matches, const struct device_node *node);
+ 
+ #endif /* _LINUX_OF_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/linux/of_device.h powerpc.git/include/linux/of_device.h
+--- linux-2.6.24/include/linux/of_device.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/linux/of_device.h	2008-01-28 20:26:44.000000000 +0100
+@@ -10,8 +10,6 @@
+ 
+ #define	to_of_device(d) container_of(d, struct of_device, dev)
+ 
+-extern const struct of_device_id *of_match_node(
+-	const struct of_device_id *matches, const struct device_node *node);
+ extern const struct of_device_id *of_match_device(
+ 	const struct of_device_id *matches, const struct of_device *dev);
+ 
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/linux/pata_platform.h powerpc.git/include/linux/pata_platform.h
+--- linux-2.6.24/include/linux/pata_platform.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/linux/pata_platform.h	2008-01-28 20:26:44.000000000 +0100
+@@ -15,4 +15,13 @@
+ 	unsigned int irq_flags;
+ };
+ 
++extern int __devinit __pata_platform_probe(struct device *dev,
++					   struct resource *io_res,
++					   struct resource *ctl_res,
++					   struct resource *irq_res,
++					   unsigned int ioport_shift,
++					   int __pio_mask);
++
++extern int __devexit __pata_platform_remove(struct device *dev);
++
+ #endif /* __LINUX_PATA_PLATFORM_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/linux/phy_fixed.h powerpc.git/include/linux/phy_fixed.h
+--- linux-2.6.24/include/linux/phy_fixed.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/linux/phy_fixed.h	2008-01-28 20:26:44.000000000 +0100
+@@ -1,38 +1,31 @@
+ #ifndef __PHY_FIXED_H
+ #define __PHY_FIXED_H
+ 
+-#define MII_REGS_NUM	29
+-
+-/* max number of virtual phy stuff */
+-#define MAX_PHY_AMNT	10
+-/*
+-    The idea is to emulate normal phy behavior by responding with
+-    pre-defined values to mii BMCR read, so that read_status hook could
+-    take all the needed info.
+-*/
+-
+ struct fixed_phy_status {
+-	u8 link;
+-	u16 speed;
+-	u8 duplex;
++	int link;
++	int speed;
++	int duplex;
++	int pause;
++	int asym_pause;
+ };
+ 
+-/*-----------------------------------------------------------------------------
+- *  Private information hoder for mii_bus
+- *-----------------------------------------------------------------------------*/
+-struct fixed_info {
+-	u16 *regs;
+-	u8 regs_num;
+-	struct fixed_phy_status phy_status;
+-	struct phy_device *phydev;	/* pointer to the container */
+-	/* link & speed cb */
+-	int (*link_update) (struct net_device *, struct fixed_phy_status *);
++#ifdef CONFIG_FIXED_PHY
++extern int fixed_phy_add(unsigned int irq, int phy_id,
++			 struct fixed_phy_status *status);
++#else
++static inline int fixed_phy_add(unsigned int irq, int phy_id,
++				struct fixed_phy_status *status)
++{
++	return -ENODEV;
++}
++#endif /* CONFIG_FIXED_PHY */
+ 
+-};
+-
+-
+-int fixed_mdio_set_link_update(struct phy_device *,
+-       int (*link_update) (struct net_device *, struct fixed_phy_status *));
+-struct fixed_info *fixed_mdio_get_phydev (int phydev_ind);
++/*
++ * This function issued only by fixed_phy-aware drivers, no need
++ * protect it with #ifdef
++ */
++extern int fixed_phy_set_link_update(struct phy_device *phydev,
++			int (*link_update)(struct net_device *,
++					   struct fixed_phy_status *));
+ 
+ #endif /* __PHY_FIXED_H */
+diff -x .git -x .gitignore -Nur linux-2.6.24/include/linux/pmu.h powerpc.git/include/linux/pmu.h
+--- linux-2.6.24/include/linux/pmu.h	2008-01-24 23:58:37.000000000 +0100
++++ powerpc.git/include/linux/pmu.h	2008-01-28 20:26:44.000000000 +0100
+@@ -159,41 +159,7 @@
+ extern int pmu_present(void);
+ extern int pmu_get_model(void);
+ 
+-#ifdef CONFIG_PM
+-/*
+- * Stuff for putting the powerbook to sleep and waking it again.
+- *
+- */
+-#include <linux/list.h>
+-
+-struct pmu_sleep_notifier
+-{
+-	void (*notifier_call)(struct pmu_sleep_notifier *self, int when);
+-	int priority;
+-	struct list_head list;
+-};
+-
+-/* Code values for calling sleep/wakeup handlers
+- */
+-#define PBOOK_SLEEP_REQUEST	1
+-#define PBOOK_SLEEP_NOW		2
+-#define PBOOK_WAKE		3
+-
+-/* priority levels in notifiers */
+-#define SLEEP_LEVEL_VIDEO	100	/* Video driver (first wake) */
+-#define SLEEP_LEVEL_MEDIABAY	90	/* Media bay driver */
+-#define SLEEP_LEVEL_BLOCK	80	/* IDE, SCSI */
+-#define SLEEP_LEVEL_NET		70	/* bmac, gmac */
+-#define SLEEP_LEVEL_MISC	60	/* Anything else */
+-#define SLEEP_LEVEL_USERLAND	55	/* Reserved for apm_emu */
+-#define SLEEP_LEVEL_ADB		50	/* ADB (async) */
+-#define SLEEP_LEVEL_SOUND	40	/* Sound driver (blocking) */
+-
+-/* special register notifier functions */
+-int pmu_register_sleep_notifier(struct pmu_sleep_notifier* notifier);
+-int pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* notifier);
+-
+-#endif /* CONFIG_PM */
++extern void pmu_backlight_set_sleep(int sleep);
+ 
+ #define PMU_MAX_BATTERIES	2
+ 
-- 
2.30.2