浏览代码

Merge branch 'for-2.6.23' into merge

Paul Mackerras 18 年之前
父节点
当前提交
bf22f6fe2d
共有 100 个文件被更改,包括 3563 次插入3795 次删除
  1. 1 1
      Documentation/cachetlb.txt
  2. 12 0
      Documentation/feature-removal-schedule.txt
  3. 38 2
      Documentation/powerpc/booting-without-of.txt
  4. 4 263
      arch/powerpc/Kconfig
  5. 1 1
      arch/powerpc/Makefile
  6. 45 0
      arch/powerpc/boot/44x.c
  7. 3 0
      arch/powerpc/boot/44x.h
  8. 35 46
      arch/powerpc/boot/Makefile
  9. 2 11
      arch/powerpc/boot/cuboot-83xx.c
  10. 2 11
      arch/powerpc/boot/cuboot-85xx.c
  11. 2 14
      arch/powerpc/boot/cuboot-ebony.c
  12. 35 0
      arch/powerpc/boot/cuboot.c
  13. 14 0
      arch/powerpc/boot/cuboot.h
  14. 37 0
      arch/powerpc/boot/dcr.h
  15. 5 7
      arch/powerpc/boot/dts/ebony.dts
  16. 27 25
      arch/powerpc/boot/dts/holly.dts
  17. 16 17
      arch/powerpc/boot/dts/mpc7448hpc2.dts
  18. 15 27
      arch/powerpc/boot/dts/mpc8272ads.dts
  19. 14 2
      arch/powerpc/boot/dts/mpc832x_mds.dts
  20. 14 2
      arch/powerpc/boot/dts/mpc832x_rdb.dts
  21. 10 0
      arch/powerpc/boot/dts/mpc8349emitx.dts
  22. 10 0
      arch/powerpc/boot/dts/mpc834x_mds.dts
  23. 14 2
      arch/powerpc/boot/dts/mpc836x_mds.dts
  24. 81 66
      arch/powerpc/boot/dts/mpc8540ads.dts
  25. 45 45
      arch/powerpc/boot/dts/mpc8541cds.dts
  26. 9 9
      arch/powerpc/boot/dts/mpc8544ds.dts
  27. 57 51
      arch/powerpc/boot/dts/mpc8548cds.dts
  28. 45 45
      arch/powerpc/boot/dts/mpc8555cds.dts
  29. 86 62
      arch/powerpc/boot/dts/mpc8560ads.dts
  30. 45 21
      arch/powerpc/boot/dts/mpc8568mds.dts
  31. 121 26
      arch/powerpc/boot/dts/mpc8641_hpcn.dts
  32. 11 20
      arch/powerpc/boot/dts/mpc866ads.dts
  33. 27 27
      arch/powerpc/boot/dts/mpc885ads.dts
  34. 1 1
      arch/powerpc/boot/dts/prpmc2800.dts
  35. 68 0
      arch/powerpc/boot/dts/ps3.dts
  36. 2 17
      arch/powerpc/boot/ebony.c
  37. 0 2
      arch/powerpc/boot/main.c
  38. 4 208
      arch/powerpc/boot/of.c
  39. 21 0
      arch/powerpc/boot/of.h
  40. 45 0
      arch/powerpc/boot/ofconsole.c
  41. 202 0
      arch/powerpc/boot/oflib.c
  42. 3 1
      arch/powerpc/boot/ops.h
  43. 80 0
      arch/powerpc/boot/ps3-head.S
  44. 184 0
      arch/powerpc/boot/ps3-hvcall.S
  45. 161 0
      arch/powerpc/boot/ps3.c
  46. 1 1
      arch/powerpc/boot/serial.c
  47. 9 1
      arch/powerpc/boot/stdio.c
  48. 4 0
      arch/powerpc/boot/types.h
  49. 55 0
      arch/powerpc/boot/wrapper
  50. 50 0
      arch/powerpc/boot/zImage.ps3.lds.S
  51. 4 2
      arch/powerpc/configs/holly_defconfig
  52. 35 17
      arch/powerpc/configs/ps3_defconfig
  53. 4 3
      arch/powerpc/kernel/Makefile
  54. 30 5
      arch/powerpc/kernel/cputable.c
  55. 3 119
      arch/powerpc/kernel/head_32.S
  56. 2 2
      arch/powerpc/kernel/head_64.S
  57. 6 6
      arch/powerpc/kernel/io.c
  58. 47 13
      arch/powerpc/kernel/irq.c
  59. 271 0
      arch/powerpc/kernel/isa-bridge.c
  60. 5 5
      arch/powerpc/kernel/misc_32.S
  61. 13 13
      arch/powerpc/kernel/misc_64.S
  62. 0 8
      arch/powerpc/kernel/of_platform.c
  63. 454 0
      arch/powerpc/kernel/pci-common.c
  64. 15 495
      arch/powerpc/kernel/pci_32.c
  65. 126 624
      arch/powerpc/kernel/pci_64.c
  66. 0 5
      arch/powerpc/kernel/ppc_ksyms.c
  67. 7 7
      arch/powerpc/kernel/process.c
  68. 19 10
      arch/powerpc/kernel/prom.c
  69. 3 1
      arch/powerpc/kernel/prom_init.c
  70. 0 161
      arch/powerpc/kernel/ptrace-common.h
  71. 218 107
      arch/powerpc/kernel/ptrace.c
  72. 104 135
      arch/powerpc/kernel/ptrace32.c
  73. 2 5
      arch/powerpc/kernel/rtas_pci.c
  74. 21 0
      arch/powerpc/kernel/setup-common.c
  75. 5 7
      arch/powerpc/kernel/setup_32.c
  76. 8 4
      arch/powerpc/kernel/setup_64.c
  77. 180 0
      arch/powerpc/kernel/signal.c
  78. 55 0
      arch/powerpc/kernel/signal.h
  79. 28 163
      arch/powerpc/kernel/signal_32.c
  80. 5 177
      arch/powerpc/kernel/signal_64.c
  81. 2 3
      arch/powerpc/kernel/sysfs.c
  82. 41 24
      arch/powerpc/kernel/time.c
  83. 1 1
      arch/powerpc/kernel/vdso.c
  84. 6 0
      arch/powerpc/kernel/vmlinux.lds.S
  85. 0 1
      arch/powerpc/mm/44x_mmu.c
  86. 0 1
      arch/powerpc/mm/4xx_mmu.c
  87. 1 2
      arch/powerpc/mm/Makefile
  88. 1 1
      arch/powerpc/mm/fault.c
  89. 0 1
      arch/powerpc/mm/fsl_booke_mmu.c
  90. 13 14
      arch/powerpc/mm/hash_native_64.c
  91. 1 1
      arch/powerpc/mm/hash_utils_64.c
  92. 0 313
      arch/powerpc/mm/imalloc.c
  93. 0 1
      arch/powerpc/mm/init_32.c
  94. 0 1
      arch/powerpc/mm/init_64.c
  95. 0 3
      arch/powerpc/mm/mem.c
  96. 0 1
      arch/powerpc/mm/mmu_context_32.c
  97. 2 15
      arch/powerpc/mm/mmu_decl.h
  98. 0 123
      arch/powerpc/mm/pgtable_32.c
  99. 49 157
      arch/powerpc/mm/pgtable_64.c
  100. 3 4
      arch/powerpc/mm/ppc_mmu_32.c

+ 1 - 1
Documentation/cachetlb.txt

@@ -253,7 +253,7 @@ Here are the routines, one by one:
 
 
 	The first of these two routines is invoked after map_vm_area()
 	The first of these two routines is invoked after map_vm_area()
 	has installed the page table entries.  The second is invoked
 	has installed the page table entries.  The second is invoked
-	before unmap_vm_area() deletes the page table entries.
+	before unmap_kernel_range() deletes the page table entries.
 
 
 There exists another whole class of cpu cache issues which currently
 There exists another whole class of cpu cache issues which currently
 require a whole different set of interfaces to handle properly.
 require a whole different set of interfaces to handle properly.

+ 12 - 0
Documentation/feature-removal-schedule.txt

@@ -330,3 +330,15 @@ Who:  Tejun Heo <htejun@gmail.com>
 
 
 ---------------------------
 ---------------------------
 
 
+What: The arch/ppc and include/asm-ppc directories
+When: Jun 2008
+Why:  The arch/powerpc tree is the merged architecture for ppc32 and ppc64
+      platforms.  Currently there are efforts underway to port the remaining
+      arch/ppc platforms to the merged tree.  New submissions to the arch/ppc
+      tree have been frozen with the 2.6.22 kernel release and that tree will
+      remain in bug-fix only mode until its scheduled removal.  Platforms
+      that are not ported by June 2008 will be removed due to the lack of an
+      interested maintainer.
+Who:  linuxppc-dev@ozlabs.org
+
+---------------------------

+ 38 - 2
Documentation/powerpc/booting-without-of.txt

@@ -42,15 +42,16 @@ Table of Contents
     1) Defining child nodes of an SOC
     1) Defining child nodes of an SOC
     2) Representing devices without a current OF specification
     2) Representing devices without a current OF specification
       a) MDIO IO device
       a) MDIO IO device
-      c) PHY nodes
       b) Gianfar-compatible ethernet nodes
       b) Gianfar-compatible ethernet nodes
+      c) PHY nodes
       d) Interrupt controllers
       d) Interrupt controllers
       e) I2C
       e) I2C
       f) Freescale SOC USB controllers
       f) Freescale SOC USB controllers
       g) Freescale SOC SEC Security Engines
       g) Freescale SOC SEC Security Engines
       h) Board Control and Status (BCSR)
       h) Board Control and Status (BCSR)
       i) Freescale QUICC Engine module (QE)
       i) Freescale QUICC Engine module (QE)
-      g) Flash chip nodes
+      j) Flash chip nodes
+      k) Global Utilities Block
 
 
   VII - Specifying interrupt information for devices
   VII - Specifying interrupt information for devices
     1) interrupts property
     1) interrupts property
@@ -626,6 +627,14 @@ So the node content can be summarized as a start token, a full path,
 a list of properties, a list of child nodes, and an end token. Every
 a list of properties, a list of child nodes, and an end token. Every
 child node is a full node structure itself as defined above.
 child node is a full node structure itself as defined above.
 
 
+NOTE: The above definition requires that all property definitions for
+a particular node MUST precede any subnode definitions for that node.
+Although the structure would not be ambiguous if properties and
+subnodes were intermingled, the kernel parser requires that the
+properties come first (up until at least 2.6.22).  Any tools
+manipulating a flattened tree must take care to preserve this
+constraint.
+
 4) Device tree "strings" block
 4) Device tree "strings" block
 
 
 In order to save space, property names, which are generally redundant,
 In order to save space, property names, which are generally redundant,
@@ -1782,6 +1791,33 @@ platforms are moved over to use the flattened-device-tree model.
  		partition-names = "fs\0firmware";
  		partition-names = "fs\0firmware";
  	};
  	};
 
 
+   k) Global Utilities Block
+
+   The global utilities block controls power management, I/O device
+   enabling, power-on-reset configuration monitoring, general-purpose
+   I/O signal configuration, alternate function selection for multiplexed
+   signals, and clock control.
+
+   Required properties:
+
+    - compatible : Should define the compatible device type for
+      global-utilities.
+    - reg : Offset and length of the register set for the device.
+
+  Recommended properties:
+
+    - fsl,has-rstcr : Indicates that the global utilities register set
+      contains a functioning "reset control register" (i.e. the board
+      is wired to reset upon setting the HRESET_REQ bit in this register).
+
+    Example:
+
+	global-utilities@e0000 {	/* global utilities block */
+		compatible = "fsl,mpc8548-guts";
+		reg = <e0000 1000>;
+		fsl,has-rstcr;
+	};
+
    More devices will be defined as this spec matures.
    More devices will be defined as this spec matures.
 
 
 VII - Specifying interrupt information for devices
 VII - Specifying interrupt information for devices

+ 4 - 263
arch/powerpc/Kconfig

@@ -4,17 +4,7 @@
 
 
 mainmenu "Linux/PowerPC Kernel Configuration"
 mainmenu "Linux/PowerPC Kernel Configuration"
 
 
-config PPC64
-	bool "64-bit kernel"
-	default n
-	help
-	  This option selects whether a 32-bit or a 64-bit kernel
-	  will be built.
-
-config PPC_PM_NEEDS_RTC_LIB
-	bool
-	select RTC_LIB
-	default y if PM
+source "arch/powerpc/platforms/Kconfig.cputype"
 
 
 config PPC32
 config PPC32
 	bool
 	bool
@@ -132,123 +122,6 @@ config PPC64_SWSUSP
 	depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL))
 	depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL))
 	default y
 	default y
 
 
-menu "Processor support"
-choice
-	prompt "Processor Type"
-	depends on PPC32
-	default 6xx
-
-config CLASSIC32
-	bool "52xx/6xx/7xx/74xx"
-	select PPC_FPU
-	select 6xx
-	help
-	  There are four families of PowerPC chips supported.  The more common
-	  types (601, 603, 604, 740, 750, 7400), the Motorola embedded
-	  versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC
-	  embedded versions (403 and 405) and the high end 64 bit Power
-	  processors (POWER 3, POWER4, and IBM PPC970 also known as G5).
-
-	  This option is the catch-all for 6xx types, including some of the
-	  embedded versions.  Unless there is see an option for the specific
-	  chip family you are using, you want this option.
-	  
-	  You do not want this if you are building a kernel for a 64 bit
-	  IBM RS/6000 or an Apple G5, choose 6xx.
-	  
-	  If unsure, select this option
-	  
-	  Note that the kernel runs in 32-bit mode even on 64-bit chips.
-
-config PPC_82xx
-	bool "Freescale 82xx"
-	select 6xx
-	select PPC_FPU
-
-config PPC_83xx
-	bool "Freescale 83xx"
-	select 6xx
-	select FSL_SOC
-	select 83xx
-	select PPC_FPU
-	select WANT_DEVICE_TREE
-
-config PPC_85xx
-	bool "Freescale 85xx"
-	select E500
-	select FSL_SOC
-	select 85xx
-	select WANT_DEVICE_TREE
-
-config PPC_86xx
-	bool "Freescale 86xx"
-	select 6xx
-	select FSL_SOC
-	select FSL_PCIE
-	select PPC_FPU
-	select ALTIVEC
-	help
-	  The Freescale E600 SoCs have 74xx cores.
-
-config PPC_8xx
-	bool "Freescale 8xx"
-	select FSL_SOC
-	select 8xx
-
-config 40x
-	bool "AMCC 40x"
-	select PPC_DCR_NATIVE
-
-config 44x
-	bool "AMCC 44x"
-	select PPC_DCR_NATIVE
-	select WANT_DEVICE_TREE
-
-config E200
-	bool "Freescale e200"
-
-endchoice
-
-config POWER4_ONLY
-	bool "Optimize for POWER4"
-	depends on PPC64
-	default n
-	---help---
-	  Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
-	  The resulting binary will not work on POWER3 or RS64 processors
-	  when compiled with binutils 2.15 or later.
-
-config POWER3
-	bool
-	depends on PPC64
-	default y if !POWER4_ONLY
-
-config POWER4
-	depends on PPC64
-	def_bool y
-
-config 6xx
-	bool
-
-# this is temp to handle compat with arch=ppc
-config 8xx
-	bool
-
-# this is temp to handle compat with arch=ppc
-config 83xx
-	bool
-
-# this is temp to handle compat with arch=ppc
-config 85xx
-	bool
-
-config E500
-	bool
-
-config PPC_FPU
-	bool
-	default y if PPC64
-
 config PPC_DCR_NATIVE
 config PPC_DCR_NATIVE
 	bool
 	bool
 	default n
 	default n
@@ -267,134 +140,6 @@ config PPC_OF_PLATFORM_PCI
 	depends on PPC64 # not supported on 32 bits yet
 	depends on PPC64 # not supported on 32 bits yet
 	default n
 	default n
 
 
-config 4xx
-	bool
-	depends on 40x || 44x
-	default y
-
-config BOOKE
-	bool
-	depends on E200 || E500 || 44x
-	default y
-
-config FSL_BOOKE
-	bool
-	depends on E200 || E500
-	default y
-
-config PTE_64BIT
-	bool
-	depends on 44x || E500
-	default y if 44x
-	default y if E500 && PHYS_64BIT
-
-config PHYS_64BIT
-	bool 'Large physical address support' if E500
-	depends on 44x || E500
-	select RESOURCES_64BIT
-	default y if 44x
-	---help---
-	  This option enables kernel support for larger than 32-bit physical
-	  addresses.  This features is not be available on all e500 cores.
-
-	  If in doubt, say N here.
-
-config ALTIVEC
-	bool "AltiVec Support"
-	depends on CLASSIC32 || POWER4
-	---help---
-	  This option enables kernel support for the Altivec extensions to the
-	  PowerPC processor. The kernel currently supports saving and restoring
-	  altivec registers, and turning on the 'altivec enable' bit so user
-	  processes can execute altivec instructions.
-
-	  This option is only usefully if you have a processor that supports
-	  altivec (G4, otherwise known as 74xx series), but does not have
-	  any affect on a non-altivec cpu (it does, however add code to the
-	  kernel).
-
-	  If in doubt, say Y here.
-
-config SPE
-	bool "SPE Support"
-	depends on E200 || E500
-	default y
-	---help---
-	  This option enables kernel support for the Signal Processing
-	  Extensions (SPE) to the PowerPC processor. The kernel currently
-	  supports saving and restoring SPE registers, and turning on the
-	  'spe enable' bit so user processes can execute SPE instructions.
-
-	  This option is only useful if you have a processor that supports
-	  SPE (e500, otherwise known as 85xx series), but does not have any
-	  effect on a non-spe cpu (it does, however add code to the kernel).
-
-	  If in doubt, say Y here.
-
-config PPC_STD_MMU
-	bool
-	depends on 6xx || POWER3 || POWER4 || PPC64
-	default y
-
-config PPC_STD_MMU_32
-	def_bool y
-	depends on PPC_STD_MMU && PPC32
-
-config PPC_MM_SLICES
-	bool
-	default y if HUGETLB_PAGE
-	default n
-
-config VIRT_CPU_ACCOUNTING
-	bool "Deterministic task and CPU time accounting"
-	depends on PPC64
-	default y
-	help
-	  Select this option to enable more accurate task and CPU time
-	  accounting.  This is done by reading a CPU counter on each
-	  kernel entry and exit and on transitions within the kernel
-	  between system, softirq and hardirq state, so there is a
-	  small performance impact.  This also enables accounting of
-	  stolen time on logically-partitioned systems running on
-	  IBM POWER5-based machines.
-
-	  If in doubt, say Y here.
-
-config SMP
-	depends on PPC_STD_MMU
-	bool "Symmetric multi-processing support"
-	---help---
-	  This enables support for systems with more than one CPU. If you have
-	  a system with only one CPU, say N. If you have a system with more
-	  than one CPU, say Y.  Note that the kernel does not currently
-	  support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
-	  since they have inadequate hardware support for multiprocessor
-	  operation.
-
-	  If you say N here, the kernel will run on single and multiprocessor
-	  machines, but will use only one CPU of a multiprocessor machine. If
-	  you say Y here, the kernel will run on single-processor machines.
-	  On a single-processor machine, the kernel will run faster if you say
-	  N here.
-
-	  If you don't know what to do here, say N.
-
-config NR_CPUS
-	int "Maximum number of CPUs (2-128)"
-	range 2 128
-	depends on SMP
-	default "32" if PPC64
-	default "4"
-
-config NOT_COHERENT_CACHE
-	bool
-	depends on 4xx || 8xx || E200
-	default y
-
-config CONFIG_CHECK_CACHE_COHERENCY
-	bool
-endmenu
-
 source "init/Kconfig"
 source "init/Kconfig"
 
 
 source "arch/powerpc/platforms/Kconfig"
 source "arch/powerpc/platforms/Kconfig"
@@ -674,10 +419,6 @@ config SBUS
 config FSL_SOC
 config FSL_SOC
 	bool
 	bool
 
 
-config FSL_PCIE
-	bool
-	depends on PPC_86xx
-
 # Yes MCA RS/6000s exist but Linux-PPC does not currently support any
 # Yes MCA RS/6000s exist but Linux-PPC does not currently support any
 config MCA
 config MCA
 	bool
 	bool
@@ -685,10 +426,10 @@ config MCA
 config PCI
 config PCI
 	bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
 	bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
 		|| PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
 		|| PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
-		|| MPC7448HPC2 || PPC_PS3 || PPC_HOLLY
-	default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \
+		|| PPC_PS3
+	default y if !40x && !CPM2 && !8xx && !PPC_83xx \
 		&& !PPC_85xx && !PPC_86xx
 		&& !PPC_85xx && !PPC_86xx
-	default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
+	default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
 	default PCI_QSPAN if !4xx && !CPM2 && 8xx
 	default PCI_QSPAN if !4xx && !CPM2 && 8xx
 	select ARCH_SUPPORTS_MSI
 	select ARCH_SUPPORTS_MSI
 	help
 	help

+ 1 - 1
arch/powerpc/Makefile

@@ -148,7 +148,7 @@ all: $(KBUILD_IMAGE)
 
 
 CPPFLAGS_vmlinux.lds	:= -Upowerpc
 CPPFLAGS_vmlinux.lds	:= -Upowerpc
 
 
-BOOT_TARGETS = zImage zImage.initrd zImage.dts zImage.dts_initrd uImage
+BOOT_TARGETS = zImage zImage.initrd uImage
 
 
 PHONY += $(BOOT_TARGETS)
 PHONY += $(BOOT_TARGETS)
 
 

+ 45 - 0
arch/powerpc/boot/44x.c

@@ -38,3 +38,48 @@ void ibm44x_fixup_memsize(void)
 
 
 	dt_fixup_memory(0, memsize);
 	dt_fixup_memory(0, memsize);
 }
 }
+
+#define SPRN_DBCR0		0x134
+#define   DBCR0_RST_SYSTEM	0x30000000
+
+void ibm44x_dbcr_reset(void)
+{
+	unsigned long tmp;
+
+	asm volatile (
+		"mfspr	%0,%1\n"
+		"oris	%0,%0,%2@h\n"
+		"mtspr	%1,%0"
+		: "=&r"(tmp) : "i"(SPRN_DBCR0), "i"(DBCR0_RST_SYSTEM)
+		);
+
+}
+
+/* Read 4xx EBC bus bridge registers to get mappings of the peripheral
+ * banks into the OPB address space */
+void ibm4xx_fixup_ebc_ranges(const char *ebc)
+{
+	void *devp;
+	u32 bxcr;
+	u32 ranges[EBC_NUM_BANKS*4];
+	u32 *p = ranges;
+	int i;
+
+	for (i = 0; i < EBC_NUM_BANKS; i++) {
+		mtdcr(DCRN_EBC0_CFGADDR, EBC_BXCR(i));
+		bxcr = mfdcr(DCRN_EBC0_CFGDATA);
+
+		if ((bxcr & EBC_BXCR_BU) != EBC_BXCR_BU_OFF) {
+			*p++ = i;
+			*p++ = 0;
+			*p++ = bxcr & EBC_BXCR_BAS;
+			*p++ = EBC_BXCR_BANK_SIZE(bxcr);
+		}
+	}
+
+	devp = finddevice(ebc);
+	if (! devp)
+		fatal("Couldn't locate EBC node %s\n\r", ebc);
+
+	setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32));
+}

+ 3 - 0
arch/powerpc/boot/44x.h

@@ -11,6 +11,9 @@
 #define _PPC_BOOT_44X_H_
 #define _PPC_BOOT_44X_H_
 
 
 void ibm44x_fixup_memsize(void);
 void ibm44x_fixup_memsize(void);
+void ibm4xx_fixup_ebc_ranges(const char *ebc);
+
+void ibm44x_dbcr_reset(void);
 void ebony_init(void *mac0, void *mac1);
 void ebony_init(void *mac0, void *mac1);
 
 
 #endif /* _PPC_BOOT_44X_H_ */
 #endif /* _PPC_BOOT_44X_H_ */

+ 35 - 46
arch/powerpc/boot/Makefile

@@ -43,10 +43,11 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
 
 
 src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
 src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
 		ns16550.c serial.c simple_alloc.c div64.S util.S \
 		ns16550.c serial.c simple_alloc.c div64.S util.S \
-		gunzip_util.c elf_util.c $(zlib) devtree.c \
-		44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c
+		gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
+		44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c
 src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
 src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
-		cuboot-ebony.c treeboot-ebony.c prpmc2800.c
+		cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
+		ps3-head.S ps3-hvcall.S ps3.c
 src-boot := $(src-wlib) $(src-plat) empty.c
 src-boot := $(src-wlib) $(src-plat) empty.c
 
 
 src-boot := $(addprefix $(obj)/, $(src-boot))
 src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -75,11 +76,11 @@ $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
 $(obj)/empty.c:
 $(obj)/empty.c:
 	@touch $@
 	@touch $@
 
 
-$(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S
+$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S
 	@cp $< $@
 	@cp $< $@
 
 
 clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
 clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
-		empty.c zImage.coff.lds zImage.lds
+		empty.c zImage zImage.coff.lds zImage.ps3.lds zImage.lds
 
 
 quiet_cmd_bootcc = BOOTCC  $@
 quiet_cmd_bootcc = BOOTCC  $@
       cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
       cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -102,7 +103,7 @@ hostprogs-y	:= addnote addRamDisk hack-coff mktree
 
 
 targets		+= $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
 targets		+= $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
 extra-y		:= $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
 extra-y		:= $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
-		   $(obj)/zImage.lds $(obj)/zImage.coff.lds
+		   $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
 
 
 wrapper		:=$(srctree)/$(src)/wrapper
 wrapper		:=$(srctree)/$(src)/wrapper
 wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
 wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
@@ -132,7 +133,7 @@ image-$(CONFIG_PPC_CELLEB)		+= zImage.pseries
 image-$(CONFIG_PPC_CHRP)		+= zImage.chrp
 image-$(CONFIG_PPC_CHRP)		+= zImage.chrp
 image-$(CONFIG_PPC_EFIKA)		+= zImage.chrp
 image-$(CONFIG_PPC_EFIKA)		+= zImage.chrp
 image-$(CONFIG_PPC_PMAC)		+= zImage.pmac
 image-$(CONFIG_PPC_PMAC)		+= zImage.pmac
-image-$(CONFIG_PPC_HOLLY)		+= zImage.holly-elf
+image-$(CONFIG_PPC_HOLLY)		+= zImage.holly
 image-$(CONFIG_PPC_PRPMC2800)		+= zImage.prpmc2800
 image-$(CONFIG_PPC_PRPMC2800)		+= zImage.prpmc2800
 image-$(CONFIG_PPC_ISERIES)		+= zImage.iseries
 image-$(CONFIG_PPC_ISERIES)		+= zImage.iseries
 image-$(CONFIG_DEFAULT_UIMAGE)		+= uImage
 image-$(CONFIG_DEFAULT_UIMAGE)		+= uImage
@@ -157,55 +158,43 @@ targets	+= $(image-y) $(initrd-y)
 
 
 $(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
 $(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
 
 
-dts-  := $(patsubst zImage%, zImage.dts%, $(image-n) $(image-))
-dts-y := $(patsubst zImage%, zImage.dts%, $(image-y))
-dts-y := $(filter-out $(image-y), $(dts-y))
-targets	+= $(image-y) $(dts-y)
-
-dts_initrd-  := $(patsubst zImage%, zImage.dts_initrd%, $(image-n) $(image-))
-dts_initrd-y := $(patsubst zImage%, zImage.dts_initrd%, $(image-y))
-dts_initrd-y := $(filter-out $(image-y), $(dts_initrd-y))
-targets	+= $(image-y) $(dts_initrd-y)
-
-$(addprefix $(obj)/, $(dts_initrd-y)): $(obj)/ramdisk.image.gz
+# If CONFIG_WANT_DEVICE_TREE is set and CONFIG_DEVICE_TREE isn't an
+# empty string, define 'dts' to be path to the dts
+# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them
+ifeq ($(CONFIG_WANT_DEVICE_TREE),y)
+ifneq ($(CONFIG_DEVICE_TREE),"")
+dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\
+	,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%)
+endif
+endif
 
 
 # Don't put the ramdisk on the pattern rule; when its missing make will try
 # Don't put the ramdisk on the pattern rule; when its missing make will try
 # the pattern rule with less dependencies that also matches (even with the
 # the pattern rule with less dependencies that also matches (even with the
 # hard dependency listed).
 # hard dependency listed).
-$(obj)/zImage.dts_initrd.%: vmlinux $(wrapperbits) $(dts) $(obj)/ramdisk.image.gz
+$(obj)/zImage.initrd.%: vmlinux $(wrapperbits) $(dts)
 	$(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz)
 	$(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz)
 
 
-$(obj)/zImage.dts.%: vmlinux $(wrapperbits) $(dts)
+$(obj)/zImage.%: vmlinux $(wrapperbits) $(dts)
 	$(call if_changed,wrap,$*,$(dts))
 	$(call if_changed,wrap,$*,$(dts))
 
 
-$(obj)/zImage.initrd.%: vmlinux $(wrapperbits)
-	$(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz)
-
-$(obj)/zImage.%: vmlinux $(wrapperbits)
-	$(call if_changed,wrap,$*)
-
-$(obj)/zImage.iseries: vmlinux
+# This cannot be in the root of $(src) as the zImage rule always adds a $(obj)
+# prefix
+$(obj)/vmlinux.strip: vmlinux
 	$(STRIP) -s -R .comment $< -o $@
 	$(STRIP) -s -R .comment $< -o $@
 
 
-$(obj)/zImage.ps3: vmlinux
+$(obj)/zImage.iseries: vmlinux
 	$(STRIP) -s -R .comment $< -o $@
 	$(STRIP) -s -R .comment $< -o $@
 
 
-$(obj)/zImage.initrd.ps3: vmlinux
-	@echo "  WARNING zImage.initrd.ps3 not supported (yet)"
-
-$(obj)/zImage.holly-elf: vmlinux $(wrapperbits)
-	$(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,)
+$(obj)/zImage.ps3: vmlinux  $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts
+	$(STRIP) -s -R .comment $< -o vmlinux.strip
+	$(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,)
 
 
-$(obj)/zImage.initrd.holly-elf: vmlinux $(wrapperbits) $(obj)/ramdisk.image.gz
-	$(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,$(obj)/ramdisk.image.gz)
+$(obj)/zImage.initrd.ps3: vmlinux  $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts $(obj)/ramdisk.image.gz
+	$(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,$(obj)/ramdisk.image.gz)
 
 
 $(obj)/uImage: vmlinux $(wrapperbits)
 $(obj)/uImage: vmlinux $(wrapperbits)
 	$(call if_changed,wrap,uboot)
 	$(call if_changed,wrap,uboot)
 
 
-# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them
-dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\
-	,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%)
-
 $(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits)
 $(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits)
 	$(call if_changed,wrap,cuboot-$*,$(dts))
 	$(call if_changed,wrap,cuboot-$*,$(dts))
 
 
@@ -215,22 +204,22 @@ $(obj)/treeImage.initrd.%: vmlinux $(dts) $(wrapperbits)
 $(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits)
 $(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits)
 	$(call if_changed,wrap,treeboot-$*,$(dts))
 	$(call if_changed,wrap,treeboot-$*,$(dts))
 
 
+# If there isn't a platform selected then just strip the vmlinux.
+ifeq (,$(image-y))
+image-y := vmlinux.strip
+endif
+
 $(obj)/zImage:		$(addprefix $(obj)/, $(image-y))
 $(obj)/zImage:		$(addprefix $(obj)/, $(image-y))
 	@rm -f $@; ln $< $@
 	@rm -f $@; ln $< $@
 $(obj)/zImage.initrd:	$(addprefix $(obj)/, $(initrd-y))
 $(obj)/zImage.initrd:	$(addprefix $(obj)/, $(initrd-y))
 	@rm -f $@; ln $< $@
 	@rm -f $@; ln $< $@
-$(obj)/zImage.dts:	$(addprefix $(obj)/, $(dts-y))
-	@rm -f $@; ln $< $@
-$(obj)/zImage.dts_initrd:	$(addprefix $(obj)/, $(dts_initrd-y))
-	@rm -f $@; ln $< $@
-
 
 
 install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y))
 install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y))
 	sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
 	sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
 
 
 # anything not in $(targets)
 # anything not in $(targets)
-clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* \
-	treeImage.* zImage.dts zImage.dts_initrd
+clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* treeImage.* \
+	otheros.bld
 
 
 # clean up files cached by wrapper
 # clean up files cached by wrapper
 clean-kernel := vmlinux.strip vmlinux.bin
 clean-kernel := vmlinux.strip vmlinux.bin

+ 2 - 11
arch/powerpc/boot/cuboot-83xx.c

@@ -12,12 +12,12 @@
 
 
 #include "ops.h"
 #include "ops.h"
 #include "stdio.h"
 #include "stdio.h"
+#include "cuboot.h"
 
 
 #define TARGET_83xx
 #define TARGET_83xx
 #include "ppcboot.h"
 #include "ppcboot.h"
 
 
 static bd_t bd;
 static bd_t bd;
-extern char _end[];
 extern char _dtb_start[], _dtb_end[];
 extern char _dtb_start[], _dtb_end[];
 
 
 static void platform_fixups(void)
 static void platform_fixups(void)
@@ -52,16 +52,7 @@ static void platform_fixups(void)
 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                    unsigned long r6, unsigned long r7)
                    unsigned long r6, unsigned long r7)
 {
 {
-	unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize;
-	unsigned long avail_ram = end_of_ram - (unsigned long)_end;
-
-	memcpy(&bd, (bd_t *)r3, sizeof(bd));
-	loader_info.initrd_addr = r4;
-	loader_info.initrd_size = r4 ? r5 - r4 : 0;
-	loader_info.cmdline = (char *)r6;
-	loader_info.cmdline_len = r7 - r6;
-
-	simple_alloc_init(_end, avail_ram - 1024*1024, 32, 64);
+	CUBOOT_INIT();
 	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
 	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
 	serial_console_init();
 	serial_console_init();
 	platform_ops.fixups = platform_fixups;
 	platform_ops.fixups = platform_fixups;

+ 2 - 11
arch/powerpc/boot/cuboot-85xx.c

@@ -12,12 +12,12 @@
 
 
 #include "ops.h"
 #include "ops.h"
 #include "stdio.h"
 #include "stdio.h"
+#include "cuboot.h"
 
 
 #define TARGET_85xx
 #define TARGET_85xx
 #include "ppcboot.h"
 #include "ppcboot.h"
 
 
 static bd_t bd;
 static bd_t bd;
-extern char _end[];
 extern char _dtb_start[], _dtb_end[];
 extern char _dtb_start[], _dtb_end[];
 
 
 static void platform_fixups(void)
 static void platform_fixups(void)
@@ -53,16 +53,7 @@ static void platform_fixups(void)
 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                    unsigned long r6, unsigned long r7)
                    unsigned long r6, unsigned long r7)
 {
 {
-	unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize;
-	unsigned long avail_ram = end_of_ram - (unsigned long)_end;
-
-	memcpy(&bd, (bd_t *)r3, sizeof(bd));
-	loader_info.initrd_addr = r4;
-	loader_info.initrd_size = r4 ? r5 - r4 : 0;
-	loader_info.cmdline = (char *)r6;
-	loader_info.cmdline_len = r7 - r6;
-
-	simple_alloc_init(_end, avail_ram - 1024*1024, 32, 64);
+	CUBOOT_INIT();
 	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
 	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
 	serial_console_init();
 	serial_console_init();
 	platform_ops.fixups = platform_fixups;
 	platform_ops.fixups = platform_fixups;

+ 2 - 14
arch/powerpc/boot/cuboot-ebony.c

@@ -15,28 +15,16 @@
 #include "ops.h"
 #include "ops.h"
 #include "stdio.h"
 #include "stdio.h"
 #include "44x.h"
 #include "44x.h"
+#include "cuboot.h"
 
 
 #define TARGET_44x
 #define TARGET_44x
 #include "ppcboot.h"
 #include "ppcboot.h"
 
 
 static bd_t bd;
 static bd_t bd;
-extern char _end[];
-
-BSS_STACK(4096);
 
 
 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                    unsigned long r6, unsigned long r7)
                    unsigned long r6, unsigned long r7)
 {
 {
-	unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize;
-	unsigned long avail_ram = end_of_ram - (unsigned long)_end;
-
-	memcpy(&bd, (bd_t *)r3, sizeof(bd));
-	loader_info.initrd_addr = r4;
-	loader_info.initrd_size = r4 ? r5 : 0;
-	loader_info.cmdline = (char *)r6;
-	loader_info.cmdline_len = r7 - r6;
-
-	simple_alloc_init(_end, avail_ram, 32, 64);
-
+	CUBOOT_INIT();
 	ebony_init(&bd.bi_enetaddr, &bd.bi_enet1addr);
 	ebony_init(&bd.bi_enetaddr, &bd.bi_enet1addr);
 }
 }

+ 35 - 0
arch/powerpc/boot/cuboot.c

@@ -0,0 +1,35 @@
+/*
+ * Compatibility for old (not device tree aware) U-Boot versions
+ *
+ * Author: Scott Wood <scottwood@freescale.com>
+ * Consolidated using macros by David Gibson <david@gibson.dropbear.id.au>
+ *
+ * Copyright 2007 David Gibson, IBM Corporation.
+ * 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 "ppcboot.h"
+
+extern char _end[];
+extern char _dtb_start[], _dtb_end[];
+
+void cuboot_init(unsigned long r4, unsigned long r5,
+		 unsigned long r6, unsigned long r7,
+		 unsigned long end_of_ram)
+{
+	unsigned long avail_ram = end_of_ram - (unsigned long)_end;
+
+	loader_info.initrd_addr = r4;
+	loader_info.initrd_size = r4 ? r5 - r4 : 0;
+	loader_info.cmdline = (char *)r6;
+	loader_info.cmdline_len = r7 - r6;
+
+	simple_alloc_init(_end, avail_ram - 1024*1024, 32, 64);
+}

+ 14 - 0
arch/powerpc/boot/cuboot.h

@@ -0,0 +1,14 @@
+#ifndef _PPC_BOOT_CUBOOT_H_
+#define _PPC_BOOT_CUBOOT_H_
+
+void cuboot_init(unsigned long r4, unsigned long r5,
+		 unsigned long r6, unsigned long r7,
+		 unsigned long end_of_ram);
+
+#define CUBOOT_INIT() \
+	do { \
+		memcpy(&bd, (bd_t *)r3, sizeof(bd)); \
+		cuboot_init(r4, r5, r6, r7, bd.bi_memstart + bd.bi_memsize); \
+	} while (0)
+
+#endif /* _PPC_BOOT_CUBOOT_H_ */

+ 37 - 0
arch/powerpc/boot/dcr.h

@@ -26,6 +26,43 @@ static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2C
 #define			SDRAM_CONFIG_BANK_SIZE(reg)	\
 #define			SDRAM_CONFIG_BANK_SIZE(reg)	\
 	(0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17))
 	(0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17))
 
 
+/* 440GP External Bus Controller (EBC) */
+#define DCRN_EBC0_CFGADDR				0x012
+#define DCRN_EBC0_CFGDATA				0x013
+#define   EBC_NUM_BANKS					  8
+#define   EBC_B0CR					  0x00
+#define   EBC_B1CR					  0x01
+#define   EBC_B2CR					  0x02
+#define   EBC_B3CR					  0x03
+#define   EBC_B4CR					  0x04
+#define   EBC_B5CR					  0x05
+#define   EBC_B6CR					  0x06
+#define   EBC_B7CR					  0x07
+#define   EBC_BXCR(n)					  (n)
+#define	    EBC_BXCR_BAS				    0xfff00000
+#define	    EBC_BXCR_BS				  	    0x000e0000
+#define	    EBC_BXCR_BANK_SIZE(reg) \
+	(0x100000 << (((reg) & EBC_BXCR_BS) >> 17))
+#define	    EBC_BXCR_BU				  	    0x00018000
+#define	      EBC_BXCR_BU_OFF			  	      0x00000000
+#define	      EBC_BXCR_BU_RO			  	      0x00008000
+#define	      EBC_BXCR_BU_WO			  	      0x00010000
+#define	      EBC_BXCR_BU_RW			  	      0x00018000
+#define	    EBC_BXCR_BW				  	    0x00006000
+#define   EBC_B0AP					  0x10
+#define   EBC_B1AP					  0x11
+#define   EBC_B2AP					  0x12
+#define   EBC_B3AP					  0x13
+#define   EBC_B4AP					  0x14
+#define   EBC_B5AP					  0x15
+#define   EBC_B6AP					  0x16
+#define   EBC_B7AP					  0x17
+#define   EBC_BXAP(n)					  (0x10+(n))
+#define   EBC_BEAR					  0x20
+#define   EBC_BESR					  0x21
+#define   EBC_CFG					  0x23
+#define   EBC_CID					  0x24
+
 /* 440GP Clock, PM, chip control */
 /* 440GP Clock, PM, chip control */
 #define DCRN_CPC0_SR					0x0b0
 #define DCRN_CPC0_SR					0x0b0
 #define DCRN_CPC0_ER					0x0b1
 #define DCRN_CPC0_ER					0x0b1

+ 5 - 7
arch/powerpc/boot/dts/ebony.dts

@@ -31,8 +31,8 @@
 			reg = <0>;
 			reg = <0>;
 			clock-frequency = <0>; // Filled in by zImage
 			clock-frequency = <0>; // Filled in by zImage
 			timebase-frequency = <0>; // Filled in by zImage
 			timebase-frequency = <0>; // Filled in by zImage
-			i-cache-line-size = <32>;
-			d-cache-line-size = <32>;
+			i-cache-line-size = <20>;
+			d-cache-line-size = <20>;
 			i-cache-size = <8000>; /* 32 kB */
 			i-cache-size = <8000>; /* 32 kB */
 			d-cache-size = <8000>; /* 32 kB */
 			d-cache-size = <8000>; /* 32 kB */
 			dcr-controller;
 			dcr-controller;
@@ -135,11 +135,9 @@
 				#address-cells = <2>;
 				#address-cells = <2>;
 				#size-cells = <1>;
 				#size-cells = <1>;
 				clock-frequency = <0>; // Filled in by zImage
 				clock-frequency = <0>; // Filled in by zImage
-				ranges = <0 00000000 fff00000 100000
-					  1 00000000 48000000 100000
-					  2 00000000 ff800000 400000
-					  3 00000000 48200000 100000
-					  7 00000000 48300000 100000>;
+				// ranges property is supplied by zImage
+				// based on firmware's configuration of the
+				// EBC bridge
 				interrupts = <5 4>;
 				interrupts = <5 4>;
 				interrupt-parent = <&UIC1>;
 				interrupt-parent = <&UIC1>;
 
 

+ 27 - 25
arch/powerpc/boot/dts/holly.dts

@@ -46,7 +46,7 @@
 
 
   	tsi109@c0000000 {
   	tsi109@c0000000 {
 		device_type = "tsi-bridge";
 		device_type = "tsi-bridge";
-		compatible = "tsi-bridge";
+		compatible = "tsi109-bridge", "tsi108-bridge";
 		#address-cells = <1>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 		#size-cells = <1>;
 		ranges = <00000000 c0000000 00010000>;
 		ranges = <00000000 c0000000 00010000>;
@@ -54,52 +54,55 @@
 
 
 		i2c@7000 {
 		i2c@7000 {
 			device_type = "i2c";
 			device_type = "i2c";
-			compatible  = "tsi-i2c";
-			interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+			compatible  = "tsi109-i2c", "tsi108-i2c";
+			interrupt-parent = <&MPIC>;
 			interrupts = <e 2>;
 			interrupts = <e 2>;
 			reg = <7000 400>;
 			reg = <7000 400>;
 		};
 		};
 
 
-		mdio@6000 {
+		MDIO: mdio@6000 {
 			device_type = "mdio";
 			device_type = "mdio";
-			compatible = "tsi-ethernet";
+			compatible = "tsi109-mdio", "tsi108-mdio";
+			reg = <6000 50>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 
-			PHY1: ethernet-phy@6000 {
-				device_type = "ethernet-phy";
-				compatible = "bcm54xx";
-				reg = <6000 50>;
-				phy-id = <1>;
+			PHY1: ethernet-phy@1 {
+				compatible = "bcm5461a";
+				reg = <1>;
+				txc-rxc-delay-disable;
 			};
 			};
 
 
-			PHY2: ethernet-phy@6400 {
-				device_type = "ethernet-phy";
-				compatible = "bcm54xx";
-				reg = <6000 50>;
-				phy-id = <2>;
+			PHY2: ethernet-phy@2 {
+				compatible = "bcm5461a";
+				reg = <2>;
+				txc-rxc-delay-disable;
 			};
 			};
 		};
 		};
 
 
 		ethernet@6200 {
 		ethernet@6200 {
 			device_type = "network";
 			device_type = "network";
-			compatible = "tsi-ethernet";
+			compatible = "tsi109-ethernet", "tsi108-ethernet";
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			#size-cells = <0>;
 			reg = <6000 200>;
 			reg = <6000 200>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+			interrupt-parent = <&MPIC>;
 			interrupts = <10 2>;
 			interrupts = <10 2>;
+			mdio-handle = <&MDIO>;
 			phy-handle = <&PHY1>;
 			phy-handle = <&PHY1>;
 		};
 		};
 
 
 		ethernet@6600 {
 		ethernet@6600 {
 			device_type = "network";
 			device_type = "network";
-			compatible = "tsi-ethernet";
+			compatible = "tsi109-ethernet", "tsi108-ethernet";
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			#size-cells = <0>;
 			reg = <6400 200>;
 			reg = <6400 200>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+			interrupt-parent = <&MPIC>;
 			interrupts = <11 2>;
 			interrupts = <11 2>;
+			mdio-handle = <&MDIO>;
 			phy-handle = <&PHY2>;
 			phy-handle = <&PHY2>;
 		};
 		};
 
 
@@ -110,7 +113,7 @@
 			virtual-reg = <c0007808>;
 			virtual-reg = <c0007808>;
 			clock-frequency = <3F9C6000>;
 			clock-frequency = <3F9C6000>;
 			current-speed = <1c200>;
 			current-speed = <1c200>;
-			interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+			interrupt-parent = <&MPIC>;
 			interrupts = <c 2>;
 			interrupts = <c 2>;
 		};
 		};
 
 
@@ -121,7 +124,7 @@
 			virtual-reg = <c0007c08>;
 			virtual-reg = <c0007c08>;
 			clock-frequency = <3F9C6000>;
 			clock-frequency = <3F9C6000>;
 			current-speed = <1c200>;
 			current-speed = <1c200>;
-			interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+			interrupt-parent = <&MPIC>;
 			interrupts = <d 2>;
 			interrupts = <d 2>;
 		};
 		};
 
 
@@ -136,7 +139,7 @@
 
 
 		pci@1000 {
 		pci@1000 {
 			device_type = "pci";
 			device_type = "pci";
-			compatible = "tsi109";
+			compatible = "tsi109-pci", "tsi108-pci";
 			#interrupt-cells = <1>;
 			#interrupt-cells = <1>;
 			#size-cells = <2>;
 			#size-cells = <2>;
 			#address-cells = <3>;
 			#address-cells = <3>;
@@ -150,7 +153,7 @@
 			ranges = <02000000 0 40000000 40000000 0 10000000
 			ranges = <02000000 0 40000000 40000000 0 10000000
 				  01000000 0 00000000 7e000000 0 00010000>;
 				  01000000 0 00000000 7e000000 0 00010000>;
 			clock-frequency = <7f28154>;
 			clock-frequency = <7f28154>;
-			interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+			interrupt-parent = <&MPIC>;
 			interrupts = <17 2>;
 			interrupts = <17 2>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map-mask = <f800 0 0 7>;
 			/*----------------------------------------------------+
 			/*----------------------------------------------------+
@@ -186,13 +189,12 @@
  				#address-cells = <0>;
  				#address-cells = <0>;
  				#interrupt-cells = <2>;
  				#interrupt-cells = <2>;
  				interrupts = <17 2>;
  				interrupts = <17 2>;
-				interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+				interrupt-parent = <&MPIC>;
 			};
 			};
 		};
 		};
 	};
 	};
 
 
 	chosen {
 	chosen {
 		linux,stdout-path = "/tsi109@c0000000/serial@7808";
 		linux,stdout-path = "/tsi109@c0000000/serial@7808";
-		bootargs = "console=ttyS0,115200";
 	};
 	};
 };
 };

+ 16 - 17
arch/powerpc/boot/dts/mpc7448hpc2.dts

@@ -45,7 +45,7 @@
 		#address-cells = <1>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 		#size-cells = <1>;
 		#interrupt-cells = <2>;
 		#interrupt-cells = <2>;
-		device_type = "tsi-bridge";
+		device_type = "tsi108-bridge";
 		ranges = <00000000 c0000000 00010000>;
 		ranges = <00000000 c0000000 00010000>;
 		reg = <c0000000 00010000>;
 		reg = <c0000000 00010000>;
 		bus-frequency = <0>;
 		bus-frequency = <0>;
@@ -55,27 +55,26 @@
 			interrupts = <E 0>;
 			interrupts = <E 0>;
 			reg = <7000 400>;
 			reg = <7000 400>;
 			device_type = "i2c";
 			device_type = "i2c";
-			compatible  = "tsi-i2c";
+			compatible  = "tsi108-i2c";
 		};
 		};
 
 
-		mdio@6000 {
+		MDIO: mdio@6000 {
 			device_type = "mdio";
 			device_type = "mdio";
-			compatible = "tsi-ethernet";
+			compatible = "tsi108-mdio";
+			reg = <6000 50>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 
-			phy8: ethernet-phy@6000 {
+			phy8: ethernet-phy@8 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
 				interrupts = <2 1>;
 				interrupts = <2 1>;
-				reg = <6000 50>;
-				phy-id = <8>;
-				device_type = "ethernet-phy";
+				reg = <8>;
 			};
 			};
 
 
-			phy9: ethernet-phy@6400 {
+			phy9: ethernet-phy@9 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
 				interrupts = <2 1>;
 				interrupts = <2 1>;
-				reg = <6000 50>;
-				phy-id = <9>;
-				device_type = "ethernet-phy";
+				reg = <9>;
 			};
 			};
 
 
 		};
 		};
@@ -83,12 +82,12 @@
 		ethernet@6200 {
 		ethernet@6200 {
 			#size-cells = <0>;
 			#size-cells = <0>;
 			device_type = "network";
 			device_type = "network";
-			model = "TSI-ETH";
-			compatible = "tsi-ethernet";
+			compatible = "tsi108-ethernet";
 			reg = <6000 200>;
 			reg = <6000 200>;
 			address = [ 00 06 D2 00 00 01 ];
 			address = [ 00 06 D2 00 00 01 ];
 			interrupts = <10 2>;
 			interrupts = <10 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
+			mdio-handle = <&MDIO>;
 			phy-handle = <&phy8>;
 			phy-handle = <&phy8>;
 		};
 		};
 
 
@@ -96,12 +95,12 @@
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			#size-cells = <0>;
 			device_type = "network";
 			device_type = "network";
-			model = "TSI-ETH";
-			compatible = "tsi-ethernet";
+			compatible = "tsi108-ethernet";
 			reg = <6400 200>;
 			reg = <6400 200>;
 			address = [ 00 06 D2 00 00 02 ];
 			address = [ 00 06 D2 00 00 02 ];
 			interrupts = <11 2>;
 			interrupts = <11 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
+			mdio-handle = <&MDIO>;
 			phy-handle = <&phy9>;
 			phy-handle = <&phy9>;
 		};
 		};
 
 
@@ -135,7 +134,7 @@
                        	big-endian;
                        	big-endian;
 		};
 		};
 		pci@1000 {
 		pci@1000 {
-			compatible = "tsi10x";
+			compatible = "tsi108-pci";
 			device_type = "pci";
 			device_type = "pci";
 			#interrupt-cells = <1>;
 			#interrupt-cells = <1>;
 			#size-cells = <2>;
 			#size-cells = <2>;

+ 15 - 27
arch/powerpc/boot/dts/mpc8272ads.dts

@@ -14,12 +14,10 @@
        compatible = "MPC8260ADS";
        compatible = "MPC8260ADS";
        #address-cells = <1>;
        #address-cells = <1>;
        #size-cells = <1>;
        #size-cells = <1>;
-       linux,phandle = <100>;
 
 
        cpus {
        cpus {
                #address-cells = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
                #size-cells = <0>;
-               linux,phandle = <200>;
 
 
                PowerPC,8272@0 {
                PowerPC,8272@0 {
                        device_type = "cpu";
                        device_type = "cpu";
@@ -32,12 +30,10 @@
                        bus-frequency = <0>;
                        bus-frequency = <0>;
                        clock-frequency = <0>;
                        clock-frequency = <0>;
                        32-bit;
                        32-bit;
-                       linux,phandle = <201>;
                };
                };
        };
        };
 
 
-       interrupt-controller@f8200000 {
-               linux,phandle = <f8200000>;
+		pci_pic: interrupt-controller@f8200000 {
                #address-cells = <0>;
                #address-cells = <0>;
                #interrupt-cells = <2>;
                #interrupt-cells = <2>;
                interrupt-controller;
                interrupt-controller;
@@ -47,15 +43,13 @@
        };
        };
        memory {
        memory {
                device_type = "memory";
                device_type = "memory";
-               linux,phandle = <300>;
                reg = <00000000 4000000 f4500000 00000020>;
                reg = <00000000 4000000 f4500000 00000020>;
        };
        };
 
 
        chosen {
        chosen {
                name = "chosen";
                name = "chosen";
                linux,platform = <0>;
                linux,platform = <0>;
-               interrupt-controller = <10c00>;
-               linux,phandle = <400>;
+		interrupt-controller = <&Cpm_pic>;
        };
        };
 
 
        soc8272@f0000000 {
        soc8272@f0000000 {
@@ -70,20 +64,17 @@
                        device_type = "mdio";
                        device_type = "mdio";
                        compatible = "fs_enet";
                        compatible = "fs_enet";
                        reg = <0 0>;
                        reg = <0 0>;
-                       linux,phandle = <24520>;
                        #address-cells = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        #size-cells = <0>;
-                       ethernet-phy@0 {
-                               linux,phandle = <2452000>;
-                               interrupt-parent = <10c00>;
+			phy0:ethernet-phy@0 {
+				interrupt-parent = <&Cpm_pic>;
                                interrupts = <17 4>;
                                interrupts = <17 4>;
                                reg = <0>;
                                reg = <0>;
                                bitbang = [ 12 12 13 02 02 01 ];
                                bitbang = [ 12 12 13 02 02 01 ];
                                device_type = "ethernet-phy";
                                device_type = "ethernet-phy";
                        };
                        };
-                       ethernet-phy@1 {
-                               linux,phandle = <2452001>;
-                               interrupt-parent = <10c00>;
+			phy1:ethernet-phy@1 {
+				interrupt-parent = <&Cpm_pic>;
                                interrupts = <17 4>;
                                interrupts = <17 4>;
                                bitbang = [ 12 12 13 02 02 01 ];
                                bitbang = [ 12 12 13 02 02 01 ];
                                reg = <3>;
                                reg = <3>;
@@ -101,8 +92,8 @@
                        reg = <11300 20 8400 100 11380 30>;
                        reg = <11300 20 8400 100 11380 30>;
                        mac-address = [ 00 11 2F 99 43 54 ];
                        mac-address = [ 00 11 2F 99 43 54 ];
                        interrupts = <20 2>;
                        interrupts = <20 2>;
-                       interrupt-parent = <10c00>;
-                       phy-handle = <2452000>;
+			interrupt-parent = <&Cpm_pic>;
+			phy-handle = <&Phy0>;
                        rx-clock = <13>;
                        rx-clock = <13>;
                        tx-clock = <12>;
                        tx-clock = <12>;
                };
                };
@@ -115,14 +106,13 @@
                        reg = <11320 20 8500 100 113b0 30>;
                        reg = <11320 20 8500 100 113b0 30>;
                        mac-address = [ 00 11 2F 99 44 54 ];
                        mac-address = [ 00 11 2F 99 44 54 ];
                        interrupts = <21 2>;
                        interrupts = <21 2>;
-                       interrupt-parent = <10c00>;
-                       phy-handle = <2452001>;
+			interrupt-parent = <&Cpm_pic>;
+			phy-handle = <&Phy1>;
                        rx-clock = <17>;
                        rx-clock = <17>;
                        tx-clock = <18>;
                        tx-clock = <18>;
                };
                };
 
 
                cpm@f0000000 {
                cpm@f0000000 {
-                       linux,phandle = <f0000000>;
                        #address-cells = <1>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                        #size-cells = <1>;
                        #interrupt-cells = <2>;
                        #interrupt-cells = <2>;
@@ -142,7 +132,7 @@
                                reg = <11a00 20 8000 100>;
                                reg = <11a00 20 8000 100>;
                                current-speed = <1c200>;
                                current-speed = <1c200>;
                                interrupts = <28 2>;
                                interrupts = <28 2>;
-                               interrupt-parent = <10c00>;
+				interrupt-parent = <&Cpm_pic>;
                                clock-setup = <0 00ffffff>;
                                clock-setup = <0 00ffffff>;
                                rx-clock = <1>;
                                rx-clock = <1>;
                                tx-clock = <1>;
                                tx-clock = <1>;
@@ -156,15 +146,14 @@
                                reg = <11a60 20 8300 100>;
                                reg = <11a60 20 8300 100>;
                                current-speed = <1c200>;
                                current-speed = <1c200>;
                                interrupts = <2b 2>;
                                interrupts = <2b 2>;
-                               interrupt-parent = <10c00>;
+				interrupt-parent = <&Cpm_pic>;
                                clock-setup = <1b ffffff00>;
                                clock-setup = <1b ffffff00>;
                                rx-clock = <4>;
                                rx-clock = <4>;
                                tx-clock = <4>;
                                tx-clock = <4>;
                        };
                        };
 
 
                };
                };
-               interrupt-controller@10c00 {
-                       linux,phandle = <10c00>;
+			cpm_pic:interrupt-controller@10c00 {
                        #address-cells = <0>;
                        #address-cells = <0>;
                        #interrupt-cells = <2>;
                        #interrupt-cells = <2>;
                        interrupt-controller;
                        interrupt-controller;
@@ -174,7 +163,6 @@
 		       compatible = "CPM2";
 		       compatible = "CPM2";
                };
                };
                pci@0500 {
                pci@0500 {
-                       linux,phandle = <0500>;
                        #interrupt-cells = <1>;
                        #interrupt-cells = <1>;
                        #size-cells = <2>;
                        #size-cells = <2>;
                        #address-cells = <3>;
                        #address-cells = <3>;
@@ -202,7 +190,7 @@
                                         c000 0 0 2 f8200000 43 8
                                         c000 0 0 2 f8200000 43 8
                                         c000 0 0 3 f8200000 40 8
                                         c000 0 0 3 f8200000 40 8
                                         c000 0 0 4 f8200000 41 8>;
                                         c000 0 0 4 f8200000 41 8>;
-                       interrupt-parent = <10c00>;
+			interrupt-parent = <&Cpm_pic>;
                        interrupts = <14 8>;
                        interrupts = <14 8>;
                        bus-range = <0 0>;
                        bus-range = <0 0>;
                        ranges = <02000000 0 80000000 80000000 0 40000000
                        ranges = <02000000 0 80000000 80000000 0 40000000
@@ -216,7 +204,7 @@
                        compatible = "talitos";
                        compatible = "talitos";
                        reg = <30000 10000>;
                        reg = <30000 10000>;
                        interrupts = <b 2>;
                        interrupts = <b 2>;
-                       interrupt-parent = <10c00>;
+			interrupt-parent = <&Cpm_pic>;
                        num-channels = <4>;
                        num-channels = <4>;
                        channel-fifo-len = <18>;
                        channel-fifo-len = <18>;
                        exec-units-mask = <0000007e>;
                        exec-units-mask = <0000007e>;

+ 14 - 2
arch/powerpc/boot/dts/mpc832x_mds.dts

@@ -272,7 +272,13 @@
 			reg = <2200 200>;
 			reg = <2200 200>;
 			interrupts = <22>;
 			interrupts = <22>;
 			interrupt-parent = < &qeic >;
 			interrupt-parent = < &qeic >;
-			mac-address = [ 00 04 9f 00 23 23 ];
+			/*
+			 * 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>;
 			rx-clock = <19>;
 			tx-clock = <1a>;
 			tx-clock = <1a>;
 			phy-handle = < &phy3 >;
 			phy-handle = < &phy3 >;
@@ -287,7 +293,13 @@
 			reg = <3000 200>;
 			reg = <3000 200>;
 			interrupts = <23>;
 			interrupts = <23>;
 			interrupt-parent = < &qeic >;
 			interrupt-parent = < &qeic >;
-			mac-address = [ 00 11 22 33 44 55 ];
+			/*
+			 * 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>;
 			rx-clock = <17>;
 			tx-clock = <18>;
 			tx-clock = <18>;
 			phy-handle = < &phy4 >;
 			phy-handle = < &phy4 >;

+ 14 - 2
arch/powerpc/boot/dts/mpc832x_rdb.dts

@@ -231,7 +231,13 @@
 			reg = <3000 200>;
 			reg = <3000 200>;
 			interrupts = <21>;
 			interrupts = <21>;
 			interrupt-parent = <&qeic>;
 			interrupt-parent = <&qeic>;
-			mac-address = [ 00 04 9f ef 03 02 ];
+			/*
+			 * 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>;
 			rx-clock = <20>;
 			tx-clock = <13>;
 			tx-clock = <13>;
 			phy-handle = <&phy00>;
 			phy-handle = <&phy00>;
@@ -246,7 +252,13 @@
 			reg = <2200 200>;
 			reg = <2200 200>;
 			interrupts = <22>;
 			interrupts = <22>;
 			interrupt-parent = <&qeic>;
 			interrupt-parent = <&qeic>;
-			mac-address = [ 00 04 9f ef 03 01 ];
+			/*
+			 * 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>;
 			rx-clock = <19>;
 			tx-clock = <1a>;
 			tx-clock = <1a>;
 			phy-handle = <&phy04>;
 			phy-handle = <&phy04>;

+ 10 - 0
arch/powerpc/boot/dts/mpc8349emitx.dts

@@ -131,6 +131,11 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			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 ];
 			address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <20 8 21 8 22 8>;
 			interrupts = <20 8 21 8 22 8>;
@@ -145,6 +150,11 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			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 ];
 			address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <23 8 24 8 25 8>;
 			interrupts = <23 8 24 8 25 8>;

+ 10 - 0
arch/powerpc/boot/dts/mpc834x_mds.dts

@@ -136,6 +136,11 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			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 ];
 			address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <20 8 21 8 22 8>;
 			interrupts = <20 8 21 8 22 8>;
@@ -150,6 +155,11 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			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 ];
 			address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <23 8 24 8 25 8>;
 			interrupts = <23 8 24 8 25 8>;

+ 14 - 2
arch/powerpc/boot/dts/mpc836x_mds.dts

@@ -301,7 +301,13 @@
 			reg = <2000 200>;
 			reg = <2000 200>;
 			interrupts = <20>;
 			interrupts = <20>;
 			interrupt-parent = < &qeic >;
 			interrupt-parent = < &qeic >;
-			mac-address = [ 00 04 9f 00 23 23 ];
+			/*
+			 * 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>;
 			rx-clock = <0>;
 			tx-clock = <19>;
 			tx-clock = <19>;
 			phy-handle = < &phy0 >;
 			phy-handle = < &phy0 >;
@@ -317,7 +323,13 @@
 			reg = <3000 200>;
 			reg = <3000 200>;
 			interrupts = <21>;
 			interrupts = <21>;
 			interrupt-parent = < &qeic >;
 			interrupt-parent = < &qeic >;
-			mac-address = [ 00 11 22 33 44 55 ];
+			/*
+			 * 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>;
 			rx-clock = <0>;
 			tx-clock = <14>;
 			tx-clock = <14>;
 			phy-handle = < &phy1 >;
 			phy-handle = < &phy1 >;

+ 81 - 66
arch/powerpc/boot/dts/mpc8540ads.dts

@@ -52,7 +52,7 @@
 			compatible = "fsl,8540-memory-controller";
 			compatible = "fsl,8540-memory-controller";
 			reg = <2000 1000>;
 			reg = <2000 1000>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <2 2>;
+			interrupts = <12 2>;
 		};
 		};
 
 
 		l2-cache-controller@20000 {
 		l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
 			cache-line-size = <20>;	// 32 bytes
 			cache-line-size = <20>;	// 32 bytes
 			cache-size = <40000>;	// L2, 256K
 			cache-size = <40000>;	// L2, 256K
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <0 2>;
+			interrupts = <10 2>;
 		};
 		};
 
 
 		i2c@3000 {
 		i2c@3000 {
 			device_type = "i2c";
 			device_type = "i2c";
 			compatible = "fsl-i2c";
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			reg = <3000 100>;
-			interrupts = <1b 2>;
+			interrupts = <2b 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
 			dfsrr;
 		};
 		};
@@ -81,19 +81,19 @@
 			reg = <24520 20>;
 			reg = <24520 20>;
 			phy0: ethernet-phy@0 {
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 1>;
+				interrupts = <5 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy1: ethernet-phy@1 {
 			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 1>;
+				interrupts = <5 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy3: ethernet-phy@3 {
 			phy3: ethernet-phy@3 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <37 1>;
+				interrupts = <7 1>;
 				reg = <3>;
 				reg = <3>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -106,9 +106,14 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			reg = <24000 1000>;
-			address = [ 00 E0 0C 00 73 00 ];
-			local-mac-address = [ 00 E0 0C 00 73 00 ];
-			interrupts = <d 2 e 2 12 2>;
+			/*
+			 * 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>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			phy-handle = <&phy0>;
 		};
 		};
@@ -120,9 +125,14 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			reg = <25000 1000>;
-			address = [ 00 E0 0C 00 73 01 ];
-			local-mac-address = [ 00 E0 0C 00 73 01 ];
-			interrupts = <13 2 14 2 18 2>;
+			/*
+			 * 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>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-handle = <&phy1>;
 		};
 		};
@@ -134,9 +144,14 @@
 			model = "FEC";
 			model = "FEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <26000 1000>;
 			reg = <26000 1000>;
-			address = [ 00 E0 0C 00 73 02 ];
-			local-mac-address = [ 00 E0 0C 00 73 02 ];
-			interrupts = <19 2>;
+			/*
+			 * 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>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy3>;
 			phy-handle = <&phy3>;
 		};
 		};
@@ -146,7 +161,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4500 100>; 	// reg base, size
 			reg = <4500 100>; 	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			clock-frequency = <0>; 	// should we fill in in uboot?
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -155,7 +170,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4600 100>;	// reg base, size
 			reg = <4600 100>;	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			clock-frequency = <0>; 	// should we fill in in uboot?
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 		pci@8000 {
 		pci@8000 {
@@ -163,78 +178,78 @@
 			interrupt-map = <
 			interrupt-map = <
 
 
 				/* IDSEL 0x02 */
 				/* IDSEL 0x02 */
-				1000 0 0 1 &mpic 31 1
-				1000 0 0 2 &mpic 32 1
-				1000 0 0 3 &mpic 33 1
-				1000 0 0 4 &mpic 34 1
+				1000 0 0 1 &mpic 1 1
+				1000 0 0 2 &mpic 2 1
+				1000 0 0 3 &mpic 3 1
+				1000 0 0 4 &mpic 4 1
 
 
 				/* IDSEL 0x03 */
 				/* IDSEL 0x03 */
-				1800 0 0 1 &mpic 34 1
-				1800 0 0 2 &mpic 31 1
-				1800 0 0 3 &mpic 32 1
-				1800 0 0 4 &mpic 33 1
+				1800 0 0 1 &mpic 4 1
+				1800 0 0 2 &mpic 1 1
+				1800 0 0 3 &mpic 2 1
+				1800 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x04 */
 				/* IDSEL 0x04 */
-				2000 0 0 1 &mpic 33 1
-				2000 0 0 2 &mpic 34 1
-				2000 0 0 3 &mpic 31 1
-				2000 0 0 4 &mpic 32 1
+				2000 0 0 1 &mpic 3 1
+				2000 0 0 2 &mpic 4 1
+				2000 0 0 3 &mpic 1 1
+				2000 0 0 4 &mpic 2 1
 
 
 				/* IDSEL 0x05 */
 				/* IDSEL 0x05 */
-				2800 0 0 1 &mpic 32 1
-				2800 0 0 2 &mpic 33 1
-				2800 0 0 3 &mpic 34 1
-				2800 0 0 4 &mpic 31 1
+				2800 0 0 1 &mpic 2 1
+				2800 0 0 2 &mpic 3 1
+				2800 0 0 3 &mpic 4 1
+				2800 0 0 4 &mpic 1 1
 
 
 				/* IDSEL 0x0c */
 				/* IDSEL 0x0c */
-				6000 0 0 1 &mpic 31 1
-				6000 0 0 2 &mpic 32 1
-				6000 0 0 3 &mpic 33 1
-				6000 0 0 4 &mpic 34 1
+				6000 0 0 1 &mpic 1 1
+				6000 0 0 2 &mpic 2 1
+				6000 0 0 3 &mpic 3 1
+				6000 0 0 4 &mpic 4 1
 
 
 				/* IDSEL 0x0d */
 				/* IDSEL 0x0d */
-				6800 0 0 1 &mpic 34 1
-				6800 0 0 2 &mpic 31 1
-				6800 0 0 3 &mpic 32 1
-				6800 0 0 4 &mpic 33 1
+				6800 0 0 1 &mpic 4 1
+				6800 0 0 2 &mpic 1 1
+				6800 0 0 3 &mpic 2 1
+				6800 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x0e */
 				/* IDSEL 0x0e */
-				7000 0 0 1 &mpic 33 1
-				7000 0 0 2 &mpic 34 1
-				7000 0 0 3 &mpic 31 1
-				7000 0 0 4 &mpic 32 1
+				7000 0 0 1 &mpic 3 1
+				7000 0 0 2 &mpic 4 1
+				7000 0 0 3 &mpic 1 1
+				7000 0 0 4 &mpic 2 1
 
 
 				/* IDSEL 0x0f */
 				/* IDSEL 0x0f */
-				7800 0 0 1 &mpic 32 1
-				7800 0 0 2 &mpic 33 1
-				7800 0 0 3 &mpic 34 1
-				7800 0 0 4 &mpic 31 1
+				7800 0 0 1 &mpic 2 1
+				7800 0 0 2 &mpic 3 1
+				7800 0 0 3 &mpic 4 1
+				7800 0 0 4 &mpic 1 1
 
 
 				/* IDSEL 0x12 */
 				/* IDSEL 0x12 */
-				9000 0 0 1 &mpic 31 1
-				9000 0 0 2 &mpic 32 1
-				9000 0 0 3 &mpic 33 1
-				9000 0 0 4 &mpic 34 1
+				9000 0 0 1 &mpic 1 1
+				9000 0 0 2 &mpic 2 1
+				9000 0 0 3 &mpic 3 1
+				9000 0 0 4 &mpic 4 1
 
 
 				/* IDSEL 0x13 */
 				/* IDSEL 0x13 */
-				9800 0 0 1 &mpic 34 1
-				9800 0 0 2 &mpic 31 1
-				9800 0 0 3 &mpic 32 1
-				9800 0 0 4 &mpic 33 1
+				9800 0 0 1 &mpic 4 1
+				9800 0 0 2 &mpic 1 1
+				9800 0 0 3 &mpic 2 1
+				9800 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x14 */
 				/* IDSEL 0x14 */
-				a000 0 0 1 &mpic 33 1
-				a000 0 0 2 &mpic 34 1
-				a000 0 0 3 &mpic 31 1
-				a000 0 0 4 &mpic 32 1
+				a000 0 0 1 &mpic 3 1
+				a000 0 0 2 &mpic 4 1
+				a000 0 0 3 &mpic 1 1
+				a000 0 0 4 &mpic 2 1
 
 
 				/* IDSEL 0x15 */
 				/* IDSEL 0x15 */
-				a800 0 0 1 &mpic 32 1
-				a800 0 0 2 &mpic 33 1
-				a800 0 0 3 &mpic 34 1
-				a800 0 0 4 &mpic 31 1>;
+				a800 0 0 1 &mpic 2 1
+				a800 0 0 2 &mpic 3 1
+				a800 0 0 3 &mpic 4 1
+				a800 0 0 4 &mpic 1 1>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <08 2>;
+			interrupts = <18 2>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
 			ranges = <02000000 0 80000000 80000000 0 20000000
 				  01000000 0 00000000 e2000000 0 00100000>;
 				  01000000 0 00000000 e2000000 0 00100000>;

+ 45 - 45
arch/powerpc/boot/dts/mpc8541cds.dts

@@ -52,7 +52,7 @@
 			compatible = "fsl,8541-memory-controller";
 			compatible = "fsl,8541-memory-controller";
 			reg = <2000 1000>;
 			reg = <2000 1000>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <2 2>;
+			interrupts = <12 2>;
 		};
 		};
 
 
 		l2-cache-controller@20000 {
 		l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
 			cache-line-size = <20>;	// 32 bytes
 			cache-line-size = <20>;	// 32 bytes
 			cache-size = <40000>;	// L2, 256K
 			cache-size = <40000>;	// L2, 256K
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <0 2>;
+			interrupts = <10 2>;
 		};
 		};
 
 
 		i2c@3000 {
 		i2c@3000 {
 			device_type = "i2c";
 			device_type = "i2c";
 			compatible = "fsl-i2c";
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			reg = <3000 100>;
-			interrupts = <1b 2>;
+			interrupts = <2b 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
 			dfsrr;
 		};
 		};
@@ -81,13 +81,13 @@
 			reg = <24520 20>;
 			reg = <24520 20>;
 			phy0: ethernet-phy@0 {
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 0>;
+				interrupts = <5 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy1: ethernet-phy@1 {
 			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 0>;
+				interrupts = <5 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -100,8 +100,8 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			reg = <24000 1000>;
-			local-mac-address = [ 00 E0 0C 00 73 00 ];
-			interrupts = <d 2 e 2 12 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <1d 2 1e 2 22 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			phy-handle = <&phy0>;
 		};
 		};
@@ -113,8 +113,8 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			reg = <25000 1000>;
-			local-mac-address = [ 00 E0 0C 00 73 01 ];
-			interrupts = <13 2 14 2 18 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <23 2 24 2 28 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-handle = <&phy1>;
 		};
 		};
@@ -124,7 +124,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4500 100>; 	// reg base, size
 			reg = <4500 100>; 	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			clock-frequency = <0>; 	// should we fill in in uboot?
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -133,7 +133,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4600 100>;	// reg base, size
 			reg = <4600 100>;	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			clock-frequency = <0>; 	// should we fill in in uboot?
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -142,49 +142,49 @@
 			interrupt-map = <
 			interrupt-map = <
 
 
 				/* IDSEL 0x10 */
 				/* IDSEL 0x10 */
-				08000 0 0 1 &mpic 30 1
-				08000 0 0 2 &mpic 31 1
-				08000 0 0 3 &mpic 32 1
-				08000 0 0 4 &mpic 33 1
+				08000 0 0 1 &mpic 0 1
+				08000 0 0 2 &mpic 1 1
+				08000 0 0 3 &mpic 2 1
+				08000 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x11 */
 				/* IDSEL 0x11 */
-				08800 0 0 1 &mpic 30 1
-				08800 0 0 2 &mpic 31 1
-				08800 0 0 3 &mpic 32 1
-				08800 0 0 4 &mpic 33 1
+				08800 0 0 1 &mpic 0 1
+				08800 0 0 2 &mpic 1 1
+				08800 0 0 3 &mpic 2 1
+				08800 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x12 (Slot 1) */
 				/* IDSEL 0x12 (Slot 1) */
-				09000 0 0 1 &mpic 30 1
-				09000 0 0 2 &mpic 31 1
-				09000 0 0 3 &mpic 32 1
-				09000 0 0 4 &mpic 33 1
+				09000 0 0 1 &mpic 0 1
+				09000 0 0 2 &mpic 1 1
+				09000 0 0 3 &mpic 2 1
+				09000 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x13 (Slot 2) */
 				/* IDSEL 0x13 (Slot 2) */
-				09800 0 0 1 &mpic 31 1
-				09800 0 0 2 &mpic 32 1
-				09800 0 0 3 &mpic 33 1
-				09800 0 0 4 &mpic 30 1
+				09800 0 0 1 &mpic 1 1
+				09800 0 0 2 &mpic 2 1
+				09800 0 0 3 &mpic 3 1
+				09800 0 0 4 &mpic 0 1
 
 
 				/* IDSEL 0x14 (Slot 3) */
 				/* IDSEL 0x14 (Slot 3) */
-				0a000 0 0 1 &mpic 32 1
-				0a000 0 0 2 &mpic 33 1
-				0a000 0 0 3 &mpic 30 1
-				0a000 0 0 4 &mpic 31 1
+				0a000 0 0 1 &mpic 2 1
+				0a000 0 0 2 &mpic 3 1
+				0a000 0 0 3 &mpic 0 1
+				0a000 0 0 4 &mpic 1 1
 
 
 				/* IDSEL 0x15 (Slot 4) */
 				/* IDSEL 0x15 (Slot 4) */
-				0a800 0 0 1 &mpic 33 1
-				0a800 0 0 2 &mpic 30 1
-				0a800 0 0 3 &mpic 31 1
-				0a800 0 0 4 &mpic 32 1
+				0a800 0 0 1 &mpic 3 1
+				0a800 0 0 2 &mpic 0 1
+				0a800 0 0 3 &mpic 1 1
+				0a800 0 0 4 &mpic 2 1
 
 
 				/* Bus 1 (Tundra Bridge) */
 				/* Bus 1 (Tundra Bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
-				19000 0 0 1 &mpic 30 1
-				19000 0 0 2 &mpic 31 1
-				19000 0 0 3 &mpic 32 1
-				19000 0 0 4 &mpic 33 1>;
+				19000 0 0 1 &mpic 0 1
+				19000 0 0 2 &mpic 1 1
+				19000 0 0 3 &mpic 2 1
+				19000 0 0 4 &mpic 3 1>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <08 2>;
+			interrupts = <18 2>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
 			ranges = <02000000 0 80000000 80000000 0 20000000
 				  01000000 0 00000000 e2000000 0 00100000>;
 				  01000000 0 00000000 e2000000 0 00100000>;
@@ -216,12 +216,12 @@
 			interrupt-map = <
 			interrupt-map = <
 
 
 				/* IDSEL 0x15 */
 				/* IDSEL 0x15 */
-				a800 0 0 1 &mpic 3b 1
-				a800 0 0 2 &mpic 3b 1
-				a800 0 0 3 &mpic 3b 1
-				a800 0 0 4 &mpic 3b 1>;
+				a800 0 0 1 &mpic b 1
+				a800 0 0 2 &mpic b 1
+				a800 0 0 3 &mpic b 1
+				a800 0 0 4 &mpic b 1>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <09 2>;
+			interrupts = <19 2>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
 				  01000000 0 00000000 e3000000 0 00100000>;
 				  01000000 0 00000000 e3000000 0 00100000>;

+ 9 - 9
arch/powerpc/boot/dts/mpc8544ds.dts

@@ -52,7 +52,7 @@
 			compatible = "fsl,8544-memory-controller";
 			compatible = "fsl,8544-memory-controller";
 			reg = <2000 1000>;
 			reg = <2000 1000>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <2 2>;
+			interrupts = <12 2>;
 		};
 		};
 
 
 		l2-cache-controller@20000 {
 		l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
 			cache-line-size = <20>;	// 32 bytes
 			cache-line-size = <20>;	// 32 bytes
 			cache-size = <40000>;	// L2, 256K
 			cache-size = <40000>;	// L2, 256K
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <0 2>;
+			interrupts = <10 2>;
 		};
 		};
 
 
 		i2c@3000 {
 		i2c@3000 {
 			device_type = "i2c";
 			device_type = "i2c";
 			compatible = "fsl-i2c";
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			reg = <3000 100>;
-			interrupts = <1b 2>;
+			interrupts = <2b 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
 			dfsrr;
 		};
 		};
@@ -81,13 +81,13 @@
 			reg = <24520 20>;
 			reg = <24520 20>;
 			phy0: ethernet-phy@0 {
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <3a 1>;
+				interrupts = <a 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy1: ethernet-phy@1 {
 			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <3a 1>;
+				interrupts = <a 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -101,7 +101,7 @@
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			reg = <24000 1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <d 2 e 2 12 2>;
+			interrupts = <1d 2 1e 2 22 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			phy-handle = <&phy0>;
 		};
 		};
@@ -114,7 +114,7 @@
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <26000 1000>;
 			reg = <26000 1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <f 2 10 2 11 2>;
+			interrupts = <1f 2 20 2 21 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-handle = <&phy1>;
 		};
 		};
@@ -124,7 +124,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4500 100>;
 			reg = <4500 100>;
 			clock-frequency = <0>;
 			clock-frequency = <0>;
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -133,7 +133,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4600 100>;
 			reg = <4600 100>;
 			clock-frequency = <0>;
 			clock-frequency = <0>;
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 

+ 57 - 51
arch/powerpc/boot/dts/mpc8548cds.dts

@@ -52,7 +52,7 @@
 			compatible = "fsl,8548-memory-controller";
 			compatible = "fsl,8548-memory-controller";
 			reg = <2000 1000>;
 			reg = <2000 1000>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <2 2>;
+			interrupts = <12 2>;
 		};
 		};
 
 
 		l2-cache-controller@20000 {
 		l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
 			cache-line-size = <20>;	// 32 bytes
 			cache-line-size = <20>;	// 32 bytes
 			cache-size = <80000>;	// L2, 512K
 			cache-size = <80000>;	// L2, 512K
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <0 2>;
+			interrupts = <10 2>;
 		};
 		};
 
 
 		i2c@3000 {
 		i2c@3000 {
 			device_type = "i2c";
 			device_type = "i2c";
 			compatible = "fsl-i2c";
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			reg = <3000 100>;
-			interrupts = <1b 2>;
+			interrupts = <2b 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
 			dfsrr;
 		};
 		};
@@ -81,25 +81,25 @@
 			reg = <24520 20>;
 			reg = <24520 20>;
 			phy0: ethernet-phy@0 {
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 0>;
+				interrupts = <5 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy1: ethernet-phy@1 {
 			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 0>;
+				interrupts = <5 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy2: ethernet-phy@2 {
 			phy2: ethernet-phy@2 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 0>;
+				interrupts = <5 1>;
 				reg = <2>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy3: ethernet-phy@3 {
 			phy3: ethernet-phy@3 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 0>;
+				interrupts = <5 1>;
 				reg = <3>;
 				reg = <3>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -112,8 +112,8 @@
 			model = "eTSEC";
 			model = "eTSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			reg = <24000 1000>;
-			local-mac-address = [ 00 E0 0C 00 73 00 ];
-			interrupts = <d 2 e 2 12 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <1d 2 1e 2 22 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			phy-handle = <&phy0>;
 		};
 		};
@@ -125,8 +125,8 @@
 			model = "eTSEC";
 			model = "eTSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			reg = <25000 1000>;
-			local-mac-address = [ 00 E0 0C 00 73 01 ];
-			interrupts = <13 2 14 2 18 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <23 2 24 2 28 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-handle = <&phy1>;
 		};
 		};
@@ -139,8 +139,8 @@
 			model = "eTSEC";
 			model = "eTSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <26000 1000>;
 			reg = <26000 1000>;
-			local-mac-address = [ 00 E0 0C 00 73 02 ];
-			interrupts = <f 2 10 2 11 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <1f 2 20 2 21 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy2>;
 			phy-handle = <&phy2>;
 		};
 		};
@@ -152,8 +152,8 @@
 			model = "eTSEC";
 			model = "eTSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <27000 1000>;
 			reg = <27000 1000>;
-			local-mac-address = [ 00 E0 0C 00 73 03 ];
-			interrupts = <15 2 16 2 17 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <25 2 26 2 27 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy3>;
 			phy-handle = <&phy3>;
 		};
 		};
@@ -164,7 +164,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4500 100>; 	// reg base, size
 			reg = <4500 100>; 	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			clock-frequency = <0>; 	// should we fill in in uboot?
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -173,58 +173,64 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4600 100>;	// reg base, size
 			reg = <4600 100>;	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			clock-frequency = <0>; 	// should we fill in in uboot?
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
+		global-utilities@e0000 {	//global utilities reg
+			compatible = "fsl,mpc8548-guts";
+			reg = <e0000 1000>;
+			fsl,has-rstcr;
+		};
+
 		pci1: pci@8000 {
 		pci1: pci@8000 {
 			interrupt-map-mask = <1f800 0 0 7>;
 			interrupt-map-mask = <1f800 0 0 7>;
 			interrupt-map = <
 			interrupt-map = <
 
 
 				/* IDSEL 0x10 */
 				/* IDSEL 0x10 */
-				08000 0 0 1 &mpic 30 1
-				08000 0 0 2 &mpic 31 1
-				08000 0 0 3 &mpic 32 1
-				08000 0 0 4 &mpic 33 1
+				08000 0 0 1 &mpic 0 1
+				08000 0 0 2 &mpic 1 1
+				08000 0 0 3 &mpic 2 1
+				08000 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x11 */
 				/* IDSEL 0x11 */
-				08800 0 0 1 &mpic 30 1
-				08800 0 0 2 &mpic 31 1
-				08800 0 0 3 &mpic 32 1
-				08800 0 0 4 &mpic 33 1
+				08800 0 0 1 &mpic 0 1
+				08800 0 0 2 &mpic 1 1
+				08800 0 0 3 &mpic 2 1
+				08800 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x12 (Slot 1) */
 				/* IDSEL 0x12 (Slot 1) */
-				09000 0 0 1 &mpic 30 1
-				09000 0 0 2 &mpic 31 1
-				09000 0 0 3 &mpic 32 1
-				09000 0 0 4 &mpic 33 1
+				09000 0 0 1 &mpic 0 1
+				09000 0 0 2 &mpic 1 1
+				09000 0 0 3 &mpic 2 1
+				09000 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x13 (Slot 2) */
 				/* IDSEL 0x13 (Slot 2) */
-				09800 0 0 1 &mpic 31 1
-				09800 0 0 2 &mpic 32 1
-				09800 0 0 3 &mpic 33 1
-				09800 0 0 4 &mpic 30 1
+				09800 0 0 1 &mpic 1 1
+				09800 0 0 2 &mpic 2 1
+				09800 0 0 3 &mpic 3 1
+				09800 0 0 4 &mpic 0 1
 
 
 				/* IDSEL 0x14 (Slot 3) */
 				/* IDSEL 0x14 (Slot 3) */
-				0a000 0 0 1 &mpic 32 1
-				0a000 0 0 2 &mpic 33 1
-				0a000 0 0 3 &mpic 30 1
-				0a000 0 0 4 &mpic 31 1
+				0a000 0 0 1 &mpic 2 1
+				0a000 0 0 2 &mpic 3 1
+				0a000 0 0 3 &mpic 0 1
+				0a000 0 0 4 &mpic 1 1
 
 
 				/* IDSEL 0x15 (Slot 4) */
 				/* IDSEL 0x15 (Slot 4) */
-				0a800 0 0 1 &mpic 33 1
-				0a800 0 0 2 &mpic 30 1
-				0a800 0 0 3 &mpic 31 1
-				0a800 0 0 4 &mpic 32 1
+				0a800 0 0 1 &mpic 3 1
+				0a800 0 0 2 &mpic 0 1
+				0a800 0 0 3 &mpic 1 1
+				0a800 0 0 4 &mpic 2 1
 
 
 				/* Bus 1 (Tundra Bridge) */
 				/* Bus 1 (Tundra Bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
-				19000 0 0 1 &mpic 30 1
-				19000 0 0 2 &mpic 31 1
-				19000 0 0 3 &mpic 32 1
-				19000 0 0 4 &mpic 33 1>;
+				19000 0 0 1 &mpic 0 1
+				19000 0 0 2 &mpic 1 1
+				19000 0 0 3 &mpic 2 1
+				19000 0 0 4 &mpic 3 1>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <08 2>;
+			interrupts = <18 2>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
 			ranges = <02000000 0 80000000 80000000 0 20000000
 				  01000000 0 00000000 e2000000 0 00100000>;
 				  01000000 0 00000000 e2000000 0 00100000>;
@@ -256,12 +262,12 @@
 			interrupt-map = <
 			interrupt-map = <
 
 
 				/* IDSEL 0x15 */
 				/* IDSEL 0x15 */
-				a800 0 0 1 &mpic 3b 1
-				a800 0 0 2 &mpic 3b 1
-				a800 0 0 3 &mpic 3b 1
-				a800 0 0 4 &mpic 3b 1>;
+				a800 0 0 1 &mpic b 1
+				a800 0 0 2 &mpic b 1
+				a800 0 0 3 &mpic b 1
+				a800 0 0 4 &mpic b 1>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <09 2>;
+			interrupts = <19 2>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
 				  01000000 0 00000000 e3000000 0 00100000>;
 				  01000000 0 00000000 e3000000 0 00100000>;

+ 45 - 45
arch/powerpc/boot/dts/mpc8555cds.dts

@@ -52,7 +52,7 @@
 			compatible = "fsl,8555-memory-controller";
 			compatible = "fsl,8555-memory-controller";
 			reg = <2000 1000>;
 			reg = <2000 1000>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <2 2>;
+			interrupts = <12 2>;
 		};
 		};
 
 
 		l2-cache-controller@20000 {
 		l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
 			cache-line-size = <20>;	// 32 bytes
 			cache-line-size = <20>;	// 32 bytes
 			cache-size = <40000>;	// L2, 256K
 			cache-size = <40000>;	// L2, 256K
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <0 2>;
+			interrupts = <10 2>;
 		};
 		};
 
 
 		i2c@3000 {
 		i2c@3000 {
 			device_type = "i2c";
 			device_type = "i2c";
 			compatible = "fsl-i2c";
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			reg = <3000 100>;
-			interrupts = <1b 2>;
+			interrupts = <2b 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
 			dfsrr;
 		};
 		};
@@ -81,13 +81,13 @@
 			reg = <24520 20>;
 			reg = <24520 20>;
 			phy0: ethernet-phy@0 {
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 0>;
+				interrupts = <5 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy1: ethernet-phy@1 {
 			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 0>;
+				interrupts = <5 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -100,8 +100,8 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			reg = <24000 1000>;
-			local-mac-address = [ 00 E0 0C 00 73 00 ];
-			interrupts = <0d 2 0e 2 12 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <1d 2 1e 2 22 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			phy-handle = <&phy0>;
 		};
 		};
@@ -113,8 +113,8 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			reg = <25000 1000>;
-			local-mac-address = [ 00 E0 0C 00 73 01 ];
-			interrupts = <13 2 14 2 18 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <23 2 24 2 28 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-handle = <&phy1>;
 		};
 		};
@@ -124,7 +124,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4500 100>; 	// reg base, size
 			reg = <4500 100>; 	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			clock-frequency = <0>; 	// should we fill in in uboot?
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -133,7 +133,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4600 100>;	// reg base, size
 			reg = <4600 100>;	// reg base, size
 			clock-frequency = <0>; 	// should we fill in in uboot?
 			clock-frequency = <0>; 	// should we fill in in uboot?
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -142,49 +142,49 @@
 			interrupt-map = <
 			interrupt-map = <
 
 
 				/* IDSEL 0x10 */
 				/* IDSEL 0x10 */
-				08000 0 0 1 &mpic 30 1
-				08000 0 0 2 &mpic 31 1
-				08000 0 0 3 &mpic 32 1
-				08000 0 0 4 &mpic 33 1
+				08000 0 0 1 &mpic 0 1
+				08000 0 0 2 &mpic 1 1
+				08000 0 0 3 &mpic 2 1
+				08000 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x11 */
 				/* IDSEL 0x11 */
-				08800 0 0 1 &mpic 30 1
-				08800 0 0 2 &mpic 31 1
-				08800 0 0 3 &mpic 32 1
-				08800 0 0 4 &mpic 33 1
+				08800 0 0 1 &mpic 0 1
+				08800 0 0 2 &mpic 1 1
+				08800 0 0 3 &mpic 2 1
+				08800 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x12 (Slot 1) */
 				/* IDSEL 0x12 (Slot 1) */
-				09000 0 0 1 &mpic 30 1
-				09000 0 0 2 &mpic 31 1
-				09000 0 0 3 &mpic 32 1
-				09000 0 0 4 &mpic 33 1
+				09000 0 0 1 &mpic 0 1
+				09000 0 0 2 &mpic 1 1
+				09000 0 0 3 &mpic 2 1
+				09000 0 0 4 &mpic 3 1
 
 
 				/* IDSEL 0x13 (Slot 2) */
 				/* IDSEL 0x13 (Slot 2) */
-				09800 0 0 1 &mpic 31 1
-				09800 0 0 2 &mpic 32 1
-				09800 0 0 3 &mpic 33 1
-				09800 0 0 4 &mpic 30 1
+				09800 0 0 1 &mpic 1 1
+				09800 0 0 2 &mpic 2 1
+				09800 0 0 3 &mpic 3 1
+				09800 0 0 4 &mpic 0 1
 
 
 				/* IDSEL 0x14 (Slot 3) */
 				/* IDSEL 0x14 (Slot 3) */
-				0a000 0 0 1 &mpic 32 1
-				0a000 0 0 2 &mpic 33 1
-				0a000 0 0 3 &mpic 30 1
-				0a000 0 0 4 &mpic 31 1
+				0a000 0 0 1 &mpic 2 1
+				0a000 0 0 2 &mpic 3 1
+				0a000 0 0 3 &mpic 0 1
+				0a000 0 0 4 &mpic 1 1
 
 
 				/* IDSEL 0x15 (Slot 4) */
 				/* IDSEL 0x15 (Slot 4) */
-				0a800 0 0 1 &mpic 33 1
-				0a800 0 0 2 &mpic 30 1
-				0a800 0 0 3 &mpic 31 1
-				0a800 0 0 4 &mpic 32 1
+				0a800 0 0 1 &mpic 3 1
+				0a800 0 0 2 &mpic 0 1
+				0a800 0 0 3 &mpic 1 1
+				0a800 0 0 4 &mpic 2 1
 
 
 				/* Bus 1 (Tundra Bridge) */
 				/* Bus 1 (Tundra Bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
 				/* IDSEL 0x12 (ISA bridge) */
-				19000 0 0 1 &mpic 30 1
-				19000 0 0 2 &mpic 31 1
-				19000 0 0 3 &mpic 32 1
-				19000 0 0 4 &mpic 33 1>;
+				19000 0 0 1 &mpic 0 1
+				19000 0 0 2 &mpic 1 1
+				19000 0 0 3 &mpic 2 1
+				19000 0 0 4 &mpic 3 1>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <08 2>;
+			interrupts = <18 2>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
 			ranges = <02000000 0 80000000 80000000 0 20000000
 				  01000000 0 00000000 e2000000 0 00100000>;
 				  01000000 0 00000000 e2000000 0 00100000>;
@@ -216,12 +216,12 @@
 			interrupt-map = <
 			interrupt-map = <
 
 
 				/* IDSEL 0x15 */
 				/* IDSEL 0x15 */
-				a800 0 0 1 &mpic 3b 1
-				a800 0 0 2 &mpic 3b 1
-				a800 0 0 3 &mpic 3b 1
-				a800 0 0 4 &mpic 3b 1>;
+				a800 0 0 1 &mpic b 1
+				a800 0 0 2 &mpic b 1
+				a800 0 0 3 &mpic b 1
+				a800 0 0 4 &mpic b 1>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <09 2>;
+			interrupts = <19 2>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
 			ranges = <02000000 0 a0000000 a0000000 0 20000000
 				  01000000 0 00000000 e3000000 0 00100000>;
 				  01000000 0 00000000 e3000000 0 00100000>;

+ 86 - 62
arch/powerpc/boot/dts/mpc8560ads.dts

@@ -52,7 +52,7 @@
 			compatible = "fsl,8540-memory-controller";
 			compatible = "fsl,8540-memory-controller";
 			reg = <2000 1000>;
 			reg = <2000 1000>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <2 2>;
+			interrupts = <12 2>;
 		};
 		};
 
 
 		l2-cache-controller@20000 {
 		l2-cache-controller@20000 {
@@ -61,7 +61,7 @@
 			cache-line-size = <20>;	// 32 bytes
 			cache-line-size = <20>;	// 32 bytes
 			cache-size = <40000>;	// L2, 256K
 			cache-size = <40000>;	// L2, 256K
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <0 2>;
+			interrupts = <10 2>;
 		};
 		};
 
 
 		mdio@24520 {
 		mdio@24520 {
@@ -72,25 +72,25 @@
 			#size-cells = <0>;
 			#size-cells = <0>;
 			phy0: ethernet-phy@0 {
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 1>;
+				interrupts = <5 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy1: ethernet-phy@1 {
 			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <35 1>;
+				interrupts = <5 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy2: ethernet-phy@2 {
 			phy2: ethernet-phy@2 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <37 1>;
+				interrupts = <7 1>;
 				reg = <2>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy3: ethernet-phy@3 {
 			phy3: ethernet-phy@3 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <37 1>;
+				interrupts = <7 1>;
 				reg = <3>;
 				reg = <3>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -101,8 +101,14 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			reg = <24000 1000>;
-			address = [ 00 00 0C 00 00 FD ];
-			interrupts = <d 2 e 2 12 2>;
+			/*
+			 * 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>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			phy-handle = <&phy0>;
 		};
 		};
@@ -114,8 +120,14 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			reg = <25000 1000>;
-			address = [ 00 00 0C 00 01 FD ];
-			interrupts = <13 2 14 2 18 2>;
+			/*
+			 * 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>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-handle = <&phy1>;
 		};
 		};
@@ -132,79 +144,79 @@
 			interrupt-map = <
 			interrupt-map = <
 
 
 					/* IDSEL 0x2 */
 					/* IDSEL 0x2 */
-					 1000 0 0 1 &mpic 31 1
-					 1000 0 0 2 &mpic 32 1
-					 1000 0 0 3 &mpic 33 1
-					 1000 0 0 4 &mpic 34 1
+					 1000 0 0 1 &mpic 1 1
+					 1000 0 0 2 &mpic 2 1
+					 1000 0 0 3 &mpic 3 1
+					 1000 0 0 4 &mpic 4 1
 
 
 					/* IDSEL 0x3 */
 					/* IDSEL 0x3 */
-					 1800 0 0 1 &mpic 34 1
-					 1800 0 0 2 &mpic 31 1
-					 1800 0 0 3 &mpic 32 1
-					 1800 0 0 4 &mpic 33 1
+					 1800 0 0 1 &mpic 4 1
+					 1800 0 0 2 &mpic 1 1
+					 1800 0 0 3 &mpic 2 1
+					 1800 0 0 4 &mpic 3 1
 
 
 					/* IDSEL 0x4 */
 					/* IDSEL 0x4 */
-					 2000 0 0 1 &mpic 33 1
-					 2000 0 0 2 &mpic 34 1
-					 2000 0 0 3 &mpic 31 1
-					 2000 0 0 4 &mpic 32 1
+					 2000 0 0 1 &mpic 3 1
+					 2000 0 0 2 &mpic 4 1
+					 2000 0 0 3 &mpic 1 1
+					 2000 0 0 4 &mpic 2 1
 
 
 					/* IDSEL 0x5  */
 					/* IDSEL 0x5  */
-					 2800 0 0 1 &mpic 32 1
-					 2800 0 0 2 &mpic 33 1
-					 2800 0 0 3 &mpic 34 1
-					 2800 0 0 4 &mpic 31 1
+					 2800 0 0 1 &mpic 2 1
+					 2800 0 0 2 &mpic 3 1
+					 2800 0 0 3 &mpic 4 1
+					 2800 0 0 4 &mpic 1 1
 
 
 					/* IDSEL 12 */
 					/* IDSEL 12 */
-					 6000 0 0 1 &mpic 31 1
-					 6000 0 0 2 &mpic 32 1
-					 6000 0 0 3 &mpic 33 1
-					 6000 0 0 4 &mpic 34 1
+					 6000 0 0 1 &mpic 1 1
+					 6000 0 0 2 &mpic 2 1
+					 6000 0 0 3 &mpic 3 1
+					 6000 0 0 4 &mpic 4 1
 
 
 					/* IDSEL 13 */
 					/* IDSEL 13 */
-					 6800 0 0 1 &mpic 34 1
-					 6800 0 0 2 &mpic 31 1
-					 6800 0 0 3 &mpic 32 1
-					 6800 0 0 4 &mpic 33 1
+					 6800 0 0 1 &mpic 4 1
+					 6800 0 0 2 &mpic 1 1
+					 6800 0 0 3 &mpic 2 1
+					 6800 0 0 4 &mpic 3 1
 
 
 					/* IDSEL 14*/
 					/* IDSEL 14*/
-					 7000 0 0 1 &mpic 33 1
-					 7000 0 0 2 &mpic 34 1
-					 7000 0 0 3 &mpic 31 1
-					 7000 0 0 4 &mpic 32 1
+					 7000 0 0 1 &mpic 3 1
+					 7000 0 0 2 &mpic 4 1
+					 7000 0 0 3 &mpic 1 1
+					 7000 0 0 4 &mpic 2 1
 
 
 					/* IDSEL 15 */
 					/* IDSEL 15 */
-					 7800 0 0 1 &mpic 32 1
-					 7800 0 0 2 &mpic 33 1
-					 7800 0 0 3 &mpic 34 1
-					 7800 0 0 4 &mpic 31 1
+					 7800 0 0 1 &mpic 2 1
+					 7800 0 0 2 &mpic 3 1
+					 7800 0 0 3 &mpic 4 1
+					 7800 0 0 4 &mpic 1 1
 
 
 					/* IDSEL 18 */
 					/* IDSEL 18 */
-					 9000 0 0 1 &mpic 31 1
-					 9000 0 0 2 &mpic 32 1
-					 9000 0 0 3 &mpic 33 1
-					 9000 0 0 4 &mpic 34 1
+					 9000 0 0 1 &mpic 1 1
+					 9000 0 0 2 &mpic 2 1
+					 9000 0 0 3 &mpic 3 1
+					 9000 0 0 4 &mpic 4 1
 
 
 					/* IDSEL 19 */
 					/* IDSEL 19 */
-					 9800 0 0 1 &mpic 34 1
-					 9800 0 0 2 &mpic 31 1
-					 9800 0 0 3 &mpic 32 1
-					 9800 0 0 4 &mpic 33 1
+					 9800 0 0 1 &mpic 4 1
+					 9800 0 0 2 &mpic 1 1
+					 9800 0 0 3 &mpic 2 1
+					 9800 0 0 4 &mpic 3 1
 
 
 					/* IDSEL 20 */
 					/* IDSEL 20 */
-					 a000 0 0 1 &mpic 33 1
-					 a000 0 0 2 &mpic 34 1
-					 a000 0 0 3 &mpic 31 1
-					 a000 0 0 4 &mpic 32 1
+					 a000 0 0 1 &mpic 3 1
+					 a000 0 0 2 &mpic 4 1
+					 a000 0 0 3 &mpic 1 1
+					 a000 0 0 4 &mpic 2 1
 
 
 					/* IDSEL 21 */
 					/* IDSEL 21 */
-					 a800 0 0 1 &mpic 32 1
-					 a800 0 0 2 &mpic 33 1
-					 a800 0 0 3 &mpic 34 1
-					 a800 0 0 4 &mpic 31 1>;
+					 a800 0 0 1 &mpic 2 1
+					 a800 0 0 2 &mpic 3 1
+					 a800 0 0 3 &mpic 4 1
+					 a800 0 0 4 &mpic 1 1>;
 
 
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <8 0>;
+			interrupts = <18 2>;
 			bus-range = <0 0>;
 			bus-range = <0 0>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
 			ranges = <02000000 0 80000000 80000000 0 20000000
 				  01000000 0 00000000 e2000000 0 01000000>;
 				  01000000 0 00000000 e2000000 0 01000000>;
@@ -234,7 +246,7 @@
 				interrupt-controller;
 				interrupt-controller;
 				#address-cells = <0>;
 				#address-cells = <0>;
 				#interrupt-cells = <2>;
 				#interrupt-cells = <2>;
-				interrupts = <1e 0>;
+				interrupts = <2e 2>;
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
 				reg = <90c00 80>;
 				reg = <90c00 80>;
 				built-in;
 				built-in;
@@ -275,7 +287,13 @@
 				model = "FCC";
 				model = "FCC";
 				device-id = <2>;
 				device-id = <2>;
 				reg = <91320 20 88500 100 913a0 30>;
 				reg = <91320 20 88500 100 913a0 30>;
-				mac-address = [ 00 00 0C 00 02 FD ];
+				/*
+				 * 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 ];
 				clock-setup = <ff00ffff 250000>;
 				clock-setup = <ff00ffff 250000>;
 				rx-clock = <15>;
 				rx-clock = <15>;
 				tx-clock = <16>;
 				tx-clock = <16>;
@@ -290,7 +308,13 @@
 				model = "FCC";
 				model = "FCC";
 				device-id = <3>;
 				device-id = <3>;
 				reg = <91340 20 88600 100 913d0 30>;
 				reg = <91340 20 88600 100 913d0 30>;
-				mac-address = [ 00 00 0C 00 03 FD ];
+				/*
+				 * 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 ];
 				clock-setup = <ffff00ff 3700>;
 				clock-setup = <ffff00ff 3700>;
 				rx-clock = <17>;
 				rx-clock = <17>;
 				tx-clock = <18>;
 				tx-clock = <18>;

+ 45 - 21
arch/powerpc/boot/dts/mpc8568mds.dts

@@ -61,7 +61,7 @@
 			compatible = "fsl,8568-memory-controller";
 			compatible = "fsl,8568-memory-controller";
 			reg = <2000 1000>;
 			reg = <2000 1000>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <2 2>;
+			interrupts = <12 2>;
 		};
 		};
 
 
 		l2-cache-controller@20000 {
 		l2-cache-controller@20000 {
@@ -70,14 +70,14 @@
 			cache-line-size = <20>;	// 32 bytes
 			cache-line-size = <20>;	// 32 bytes
 			cache-size = <80000>;	// L2, 512K
 			cache-size = <80000>;	// L2, 512K
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
-			interrupts = <0 2>;
+			interrupts = <10 2>;
 		};
 		};
 
 
 		i2c@3000 {
 		i2c@3000 {
 			device_type = "i2c";
 			device_type = "i2c";
 			compatible = "fsl-i2c";
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			reg = <3000 100>;
-			interrupts = <1b 2>;
+			interrupts = <2b 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
 			dfsrr;
 		};
 		};
@@ -86,7 +86,7 @@
 			device_type = "i2c";
 			device_type = "i2c";
 			compatible = "fsl-i2c";
 			compatible = "fsl-i2c";
 			reg = <3100 100>;
 			reg = <3100 100>;
-			interrupts = <1b 2>;
+			interrupts = <2b 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
 			dfsrr;
 		};
 		};
@@ -99,25 +99,25 @@
 			reg = <24520 20>;
 			reg = <24520 20>;
 			phy0: ethernet-phy@0 {
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <31 1>;
+				interrupts = <1 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy1: ethernet-phy@1 {
 			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <32 1>;
+				interrupts = <2 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy2: ethernet-phy@2 {
 			phy2: ethernet-phy@2 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <31 1>;
+				interrupts = <1 1>;
 				reg = <2>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy3: ethernet-phy@3 {
 			phy3: ethernet-phy@3 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <32 1>;
+				interrupts = <2 1>;
 				reg = <3>;
 				reg = <3>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -130,8 +130,14 @@
 			model = "eTSEC";
 			model = "eTSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			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 ];
 			mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <d 2 e 2 12 2>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+ 			interrupts = <1d 2 1e 2 22 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy2>;
 			phy-handle = <&phy2>;
 		};
 		};
@@ -143,8 +149,14 @@
 			model = "eTSEC";
 			model = "eTSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			reg = <25000 1000>;
-			mac-address = [ 00 00 00 00 00 00];
-			interrupts = <13 2 14 2 18 2>;
+			/*
+			 * 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>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy3>;
 			phy-handle = <&phy3>;
 		};
 		};
@@ -154,7 +166,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4500 100>;
 			reg = <4500 100>;
 			clock-frequency = <0>;
 			clock-frequency = <0>;
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -163,7 +175,7 @@
 			compatible = "ns16550";
 			compatible = "ns16550";
 			reg = <4600 100>;
 			reg = <4600 100>;
 			clock-frequency = <0>;
 			clock-frequency = <0>;
-			interrupts = <1a 2>;
+			interrupts = <2a 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 
@@ -172,7 +184,7 @@
 			model = "SEC2";
 			model = "SEC2";
 			compatible = "talitos";
 			compatible = "talitos";
 			reg = <30000 f000>;
 			reg = <30000 f000>;
-			interrupts = <1d 2>;
+			interrupts = <2d 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			num-channels = <4>;
 			num-channels = <4>;
 			channel-fifo-len = <18>;
 			channel-fifo-len = <18>;
@@ -300,7 +312,13 @@
 			reg = <2000 200>;
 			reg = <2000 200>;
 			interrupts = <20>;
 			interrupts = <20>;
 			interrupt-parent = <&qeic>;
 			interrupt-parent = <&qeic>;
-			mac-address = [ 00 04 9f 00 23 23 ];
+			/*
+			 * 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>;
 			rx-clock = <0>;
 			tx-clock = <19>;
 			tx-clock = <19>;
 			phy-handle = <&qe_phy0>;
 			phy-handle = <&qe_phy0>;
@@ -316,7 +334,13 @@
 			reg = <3000 200>;
 			reg = <3000 200>;
 			interrupts = <21>;
 			interrupts = <21>;
 			interrupt-parent = <&qeic>;
 			interrupt-parent = <&qeic>;
-			mac-address = [ 00 11 22 33 44 55 ];
+			/*
+			 * 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>;
 			rx-clock = <0>;
 			tx-clock = <14>;
 			tx-clock = <14>;
 			phy-handle = <&qe_phy1>;
 			phy-handle = <&qe_phy1>;
@@ -335,25 +359,25 @@
 			 * gianfar's MDIO bus */
 			 * gianfar's MDIO bus */
 			qe_phy0: ethernet-phy@00 {
 			qe_phy0: ethernet-phy@00 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <31 1>;
+				interrupts = <1 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			qe_phy1: ethernet-phy@01 {
 			qe_phy1: ethernet-phy@01 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <32 1>;
+				interrupts = <2 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			qe_phy2: ethernet-phy@02 {
 			qe_phy2: ethernet-phy@02 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <31 1>;
+				interrupts = <1 1>;
 				reg = <2>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			qe_phy3: ethernet-phy@03 {
 			qe_phy3: ethernet-phy@03 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <32 1>;
+				interrupts = <2 1>;
 				reg = <3>;
 				reg = <3>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -367,7 +391,7 @@
 			reg = <80 80>;
 			reg = <80 80>;
 			built-in;
 			built-in;
 			big-endian;
 			big-endian;
-			interrupts = <1e 2 1e 2>; //high:30 low:30
+			interrupts = <2e 2 2e 2>; //high:30 low:30
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 		};
 		};
 
 

+ 121 - 26
arch/powerpc/boot/dts/mpc8641_hpcn.dts

@@ -56,8 +56,12 @@
 		#size-cells = <1>;
 		#size-cells = <1>;
 		#interrupt-cells = <2>;
 		#interrupt-cells = <2>;
 		device_type = "soc";
 		device_type = "soc";
-		ranges = <0 f8000000 00100000>;
-		reg = <f8000000 00100000>;	// CCSRBAR 1M
+		ranges = <00001000 f8001000 000ff000
+			  80000000 80000000 20000000
+			  e2000000 e2000000 00100000
+			  a0000000 a0000000 20000000
+			  e3000000 e3000000 00100000>;
+		reg = <f8000000 00001000>;	// CCSRBAR
 		bus-frequency = <0>;
 		bus-frequency = <0>;
 
 
 		i2c@3000 {
 		i2c@3000 {
@@ -86,25 +90,25 @@
 			reg = <24520 20>;
 			reg = <24520 20>;
 			phy0: ethernet-phy@0 {
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <4a 1>;
+				interrupts = <a 1>;
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy1: ethernet-phy@1 {
 			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <4a 1>;
+				interrupts = <a 1>;
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy2: ethernet-phy@2 {
 			phy2: ethernet-phy@2 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <4a 1>;
+				interrupts = <a 1>;
 				reg = <2>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
 			phy3: ethernet-phy@3 {
 			phy3: ethernet-phy@3 {
 				interrupt-parent = <&mpic>;
 				interrupt-parent = <&mpic>;
-				interrupts = <4a 1>;
+				interrupts = <a 1>;
 				reg = <3>;
 				reg = <3>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -117,7 +121,13 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <24000 1000>;
 			reg = <24000 1000>;
-			mac-address = [ 00 E0 0C 00 73 00 ];
+			/*
+			 * 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>;
 			interrupts = <1d 2 1e 2 22 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			phy-handle = <&phy0>;
@@ -130,7 +140,13 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <25000 1000>;
 			reg = <25000 1000>;
-			mac-address = [ 00 E0 0C 00 73 01 ];
+			/*
+			 * 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>;
 			interrupts = <23 2 24 2 28 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-handle = <&phy1>;
@@ -143,7 +159,13 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <26000 1000>;
 			reg = <26000 1000>;
-			mac-address = [ 00 E0 0C 00 02 FD ];
+			/*
+			 * 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>;
 			interrupts = <1F 2 20 2 21 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy2>;
 			phy-handle = <&phy2>;
@@ -156,7 +178,13 @@
 			model = "TSEC";
 			model = "TSEC";
 			compatible = "gianfar";
 			compatible = "gianfar";
 			reg = <27000 1000>;
 			reg = <27000 1000>;
-			mac-address = [ 00 E0 0C 00 03 FD ];
+			/*
+			 * 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>;
 			interrupts = <25 2 26 2 27 2>;
 			interrupt-parent = <&mpic>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy3>;
 			phy-handle = <&phy3>;
@@ -186,7 +214,7 @@
 			#size-cells = <2>;
 			#size-cells = <2>;
 			#address-cells = <3>;
 			#address-cells = <3>;
 			reg = <8000 1000>;
 			reg = <8000 1000>;
-			bus-range = <0 fe>;
+			bus-range = <0 ff>;
 			ranges = <02000000 0 80000000 80000000 0 20000000
 			ranges = <02000000 0 80000000 80000000 0 20000000
 				  01000000 0 00000000 e2000000 0 00100000>;
 				  01000000 0 00000000 e2000000 0 00100000>;
 			clock-frequency = <1fca055>;
 			clock-frequency = <1fca055>;
@@ -285,17 +313,84 @@
 				f800 0 0 3 &i8259 0 0
 				f800 0 0 3 &i8259 0 0
 				f800 0 0 4 &i8259 0 0
 				f800 0 0 4 &i8259 0 0
 				>;
 				>;
-			i8259: i8259@4d0 {
-				clock-frequency = <0>;
-				interrupt-controller;
-				device_type = "interrupt-controller";
-				#address-cells = <0>;
-				#interrupt-cells = <2>;
-				built-in;
-				compatible = "chrp,iic";
-                	        big-endian;
-				interrupts = <49 2>;
-				interrupt-parent = <&mpic>;
+			uli1575@0 {
+				reg = <0 0 0 0 0>;
+				#size-cells = <2>;
+				#address-cells = <3>;
+				ranges = <02000000 0 80000000
+					  02000000 0 80000000
+					  0 20000000
+					  01000000 0 00000000
+					  01000000 0 00000000
+					  0 00100000>;
+
+				pci_bridge@0 {
+					reg = <0 0 0 0 0>;
+					#size-cells = <2>;
+					#address-cells = <3>;
+					ranges = <02000000 0 80000000
+						  02000000 0 80000000
+						  0 20000000
+						  01000000 0 00000000
+						  01000000 0 00000000
+						  0 00100000>;
+
+					isa@1e {
+						device_type = "isa";
+						#interrupt-cells = <2>;
+						#size-cells = <1>;
+						#address-cells = <2>;
+						reg = <f000 0 0 0 0>;
+						ranges = <1 0 01000000 0 0
+							  00001000>;
+						interrupt-parent = <&i8259>;
+
+						i8259: interrupt-controller@20 {
+							reg = <1 20 2
+							       1 a0 2
+							       1 4d0 2>;
+							clock-frequency = <0>;
+							interrupt-controller;
+							device_type = "interrupt-controller";
+							#address-cells = <0>;
+							#interrupt-cells = <2>;
+							built-in;
+							compatible = "chrp,iic";
+							interrupts = <9 2>;
+							interrupt-parent =
+								<&mpic>;
+						};
+
+						i8042@60 {
+							#size-cells = <0>;
+							#address-cells = <1>;
+							reg = <1 60 1 1 64 1>;
+							interrupts = <1 3 c 3>;
+							interrupt-parent =
+								<&i8259>;
+
+							keyboard@0 {
+								reg = <0>;
+								compatible = "pnpPNP,303";
+							};
+
+							mouse@1 {
+								reg = <1>;
+								compatible = "pnpPNP,f03";
+							};
+						};
+
+						rtc@70 {
+							compatible =
+								"pnpPNP,b00";
+							reg = <1 70 2>;
+						};
+
+						gpio@400 {
+							reg = <1 400 80>;
+						};
+					};
+				};
 			};
 			};
 
 
 		};
 		};
@@ -316,10 +411,10 @@
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map-mask = <f800 0 0 7>;
 			interrupt-map = <
 			interrupt-map = <
 				/* IDSEL 0x0 */
 				/* IDSEL 0x0 */
-				0000 0 0 1 &mpic 44 1
-				0000 0 0 2 &mpic 45 1
-				0000 0 0 3 &mpic 46 1
-				0000 0 0 4 &mpic 47 1
+				0000 0 0 1 &mpic 4 1
+				0000 0 0 2 &mpic 5 1
+				0000 0 0 3 &mpic 6 1
+				0000 0 0 4 &mpic 7 1
 				>;
 				>;
 		};
 		};
 
 

+ 11 - 20
arch/powerpc/boot/dts/mpc866ads.dts

@@ -15,12 +15,10 @@
 	compatible = "mpc8xx";
 	compatible = "mpc8xx";
 	#address-cells = <1>;
 	#address-cells = <1>;
 	#size-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 
 	cpus {
 	cpus {
 		#address-cells = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 
 		PowerPC,866@0 {
 		PowerPC,866@0 {
 			device_type = "cpu";
 			device_type = "cpu";
@@ -34,14 +32,12 @@
 			clock-frequency = <0>;
 			clock-frequency = <0>;
 			32-bit;
 			32-bit;
 			interrupts = <f 2>;	// decrementer interrupt
 			interrupts = <f 2>;	// decrementer interrupt
-			interrupt-parent = <ff000000>;
-			linux,phandle = <201>;
+			interrupt-parent = <&Mpc8xx_pic>;
 		};
 		};
 	};
 	};
 
 
 	memory {
 	memory {
 		device_type = "memory";
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 800000>;
 		reg = <00000000 800000>;
 	};
 	};
 
 
@@ -57,11 +53,9 @@
 			device_type = "mdio";
 			device_type = "mdio";
 			compatible = "fs_enet";
 			compatible = "fs_enet";
 			reg = <e80 8>;
 			reg = <e80 8>;
-			linux,phandle = <e80>;
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			#size-cells = <0>;
-			ethernet-phy@f {
-				linux,phandle = <e800f>;
+			phy: ethernet-phy@f {
 				reg = <f>;
 				reg = <f>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -75,12 +69,11 @@
 			reg = <e00 188>;
 			reg = <e00 188>;
 			mac-address = [ 00 00 0C 00 01 FD ];
 			mac-address = [ 00 00 0C 00 01 FD ];
 			interrupts = <3 1>;
 			interrupts = <3 1>;
-			interrupt-parent = <ff000000>;
-			phy-handle = <e800f>;
+			interrupt-parent = <&Mpc8xx_pic>;
+			phy-handle = <&Phy>;
 		};
 		};
 
 
-		pic@ff000000 {
-			linux,phandle = <ff000000>;
+		mpc8xx_pic: pic@ff000000 {
 			interrupt-controller;
 			interrupt-controller;
 			#address-cells = <0>;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
 			#interrupt-cells = <2>;
@@ -91,7 +84,6 @@
 		};
 		};
 
 
 		cpm@ff000000 {
 		cpm@ff000000 {
-			linux,phandle = <ff000000>;
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			#size-cells = <1>;
 			#interrupt-cells = <2>;
 			#interrupt-cells = <2>;
@@ -102,15 +94,14 @@
 			command-proc = <9c0>;
 			command-proc = <9c0>;
 			brg-frequency = <0>;
 			brg-frequency = <0>;
 			interrupts = <0 2>;	// cpm error interrupt
 			interrupts = <0 2>;	// cpm error interrupt
-			interrupt-parent = <930>;
+			interrupt-parent = <&Cpm_pic>;
 
 
-			pic@930 {
-				linux,phandle = <930>;
+			cpm_pic: pic@930 {
 				interrupt-controller;
 				interrupt-controller;
 				#address-cells = <0>;
 				#address-cells = <0>;
 				#interrupt-cells = <2>;
 				#interrupt-cells = <2>;
 				interrupts = <5 2 0 2>;
 				interrupts = <5 2 0 2>;
-				interrupt-parent = <ff000000>;
+				interrupt-parent = <&Mpc8xx_pic>;
 				reg = <930 20>;
 				reg = <930 20>;
 				built-in;
 				built-in;
 				device_type = "cpm-pic";
 				device_type = "cpm-pic";
@@ -128,7 +119,7 @@
 				tx-clock = <1>;
 				tx-clock = <1>;
 				current-speed = <0>;
 				current-speed = <0>;
 				interrupts = <4 3>;
 				interrupts = <4 3>;
-				interrupt-parent = <930>;
+				interrupt-parent = <&Cpm_pic>;
 			};
 			};
 
 
 			smc@a90 {
 			smc@a90 {
@@ -142,7 +133,7 @@
 				tx-clock = <2>;
 				tx-clock = <2>;
 				current-speed = <0>;
 				current-speed = <0>;
 				interrupts = <3 3>;
 				interrupts = <3 3>;
-				interrupt-parent = <930>;
+				interrupt-parent = <&Cpm_pic>;
 			};
 			};
 
 
 			scc@a00 {
 			scc@a00 {
@@ -153,7 +144,7 @@
 				reg = <a00 18 3c00 80>;
 				reg = <a00 18 3c00 80>;
 				mac-address = [ 00 00 0C 00 03 FD ];
 				mac-address = [ 00 00 0C 00 03 FD ];
 				interrupts = <1e 3>;
 				interrupts = <1e 3>;
-				interrupt-parent = <930>;
+				interrupt-parent = <&Cpm_pic>;
 			};
 			};
 		};
 		};
 	};
 	};

+ 27 - 27
arch/powerpc/boot/dts/mpc885ads.dts

@@ -15,12 +15,10 @@
 	compatible = "mpc8xx";
 	compatible = "mpc8xx";
 	#address-cells = <1>;
 	#address-cells = <1>;
 	#size-cells = <1>;
 	#size-cells = <1>;
-	linux,phandle = <100>;
 
 
 	cpus {
 	cpus {
 		#address-cells = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#size-cells = <0>;
-		linux,phandle = <200>;
 
 
 		PowerPC,885@0 {
 		PowerPC,885@0 {
 			device_type = "cpu";
 			device_type = "cpu";
@@ -34,14 +32,12 @@
 			clock-frequency = <0>;
 			clock-frequency = <0>;
 			32-bit;
 			32-bit;
 			interrupts = <f 2>;	// decrementer interrupt
 			interrupts = <f 2>;	// decrementer interrupt
-			interrupt-parent = <ff000000>;
-			linux,phandle = <201>;
+			interrupt-parent = <&Mpc8xx_pic>;
 		};
 		};
 	};
 	};
 
 
 	memory {
 	memory {
 		device_type = "memory";
 		device_type = "memory";
-		linux,phandle = <300>;
 		reg = <00000000 800000>;
 		reg = <00000000 800000>;
 	};
 	};
 
 
@@ -57,21 +53,17 @@
 			device_type = "mdio";
 			device_type = "mdio";
 			compatible = "fs_enet";
 			compatible = "fs_enet";
 			reg = <e80 8>;
 			reg = <e80 8>;
-			linux,phandle = <e80>;
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			#size-cells = <0>;
-			ethernet-phy@0 {
-				linux,phandle = <e8000>;
+			Phy0: ethernet-phy@0 {
 				reg = <0>;
 				reg = <0>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
-			ethernet-phy@1 {
-				linux,phandle = <e8001>;
+			Phy1: ethernet-phy@1 {
 				reg = <1>;
 				reg = <1>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
-			ethernet-phy@2 {
-				linux,phandle = <e8002>;
+			Phy2: ethernet-phy@2 {
 				reg = <2>;
 				reg = <2>;
 				device_type = "ethernet-phy";
 				device_type = "ethernet-phy";
 			};
 			};
@@ -85,8 +77,8 @@
 			reg = <e00 188>;
 			reg = <e00 188>;
 			mac-address = [ 00 00 0C 00 01 FD ];
 			mac-address = [ 00 00 0C 00 01 FD ];
 			interrupts = <3 1>;
 			interrupts = <3 1>;
-			interrupt-parent = <ff000000>;
-			phy-handle = <e8000>;
+			interrupt-parent = <&Mpc8xx_pic>;
+			phy-handle = <&Phy1>;
 		};
 		};
 
 
 		fec@1e00 {
 		fec@1e00 {
@@ -97,12 +89,11 @@
 			reg = <1e00 188>;
 			reg = <1e00 188>;
 			mac-address = [ 00 00 0C 00 02 FD ];
 			mac-address = [ 00 00 0C 00 02 FD ];
 			interrupts = <7 1>;
 			interrupts = <7 1>;
-			interrupt-parent = <ff000000>;
-			phy-handle = <e8001>;
+			interrupt-parent = <&Mpc8xx_pic>;
+			phy-handle = <&Phy2>;
 		};
 		};
 
 
-		pic@ff000000 {
-			linux,phandle = <ff000000>;
+		Mpc8xx_pic: pic@ff000000 {
 			interrupt-controller;
 			interrupt-controller;
 			#address-cells = <0>;
 			#address-cells = <0>;
 			#interrupt-cells = <2>;
 			#interrupt-cells = <2>;
@@ -112,8 +103,18 @@
 			compatible = "CPM";
 			compatible = "CPM";
 		};
 		};
 
 
+		pcmcia@0080 {
+			#address-cells = <3>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			compatible = "fsl,pq-pcmcia";
+			device_type = "pcmcia";
+			reg = <80 80>;
+			interrupt-parent = <&Mpc8xx_pic>;
+			interrupts = <d 1>;
+		};
+
 		cpm@ff000000 {
 		cpm@ff000000 {
-			linux,phandle = <ff000000>;
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			#size-cells = <1>;
 			#interrupt-cells = <2>;
 			#interrupt-cells = <2>;
@@ -124,15 +125,14 @@
 			command-proc = <9c0>;
 			command-proc = <9c0>;
 			brg-frequency = <0>;
 			brg-frequency = <0>;
 			interrupts = <0 2>;	// cpm error interrupt
 			interrupts = <0 2>;	// cpm error interrupt
-			interrupt-parent = <930>;
+			interrupt-parent = <&Cpm_pic>;
 
 
-			pic@930 {
-				linux,phandle = <930>;
+			Cpm_pic: pic@930 {
 				interrupt-controller;
 				interrupt-controller;
 				#address-cells = <0>;
 				#address-cells = <0>;
 				#interrupt-cells = <2>;
 				#interrupt-cells = <2>;
 				interrupts = <5 2 0 2>;
 				interrupts = <5 2 0 2>;
-				interrupt-parent = <ff000000>;
+				interrupt-parent = <&Mpc8xx_pic>;
 				reg = <930 20>;
 				reg = <930 20>;
 				built-in;
 				built-in;
 				device_type = "cpm-pic";
 				device_type = "cpm-pic";
@@ -150,7 +150,7 @@
 				tx-clock = <1>;
 				tx-clock = <1>;
 				current-speed = <0>;
 				current-speed = <0>;
 				interrupts = <4 3>;
 				interrupts = <4 3>;
-				interrupt-parent = <930>;
+				interrupt-parent = <&Cpm_pic>;
 			};
 			};
 
 
 			smc@a90 {
 			smc@a90 {
@@ -164,7 +164,7 @@
 				tx-clock = <2>;
 				tx-clock = <2>;
 				current-speed = <0>;
 				current-speed = <0>;
 				interrupts = <3 3>;
 				interrupts = <3 3>;
-				interrupt-parent = <930>;
+				interrupt-parent = <&Cpm_pic>;
 			};
 			};
 
 
 			scc@a40 {
 			scc@a40 {
@@ -175,8 +175,8 @@
 				reg = <a40 18 3e00 80>;
 				reg = <a40 18 3e00 80>;
 				mac-address = [ 00 00 0C 00 03 FD ];
 				mac-address = [ 00 00 0C 00 03 FD ];
 				interrupts = <1c 3>;
 				interrupts = <1c 3>;
-				interrupt-parent = <930>;
-				phy-handle = <e8002>;
+				interrupt-parent = <&Cpm_pic>;
+				phy-handle = <&Phy2>;
 			};
 			};
 		};
 		};
 	};
 	};

+ 1 - 1
arch/powerpc/boot/dts/prpmc2800.dts

@@ -309,7 +309,7 @@
 	};
 	};
 
 
 	chosen {
 	chosen {
-		bootargs = "ip=on console=ttyMM0";
+		bootargs = "ip=on";
 		linux,stdout-path = "/mv64x60@f1000000/mpsc@8000";
 		linux,stdout-path = "/mv64x60@f1000000/mpsc@8000";
 	};
 	};
 };
 };

+ 68 - 0
arch/powerpc/boot/dts/ps3.dts

@@ -0,0 +1,68 @@
+/*
+ *  PS3 Game Console device tree.
+ *
+ *  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
+ */
+
+/ {
+	model = "SonyPS3";
+	compatible = "sony,ps3";
+	#size-cells = <2>;
+	#address-cells = <2>;
+
+	chosen {
+	};
+
+	/*
+	 * We'll get the size of the bootmem block from lv1 after startup,
+	 * so we'll put a null entry here.
+	 */
+
+	memory {
+		device_type = "memory";
+		reg = <0 0 0 0>;
+	};
+
+	/*
+	 * The boot cpu is always zero for PS3.
+	 *
+	 * dtc expects a clock-frequency and timebase-frequency entries, so
+	 * we'll put a null entries here.  These will be initialized after
+	 * startup with data from lv1.
+	 *
+	 * Seems the only way currently to indicate a processor has multiple
+	 * threads is with an ibm,ppc-interrupt-server#s entry.  We'll put one
+	 * here so we can bring up both of ours.  See smp_setup_cpu_maps().
+	 */
+
+	cpus {
+		#size-cells = <0>;
+		#address-cells = <1>;
+
+		cpu@0 {
+			device_type = "cpu";
+			reg = <0>;
+			ibm,ppc-interrupt-server#s = <0 1>;
+			clock-frequency = <0>;
+			timebase-frequency = <0>;
+			i-cache-size = <8000>;
+			d-cache-size = <8000>;
+			i-cache-line-size = <80>;
+			d-cache-line-size = <80>;
+		};
+	};
+};

+ 2 - 17
arch/powerpc/boot/ebony.c

@@ -100,28 +100,13 @@ static void ebony_fixups(void)
 	ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
 	ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
 	ibm44x_fixup_memsize();
 	ibm44x_fixup_memsize();
 	dt_fixup_mac_addresses(ebony_mac0, ebony_mac1);
 	dt_fixup_mac_addresses(ebony_mac0, ebony_mac1);
-}
-
-#define SPRN_DBCR0		0x134
-#define   DBCR0_RST_SYSTEM	0x30000000
-
-static void ebony_exit(void)
-{
-	unsigned long tmp;
-
-	asm volatile (
-		"mfspr	%0,%1\n"
-		"oris	%0,%0,%2@h\n"
-		"mtspr	%1,%0"
-		: "=&r"(tmp) : "i"(SPRN_DBCR0), "i"(DBCR0_RST_SYSTEM)
-		);
-
+	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
 }
 }
 
 
 void ebony_init(void *mac0, void *mac1)
 void ebony_init(void *mac0, void *mac1)
 {
 {
 	platform_ops.fixups = ebony_fixups;
 	platform_ops.fixups = ebony_fixups;
-	platform_ops.exit = ebony_exit;
+	platform_ops.exit = ibm44x_dbcr_reset;
 	ebony_mac0 = mac0;
 	ebony_mac0 = mac0;
 	ebony_mac1 = mac1;
 	ebony_mac1 = mac1;
 	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
 	ft_init(_dtb_start, _dtb_end - _dtb_start, 32);

+ 0 - 2
arch/powerpc/boot/main.c

@@ -36,8 +36,6 @@ struct addr_range {
 	unsigned long size;
 	unsigned long size;
 };
 };
 
 
-typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
-
 #undef DEBUG
 #undef DEBUG
 
 
 static struct addr_range prep_kernel(void)
 static struct addr_range prep_kernel(void)

+ 4 - 208
arch/powerpc/boot/of.c

@@ -15,8 +15,7 @@
 #include "page.h"
 #include "page.h"
 #include "ops.h"
 #include "ops.h"
 
 
-typedef void *ihandle;
-typedef void *phandle;
+#include "of.h"
 
 
 extern char _end[];
 extern char _end[];
 
 
@@ -25,154 +24,10 @@ extern char _end[];
 #define RAM_END		(512<<20)	/* Fixme: use OF */
 #define RAM_END		(512<<20)	/* Fixme: use OF */
 #define	ONE_MB		0x100000
 #define	ONE_MB		0x100000
 
 
-int (*prom) (void *);
 
 
 
 
 static unsigned long claim_base;
 static unsigned long claim_base;
 
 
-static int call_prom(const char *service, int nargs, int nret, ...)
-{
-	int i;
-	struct prom_args {
-		const char *service;
-		int nargs;
-		int nret;
-		unsigned int args[12];
-	} args;
-	va_list list;
-
-	args.service = service;
-	args.nargs = nargs;
-	args.nret = nret;
-
-	va_start(list, nret);
-	for (i = 0; i < nargs; i++)
-		args.args[i] = va_arg(list, unsigned int);
-	va_end(list);
-
-	for (i = 0; i < nret; i++)
-		args.args[nargs+i] = 0;
-
-	if (prom(&args) < 0)
-		return -1;
-
-	return (nret > 0)? args.args[nargs]: 0;
-}
-
-static int call_prom_ret(const char *service, int nargs, int nret,
-		  unsigned int *rets, ...)
-{
-	int i;
-	struct prom_args {
-		const char *service;
-		int nargs;
-		int nret;
-		unsigned int args[12];
-	} args;
-	va_list list;
-
-	args.service = service;
-	args.nargs = nargs;
-	args.nret = nret;
-
-	va_start(list, rets);
-	for (i = 0; i < nargs; i++)
-		args.args[i] = va_arg(list, unsigned int);
-	va_end(list);
-
-	for (i = 0; i < nret; i++)
-		args.args[nargs+i] = 0;
-
-	if (prom(&args) < 0)
-		return -1;
-
-	if (rets != (void *) 0)
-		for (i = 1; i < nret; ++i)
-			rets[i-1] = args.args[nargs+i];
-
-	return (nret > 0)? args.args[nargs]: 0;
-}
-
-/*
- * Older OF's require that when claiming a specific range of addresses,
- * we claim the physical space in the /memory node and the virtual
- * space in the chosen mmu node, and then do a map operation to
- * map virtual to physical.
- */
-static int need_map = -1;
-static ihandle chosen_mmu;
-static phandle memory;
-
-/* returns true if s2 is a prefix of s1 */
-static int string_match(const char *s1, const char *s2)
-{
-	for (; *s2; ++s2)
-		if (*s1++ != *s2)
-			return 0;
-	return 1;
-}
-
-static int check_of_version(void)
-{
-	phandle oprom, chosen;
-	char version[64];
-
-	oprom = finddevice("/openprom");
-	if (oprom == (phandle) -1)
-		return 0;
-	if (getprop(oprom, "model", version, sizeof(version)) <= 0)
-		return 0;
-	version[sizeof(version)-1] = 0;
-	printf("OF version = '%s'\r\n", version);
-	if (!string_match(version, "Open Firmware, 1.")
-	    && !string_match(version, "FirmWorks,3."))
-		return 0;
-	chosen = finddevice("/chosen");
-	if (chosen == (phandle) -1) {
-		chosen = finddevice("/chosen@0");
-		if (chosen == (phandle) -1) {
-			printf("no chosen\n");
-			return 0;
-		}
-	}
-	if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
-		printf("no mmu\n");
-		return 0;
-	}
-	memory = (ihandle) call_prom("open", 1, 1, "/memory");
-	if (memory == (ihandle) -1) {
-		memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
-		if (memory == (ihandle) -1) {
-			printf("no memory node\n");
-			return 0;
-		}
-	}
-	printf("old OF detected\r\n");
-	return 1;
-}
-
-static void *claim(unsigned long virt, unsigned long size, unsigned long align)
-{
-	int ret;
-	unsigned int result;
-
-	if (need_map < 0)
-		need_map = check_of_version();
-	if (align || !need_map)
-		return (void *) call_prom("claim", 3, 1, virt, size, align);
-
-	ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
-			    align, size, virt);
-	if (ret != 0 || result == -1)
-		return (void *) -1;
-	ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
-			    align, size, virt);
-	/* 0x12 == coherent + read/write */
-	ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
-			0x12, size, virt, virt);
-	return (void *) virt;
-}
-
 static void *of_try_claim(unsigned long size)
 static void *of_try_claim(unsigned long size)
 {
 {
 	unsigned long addr = 0;
 	unsigned long addr = 0;
@@ -184,7 +39,7 @@ static void *of_try_claim(unsigned long size)
 #ifdef DEBUG
 #ifdef DEBUG
 		printf("    trying: 0x%08lx\n\r", claim_base);
 		printf("    trying: 0x%08lx\n\r", claim_base);
 #endif
 #endif
-		addr = (unsigned long)claim(claim_base, size, 0);
+		addr = (unsigned long)of_claim(claim_base, size, 0);
 		if ((void *)addr != (void *)-1)
 		if ((void *)addr != (void *)-1)
 			break;
 			break;
 	}
 	}
@@ -208,64 +63,6 @@ static void of_image_hdr(const void *hdr)
 	}
 	}
 }
 }
 
 
-static void *of_vmlinux_alloc(unsigned long size)
-{
-	void *p = malloc(size);
-
-	if (!p)
-		fatal("Can't allocate memory for kernel image!\n\r");
-
-	return p;
-}
-
-static void of_exit(void)
-{
-	call_prom("exit", 0, 0);
-}
-
-/*
- * OF device tree routines
- */
-static void *of_finddevice(const char *name)
-{
-	return (phandle) call_prom("finddevice", 1, 1, name);
-}
-
-static int of_getprop(const void *phandle, const char *name, void *buf,
-		const int buflen)
-{
-	return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
-}
-
-static int of_setprop(const void *phandle, const char *name, const void *buf,
-		const int buflen)
-{
-	return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
-}
-
-/*
- * OF console routines
- */
-static void *of_stdout_handle;
-
-static int of_console_open(void)
-{
-	void *devp;
-
-	if (((devp = finddevice("/chosen")) != NULL)
-			&& (getprop(devp, "stdout", &of_stdout_handle,
-				sizeof(of_stdout_handle))
-				== sizeof(of_stdout_handle)))
-		return 0;
-
-	return -1;
-}
-
-static void of_console_write(char *buf, int len)
-{
-	call_prom("write", 3, 1, of_stdout_handle, buf, len);
-}
-
 void platform_init(unsigned long a1, unsigned long a2, void *promptr)
 void platform_init(unsigned long a1, unsigned long a2, void *promptr)
 {
 {
 	platform_ops.image_hdr = of_image_hdr;
 	platform_ops.image_hdr = of_image_hdr;
@@ -277,10 +74,9 @@ void platform_init(unsigned long a1, unsigned long a2, void *promptr)
 	dt_ops.getprop = of_getprop;
 	dt_ops.getprop = of_getprop;
 	dt_ops.setprop = of_setprop;
 	dt_ops.setprop = of_setprop;
 
 
-	console_ops.open = of_console_open;
-	console_ops.write = of_console_write;
+	of_console_init();
 
 
-	prom = (int (*)(void *))promptr;
+	of_init(promptr);
 	loader_info.promptr = promptr;
 	loader_info.promptr = promptr;
 	if (a1 && a2 && a2 != 0xdeadbeef) {
 	if (a1 && a2 && a2 != 0xdeadbeef) {
 		loader_info.initrd_addr = a1;
 		loader_info.initrd_addr = a1;

+ 21 - 0
arch/powerpc/boot/of.h

@@ -0,0 +1,21 @@
+#ifndef _PPC_BOOT_OF_H_
+#define _PPC_BOOT_OF_H_
+
+typedef void *phandle;
+typedef void *ihandle;
+
+void of_init(void *promptr);
+int of_call_prom(const char *service, int nargs, int nret, ...);
+void *of_claim(unsigned long virt, unsigned long size, unsigned long align);
+void *of_vmlinux_alloc(unsigned long size);
+void of_exit(void);
+void *of_finddevice(const char *name);
+int of_getprop(const void *phandle, const char *name, void *buf,
+	       const int buflen);
+int of_setprop(const void *phandle, const char *name, const void *buf,
+	       const int buflen);
+
+/* Console functions */
+void of_console_init(void);
+
+#endif /* _PPC_BOOT_OF_H_ */

+ 45 - 0
arch/powerpc/boot/ofconsole.c

@@ -0,0 +1,45 @@
+/*
+ * OF console routines
+ *
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+
+#include "of.h"
+
+static void *of_stdout_handle;
+
+static int of_console_open(void)
+{
+	void *devp;
+
+	if (((devp = of_finddevice("/chosen")) != NULL)
+	    && (of_getprop(devp, "stdout", &of_stdout_handle,
+			   sizeof(of_stdout_handle))
+		== sizeof(of_stdout_handle)))
+		return 0;
+
+	return -1;
+}
+
+static void of_console_write(const char *buf, int len)
+{
+	of_call_prom("write", 3, 1, of_stdout_handle, buf, len);
+}
+
+void of_console_init(void)
+{
+	console_ops.open = of_console_open;
+	console_ops.write = of_console_write;
+}

+ 202 - 0
arch/powerpc/boot/oflib.c

@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+
+#include "of.h"
+
+static int (*prom) (void *);
+
+void of_init(void *promptr)
+{
+	prom = (int (*)(void *))promptr;
+}
+
+int of_call_prom(const char *service, int nargs, int nret, ...)
+{
+	int i;
+	struct prom_args {
+		const char *service;
+		int nargs;
+		int nret;
+		unsigned int args[12];
+	} args;
+	va_list list;
+
+	args.service = service;
+	args.nargs = nargs;
+	args.nret = nret;
+
+	va_start(list, nret);
+	for (i = 0; i < nargs; i++)
+		args.args[i] = va_arg(list, unsigned int);
+	va_end(list);
+
+	for (i = 0; i < nret; i++)
+		args.args[nargs+i] = 0;
+
+	if (prom(&args) < 0)
+		return -1;
+
+	return (nret > 0)? args.args[nargs]: 0;
+}
+
+static int of_call_prom_ret(const char *service, int nargs, int nret,
+			    unsigned int *rets, ...)
+{
+	int i;
+	struct prom_args {
+		const char *service;
+		int nargs;
+		int nret;
+		unsigned int args[12];
+	} args;
+	va_list list;
+
+	args.service = service;
+	args.nargs = nargs;
+	args.nret = nret;
+
+	va_start(list, rets);
+	for (i = 0; i < nargs; i++)
+		args.args[i] = va_arg(list, unsigned int);
+	va_end(list);
+
+	for (i = 0; i < nret; i++)
+		args.args[nargs+i] = 0;
+
+	if (prom(&args) < 0)
+		return -1;
+
+	if (rets != (void *) 0)
+		for (i = 1; i < nret; ++i)
+			rets[i-1] = args.args[nargs+i];
+
+	return (nret > 0)? args.args[nargs]: 0;
+}
+
+/* returns true if s2 is a prefix of s1 */
+static int string_match(const char *s1, const char *s2)
+{
+	for (; *s2; ++s2)
+		if (*s1++ != *s2)
+			return 0;
+	return 1;
+}
+
+/*
+ * Older OF's require that when claiming a specific range of addresses,
+ * we claim the physical space in the /memory node and the virtual
+ * space in the chosen mmu node, and then do a map operation to
+ * map virtual to physical.
+ */
+static int need_map = -1;
+static ihandle chosen_mmu;
+static phandle memory;
+
+static int check_of_version(void)
+{
+	phandle oprom, chosen;
+	char version[64];
+
+	oprom = of_finddevice("/openprom");
+	if (oprom == (phandle) -1)
+		return 0;
+	if (of_getprop(oprom, "model", version, sizeof(version)) <= 0)
+		return 0;
+	version[sizeof(version)-1] = 0;
+	printf("OF version = '%s'\r\n", version);
+	if (!string_match(version, "Open Firmware, 1.")
+	    && !string_match(version, "FirmWorks,3."))
+		return 0;
+	chosen = of_finddevice("/chosen");
+	if (chosen == (phandle) -1) {
+		chosen = of_finddevice("/chosen@0");
+		if (chosen == (phandle) -1) {
+			printf("no chosen\n");
+			return 0;
+		}
+	}
+	if (of_getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
+		printf("no mmu\n");
+		return 0;
+	}
+	memory = (ihandle) of_call_prom("open", 1, 1, "/memory");
+	if (memory == (ihandle) -1) {
+		memory = (ihandle) of_call_prom("open", 1, 1, "/memory@0");
+		if (memory == (ihandle) -1) {
+			printf("no memory node\n");
+			return 0;
+		}
+	}
+	printf("old OF detected\r\n");
+	return 1;
+}
+
+void *of_claim(unsigned long virt, unsigned long size, unsigned long align)
+{
+	int ret;
+	unsigned int result;
+
+	if (need_map < 0)
+		need_map = check_of_version();
+	if (align || !need_map)
+		return (void *) of_call_prom("claim", 3, 1, virt, size, align);
+
+	ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", memory,
+			       align, size, virt);
+	if (ret != 0 || result == -1)
+		return (void *) -1;
+	ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
+			       align, size, virt);
+	/* 0x12 == coherent + read/write */
+	ret = of_call_prom("call-method", 6, 1, "map", chosen_mmu,
+			   0x12, size, virt, virt);
+	return (void *) virt;
+}
+
+void *of_vmlinux_alloc(unsigned long size)
+{
+	void *p = malloc(size);
+
+	if (!p)
+		fatal("Can't allocate memory for kernel image!\n\r");
+
+	return p;
+}
+
+void of_exit(void)
+{
+	of_call_prom("exit", 0, 0);
+}
+
+/*
+ * OF device tree routines
+ */
+void *of_finddevice(const char *name)
+{
+	return (phandle) of_call_prom("finddevice", 1, 1, name);
+}
+
+int of_getprop(const void *phandle, const char *name, void *buf,
+	       const int buflen)
+{
+	return of_call_prom("getprop", 4, 1, phandle, name, buf, buflen);
+}
+
+int of_setprop(const void *phandle, const char *name, const void *buf,
+	       const int buflen)
+{
+	return of_call_prom("setprop", 4, 1, phandle, name, buf, buflen);
+}

+ 3 - 1
arch/powerpc/boot/ops.h

@@ -19,6 +19,8 @@
 #define	MAX_PATH_LEN		256
 #define	MAX_PATH_LEN		256
 #define	MAX_PROP_LEN		256 /* What should this be? */
 #define	MAX_PROP_LEN		256 /* What should this be? */
 
 
+typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5);
+
 /* Platform specific operations */
 /* Platform specific operations */
 struct platform_ops {
 struct platform_ops {
 	void	(*fixups)(void);
 	void	(*fixups)(void);
@@ -51,7 +53,7 @@ extern struct dt_ops dt_ops;
 /* Console operations */
 /* Console operations */
 struct console_ops {
 struct console_ops {
 	int	(*open)(void);
 	int	(*open)(void);
-	void	(*write)(char *buf, int len);
+	void	(*write)(const char *buf, int len);
 	void	(*edit_cmdline)(char *buf, int len);
 	void	(*edit_cmdline)(char *buf, int len);
 	void	(*close)(void);
 	void	(*close)(void);
 	void	*data;
 	void	*data;

+ 80 - 0
arch/powerpc/boot/ps3-head.S

@@ -0,0 +1,80 @@
+/*
+ *  PS3 bootwrapper entry.
+ *
+ *  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 "ppc_asm.h"
+
+	.text
+
+/*
+ * __system_reset_overlay - The PS3 first stage entry.
+ *
+ * The bootwraper build script copies the 0x100 bytes at symbol
+ * __system_reset_overlay to offset 0x100 of the rom image.
+ *
+ * The PS3 has a single processor with two threads.
+ */
+
+	.globl __system_reset_overlay
+__system_reset_overlay:
+
+	/* Switch to 32-bit mode. */
+
+	mfmsr	r9
+	clrldi	r9,r9,1
+	mtmsrd	r9
+	nop
+
+	/* Get thread number in r3 and branch. */
+
+	mfspr	r3, 0x88
+	cntlzw.	r3, r3
+	li	r4, 0
+	li	r5, 0
+	beq	1f
+
+	/* Secondary goes to __secondary_hold in kernel. */
+
+	li	r4, 0x60
+	mtctr	r4
+	bctr
+
+	/* Primary delays then goes to _zimage_start in wrapper. */
+1:
+	or	31, 31, 31 /* db16cyc */
+	or	31, 31, 31 /* db16cyc */
+
+	lis	r4, _zimage_start@ha
+	addi	r4, r4, _zimage_start@l
+	mtctr	r4
+	bctr
+
+/*
+ * __system_reset_kernel - Place holder for the kernel reset vector.
+ *
+ * The bootwrapper build script copies 0x100 bytes from offset 0x100
+ * of the rom image to the symbol __system_reset_kernel.  At runtime
+ * the bootwrapper program copies the 0x100 bytes at __system_reset_kernel
+ * to ram address 0x100.  This symbol must occupy 0x100 bytes.
+ */
+
+	.globl __system_reset_kernel
+__system_reset_kernel:
+
+	. = __system_reset_kernel + 0x100

+ 184 - 0
arch/powerpc/boot/ps3-hvcall.S

@@ -0,0 +1,184 @@
+/*
+ *  PS3 bootwrapper hvcalls.
+ *
+ *  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 "ppc_asm.h"
+
+/*
+ * The PS3 hypervisor uses a 64 bit "C" language calling convention.
+ * The routines here marshal arguments between the 32 bit wrapper
+ * program and the 64 bit hvcalls.
+ *
+ *  wrapper           lv1
+ *  32-bit (h,l)      64-bit
+ *
+ *  1: r3,r4          <-> r3
+ *  2: r5,r6          <-> r4
+ *  3: r7,r8          <-> r5
+ *  4: r9,r10         <-> r6
+ *  5: 8(r1),12(r1)   <-> r7
+ *  6: 16(r1),20(r1)  <-> r8
+ *  7: 24(r1),28(r1)  <-> r9
+ *  8: 32(r1),36(r1)  <-> r10
+ *
+ */
+
+.macro GLOBAL name
+	.section ".text"
+	.balign 4
+	.globl \name
+\name:
+.endm
+
+.macro NO_SUPPORT name
+	GLOBAL \name
+	b ps3_no_support
+.endm
+
+.macro HVCALL num
+	li r11, \num
+	.long 0x44000022
+	extsw r3, r3
+.endm
+
+.macro SAVE_LR offset=4
+	mflr r0
+	stw r0, \offset(r1)
+.endm
+
+.macro LOAD_LR offset=4
+	lwz r0, \offset(r1)
+	mtlr r0
+.endm
+
+.macro LOAD_64_REG target,high,low
+	sldi r11, \high, 32
+	or \target, r11, \low
+.endm
+
+.macro LOAD_64_STACK target,offset
+	ld \target, \offset(r1)
+.endm
+
+.macro LOAD_R3
+	LOAD_64_REG r3,r3,r4
+.endm
+
+.macro LOAD_R4
+	LOAD_64_REG r4,r5,r6
+.endm
+
+.macro LOAD_R5
+	LOAD_64_REG r5,r7,r8
+.endm
+
+.macro LOAD_R6
+	LOAD_64_REG r6,r9,r10
+.endm
+
+.macro LOAD_R7
+	LOAD_64_STACK r7,8
+.endm
+
+.macro LOAD_R8
+	LOAD_64_STACK r8,16
+.endm
+
+.macro LOAD_R9
+	LOAD_64_STACK r9,24
+.endm
+
+.macro LOAD_R10
+	LOAD_64_STACK r10,32
+.endm
+
+.macro LOAD_REGS_0
+	stwu 1,-16(1)
+	stw 3, 8(1)
+.endm
+
+.macro LOAD_REGS_5
+	LOAD_R3
+	LOAD_R4
+	LOAD_R5
+	LOAD_R6
+	LOAD_R7
+.endm
+
+.macro LOAD_REGS_6
+	LOAD_REGS_5
+	LOAD_R8
+.endm
+
+.macro LOAD_REGS_8
+	LOAD_REGS_6
+	LOAD_R9
+	LOAD_R10
+.endm
+
+.macro STORE_REGS_0_1
+	lwz r11, 8(r1)
+	std r4, 0(r11)
+	mr r4, r3
+	li r3, 0
+	addi r1,r1,16
+.endm
+
+.macro STORE_REGS_5_2
+	lwz r11, 16(r1)
+	std r4, 0(r11)
+	lwz r11, 24(r1)
+	std r5, 0(r11)
+.endm
+
+.macro STORE_REGS_6_1
+	lwz r11, 24(r1)
+	std r4, 0(r11)
+.endm
+
+GLOBAL lv1_get_logical_ppe_id
+	SAVE_LR
+	LOAD_REGS_0
+	HVCALL 69
+	STORE_REGS_0_1
+	LOAD_LR
+	blr
+
+GLOBAL lv1_get_logical_partition_id
+	SAVE_LR
+	LOAD_REGS_0
+	HVCALL 74
+	STORE_REGS_0_1
+	LOAD_LR
+	blr
+
+GLOBAL lv1_get_repository_node_value
+	SAVE_LR
+	LOAD_REGS_5
+	HVCALL 91
+	STORE_REGS_5_2
+	LOAD_LR
+	blr
+
+GLOBAL lv1_panic
+	SAVE_LR
+	LOAD_REGS_8
+	HVCALL 255
+	LOAD_LR
+	blr

+ 161 - 0
arch/powerpc/boot/ps3.c

@@ -0,0 +1,161 @@
+/*
+ *  PS3 bootwrapper support.
+ *
+ *  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 <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+
+extern s64 lv1_panic(u64 in_1);
+extern s64 lv1_get_logical_partition_id(u64 *out_1);
+extern s64 lv1_get_logical_ppe_id(u64 *out_1);
+extern s64 lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3,
+	u64 in_4, u64 in_5, u64 *out_1, u64 *out_2);
+
+#ifdef DEBUG
+#define DBG(fmt...) printf(fmt)
+#else
+static inline int __attribute__ ((format (printf, 1, 2))) DBG(
+	const char *fmt, ...) {return 0;}
+#endif
+
+BSS_STACK(4096);
+
+/* A buffer that may be edited by tools operating on a zImage binary so as to
+ * edit the command line passed to vmlinux (by setting /chosen/bootargs).
+ * The buffer is put in it's own section so that tools may locate it easier.
+ */
+static char cmdline[COMMAND_LINE_SIZE]
+	__attribute__((__section__("__builtin_cmdline")));
+
+static void prep_cmdline(void *chosen)
+{
+	if (cmdline[0] == '\0')
+		getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1);
+	else
+		setprop_str(chosen, "bootargs", cmdline);
+
+	printf("cmdline: '%s'\n", cmdline);
+}
+
+static void ps3_console_write(const char *buf, int len)
+{
+}
+
+static void ps3_exit(void)
+{
+	printf("ps3_exit\n");
+
+	/* lv1_panic will shutdown the lpar. */
+
+	lv1_panic(0); /* zero = do not reboot */
+	while (1);
+}
+
+static int ps3_repository_read_rm_size(u64 *rm_size)
+{
+	s64 result;
+	u64 lpar_id;
+	u64 ppe_id;
+	u64 v2;
+
+	result = lv1_get_logical_partition_id(&lpar_id);
+
+	if (result)
+		return -1;
+
+	result = lv1_get_logical_ppe_id(&ppe_id);
+
+	if (result)
+		return -1;
+
+	/*
+	 * n1: 0000000062690000 : ....bi..
+	 * n2: 7075000000000000 : pu......
+	 * n3: 0000000000000001 : ........
+	 * n4: 726d5f73697a6500 : rm_size.
+	*/
+
+	result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL,
+		0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size,
+		&v2);
+
+	printf("%s:%d: ppe_id  %lu \n", __func__, __LINE__,
+		(unsigned long)ppe_id);
+	printf("%s:%d: lpar_id %lu \n", __func__, __LINE__,
+		(unsigned long)lpar_id);
+	printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size);
+
+	return result ? -1 : 0;
+}
+
+void ps3_copy_vectors(void)
+{
+	extern char __system_reset_kernel[];
+
+	memcpy((void *)0x100, __system_reset_kernel, 0x100);
+	flush_cache((void *)0x100, 0x100);
+}
+
+void platform_init(void)
+{
+	extern char _end[];
+	extern char _dtb_start[];
+	extern char _initrd_start[];
+	extern char _initrd_end[];
+	const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */
+	void *chosen;
+	unsigned long ft_addr;
+	u64 rm_size;
+
+	console_ops.write = ps3_console_write;
+	platform_ops.exit = ps3_exit;
+
+	printf("\n-- PS3 bootwrapper --\n");
+
+	simple_alloc_init(_end, heapsize, 32, 64);
+	ft_init(_dtb_start, 0, 4);
+
+	chosen = finddevice("/chosen");
+
+	ps3_repository_read_rm_size(&rm_size);
+	dt_fixup_memory(0, rm_size);
+
+	if (_initrd_end > _initrd_start) {
+		setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start));
+		setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end));
+	}
+
+	prep_cmdline(chosen);
+
+	ft_addr = dt_ops.finalize();
+
+	ps3_copy_vectors();
+
+	printf(" flat tree at 0x%lx\n\r", ft_addr);
+
+	((kernel_entry_t)0)(ft_addr, 0, NULL);
+
+	ps3_exit();
+}

+ 1 - 1
arch/powerpc/boot/serial.c

@@ -27,7 +27,7 @@ static int serial_open(void)
 	return scdp->open();
 	return scdp->open();
 }
 }
 
 
-static void serial_write(char *buf, int len)
+static void serial_write(const char *buf, int len)
 {
 {
 	struct serial_console_data *scdp = console_ops.data;
 	struct serial_console_data *scdp = console_ops.data;
 
 

+ 9 - 1
arch/powerpc/boot/stdio.c

@@ -190,7 +190,11 @@ int vsprintf(char *buf, const char *fmt, va_list args)
 
 
 		/* get the conversion qualifier */
 		/* get the conversion qualifier */
 		qualifier = -1;
 		qualifier = -1;
-		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+		if (*fmt == 'l' && *(fmt + 1) == 'l') {
+			qualifier = 'q';
+			fmt += 2;
+		} else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
+			|| *fmt == 'Z') {
 			qualifier = *fmt;
 			qualifier = *fmt;
 			++fmt;
 			++fmt;
 		}
 		}
@@ -281,6 +285,10 @@ int vsprintf(char *buf, const char *fmt, va_list args)
 			num = va_arg(args, unsigned long);
 			num = va_arg(args, unsigned long);
 			if (flags & SIGN)
 			if (flags & SIGN)
 				num = (signed long) num;
 				num = (signed long) num;
+		} else if (qualifier == 'q') {
+			num = va_arg(args, unsigned long long);
+			if (flags & SIGN)
+				num = (signed long long) num;
 		} else if (qualifier == 'Z') {
 		} else if (qualifier == 'Z') {
 			num = va_arg(args, size_t);
 			num = va_arg(args, size_t);
 		} else if (qualifier == 'h') {
 		} else if (qualifier == 'h') {

+ 4 - 0
arch/powerpc/boot/types.h

@@ -7,6 +7,10 @@ typedef unsigned char		u8;
 typedef unsigned short		u16;
 typedef unsigned short		u16;
 typedef unsigned int		u32;
 typedef unsigned int		u32;
 typedef unsigned long long	u64;
 typedef unsigned long long	u64;
+typedef signed char		s8;
+typedef short			s16;
+typedef int			s32;
+typedef long long		s64;
 
 
 #define min(x,y) ({ \
 #define min(x,y) ({ \
 	typeof(x) _x = (x);	\
 	typeof(x) _x = (x);	\

+ 55 - 0
arch/powerpc/boot/wrapper

@@ -144,6 +144,15 @@ miboot|uboot)
 cuboot*)
 cuboot*)
     gzip=
     gzip=
     ;;
     ;;
+ps3)
+    platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
+    lds=$object/zImage.ps3.lds
+    gzip=
+    ext=bin
+    objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
+    ksection=.kernel:vmlinux.bin
+    isection=.kernel:initrd
+    ;;
 esac
 esac
 
 
 vmz="$tmpdir/`basename \"$kernel\"`.$ext"
 vmz="$tmpdir/`basename \"$kernel\"`.$ext"
@@ -239,4 +248,50 @@ treeboot*)
     fi
     fi
     exit 0
     exit 0
     ;;
     ;;
+ps3)
+    # The ps3's loader supports loading gzipped binary images from flash
+    # rom to addr zero. The loader enters the image at addr 0x100.  A
+    # bootwrapper overlay is use to arrange for the kernel to be loaded
+    # to addr zero and to have a suitable bootwrapper entry at 0x100.
+    # To construct the rom image, 0x100 bytes from offset 0x100 in the
+    # kernel is copied to the bootwrapper symbol __system_reset_kernel.
+    # The 0x100 bytes at the bootwrapper symbol __system_reset_overlay is
+    # then copied to offset 0x100.  At runtime the bootwrapper program
+    # copies the 0x100 bytes at __system_reset_kernel to addr 0x100.
+
+    system_reset_overlay=0x`${CROSS}nm "$ofile" \
+        | grep ' __system_reset_overlay$'       \
+        | cut -d' ' -f1`
+    system_reset_overlay=`printf "%d" $system_reset_overlay`
+    system_reset_kernel=0x`${CROSS}nm "$ofile" \
+        | grep ' __system_reset_kernel$'       \
+        | cut -d' ' -f1`
+    system_reset_kernel=`printf "%d" $system_reset_kernel`
+    overlay_dest="256"
+    overlay_size="256"
+
+    rm -f "$object/otheros.bld"
+
+    ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
+
+    msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
+        skip=$overlay_dest seek=$system_reset_kernel      \
+        count=$overlay_size bs=1 2>&1)
+
+    if [ $? -ne "0" ]; then
+       echo $msg
+       exit 1
+    fi
+
+    msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
+        skip=$system_reset_overlay seek=$overlay_dest     \
+        count=$overlay_size bs=1 2>&1)
+
+    if [ $? -ne "0" ]; then
+       echo $msg
+       exit 2
+    fi
+
+    gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
+    ;;
 esac
 esac

+ 50 - 0
arch/powerpc/boot/zImage.ps3.lds.S

@@ -0,0 +1,50 @@
+OUTPUT_ARCH(powerpc:common)
+ENTRY(_zimage_start)
+EXTERN(_zimage_start)
+SECTIONS
+{
+  _vmlinux_start =  .;
+  .kernel:vmlinux.bin : { *(.kernel:vmlinux.bin) }
+  _vmlinux_end =  .;
+
+  . = ALIGN(4096);
+  _dtb_start = .;
+  .kernel:dtb : { *(.kernel:dtb) }
+  _dtb_end = .;
+
+  . = ALIGN(4096);
+  _initrd_start =  .;
+  .kernel:initrd : { *(.kernel:initrd) }
+  _initrd_end =  .;
+
+  _start = .;
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+  }
+  _etext = .;
+  . = ALIGN(4096);
+  .data    :
+  {
+    *(.rodata*)
+    *(.data*)
+    *(.sdata*)
+    __got2_start = .;
+    *(.got2)
+    __got2_end = .;
+  }
+
+  . = ALIGN(4096);
+  _edata  =  .;
+
+  . = ALIGN(4096);
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss)
+   *(.bss)
+  }
+  . = ALIGN(4096);
+  _end = . ;
+}

+ 4 - 2
arch/powerpc/configs/holly_defconfig

@@ -190,10 +190,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
 # CONFIG_RESOURCES_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_PROC_DEVICETREE=y
 CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200"
 # CONFIG_PM is not set
 # CONFIG_PM is not set
 # CONFIG_SECCOMP is not set
 # CONFIG_SECCOMP is not set
-# CONFIG_WANT_DEVICE_TREE is not set
+CONFIG_WANT_DEVICE_TREE=y
+CONFIG_DEVICE_TREE="holly.dts"
 CONFIG_ISA_DMA_API=y
 CONFIG_ISA_DMA_API=y
 
 
 #
 #

+ 35 - 17
arch/powerpc/configs/ps3_defconfig

@@ -156,7 +156,11 @@ CONFIG_PS3_HTAB_SIZE=20
 CONFIG_PS3_USE_LPAR_ADDR=y
 CONFIG_PS3_USE_LPAR_ADDR=y
 CONFIG_PS3_VUART=y
 CONFIG_PS3_VUART=y
 CONFIG_PS3_PS3AV=y
 CONFIG_PS3_PS3AV=y
-CONFIG_PS3_SYS_MANAGER=y
+CONFIG_PS3_SYS_MANAGER=m
+CONFIG_PS3_STORAGE=y
+CONFIG_PS3_DISK=y
+CONFIG_PS3_ROM=y
+CONFIG_PS3_FLASH=y
 CONFIG_PPC_CELL=y
 CONFIG_PPC_CELL=y
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_IBM_CELL_BLADE is not set
 # CONFIG_PPC_IBM_CELL_BLADE is not set
@@ -335,7 +339,7 @@ CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 CONFIG_BT_L2CAP=m
 CONFIG_BT_SCO=m
 CONFIG_BT_SCO=m
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM=m
-# CONFIG_BT_RFCOMM_TTY is not set
+CONFIG_BT_RFCOMM_TTY=y
 # CONFIG_BT_BNEP is not set
 # CONFIG_BT_BNEP is not set
 CONFIG_BT_HIDP=m
 CONFIG_BT_HIDP=m
 
 
@@ -344,7 +348,9 @@ CONFIG_BT_HIDP=m
 #
 #
 CONFIG_BT_HCIUSB=m
 CONFIG_BT_HCIUSB=m
 CONFIG_BT_HCIUSB_SCO=y
 CONFIG_BT_HCIUSB_SCO=y
-# CONFIG_BT_HCIUART is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
 # CONFIG_BT_HCIBCM203X is not set
 # CONFIG_BT_HCIBCM203X is not set
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIBFUSB is not set
@@ -435,7 +441,7 @@ CONFIG_CHR_DEV_SG=m
 #
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 #
-# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 # CONFIG_SCSI_LOGGING is not set
 # CONFIG_SCSI_SCAN_ASYNC is not set
 # CONFIG_SCSI_SCAN_ASYNC is not set
@@ -479,6 +485,7 @@ CONFIG_NETDEVICES=y
 CONFIG_MII=m
 CONFIG_MII=m
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_NETDEV_10000=y
+CONFIG_GELIC_NET=y
 
 
 #
 #
 # Wireless LAN
 # Wireless LAN
@@ -546,7 +553,27 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 #
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_TWIDJOY is not set
+# CONFIG_JOYSTICK_JOYDUMP is not set
+# CONFIG_JOYSTICK_XPAD is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 # CONFIG_INPUT_MISC is not set
@@ -563,7 +590,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_VT=y
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 
 #
 #
@@ -1086,7 +1113,7 @@ CONFIG_HAS_DMA=y
 #
 #
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1116,16 +1143,7 @@ CONFIG_DEBUG_STACKOVERFLOW=y
 # CONFIG_DEBUGGER is not set
 # CONFIG_DEBUGGER is not set
 CONFIG_IRQSTACKS=y
 CONFIG_IRQSTACKS=y
 # CONFIG_BOOTX_TEXT 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 is not set
-# CONFIG_PPC_EARLY_DEBUG_44x is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
 
 
 #
 #
 # Security options
 # Security options

+ 4 - 3
arch/powerpc/kernel/Makefile

@@ -12,7 +12,8 @@ endif
 
 
 obj-y				:= semaphore.o cputable.o ptrace.o syscalls.o \
 obj-y				:= semaphore.o cputable.o ptrace.o syscalls.o \
 				   irq.o align.o signal_32.o pmc.o vdso.o \
 				   irq.o align.o signal_32.o pmc.o vdso.o \
-				   init_task.o process.o systbl.o idle.o
+				   init_task.o process.o systbl.o idle.o \
+				   signal.o
 obj-y				+= vdso32/
 obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 				   signal_64.o ptrace32.o \
 				   signal_64.o ptrace32.o \
@@ -65,9 +66,9 @@ obj-$(CONFIG_PPC_UDBG_16550)	+= legacy_serial.o udbg_16550.o
 module-$(CONFIG_PPC64)		+= module_64.o
 module-$(CONFIG_PPC64)		+= module_64.o
 obj-$(CONFIG_MODULES)		+= $(module-y)
 obj-$(CONFIG_MODULES)		+= $(module-y)
 
 
-pci64-$(CONFIG_PPC64)		+= pci_64.o pci_dn.o
+pci64-$(CONFIG_PPC64)		+= pci_64.o pci_dn.o isa-bridge.o
 pci32-$(CONFIG_PPC32)		:= pci_32.o
 pci32-$(CONFIG_PPC32)		:= pci_32.o
-obj-$(CONFIG_PCI)		+= $(pci64-y) $(pci32-y)
+obj-$(CONFIG_PCI)		+= $(pci64-y) $(pci32-y) pci-common.o
 obj-$(CONFIG_PCI_MSI)		+= msi.o
 obj-$(CONFIG_PCI_MSI)		+= msi.o
 kexec-$(CONFIG_PPC64)		:= machine_kexec_64.o
 kexec-$(CONFIG_PPC64)		:= machine_kexec_64.o
 kexec-$(CONFIG_PPC32)		:= machine_kexec_32.o
 kexec-$(CONFIG_PPC32)		:= machine_kexec_32.o

+ 30 - 5
arch/powerpc/kernel/cputable.c

@@ -294,6 +294,21 @@ static struct cpu_spec cpu_specs[] = {
 		.oprofile_mmcra_sipr	= MMCRA_SIPR,
 		.oprofile_mmcra_sipr	= MMCRA_SIPR,
 		.platform		= "power5",
 		.platform		= "power5",
 	},
 	},
+	{	/* Power5++ */
+		.pvr_mask		= 0xffffff00,
+		.pvr_value		= 0x003b0300,
+		.cpu_name		= "POWER5+ (gs)",
+		.cpu_features		= CPU_FTRS_POWER5,
+		.cpu_user_features	= COMMON_USER_POWER5_PLUS,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.num_pmcs		= 6,
+		.oprofile_cpu_type	= "ppc64/power5++",
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.oprofile_mmcra_sihv	= MMCRA_SIHV,
+		.oprofile_mmcra_sipr	= MMCRA_SIPR,
+		.platform		= "power5+",
+	},
 	{	/* Power5 GS */
 	{	/* Power5 GS */
 		.pvr_mask		= 0xffff0000,
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x003b0000,
 		.pvr_value		= 0x003b0000,
@@ -1178,8 +1193,8 @@ static struct cpu_spec cpu_specs[] = {
 		.platform		= "ppc440",
 		.platform		= "ppc440",
 	},
 	},
 	{ /* 440SP Rev. A */
 	{ /* 440SP Rev. A */
-		.pvr_mask		= 0xff000fff,
-		.pvr_value		= 0x53000891,
+		.pvr_mask		= 0xfff00fff,
+		.pvr_value		= 0x53200891,
 		.cpu_name		= "440SP Rev. A",
 		.cpu_name		= "440SP Rev. A",
 		.cpu_features		= CPU_FTRS_44X,
 		.cpu_features		= CPU_FTRS_44X,
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.cpu_user_features	= COMMON_USER_BOOKE,
@@ -1188,9 +1203,19 @@ static struct cpu_spec cpu_specs[] = {
 		.platform		= "ppc440",
 		.platform		= "ppc440",
 	},
 	},
 	{ /* 440SPe Rev. A */
 	{ /* 440SPe Rev. A */
-		.pvr_mask		= 0xff000fff,
-		.pvr_value		= 0x53000890,
-		.cpu_name		= "440SPe Rev. A",
+		.pvr_mask               = 0xfff00fff,
+		.pvr_value              = 0x53400890,
+		.cpu_name               = "440SPe Rev. A",
+		.cpu_features		= CPU_FTRS_44X,
+		.cpu_user_features      = COMMON_USER_BOOKE,
+		.icache_bsize           = 32,
+		.dcache_bsize           = 32,
+		.platform               = "ppc440",
+	},
+	{ /* 440SPe Rev. B */
+		.pvr_mask		= 0xfff00fff,
+		.pvr_value		= 0x53400891,
+		.cpu_name		= "440SPe Rev. B",
 		.cpu_features		= CPU_FTRS_44X,
 		.cpu_features		= CPU_FTRS_44X,
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.icache_bsize		= 32,

+ 3 - 119
arch/powerpc/kernel/head_32.S

@@ -9,7 +9,6 @@
  *  rewritten by Paul Mackerras.
  *  rewritten by Paul Mackerras.
  *    Copyright (C) 1996 Paul Mackerras.
  *    Copyright (C) 1996 Paul Mackerras.
  *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
  *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  This file contains the low-level support and setup for the
  *  This file contains the low-level support and setup for the
  *  PowerPC platform, including trap and interrupt dispatch.
  *  PowerPC platform, including trap and interrupt dispatch.
@@ -32,10 +31,6 @@
 #include <asm/ppc_asm.h>
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/asm-offsets.h>
 
 
-#ifdef CONFIG_APUS
-#include <asm/amigappc.h>
-#endif
-
 /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
 /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
 #define LOAD_BAT(n, reg, RA, RB)	\
 #define LOAD_BAT(n, reg, RA, RB)	\
 	/* see the comment for clear_bats() -- Cort */ \
 	/* see the comment for clear_bats() -- Cort */ \
@@ -92,11 +87,6 @@ _start:
  *  r4: virtual address of boot_infos_t
  *  r4: virtual address of boot_infos_t
  *  r5: 0
  *  r5: 0
  *
  *
- * APUS
- *   r3: 'APUS'
- *   r4: physical address of memory base
- *   Linux/m68k style BootInfo structure at &_end.
- *
  * PREP
  * PREP
  * This is jumped to on prep systems right after the kernel is relocated
  * This is jumped to on prep systems right after the kernel is relocated
  * to its proper place in memory by the boot loader.  The expected layout
  * to its proper place in memory by the boot loader.  The expected layout
@@ -150,14 +140,6 @@ __start:
  */
  */
 	bl	early_init
 	bl	early_init
 
 
-#ifdef CONFIG_APUS
-/* On APUS the __va/__pa constants need to be set to the correct
- * values before continuing.
- */
-	mr	r4,r30
-	bl	fix_mem_constants
-#endif /* CONFIG_APUS */
-
 /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
 /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
  * the physical address we are running at, returned by early_init()
  * the physical address we are running at, returned by early_init()
  */
  */
@@ -167,7 +149,7 @@ __after_mmu_off:
 	bl	flush_tlbs
 	bl	flush_tlbs
 
 
 	bl	initial_bats
 	bl	initial_bats
-#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
+#if defined(CONFIG_BOOTX_TEXT)
 	bl	setup_disp_bat
 	bl	setup_disp_bat
 #endif
 #endif
 
 
@@ -183,7 +165,6 @@ __after_mmu_off:
 #endif /* CONFIG_6xx */
 #endif /* CONFIG_6xx */
 
 
 
 
-#ifndef CONFIG_APUS
 /*
 /*
  * We need to run with _start at physical address 0.
  * We need to run with _start at physical address 0.
  * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
  * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
@@ -196,7 +177,6 @@ __after_mmu_off:
 	addis	r4,r3,KERNELBASE@h	/* current address of _start */
 	addis	r4,r3,KERNELBASE@h	/* current address of _start */
 	cmpwi	0,r4,0			/* are we already running at 0? */
 	cmpwi	0,r4,0			/* are we already running at 0? */
 	bne	relocate_kernel
 	bne	relocate_kernel
-#endif /* CONFIG_APUS */
 /*
 /*
  * we now have the 1st 16M of ram mapped with the bats.
  * we now have the 1st 16M of ram mapped with the bats.
  * prep needs the mmu to be turned on here, but pmac already has it on.
  * prep needs the mmu to be turned on here, but pmac already has it on.
@@ -881,85 +861,6 @@ _GLOBAL(copy_and_flush)
 	addi	r6,r6,4
 	addi	r6,r6,4
 	blr
 	blr
 
 
-#ifdef CONFIG_APUS
-/*
- * On APUS the physical base address of the kernel is not known at compile
- * time, which means the __pa/__va constants used are incorrect. In the
- * __init section is recorded the virtual addresses of instructions using
- * these constants, so all that has to be done is fix these before
- * continuing the kernel boot.
- *
- * r4 = The physical address of the kernel base.
- */
-fix_mem_constants:
-	mr	r10,r4
-	addis	r10,r10,-KERNELBASE@h    /* virt_to_phys constant */
-	neg	r11,r10	                 /* phys_to_virt constant */
-
-	lis	r12,__vtop_table_begin@h
-	ori	r12,r12,__vtop_table_begin@l
-	add	r12,r12,r10	         /* table begin phys address */
-	lis	r13,__vtop_table_end@h
-	ori	r13,r13,__vtop_table_end@l
-	add	r13,r13,r10	         /* table end phys address */
-	subi	r12,r12,4
-	subi	r13,r13,4
-1:	lwzu	r14,4(r12)               /* virt address of instruction */
-	add     r14,r14,r10              /* phys address of instruction */
-	lwz     r15,0(r14)               /* instruction, now insert top */
-	rlwimi  r15,r10,16,16,31         /* half of vp const in low half */
-	stw	r15,0(r14)               /* of instruction and restore. */
-	dcbst	r0,r14			 /* write it to memory */
-	sync
-	icbi	r0,r14			 /* flush the icache line */
-	cmpw	r12,r13
-	bne     1b
-	sync				/* additional sync needed on g4 */
-	isync
-
-/*
- * Map the memory where the exception handlers will
- * be copied to when hash constants have been patched.
- */
-#ifdef CONFIG_APUS_FAST_EXCEPT
-	lis	r8,0xfff0
-#else
-	lis	r8,0
-#endif
-	ori	r8,r8,0x2		/* 128KB, supervisor */
-	mtspr	SPRN_DBAT3U,r8
-	mtspr	SPRN_DBAT3L,r8
-
-	lis	r12,__ptov_table_begin@h
-	ori	r12,r12,__ptov_table_begin@l
-	add	r12,r12,r10	         /* table begin phys address */
-	lis	r13,__ptov_table_end@h
-	ori	r13,r13,__ptov_table_end@l
-	add	r13,r13,r10	         /* table end phys address */
-	subi	r12,r12,4
-	subi	r13,r13,4
-1:	lwzu	r14,4(r12)               /* virt address of instruction */
-	add     r14,r14,r10              /* phys address of instruction */
-	lwz     r15,0(r14)               /* instruction, now insert top */
-	rlwimi  r15,r11,16,16,31         /* half of pv const in low half*/
-	stw	r15,0(r14)               /* of instruction and restore. */
-	dcbst	r0,r14			 /* write it to memory */
-	sync
-	icbi	r0,r14			 /* flush the icache line */
-	cmpw	r12,r13
-	bne     1b
-
-	sync				/* additional sync needed on g4 */
-	isync				/* No speculative loading until now */
-	blr
-
-/***********************************************************************
- *  Please note that on APUS the exception handlers are located at the
- *  physical address 0xfff0000. For this reason, the exception handlers
- *  cannot use relative branches to access the code below.
- ***********************************************************************/
-#endif /* CONFIG_APUS */
-
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 #ifdef CONFIG_GEMINI
 #ifdef CONFIG_GEMINI
 	.globl	__secondary_start_gemini
 	.globl	__secondary_start_gemini
@@ -1135,19 +1036,6 @@ start_here:
 	bl	__save_cpu_setup
 	bl	__save_cpu_setup
 	bl	MMU_init
 	bl	MMU_init
 
 
-#ifdef CONFIG_APUS
-	/* Copy exception code to exception vector base on APUS. */
-	lis	r4,KERNELBASE@h
-#ifdef CONFIG_APUS_FAST_EXCEPT
-	lis	r3,0xfff0		/* Copy to 0xfff00000 */
-#else
-	lis	r3,0			/* Copy to 0x00000000 */
-#endif
-	li	r5,0x4000		/* # bytes of memory to copy */
-	li	r6,0
-	bl	copy_and_flush		/* copy the first 0x4000 bytes */
-#endif  /* CONFIG_APUS */
-
 /*
 /*
  * Go back to running unmapped so we can load up new values
  * Go back to running unmapped so we can load up new values
  * for SDR1 (hash table pointer) and the segment registers
  * for SDR1 (hash table pointer) and the segment registers
@@ -1324,11 +1212,7 @@ initial_bats:
 #else
 #else
 	ori	r8,r8,2			/* R/W access */
 	ori	r8,r8,2			/* R/W access */
 #endif /* CONFIG_SMP */
 #endif /* CONFIG_SMP */
-#ifdef CONFIG_APUS
-	ori	r11,r11,BL_8M<<2|0x2	/* set up 8MB BAT registers for 604 */
-#else
 	ori	r11,r11,BL_256M<<2|0x2	/* set up BAT registers for 604 */
 	ori	r11,r11,BL_256M<<2|0x2	/* set up BAT registers for 604 */
-#endif /* CONFIG_APUS */
 
 
 	mtspr	SPRN_DBAT0L,r8		/* N.B. 6xx (not 601) have valid */
 	mtspr	SPRN_DBAT0L,r8		/* N.B. 6xx (not 601) have valid */
 	mtspr	SPRN_DBAT0U,r11		/* bit in upper BAT register */
 	mtspr	SPRN_DBAT0U,r11		/* bit in upper BAT register */
@@ -1338,7 +1222,7 @@ initial_bats:
 	blr
 	blr
 
 
 
 
-#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
+#ifdef CONFIG_BOOTX_TEXT
 setup_disp_bat:
 setup_disp_bat:
 	/*
 	/*
 	 * setup the display bat prepared for us in prom.c
 	 * setup the display bat prepared for us in prom.c
@@ -1362,7 +1246,7 @@ setup_disp_bat:
 1:	mtspr	SPRN_IBAT3L,r8
 1:	mtspr	SPRN_IBAT3L,r8
 	mtspr	SPRN_IBAT3U,r11
 	mtspr	SPRN_IBAT3U,r11
 	blr
 	blr
-#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
+#endif /* CONFIG_BOOTX_TEXT */
 
 
 #ifdef CONFIG_8260
 #ifdef CONFIG_8260
 /* Jump into the system reset for the rom.
 /* Jump into the system reset for the rom.

+ 2 - 2
arch/powerpc/kernel/head_64.S

@@ -103,8 +103,8 @@ __secondary_hold_acknowledge:
 
 
 	. = 0x60
 	. = 0x60
 /*
 /*
- * The following code is used on pSeries to hold secondary processors
- * in a spin loop after they have been freed from OpenFirmware, but
+ * The following code is used to hold secondary processors
+ * in a spin loop after they have entered the kernel, but
  * before the bulk of the kernel has been relocated.  This code
  * before the bulk of the kernel has been relocated.  This code
  * is relocated to physical address 0x60 before prom_init is run.
  * is relocated to physical address 0x60 before prom_init is run.
  * All of it must fit below the first exception vector at 0x100.
  * All of it must fit below the first exception vector at 0x100.

+ 6 - 6
arch/powerpc/kernel/io.c

@@ -35,7 +35,7 @@ void _insb(const volatile u8 __iomem *port, void *buf, long count)
 	asm volatile("sync");
 	asm volatile("sync");
 	do {
 	do {
 		tmp = *port;
 		tmp = *port;
-		asm volatile("eieio");
+		eieio();
 		*tbuf++ = tmp;
 		*tbuf++ = tmp;
 	} while (--count != 0);
 	} while (--count != 0);
 	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
 	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
@@ -66,7 +66,7 @@ void _insw_ns(const volatile u16 __iomem *port, void *buf, long count)
 	asm volatile("sync");
 	asm volatile("sync");
 	do {
 	do {
 		tmp = *port;
 		tmp = *port;
-		asm volatile("eieio");
+		eieio();
 		*tbuf++ = tmp;
 		*tbuf++ = tmp;
 	} while (--count != 0);
 	} while (--count != 0);
 	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
 	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
@@ -97,7 +97,7 @@ void _insl_ns(const volatile u32 __iomem *port, void *buf, long count)
 	asm volatile("sync");
 	asm volatile("sync");
 	do {
 	do {
 		tmp = *port;
 		tmp = *port;
-		asm volatile("eieio");
+		eieio();
 		*tbuf++ = tmp;
 		*tbuf++ = tmp;
 	} while (--count != 0);
 	} while (--count != 0);
 	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
 	asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
@@ -155,21 +155,21 @@ void _memcpy_fromio(void *dest, const volatile void __iomem *src,
 	__asm__ __volatile__ ("sync" : : : "memory");
 	__asm__ __volatile__ ("sync" : : : "memory");
 	while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) {
 	while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) {
 		*((u8 *)dest) = *((volatile u8 *)vsrc);
 		*((u8 *)dest) = *((volatile u8 *)vsrc);
-		__asm__ __volatile__ ("eieio" : : : "memory");
+		eieio();
 		vsrc++;
 		vsrc++;
 		dest++;
 		dest++;
 		n--;
 		n--;
 	}
 	}
 	while(n > 4) {
 	while(n > 4) {
 		*((u32 *)dest) = *((volatile u32 *)vsrc);
 		*((u32 *)dest) = *((volatile u32 *)vsrc);
-		__asm__ __volatile__ ("eieio" : : : "memory");
+		eieio();
 		vsrc += 4;
 		vsrc += 4;
 		dest += 4;
 		dest += 4;
 		n -= 4;
 		n -= 4;
 	}
 	}
 	while(n) {
 	while(n) {
 		*((u8 *)dest) = *((volatile u8 *)vsrc);
 		*((u8 *)dest) = *((volatile u8 *)vsrc);
-		__asm__ __volatile__ ("eieio" : : : "memory");
+		eieio();
 		vsrc++;
 		vsrc++;
 		dest++;
 		dest++;
 		n--;
 		n--;

+ 47 - 13
arch/powerpc/kernel/irq.c

@@ -7,7 +7,6 @@
  *    Copyright (C) 1996-2001 Cort Dougan
  *    Copyright (C) 1996-2001 Cort Dougan
  *  Adapted for Power Macintosh by Paul Mackerras
  *  Adapted for Power Macintosh by Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
  *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  * This program is free software; you can redistribute it and/or
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * modify it under the terms of the GNU General Public License
@@ -337,7 +336,8 @@ void do_IRQ(struct pt_regs *regs)
 
 
 void __init init_IRQ(void)
 void __init init_IRQ(void)
 {
 {
-	ppc_md.init_IRQ();
+	if (ppc_md.init_IRQ)
+		ppc_md.init_IRQ();
 #ifdef CONFIG_PPC64
 #ifdef CONFIG_PPC64
 	irq_ctx_init();
 	irq_ctx_init();
 #endif
 #endif
@@ -597,6 +597,49 @@ static void irq_radix_rdunlock(unsigned long flags)
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
 
 
+static int irq_setup_virq(struct irq_host *host, unsigned int virq,
+			    irq_hw_number_t hwirq)
+{
+	/* Clear IRQ_NOREQUEST flag */
+	get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
+
+	/* map it */
+	smp_wmb();
+	irq_map[virq].hwirq = hwirq;
+	smp_mb();
+
+	if (host->ops->map(host, virq, hwirq)) {
+		pr_debug("irq: -> mapping failed, freeing\n");
+		irq_free_virt(virq, 1);
+		return -1;
+	}
+
+	return 0;
+}
+
+unsigned int irq_create_direct_mapping(struct irq_host *host)
+{
+	unsigned int virq;
+
+	if (host == NULL)
+		host = irq_default_host;
+
+	BUG_ON(host == NULL);
+	WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
+
+	virq = irq_alloc_virt(host, 1, 0);
+	if (virq == NO_IRQ) {
+		pr_debug("irq: create_direct virq allocation failed\n");
+		return NO_IRQ;
+	}
+
+	pr_debug("irq: create_direct obtained virq %d\n", virq);
+
+	if (irq_setup_virq(host, virq, virq))
+		return NO_IRQ;
+
+	return virq;
+}
 
 
 unsigned int irq_create_mapping(struct irq_host *host,
 unsigned int irq_create_mapping(struct irq_host *host,
 				irq_hw_number_t hwirq)
 				irq_hw_number_t hwirq)
@@ -645,18 +688,9 @@ unsigned int irq_create_mapping(struct irq_host *host,
 	}
 	}
 	pr_debug("irq: -> obtained virq %d\n", virq);
 	pr_debug("irq: -> obtained virq %d\n", virq);
 
 
-	/* Clear IRQ_NOREQUEST flag */
-	get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
-
-	/* map it */
-	smp_wmb();
-	irq_map[virq].hwirq = hwirq;
-	smp_mb();
-	if (host->ops->map(host, virq, hwirq)) {
-		pr_debug("irq: -> mapping failed, freeing\n");
-		irq_free_virt(virq, 1);
+	if (irq_setup_virq(host, virq, hwirq))
 		return NO_IRQ;
 		return NO_IRQ;
-	}
+
 	return virq;
 	return virq;
 }
 }
 EXPORT_SYMBOL_GPL(irq_create_mapping);
 EXPORT_SYMBOL_GPL(irq_create_mapping);

+ 271 - 0
arch/powerpc/kernel/isa-bridge.c

@@ -0,0 +1,271 @@
+/*
+ * Routines for tracking a legacy ISA bridge
+ *
+ * Copyrigh 2007 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * Some bits and pieces moved over from pci_64.c
+ *
+ * Copyrigh 2003 Anton Blanchard <anton@au.ibm.com>, 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.
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/notifier.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/firmware.h>
+
+unsigned long isa_io_base;	/* NULL if no ISA bus */
+EXPORT_SYMBOL(isa_io_base);
+
+/* Cached ISA bridge dev. */
+static struct device_node *isa_bridge_devnode;
+struct pci_dev *isa_bridge_pcidev;
+EXPORT_SYMBOL_GPL(isa_bridge_pcidev);
+
+#define ISA_SPACE_MASK 0x1
+#define ISA_SPACE_IO 0x1
+
+static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
+						unsigned long phb_io_base_phys)
+{
+	/* We should get some saner parsing here and remove these structs */
+	struct pci_address {
+		u32 a_hi;
+		u32 a_mid;
+		u32 a_lo;
+	};
+
+	struct isa_address {
+		u32 a_hi;
+		u32 a_lo;
+	};
+
+	struct isa_range {
+		struct isa_address isa_addr;
+		struct pci_address pci_addr;
+		unsigned int size;
+	};
+
+	const struct isa_range *range;
+	unsigned long pci_addr;
+	unsigned int isa_addr;
+	unsigned int size;
+	int rlen = 0;
+
+	range = of_get_property(isa_node, "ranges", &rlen);
+	if (range == NULL || (rlen < sizeof(struct isa_range)))
+		goto inval_range;
+
+	/* From "ISA Binding to 1275"
+	 * The ranges property is laid out as an array of elements,
+	 * each of which comprises:
+	 *   cells 0 - 1:	an ISA address
+	 *   cells 2 - 4:	a PCI address
+	 *			(size depending on dev->n_addr_cells)
+	 *   cell 5:		the size of the range
+	 */
+	if ((range->isa_addr.a_hi && ISA_SPACE_MASK) != ISA_SPACE_IO) {
+		range++;
+		rlen -= sizeof(struct isa_range);
+		if (rlen < sizeof(struct isa_range))
+			goto inval_range;
+	}
+	if ((range->isa_addr.a_hi && ISA_SPACE_MASK) != ISA_SPACE_IO)
+		goto inval_range;
+
+	isa_addr = range->isa_addr.a_lo;
+	pci_addr = (unsigned long) range->pci_addr.a_mid << 32 |
+		range->pci_addr.a_lo;
+
+	/* Assume these are both zero. Note: We could fix that and
+	 * do a proper parsing instead ... oh well, that will do for
+	 * now as nobody uses fancy mappings for ISA bridges
+	 */
+	if ((pci_addr != 0) || (isa_addr != 0)) {
+		printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
+		       __FUNCTION__);
+		return;
+	}
+
+	/* Align size and make sure it's cropped to 64K */
+	size = PAGE_ALIGN(range->size);
+	if (size > 0x10000)
+		size = 0x10000;
+
+	printk(KERN_ERR "no ISA IO ranges or unexpected isa range,"
+	       "mapping 64k\n");
+
+	__ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
+		     size, _PAGE_NO_CACHE|_PAGE_GUARDED);
+	return;
+
+inval_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);
+}
+
+
+/**
+ * isa_bridge_find_early - Find and map the ISA IO space early before
+ *                         main PCI discovery. This is optionally called by
+ *                         the arch code when adding PCI PHBs to get early
+ *                         access to ISA IO ports
+ */
+void __init isa_bridge_find_early(struct pci_controller *hose)
+{
+	struct device_node *np, *parent = NULL, *tmp;
+
+	/* If we already have an ISA bridge, bail off */
+	if (isa_bridge_devnode != NULL)
+		return;
+
+	/* For each "isa" node in the system. Note : we do a search by
+	 * type and not by name. It might be better to do by name but that's
+	 * what the code used to do and I don't want to break too much at
+	 * once. We can look into changing that separately
+	 */
+	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) {
+				of_node_put(parent);
+				break;
+			}
+			tmp = parent;
+			parent = of_get_parent(parent);
+			of_node_put(tmp);
+		}
+		if (parent != NULL)
+			break;
+	}
+	if (np == NULL)
+		return;
+	isa_bridge_devnode = np;
+
+	/* Now parse the "ranges" property and setup the ISA mapping */
+	pci_process_ISA_OF_ranges(np, hose->io_base_phys);
+
+	/* Set the global ISA io base to indicate we have an ISA bridge */
+	isa_io_base = ISA_IO_BASE;
+
+	pr_debug("ISA bridge (early) is %s\n", np->full_name);
+}
+
+/**
+ * isa_bridge_find_late - Find and map the ISA IO space upon discovery of
+ *                        a new ISA bridge
+ */
+static void __devinit isa_bridge_find_late(struct pci_dev *pdev,
+					   struct device_node *devnode)
+{
+	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+
+	/* Store ISA device node and PCI device */
+	isa_bridge_devnode = of_node_get(devnode);
+	isa_bridge_pcidev = pdev;
+
+	/* Now parse the "ranges" property and setup the ISA mapping */
+	pci_process_ISA_OF_ranges(devnode, hose->io_base_phys);
+
+	/* Set the global ISA io base to indicate we have an ISA bridge */
+	isa_io_base = ISA_IO_BASE;
+
+	pr_debug("ISA bridge (late) is %s on %s\n",
+		 devnode->full_name, pci_name(pdev));
+}
+
+/**
+ * isa_bridge_remove - Remove/unmap an ISA bridge
+ */
+static void isa_bridge_remove(void)
+{
+	pr_debug("ISA bridge removed !\n");
+
+	/* Clear the global ISA io base to indicate that we have no more
+	 * ISA bridge. Note that drivers don't quite handle that, though
+	 * we should probably do something about it. But do we ever really
+	 * have ISA bridges being removed on machines using legacy devices ?
+	 */
+	isa_io_base = ISA_IO_BASE;
+
+	/* Clear references to the bridge */
+	of_node_put(isa_bridge_devnode);
+	isa_bridge_devnode = NULL;
+	isa_bridge_pcidev = NULL;
+
+	/* Unmap the ISA area */
+	__iounmap_at((void *)ISA_IO_BASE, 0x10000);
+}
+
+/**
+ * isa_bridge_notify - Get notified of PCI devices addition/removal
+ */
+static int __devinit isa_bridge_notify(struct notifier_block *nb,
+				       unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct device_node *devnode = pci_device_to_OF_node(pdev);
+
+	switch(action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		/* Check if we have an early ISA device, without PCI dev */
+		if (isa_bridge_devnode && isa_bridge_devnode == devnode &&
+		    !isa_bridge_pcidev) {
+			pr_debug("ISA bridge PCI attached: %s\n",
+				 pci_name(pdev));
+			isa_bridge_pcidev = pdev;
+		}
+
+		/* Check if we have no ISA device, and this happens to be one,
+		 * register it as such if it has an OF device
+		 */
+		if (!isa_bridge_devnode && devnode && devnode->type &&
+		    !strcmp(devnode->type, "isa"))
+			isa_bridge_find_late(pdev, devnode);
+
+		return 0;
+	case BUS_NOTIFY_DEL_DEVICE:
+		/* Check if this our existing ISA device */
+		if (pdev == isa_bridge_pcidev ||
+		    (devnode && devnode == isa_bridge_devnode))
+			isa_bridge_remove();
+		return 0;
+	}
+	return 0;
+}
+
+static struct notifier_block isa_bridge_notifier = {
+	.notifier_call = isa_bridge_notify
+};
+
+/**
+ * isa_bridge_init - register to be notified of ISA bridge addition/removal
+ *
+ */
+static int __init isa_bridge_init(void)
+{
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return 0;
+	bus_register_notifier(&pci_bus_type, &isa_bridge_notifier);
+	return 0;
+}
+arch_initcall(isa_bridge_init);

+ 5 - 5
arch/powerpc/kernel/misc_32.S

@@ -392,7 +392,7 @@ BEGIN_FTR_SECTION
 	mtspr   SPRN_L1CSR0,r3
 	mtspr   SPRN_L1CSR0,r3
 	isync
 	isync
 	blr
 	blr
-END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
 	mfspr	r3,SPRN_L1CSR1
 	mfspr	r3,SPRN_L1CSR1
 	ori	r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
 	ori	r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
 	mtspr	SPRN_L1CSR1,r3
 	mtspr	SPRN_L1CSR1,r3
@@ -419,7 +419,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 _GLOBAL(__flush_icache_range)
 _GLOBAL(__flush_icache_range)
 BEGIN_FTR_SECTION
 BEGIN_FTR_SECTION
 	blr				/* for 601, do nothing */
 	blr				/* for 601, do nothing */
-END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 	li	r5,L1_CACHE_BYTES-1
 	li	r5,L1_CACHE_BYTES-1
 	andc	r3,r3,r5
 	andc	r3,r3,r5
 	subf	r4,r3,r4
 	subf	r4,r3,r4
@@ -514,8 +514,8 @@ _GLOBAL(invalidate_dcache_range)
  */
  */
 _GLOBAL(__flush_dcache_icache)
 _GLOBAL(__flush_dcache_icache)
 BEGIN_FTR_SECTION
 BEGIN_FTR_SECTION
-	blr					/* for 601, do nothing */
-END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+	blr
+END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 	rlwinm	r3,r3,0,0,19			/* Get page base address */
 	rlwinm	r3,r3,0,0,19			/* Get page base address */
 	li	r4,4096/L1_CACHE_BYTES	/* Number of lines in a page */
 	li	r4,4096/L1_CACHE_BYTES	/* Number of lines in a page */
 	mtctr	r4
 	mtctr	r4
@@ -543,7 +543,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 _GLOBAL(__flush_dcache_icache_phys)
 _GLOBAL(__flush_dcache_icache_phys)
 BEGIN_FTR_SECTION
 BEGIN_FTR_SECTION
 	blr					/* for 601, do nothing */
 	blr					/* for 601, do nothing */
-END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
+END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 	mfmsr	r10
 	mfmsr	r10
 	rlwinm	r0,r10,0,28,26			/* clear DR */
 	rlwinm	r0,r10,0,28,26			/* clear DR */
 	mtmsr	r0
 	mtmsr	r0

+ 13 - 13
arch/powerpc/kernel/misc_64.S

@@ -646,6 +646,19 @@ _GLOBAL(kexec_sequence)
 	/* turn off mmu */
 	/* turn off mmu */
 	bl	real_mode
 	bl	real_mode
 
 
+	/* copy  0x100 bytes starting at start to 0 */
+	li	r3,0
+	mr	r4,r30		/* start, aka phys mem offset */
+	li	r5,0x100
+	li	r6,0
+	bl	.copy_and_flush	/* (dest, src, copy limit, start offset) */
+1:	/* assume normal blr return */
+
+	/* release other cpus to the new kernel secondary start at 0x60 */
+	mflr	r5
+	li	r6,1
+	stw	r6,kexec_flag-1b(5)
+
 	/* clear out hardware hash page table and tlb */
 	/* clear out hardware hash page table and tlb */
 	ld	r5,0(r27)		/* deref function descriptor */
 	ld	r5,0(r27)		/* deref function descriptor */
 	mtctr	r5
 	mtctr	r5
@@ -676,19 +689,6 @@ _GLOBAL(kexec_sequence)
  *    are the boot cpu ?????
  *    are the boot cpu ?????
  *    other device tree differences (prop sizes, va vs pa, etc)...
  *    other device tree differences (prop sizes, va vs pa, etc)...
  */
  */
-
-	/* copy  0x100 bytes starting at start to 0 */
-	li	r3,0
-	mr	r4,r30
-	li	r5,0x100
-	li	r6,0
-	bl	.copy_and_flush	/* (dest, src, copy limit, start offset) */
-1:	/* assume normal blr return */
-
-	/* release other cpus to the new kernel secondary start at 0x60 */
-	mflr	r5
-	li	r6,1
-	stw	r6,kexec_flag-1b(5)
 	mr	r3,r25	# my phys cpu
 	mr	r3,r25	# my phys cpu
 	mr	r4,r30	# start, aka phys mem offset
 	mr	r4,r30	# start, aka phys mem offset
 	mtlr	4
 	mtlr	4

+ 0 - 8
arch/powerpc/kernel/of_platform.c

@@ -427,14 +427,6 @@ static int __devinit of_pci_phb_probe(struct of_device *dev,
 	/* Process "ranges" property */
 	/* Process "ranges" property */
 	pci_process_bridge_OF_ranges(phb, dev->node, 0);
 	pci_process_bridge_OF_ranges(phb, dev->node, 0);
 
 
-	/* Setup IO space. We use the non-dynamic version of that code here,
-	 * which doesn't quite support unplugging. Next kernel release will
-	 * have a better fix for this.
-	 * Note also that we don't do ISA, this will also be fixed with a
-	 * more massive rework.
-	 */
-	pci_setup_phb_io(phb, pci_io_base == 0);
-
 	/* Init pci_dn data structures */
 	/* Init pci_dn data structures */
 	pci_devs_phb_init_dynamic(phb);
 	pci_devs_phb_init_dynamic(phb);
 
 

+ 454 - 0
arch/powerpc/kernel/pci-common.c

@@ -0,0 +1,454 @@
+/*
+ * Contains common pci routines for ALL ppc platform
+ * (based on pci_32.c and pci_64.c)
+ *
+ * Port for PPC64 David Engebretsen, IBM Corp.
+ * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ *   Rework, based on alpha PCI code.
+ *
+ * Common pmac/prep/chrp pci routines. -- Cort
+ *
+ * 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.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/syscalls.h>
+#include <linux/irq.h>
+#include <linux/vmalloc.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/firmware.h>
+
+#ifdef DEBUG
+#include <asm/udbg.h>
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+static DEFINE_SPINLOCK(hose_spinlock);
+
+/* XXX kill that some day ... */
+int global_phb_number;		/* Global phb counter */
+
+extern struct list_head hose_list;
+
+/*
+ * 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);
+}
+
+struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
+{
+	struct pci_controller *phb;
+
+	if (mem_init_done)
+		phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
+	else
+		phb = alloc_bootmem(sizeof (struct pci_controller));
+	if (phb == NULL)
+		return NULL;
+	pci_setup_pci_controller(phb);
+	phb->arch_data = dev;
+	phb->is_dynamic = mem_init_done;
+#ifdef CONFIG_PPC64
+	if (dev) {
+		int nid = of_node_to_nid(dev);
+
+		if (nid < 0 || !node_online(nid))
+			nid = -1;
+
+		PHB_SET_NODE(phb, nid);
+	}
+#endif
+	return phb;
+}
+
+void pcibios_free_controller(struct pci_controller *phb)
+{
+	spin_lock(&hose_spinlock);
+	list_del(&phb->list_node);
+	spin_unlock(&hose_spinlock);
+
+	if (phb->is_dynamic)
+		kfree(phb);
+}
+
+/*
+ * Return the domain number for this bus.
+ */
+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);
+
+		return hose->global_number;
+	}
+}
+
+EXPORT_SYMBOL(pci_domain_nr);
+
+#ifdef CONFIG_PPC_OF
+
+/* This routine is meant to be used early during boot, when the
+ * PCI bus numbers have not yet been assigned, and you need to
+ * issue PCI config cycles to an OF device.
+ * It could also be used to "fix" RTAS config cycles if you want
+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
+ * config cycles.
+ */
+struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
+{
+	if (!have_of)
+		return NULL;
+	while(node) {
+		struct pci_controller *hose, *tmp;
+		list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+			if (hose->arch_data == node)
+				return hose;
+		node = node->parent;
+	}
+	return NULL;
+}
+
+static ssize_t pci_show_devspec(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct pci_dev *pdev;
+	struct device_node *np;
+
+	pdev = to_pci_dev (dev);
+	np = pci_device_to_OF_node(pdev);
+	if (np == NULL || np->full_name == NULL)
+		return 0;
+	return sprintf(buf, "%s", np->full_name);
+}
+static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+#endif /* CONFIG_PPC_OF */
+
+/* Add sysfs properties */
+void pcibios_add_platform_entries(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PPC_OF
+	device_create_file(&pdev->dev, &dev_attr_devspec);
+#endif /* CONFIG_PPC_OF */
+}
+
+char __init *pcibios_setup(char *str)
+{
+	return str;
+}
+
+/*
+ * Reads the interrupt pin to determine if interrupt is use by card.
+ * If the interrupt is used, then gets the interrupt line from the
+ * openfirmware and sets it in the pci_dev and pci_config line.
+ */
+int pci_read_irq_line(struct pci_dev *pci_dev)
+{
+	struct of_irq oirq;
+	unsigned int virq;
+
+	DBG("Try to map irq for %s...\n", pci_name(pci_dev));
+
+#ifdef DEBUG
+	memset(&oirq, 0xff, sizeof(oirq));
+#endif
+	/* Try to get a mapping from the device-tree */
+	if (of_irq_map_pci(pci_dev, &oirq)) {
+		u8 line, pin;
+
+		/* If that fails, lets fallback to what is in the config
+		 * space and map that through the default controller. We
+		 * also set the type to level low since that's what PCI
+		 * interrupts are. If your platform does differently, then
+		 * either provide a proper interrupt tree or don't use this
+		 * function.
+		 */
+		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
+			return -1;
+		if (pin == 0)
+			return -1;
+		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
+		    line == 0xff) {
+			return -1;
+		}
+		DBG(" -> no map ! Using irq line %d from PCI config\n", line);
+
+		virq = irq_create_mapping(NULL, line);
+		if (virq != NO_IRQ)
+			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+	} else {
+		DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+		    oirq.size, oirq.specifier[0], oirq.specifier[1],
+		    oirq.controller->full_name);
+
+		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+					     oirq.size);
+	}
+	if(virq == NO_IRQ) {
+		DBG(" -> failed to map !\n");
+		return -1;
+	}
+
+	DBG(" -> mapped to linux irq %d\n", virq);
+
+	pci_dev->irq = virq;
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_read_irq_line);
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ *  -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
+					       resource_size_t *offset,
+					       enum pci_mmap_state mmap_state)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long io_offset = 0;
+	int i, res_bit;
+
+	if (hose == 0)
+		return NULL;		/* should never happen */
+
+	/* If memory, add on the PCI bridge address offset */
+	if (mmap_state == pci_mmap_mem) {
+#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
+		*offset += hose->pci_mem_offset;
+#endif
+		res_bit = IORESOURCE_MEM;
+	} else {
+		io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+		*offset += io_offset;
+		res_bit = IORESOURCE_IO;
+	}
+
+	/*
+	 * Check that the offset requested corresponds to one of the
+	 * resources of the device.
+	 */
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		struct resource *rp = &dev->resource[i];
+		int flags = rp->flags;
+
+		/* treat ROM as memory (should be already) */
+		if (i == PCI_ROM_RESOURCE)
+			flags |= IORESOURCE_MEM;
+
+		/* Active and same type? */
+		if ((flags & res_bit) == 0)
+			continue;
+
+		/* In the range of this resource? */
+		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
+			continue;
+
+		/* found it! construct the final physical address */
+		if (mmap_state == pci_mmap_io)
+			*offset += hose->io_base_phys - io_offset;
+		return rp;
+	}
+
+	return NULL;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
+				      pgprot_t protection,
+				      enum pci_mmap_state mmap_state,
+				      int write_combine)
+{
+	unsigned long prot = pgprot_val(protection);
+
+	/* Write combine is always 0 on non-memory space mappings. On
+	 * memory space, if the user didn't pass 1, we check for a
+	 * "prefetchable" resource. This is a bit hackish, but we use
+	 * this to workaround the inability of /sysfs to provide a write
+	 * combine bit
+	 */
+	if (mmap_state != pci_mmap_mem)
+		write_combine = 0;
+	else if (write_combine == 0) {
+		if (rp->flags & IORESOURCE_PREFETCH)
+			write_combine = 1;
+	}
+
+	/* XXX would be nice to have a way to ask for write-through */
+	prot |= _PAGE_NO_CACHE;
+	if (write_combine)
+		prot &= ~_PAGE_GUARDED;
+	else
+		prot |= _PAGE_GUARDED;
+
+	return __pgprot(prot);
+}
+
+/*
+ * This one is used by /dev/mem and fbdev who have no clue about the
+ * PCI device, it tries to find the PCI device first and calls the
+ * above routine
+ */
+pgprot_t pci_phys_mem_access_prot(struct file *file,
+				  unsigned long pfn,
+				  unsigned long size,
+				  pgprot_t protection)
+{
+	struct pci_dev *pdev = NULL;
+	struct resource *found = NULL;
+	unsigned long prot = pgprot_val(protection);
+	unsigned long offset = pfn << PAGE_SHIFT;
+	int i;
+
+	if (page_is_ram(pfn))
+		return __pgprot(prot);
+
+	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+
+	for_each_pci_dev(pdev) {
+		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+			struct resource *rp = &pdev->resource[i];
+			int flags = rp->flags;
+
+			/* Active and same type? */
+			if ((flags & IORESOURCE_MEM) == 0)
+				continue;
+			/* In the range of this resource? */
+			if (offset < (rp->start & PAGE_MASK) ||
+			    offset > rp->end)
+				continue;
+			found = rp;
+			break;
+		}
+		if (found)
+			break;
+	}
+	if (found) {
+		if (found->flags & IORESOURCE_PREFETCH)
+			prot &= ~_PAGE_GUARDED;
+		pci_dev_put(pdev);
+	}
+
+	DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
+
+	return __pgprot(prot);
+}
+
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture.  The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
+	struct resource *rp;
+	int ret;
+
+	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
+	if (rp == NULL)
+		return -EINVAL;
+
+	vma->vm_pgoff = offset >> PAGE_SHIFT;
+	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
+						  vma->vm_page_prot,
+						  mmap_state, write_combine);
+
+	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+	return ret;
+}
+
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+			  const struct resource *rsrc,
+			  resource_size_t *start, resource_size_t *end)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	resource_size_t offset = 0;
+
+	if (hose == NULL)
+		return;
+
+	if (rsrc->flags & IORESOURCE_IO)
+		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+
+	/* We pass a fully fixed up address to userland for MMIO instead of
+	 * a BAR value because X is lame and expects to be able to use that
+	 * to pass to /dev/mem !
+	 *
+	 * That means that we'll have potentially 64 bits values where some
+	 * userland apps only expect 32 (like X itself since it thinks only
+	 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
+	 * 32 bits CHRPs :-(
+	 *
+	 * Hopefully, the sysfs insterface is immune to that gunk. Once X
+	 * has been fixed (and the fix spread enough), we can re-enable the
+	 * 2 lines below and pass down a BAR value to userland. In that case
+	 * we'll also have to re-enable the matching code in
+	 * __pci_mmap_make_offset().
+	 *
+	 * BenH.
+	 */
+#if 0
+	else if (rsrc->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+#endif
+
+	*start = rsrc->start - offset;
+	*end = rsrc->end - offset;
+}

+ 15 - 495
arch/powerpc/kernel/pci_32.c

@@ -55,8 +55,7 @@ static u8* pci_to_OF_bus_map;
  */
  */
 int pci_assign_all_buses;
 int pci_assign_all_buses;
 
 
-struct pci_controller* hose_head;
-struct pci_controller** hose_tail = &hose_head;
+LIST_HEAD(hose_list);
 
 
 static int pci_bus_count;
 static int pci_bus_count;
 
 
@@ -573,58 +572,6 @@ pcibios_assign_resources(void)
 	}
 	}
 }
 }
 
 
-
-int
-pcibios_enable_resources(struct pci_dev *dev, int mask)
-{
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for (idx=0; idx<6; idx++) {
-		/* Only set up the requested stuff */
-		if (!(mask & (1<<idx)))
-			continue;
-	
-		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 (dev->resource[PCI_ROM_RESOURCE].start)
-		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 int next_controller_index;
-
-struct pci_controller * __init
-pcibios_alloc_controller(void)
-{
-	struct pci_controller *hose;
-
-	hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose));
-	memset(hose, 0, sizeof(struct pci_controller));
-
-	*hose_tail = hose;
-	hose_tail = &hose->next;
-
-	hose->index = next_controller_index++;
-
-	return hose;
-}
-
 #ifdef CONFIG_PPC_OF
 #ifdef CONFIG_PPC_OF
 /*
 /*
  * Functions below are used on OpenFirmware machines.
  * Functions below are used on OpenFirmware machines.
@@ -670,7 +617,7 @@ void
 pcibios_make_OF_bus_map(void)
 pcibios_make_OF_bus_map(void)
 {
 {
 	int i;
 	int i;
-	struct pci_controller* hose;
+	struct pci_controller *hose, *tmp;
 	struct property *map_prop;
 	struct property *map_prop;
 	struct device_node *dn;
 	struct device_node *dn;
 
 
@@ -687,7 +634,7 @@ pcibios_make_OF_bus_map(void)
 		pci_to_OF_bus_map[i] = 0xff;
 		pci_to_OF_bus_map[i] = 0xff;
 
 
 	/* For each hose, we begin searching bridges */
 	/* For each hose, we begin searching bridges */
-	for(hose=hose_head; hose; hose=hose->next) {
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		struct device_node* node;	
 		struct device_node* node;	
 		node = (struct device_node *)hose->arch_data;
 		node = (struct device_node *)hose->arch_data;
 		if (!node)
 		if (!node)
@@ -765,7 +712,7 @@ static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
 
 
 	/* Are we a root bus ? */
 	/* Are we a root bus ? */
 	if (bus->self == NULL || bus->parent == NULL) {
 	if (bus->self == NULL || bus->parent == NULL) {
-		struct pci_controller *hose = pci_bus_to_hose(bus->number);
+		struct pci_controller *hose = pci_bus_to_host(bus);
 		if (hose == NULL)
 		if (hose == NULL)
 			return NULL;
 			return NULL;
 		return of_node_get(hose->arch_data);
 		return of_node_get(hose->arch_data);
@@ -818,27 +765,6 @@ pci_device_to_OF_node(struct pci_dev *dev)
 }
 }
 EXPORT_SYMBOL(pci_device_to_OF_node);
 EXPORT_SYMBOL(pci_device_to_OF_node);
 
 
-/* This routine is meant to be used early during boot, when the
- * PCI bus numbers have not yet been assigned, and you need to
- * issue PCI config cycles to an OF device.
- * It could also be used to "fix" RTAS config cycles if you want
- * to set pci_assign_all_buses to 1 and still use RTAS for PCI
- * config cycles.
- */
-struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
-{
-	if (!have_of)
-		return NULL;
-	while(node) {
-		struct pci_controller* hose;
-		for (hose=hose_head;hose;hose=hose->next)
-			if (hose->arch_data == node)
-				return hose;
-		node=node->parent;
-	}
-	return NULL;
-}
-
 static int
 static int
 find_OF_pci_device_filter(struct device_node* node, void* data)
 find_OF_pci_device_filter(struct device_node* node, void* data)
 {
 {
@@ -1027,34 +953,12 @@ pci_create_OF_bus_map(void)
 	}
 	}
 }
 }
 
 
-static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct pci_dev *pdev;
-	struct device_node *np;
-
-	pdev = to_pci_dev (dev);
-	np = pci_device_to_OF_node(pdev);
-	if (np == NULL || np->full_name == NULL)
-		return 0;
-	return sprintf(buf, "%s", np->full_name);
-}
-static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-
 #else /* CONFIG_PPC_OF */
 #else /* CONFIG_PPC_OF */
 void pcibios_make_OF_bus_map(void)
 void pcibios_make_OF_bus_map(void)
 {
 {
 }
 }
 #endif /* CONFIG_PPC_OF */
 #endif /* CONFIG_PPC_OF */
 
 
-/* Add sysfs properties */
-void pcibios_add_platform_entries(struct pci_dev *pdev)
-{
-#ifdef CONFIG_PPC_OF
-	device_create_file(&pdev->dev, &dev_attr_devspec);
-#endif /* CONFIG_PPC_OF */
-}
-
-
 #ifdef CONFIG_PPC_PMAC
 #ifdef CONFIG_PPC_PMAC
 /*
 /*
  * This set of routines checks for PCI<->PCI bridges that have closed
  * This set of routines checks for PCI<->PCI bridges that have closed
@@ -1269,14 +1173,14 @@ pcibios_fixup_p2p_bridges(void)
 static int __init
 static int __init
 pcibios_init(void)
 pcibios_init(void)
 {
 {
-	struct pci_controller *hose;
+	struct pci_controller *hose, *tmp;
 	struct pci_bus *bus;
 	struct pci_bus *bus;
-	int next_busno;
+	int next_busno = 0;
 
 
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
 
 
 	/* Scan all of the recorded PCI controllers.  */
 	/* Scan all of the recorded PCI controllers.  */
-	for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		if (pci_assign_all_buses)
 		if (pci_assign_all_buses)
 			hose->first_busno = next_busno;
 			hose->first_busno = next_busno;
 		hose->last_busno = 0xff;
 		hose->last_busno = 0xff;
@@ -1319,12 +1223,6 @@ pcibios_init(void)
 
 
 subsys_initcall(pcibios_init);
 subsys_initcall(pcibios_init);
 
 
-unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
-			     unsigned long start, unsigned long size)
-{
-	return start;
-}
-
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
 {
 	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
 	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
@@ -1342,7 +1240,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 		if (!res->flags) {
 		if (!res->flags) {
 			if (io_offset)
 			if (io_offset)
 				printk(KERN_ERR "I/O resource not set for host"
 				printk(KERN_ERR "I/O resource not set for host"
-				       " bridge %d\n", hose->index);
+				       " bridge %d\n", hose->global_number);
 			res->start = 0;
 			res->start = 0;
 			res->end = IO_SPACE_LIMIT;
 			res->end = IO_SPACE_LIMIT;
 			res->flags = IORESOURCE_IO;
 			res->flags = IORESOURCE_IO;
@@ -1356,7 +1254,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 				if (i > 0)
 				if (i > 0)
 					continue;
 					continue;
 				printk(KERN_ERR "Memory resource not set for "
 				printk(KERN_ERR "Memory resource not set for "
-				       "host bridge %d\n", hose->index);
+				       "host bridge %d\n", hose->global_number);
 				res->start = hose->pci_mem_offset;
 				res->start = hose->pci_mem_offset;
 				res->end = ~0U;
 				res->end = ~0U;
 				res->flags = IORESOURCE_MEM;
 				res->flags = IORESOURCE_MEM;
@@ -1370,7 +1268,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 		for (i = 0; i < 4; ++i) {
 		for (i = 0; i < 4; ++i) {
 			if ((res = bus->resource[i]) == NULL)
 			if ((res = bus->resource[i]) == NULL)
 				continue;
 				continue;
-			if (!res->flags)
+			if (!res->flags || bus->self->transparent)
 				continue;
 				continue;
 			if (io_offset && (res->flags & IORESOURCE_IO)) {
 			if (io_offset && (res->flags & IORESOURCE_IO)) {
 				res->start += io_offset;
 				res->start += io_offset;
@@ -1395,11 +1293,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 	}
 	}
 }
 }
 
 
-char __init *pcibios_setup(char *str)
-{
-	return str;
-}
-
 /* the next one is stolen from the alpha port... */
 /* the next one is stolen from the alpha port... */
 void __init
 void __init
 pcibios_update_irq(struct pci_dev *dev, int irq)
 pcibios_update_irq(struct pci_dev *dev, int irq)
@@ -1408,64 +1301,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
 	/* XXX FIXME - update OF device tree node interrupt property */
 	/* XXX FIXME - update OF device tree node interrupt property */
 }
 }
 
 
-#ifdef CONFIG_PPC_MERGE
-/* XXX This is a copy of the ppc64 version. This is temporary until we start
- * merging the 2 PCI layers
- */
-/*
- * Reads the interrupt pin to determine if interrupt is use by card.
- * If the interrupt is used, then gets the interrupt line from the
- * openfirmware and sets it in the pci_dev and pci_config line.
- */
-int pci_read_irq_line(struct pci_dev *pci_dev)
-{
-	struct of_irq oirq;
-	unsigned int virq;
-
-	DBG("Try to map irq for %s...\n", pci_name(pci_dev));
-
-	/* Try to get a mapping from the device-tree */
-	if (of_irq_map_pci(pci_dev, &oirq)) {
-		u8 line, pin;
-
-		/* If that fails, lets fallback to what is in the config
-		 * space and map that through the default controller. We
-		 * also set the type to level low since that's what PCI
-		 * interrupts are. If your platform does differently, then
-		 * either provide a proper interrupt tree or don't use this
-		 * function.
-		 */
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
-			return -1;
-		if (pin == 0)
-			return -1;
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
-		    line == 0xff) {
-			return -1;
-		}
-		DBG(" -> no map ! Using irq line %d from PCI config\n", line);
-
-		virq = irq_create_mapping(NULL, line);
-		if (virq != NO_IRQ)
-			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
-	} else {
-		DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
-		    oirq.size, oirq.specifier[0], oirq.controller->full_name);
-
-		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
-					     oirq.size);
-	}
-	if(virq == NO_IRQ) {
-		DBG(" -> failed to map !\n");
-		return -1;
-	}
-	pci_dev->irq = virq;
-
-	return 0;
-}
-EXPORT_SYMBOL(pci_read_irq_line);
-#endif /* CONFIG_PPC_MERGE */
-
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 {
 	u16 cmd, old_cmd;
 	u16 cmd, old_cmd;
@@ -1497,281 +1332,17 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return 0;
 	return 0;
 }
 }
 
 
-struct pci_controller*
+static struct pci_controller*
 pci_bus_to_hose(int bus)
 pci_bus_to_hose(int bus)
 {
 {
-	struct pci_controller* hose = hose_head;
+	struct pci_controller *hose, *tmp;
 
 
-	for (; hose; hose = hose->next)
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
 		if (bus >= hose->first_busno && bus <= hose->last_busno)
 		if (bus >= hose->first_busno && bus <= hose->last_busno)
 			return hose;
 			return hose;
 	return NULL;
 	return NULL;
 }
 }
 
 
-void __iomem *
-pci_bus_io_base(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return NULL;
-	return hose->io_base_virt;
-}
-
-unsigned long
-pci_bus_io_base_phys(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return 0;
-	return hose->io_base_phys;
-}
-
-unsigned long
-pci_bus_mem_base_phys(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return 0;
-	return hose->pci_mem_offset;
-}
-
-unsigned long
-pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)
-{
-	/* Hack alert again ! See comments in chrp_pci.c
-	 */
-	struct pci_controller* hose =
-		(struct pci_controller *)pdev->sysdata;
-	if (hose && res->flags & IORESOURCE_MEM)
-		return res->start - hose->pci_mem_offset;
-	/* We may want to do something with IOs here... */
-	return res->start;
-}
-
-
-static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
-					       resource_size_t *offset,
-					       enum pci_mmap_state mmap_state)
-{
-	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
-	unsigned long io_offset = 0;
-	int i, res_bit;
-
-	if (hose == 0)
-		return NULL;		/* should never happen */
-
-	/* If memory, add on the PCI bridge address offset */
-	if (mmap_state == pci_mmap_mem) {
-#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
-		*offset += hose->pci_mem_offset;
-#endif
-		res_bit = IORESOURCE_MEM;
-	} else {
-		io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE;
-		*offset += io_offset;
-		res_bit = IORESOURCE_IO;
-	}
-
-	/*
-	 * Check that the offset requested corresponds to one of the
-	 * resources of the device.
-	 */
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-		struct resource *rp = &dev->resource[i];
-		int flags = rp->flags;
-
-		/* treat ROM as memory (should be already) */
-		if (i == PCI_ROM_RESOURCE)
-			flags |= IORESOURCE_MEM;
-
-		/* Active and same type? */
-		if ((flags & res_bit) == 0)
-			continue;
-
-		/* In the range of this resource? */
-		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
-			continue;
-
-		/* found it! construct the final physical address */
-		if (mmap_state == pci_mmap_io)
-			*offset += hose->io_base_phys - io_offset;
-		return rp;
-	}
-
-	return NULL;
-}
-
-/*
- * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
- * device mapping.
- */
-static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
-				      pgprot_t protection,
-				      enum pci_mmap_state mmap_state,
-				      int write_combine)
-{
-	unsigned long prot = pgprot_val(protection);
-
-	/* Write combine is always 0 on non-memory space mappings. On
-	 * memory space, if the user didn't pass 1, we check for a
-	 * "prefetchable" resource. This is a bit hackish, but we use
-	 * this to workaround the inability of /sysfs to provide a write
-	 * combine bit
-	 */
-	if (mmap_state != pci_mmap_mem)
-		write_combine = 0;
-	else if (write_combine == 0) {
-		if (rp->flags & IORESOURCE_PREFETCH)
-			write_combine = 1;
-	}
-
-	/* XXX would be nice to have a way to ask for write-through */
-	prot |= _PAGE_NO_CACHE;
-	if (write_combine)
-		prot &= ~_PAGE_GUARDED;
-	else
-		prot |= _PAGE_GUARDED;
-
-	return __pgprot(prot);
-}
-
-/*
- * This one is used by /dev/mem and fbdev who have no clue about the
- * PCI device, it tries to find the PCI device first and calls the
- * above routine
- */
-pgprot_t pci_phys_mem_access_prot(struct file *file,
-				  unsigned long pfn,
-				  unsigned long size,
-				  pgprot_t protection)
-{
-	struct pci_dev *pdev = NULL;
-	struct resource *found = NULL;
-	unsigned long prot = pgprot_val(protection);
-	unsigned long offset = pfn << PAGE_SHIFT;
-	int i;
-
-	if (page_is_ram(pfn))
-		return __pgprot(prot);
-
-	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-
-	for_each_pci_dev(pdev) {
-		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-			struct resource *rp = &pdev->resource[i];
-			int flags = rp->flags;
-
-			/* Active and same type? */
-			if ((flags & IORESOURCE_MEM) == 0)
-				continue;
-			/* In the range of this resource? */
-			if (offset < (rp->start & PAGE_MASK) ||
-			    offset > rp->end)
-				continue;
-			found = rp;
-			break;
-		}
-		if (found)
-			break;
-	}
-	if (found) {
-		if (found->flags & IORESOURCE_PREFETCH)
-			prot &= ~_PAGE_GUARDED;
-		pci_dev_put(pdev);
-	}
-
-	DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
-
-	return __pgprot(prot);
-}
-
-
-/*
- * Perform the actual remap of the pages for a PCI device mapping, as
- * appropriate for this architecture.  The region in the process to map
- * is described by vm_start and vm_end members of VMA, the base physical
- * address is found in vm_pgoff.
- * The pci device structure is provided so that architectures may make mapping
- * decisions on a per-device or per-bus basis.
- *
- * Returns a negative error code on failure, zero on success.
- */
-int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-			enum pci_mmap_state mmap_state,
-			int write_combine)
-{
-	resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
-	struct resource *rp;
-	int ret;
-
-	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
-	if (rp == NULL)
-		return -EINVAL;
-
-	vma->vm_pgoff = offset >> PAGE_SHIFT;
-	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
-						  vma->vm_page_prot,
-						  mmap_state, write_combine);
-
-	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
-
-	return ret;
-}
-
-/* Obsolete functions. Should be removed once the symbios driver
- * is fixed
- */
-unsigned long
-phys_to_bus(unsigned long pa)
-{
-	struct pci_controller *hose;
-	int i;
-
-	for (hose = hose_head; hose; hose = hose->next) {
-		for (i = 0; i < 3; ++i) {
-			if (pa >= hose->mem_resources[i].start
-			    && pa <= hose->mem_resources[i].end) {
-				/*
-				 * XXX the hose->pci_mem_offset really
-				 * only applies to mem_resources[0].
-				 * We need a way to store an offset for
-				 * the others.  -- paulus
-				 */
-				if (i == 0)
-					pa -= hose->pci_mem_offset;
-				return pa;
-			}
-		}
-	}
-	/* hmmm, didn't find it */
-	return 0;
-}
-
-unsigned long
-pci_phys_to_bus(unsigned long pa, int busnr)
-{
-	struct pci_controller* hose = pci_bus_to_hose(busnr);
-	if (!hose)
-		return pa;
-	return pa - hose->pci_mem_offset;
-}
-
-unsigned long
-pci_bus_to_phys(unsigned int ba, int busnr)
-{
-	struct pci_controller* hose = pci_bus_to_hose(busnr);
-	if (!hose)
-		return ba;
-	return ba + hose->pci_mem_offset;
-}
-
 /* Provide information on locations of various I/O regions in physical
 /* Provide information on locations of various I/O regions in physical
  * memory.  Do this on a per-card basis so that we choose the right
  * memory.  Do this on a per-card basis so that we choose the right
  * root bridge.
  * root bridge.
@@ -1814,62 +1385,11 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
 	return result;
 	return result;
 }
 }
 
 
-void pci_resource_to_user(const struct pci_dev *dev, int bar,
-			  const struct resource *rsrc,
-			  resource_size_t *start, resource_size_t *end)
-{
-	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
-	resource_size_t offset = 0;
-
-	if (hose == NULL)
-		return;
-
-	if (rsrc->flags & IORESOURCE_IO)
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-
-	/* We pass a fully fixed up address to userland for MMIO instead of
-	 * a BAR value because X is lame and expects to be able to use that
-	 * to pass to /dev/mem !
-	 *
-	 * That means that we'll have potentially 64 bits values where some
-	 * userland apps only expect 32 (like X itself since it thinks only
-	 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
-	 * 32 bits CHRPs :-(
-	 *
-	 * Hopefully, the sysfs insterface is immune to that gunk. Once X
-	 * has been fixed (and the fix spread enough), we can re-enable the
-	 * 2 lines below and pass down a BAR value to userland. In that case
-	 * we'll also have to re-enable the matching code in
-	 * __pci_mmap_make_offset().
-	 *
-	 * BenH.
-	 */
-#if 0
-	else if (rsrc->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-#endif
-
-	*start = rsrc->start - offset;
-	*end = rsrc->end - offset;
-}
-
-void __init pci_init_resource(struct resource *res, resource_size_t start,
-			      resource_size_t end, int flags, char *name)
-{
-	res->start = start;
-	res->end = end;
-	res->flags = flags;
-	res->name = name;
-	res->parent = NULL;
-	res->sibling = NULL;
-	res->child = NULL;
-}
-
 unsigned long pci_address_to_pio(phys_addr_t address)
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
 {
-	struct pci_controller* hose = hose_head;
+	struct pci_controller *hose, *tmp;
 
 
-	for (; hose; hose = hose->next) {
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		unsigned int size = hose->io_resource.end -
 		unsigned int size = hose->io_resource.end -
 			hose->io_resource.start + 1;
 			hose->io_resource.start + 1;
 		if (address >= hose->io_base_phys &&
 		if (address >= hose->io_base_phys &&

+ 126 - 624
arch/powerpc/kernel/pci_64.c

@@ -22,6 +22,7 @@
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
 #include <linux/syscalls.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
+#include <linux/vmalloc.h>
 
 
 #include <asm/processor.h>
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <asm/io.h>
@@ -41,35 +42,23 @@
 
 
 unsigned long pci_probe_only = 1;
 unsigned long pci_probe_only = 1;
 int pci_assign_all_buses = 0;
 int pci_assign_all_buses = 0;
-static int pci_initial_scan_done;
 
 
 static void fixup_resource(struct resource *res, struct pci_dev *dev);
 static void fixup_resource(struct resource *res, struct pci_dev *dev);
 static void do_bus_setup(struct pci_bus *bus);
 static void do_bus_setup(struct pci_bus *bus);
-static void phbs_remap_io(void);
 
 
 /* pci_io_base -- the base address from which io bars are offsets.
 /* 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),
  * This is the lowest I/O base address (so bar values are always positive),
  * and it *must* be the start of ISA space if an ISA bus exists because
  * and it *must* be the start of ISA space if an ISA bus exists because
- * ISA drivers use hard coded offsets.  If no ISA bus exists a dummy
- * page is mapped and isa_io_limit prevents access to it.
+ * ISA drivers use hard coded offsets.  If no ISA bus exists nothing
+ * is mapped on the first 64K of IO space
  */
  */
-unsigned long isa_io_base;	/* NULL if no ISA bus */
-EXPORT_SYMBOL(isa_io_base);
-unsigned long pci_io_base;
+unsigned long pci_io_base = ISA_IO_BASE;
 EXPORT_SYMBOL(pci_io_base);
 EXPORT_SYMBOL(pci_io_base);
 
 
-void iSeries_pcibios_init(void);
-
 LIST_HEAD(hose_list);
 LIST_HEAD(hose_list);
 
 
 static struct dma_mapping_ops *pci_dma_ops;
 static struct dma_mapping_ops *pci_dma_ops;
 
 
-int global_phb_number;		/* Global phb counter */
-
-/* Cached ISA bridge dev. */
-struct pci_dev *ppc64_isabridge_dev = NULL;
-EXPORT_SYMBOL_GPL(ppc64_isabridge_dev);
-
 void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
 void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
 {
 {
 	pci_dma_ops = dma_ops;
 	pci_dma_ops = dma_ops;
@@ -100,7 +89,7 @@ void  pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region
 		return;
 		return;
 
 
 	if (res->flags & IORESOURCE_IO)
 	if (res->flags & IORESOURCE_IO)
-	        offset = (unsigned long)hose->io_base_virt - pci_io_base;
+	        offset = (unsigned long)hose->io_base_virt - _IO_BASE;
 
 
 	if (res->flags & IORESOURCE_MEM)
 	if (res->flags & IORESOURCE_MEM)
 		offset = hose->pci_mem_offset;
 		offset = hose->pci_mem_offset;
@@ -119,7 +108,7 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 		return;
 		return;
 
 
 	if (res->flags & IORESOURCE_IO)
 	if (res->flags & IORESOURCE_IO)
-	        offset = (unsigned long)hose->io_base_virt - pci_io_base;
+	        offset = (unsigned long)hose->io_base_virt - _IO_BASE;
 
 
 	if (res->flags & IORESOURCE_MEM)
 	if (res->flags & IORESOURCE_MEM)
 		offset = hose->pci_mem_offset;
 		offset = hose->pci_mem_offset;
@@ -156,7 +145,7 @@ void pcibios_align_resource(void *data, struct resource *res,
 
 
 	if (res->flags & IORESOURCE_IO) {
 	if (res->flags & IORESOURCE_IO) {
 	        unsigned long offset = (unsigned long)hose->io_base_virt -
 	        unsigned long offset = (unsigned long)hose->io_base_virt -
-					pci_io_base;
+					_IO_BASE;
 		/* Make sure we start at our min on all hoses */
 		/* Make sure we start at our min on all hoses */
 		if (start - offset < PCIBIOS_MIN_IO)
 		if (start - offset < PCIBIOS_MIN_IO)
 			start = PCIBIOS_MIN_IO + offset;
 			start = PCIBIOS_MIN_IO + offset;
@@ -180,55 +169,6 @@ void pcibios_align_resource(void *data, struct resource *res,
 	res->start = start;
 	res->start = start;
 }
 }
 
 
-static DEFINE_SPINLOCK(hose_spinlock);
-
-/*
- * 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);
-}
-
-struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
-{
-	struct pci_controller *phb;
-
-	if (mem_init_done)
-		phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
-	else
-		phb = alloc_bootmem(sizeof (struct pci_controller));
-	if (phb == NULL)
-		return NULL;
-	pci_setup_pci_controller(phb);
-	phb->arch_data = dev;
-	phb->is_dynamic = mem_init_done;
-	if (dev) {
-		int nid = of_node_to_nid(dev);
-
-		if (nid < 0 || !node_online(nid))
-			nid = -1;
-
-		PHB_SET_NODE(phb, nid);
-	}
-	return phb;
-}
-
-void pcibios_free_controller(struct pci_controller *phb)
-{
-	spin_lock(&hose_spinlock);
-	list_del(&phb->list_node);
-	spin_unlock(&hose_spinlock);
-
-	if (phb->is_dynamic)
-		kfree(phb);
-}
-
 void __devinit pcibios_claim_one_bus(struct pci_bus *b)
 void __devinit pcibios_claim_one_bus(struct pci_bus *b)
 {
 {
 	struct pci_dev *dev;
 	struct pci_dev *dev;
@@ -291,7 +231,6 @@ static unsigned int pci_parse_of_flags(u32 addr0)
 	return flags;
 	return flags;
 }
 }
 
 
-#define GET_64BIT(prop, i)	((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1])
 
 
 static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
 static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
 {
 {
@@ -310,8 +249,8 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
 		flags = pci_parse_of_flags(addrs[0]);
 		flags = pci_parse_of_flags(addrs[0]);
 		if (!flags)
 		if (!flags)
 			continue;
 			continue;
-		base = GET_64BIT(addrs, 1);
-		size = GET_64BIT(addrs, 3);
+		base = of_read_number(&addrs[1], 2);
+		size = of_read_number(&addrs[3], 2);
 		if (!size)
 		if (!size)
 			continue;
 			continue;
 		i = addrs[0] & 0xff;
 		i = addrs[0] & 0xff;
@@ -477,7 +416,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
 	i = 1;
 	i = 1;
 	for (; len >= 32; len -= 32, ranges += 8) {
 	for (; len >= 32; len -= 32, ranges += 8) {
 		flags = pci_parse_of_flags(ranges[0]);
 		flags = pci_parse_of_flags(ranges[0]);
-		size = GET_64BIT(ranges, 6);
+		size = of_read_number(&ranges[6], 2);
 		if (flags == 0 || size == 0)
 		if (flags == 0 || size == 0)
 			continue;
 			continue;
 		if (flags & IORESOURCE_IO) {
 		if (flags & IORESOURCE_IO) {
@@ -496,7 +435,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
 			res = bus->resource[i];
 			res = bus->resource[i];
 			++i;
 			++i;
 		}
 		}
-		res->start = GET_64BIT(ranges, 1);
+		res->start = of_read_number(&ranges[1], 2);
 		res->end = res->start + size - 1;
 		res->end = res->start + size - 1;
 		res->flags = flags;
 		res->flags = flags;
 		fixup_resource(res, dev);
 		fixup_resource(res, dev);
@@ -535,10 +474,16 @@ void __devinit scan_phb(struct pci_controller *hose)
 	bus->secondary = hose->first_busno;
 	bus->secondary = hose->first_busno;
 	hose->bus = bus;
 	hose->bus = bus;
 
 
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		pcibios_map_io_space(bus);
+
 	bus->resource[0] = res = &hose->io_resource;
 	bus->resource[0] = res = &hose->io_resource;
-	if (res->flags && request_resource(&ioport_resource, res))
+	if (res->flags && request_resource(&ioport_resource, res)) {
 		printk(KERN_ERR "Failed to request PCI IO region "
 		printk(KERN_ERR "Failed to request PCI IO region "
 		       "on PCI domain %04x\n", hose->global_number);
 		       "on PCI domain %04x\n", hose->global_number);
+		DBG("res->start = 0x%016lx, res->end = 0x%016lx\n",
+		    res->start, res->end);
+	}
 
 
 	for (i = 0; i < 3; ++i) {
 	for (i = 0; i < 3; ++i) {
 		res = &hose->mem_resources[i];
 		res = &hose->mem_resources[i];
@@ -596,17 +541,6 @@ static int __init pcibios_init(void)
 	if (ppc_md.pcibios_fixup)
 	if (ppc_md.pcibios_fixup)
 		ppc_md.pcibios_fixup();
 		ppc_md.pcibios_fixup();
 
 
-	/* Cache the location of the ISA bridge (if we have one) */
-	ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
-	if (ppc64_isabridge_dev != NULL)
-		printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
-
-	if (!firmware_has_feature(FW_FEATURE_ISERIES))
-		/* map in PCI I/O space */
-		phbs_remap_io();
-
-	pci_initial_scan_done = 1;
-
 	printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
 	printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
 
 
 	return 0;
 	return 0;
@@ -614,11 +548,6 @@ static int __init pcibios_init(void)
 
 
 subsys_initcall(pcibios_init);
 subsys_initcall(pcibios_init);
 
 
-char __init *pcibios_setup(char *str)
-{
-	return str;
-}
-
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 {
 	u16 cmd, oldcmd;
 	u16 cmd, oldcmd;
@@ -649,22 +578,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return 0;
 	return 0;
 }
 }
 
 
-/*
- * Return the domain number for this bus.
- */
-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);
-
-		return hose->global_number;
-	}
-}
-
-EXPORT_SYMBOL(pci_domain_nr);
-
 /* Decide whether to display the domain number in /proc */
 /* Decide whether to display the domain number in /proc */
 int pci_proc_domain(struct pci_bus *bus)
 int pci_proc_domain(struct pci_bus *bus)
 {
 {
@@ -676,281 +589,6 @@ int pci_proc_domain(struct pci_bus *bus)
 	}
 	}
 }
 }
 
 
-/*
- * Platform support for /proc/bus/pci/X/Y mmap()s,
- * modelled on the sparc64 implementation by Dave Miller.
- *  -- paulus.
- */
-
-/*
- * Adjust vm_pgoff of VMA such that it is the physical page offset
- * corresponding to the 32-bit pci bus offset for DEV requested by the user.
- *
- * Basically, the user finds the base address for his device which he wishes
- * to mmap.  They read the 32-bit value from the config space base register,
- * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
- * offset parameter of mmap on /proc/bus/pci/XXX for that device.
- *
- * Returns negative error code on failure, zero on success.
- */
-static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
-					       resource_size_t *offset,
-					       enum pci_mmap_state mmap_state)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	unsigned long io_offset = 0;
-	int i, res_bit;
-
-	if (hose == 0)
-		return NULL;		/* should never happen */
-
-	/* If memory, add on the PCI bridge address offset */
-	if (mmap_state == pci_mmap_mem) {
-#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
-		*offset += hose->pci_mem_offset;
-#endif
-		res_bit = IORESOURCE_MEM;
-	} else {
-		io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
-		*offset += io_offset;
-		res_bit = IORESOURCE_IO;
-	}
-
-	/*
-	 * Check that the offset requested corresponds to one of the
-	 * resources of the device.
-	 */
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-		struct resource *rp = &dev->resource[i];
-		int flags = rp->flags;
-
-		/* treat ROM as memory (should be already) */
-		if (i == PCI_ROM_RESOURCE)
-			flags |= IORESOURCE_MEM;
-
-		/* Active and same type? */
-		if ((flags & res_bit) == 0)
-			continue;
-
-		/* In the range of this resource? */
-		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
-			continue;
-
-		/* found it! construct the final physical address */
-		if (mmap_state == pci_mmap_io)
-		       	*offset += hose->io_base_phys - io_offset;
-		return rp;
-	}
-
-	return NULL;
-}
-
-/*
- * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
- * device mapping.
- */
-static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
-				      pgprot_t protection,
-				      enum pci_mmap_state mmap_state,
-				      int write_combine)
-{
-	unsigned long prot = pgprot_val(protection);
-
-	/* Write combine is always 0 on non-memory space mappings. On
-	 * memory space, if the user didn't pass 1, we check for a
-	 * "prefetchable" resource. This is a bit hackish, but we use
-	 * this to workaround the inability of /sysfs to provide a write
-	 * combine bit
-	 */
-	if (mmap_state != pci_mmap_mem)
-		write_combine = 0;
-	else if (write_combine == 0) {
-		if (rp->flags & IORESOURCE_PREFETCH)
-			write_combine = 1;
-	}
-
-	/* XXX would be nice to have a way to ask for write-through */
-	prot |= _PAGE_NO_CACHE;
-	if (write_combine)
-		prot &= ~_PAGE_GUARDED;
-	else
-		prot |= _PAGE_GUARDED;
-
-	return __pgprot(prot);
-}
-
-/*
- * This one is used by /dev/mem and fbdev who have no clue about the
- * PCI device, it tries to find the PCI device first and calls the
- * above routine
- */
-pgprot_t pci_phys_mem_access_prot(struct file *file,
-				  unsigned long pfn,
-				  unsigned long size,
-				  pgprot_t protection)
-{
-	struct pci_dev *pdev = NULL;
-	struct resource *found = NULL;
-	unsigned long prot = pgprot_val(protection);
-	unsigned long offset = pfn << PAGE_SHIFT;
-	int i;
-
-	if (page_is_ram(pfn))
-		return __pgprot(prot);
-
-	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-
-	for_each_pci_dev(pdev) {
-		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-			struct resource *rp = &pdev->resource[i];
-			int flags = rp->flags;
-
-			/* Active and same type? */
-			if ((flags & IORESOURCE_MEM) == 0)
-				continue;
-			/* In the range of this resource? */
-			if (offset < (rp->start & PAGE_MASK) ||
-			    offset > rp->end)
-				continue;
-			found = rp;
-			break;
-		}
-		if (found)
-			break;
-	}
-	if (found) {
-		if (found->flags & IORESOURCE_PREFETCH)
-			prot &= ~_PAGE_GUARDED;
-		pci_dev_put(pdev);
-	}
-
-	DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
-
-	return __pgprot(prot);
-}
-
-
-/*
- * Perform the actual remap of the pages for a PCI device mapping, as
- * appropriate for this architecture.  The region in the process to map
- * is described by vm_start and vm_end members of VMA, the base physical
- * address is found in vm_pgoff.
- * The pci device structure is provided so that architectures may make mapping
- * decisions on a per-device or per-bus basis.
- *
- * Returns a negative error code on failure, zero on success.
- */
-int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-			enum pci_mmap_state mmap_state, int write_combine)
-{
-	resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
-	struct resource *rp;
-	int ret;
-
-	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
-	if (rp == NULL)
-		return -EINVAL;
-
-	vma->vm_pgoff = offset >> PAGE_SHIFT;
-	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
-						  vma->vm_page_prot,
-						  mmap_state, write_combine);
-
-	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
-
-	return ret;
-}
-
-static ssize_t pci_show_devspec(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct pci_dev *pdev;
-	struct device_node *np;
-
-	pdev = to_pci_dev (dev);
-	np = pci_device_to_OF_node(pdev);
-	if (np == NULL || np->full_name == NULL)
-		return 0;
-	return sprintf(buf, "%s", np->full_name);
-}
-static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-
-void pcibios_add_platform_entries(struct pci_dev *pdev)
-{
-	device_create_file(&pdev->dev, &dev_attr_devspec);
-}
-
-#define ISA_SPACE_MASK 0x1
-#define ISA_SPACE_IO 0x1
-
-static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
-				      unsigned long phb_io_base_phys,
-				      void __iomem * phb_io_base_virt)
-{
-	/* Remove these asap */
-
-	struct pci_address {
-		u32 a_hi;
-		u32 a_mid;
-		u32 a_lo;
-	};
-
-	struct isa_address {
-		u32 a_hi;
-		u32 a_lo;
-	};
-
-	struct isa_range {
-		struct isa_address isa_addr;
-		struct pci_address pci_addr;
-		unsigned int size;
-	};
-
-	const struct isa_range *range;
-	unsigned long pci_addr;
-	unsigned int isa_addr;
-	unsigned int size;
-	int rlen = 0;
-
-	range = of_get_property(isa_node, "ranges", &rlen);
-	if (range == NULL || (rlen < sizeof(struct isa_range))) {
-		printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
-		       "mapping 64k\n");
-		__ioremap_explicit(phb_io_base_phys,
-				   (unsigned long)phb_io_base_virt,
-				   0x10000, _PAGE_NO_CACHE | _PAGE_GUARDED);
-		return;	
-	}
-	
-	/* From "ISA Binding to 1275"
-	 * The ranges property is laid out as an array of elements,
-	 * each of which comprises:
-	 *   cells 0 - 1:	an ISA address
-	 *   cells 2 - 4:	a PCI address 
-	 *			(size depending on dev->n_addr_cells)
-	 *   cell 5:		the size of the range
-	 */
-	if ((range->isa_addr.a_hi && ISA_SPACE_MASK) == ISA_SPACE_IO) {
-		isa_addr = range->isa_addr.a_lo;
-		pci_addr = (unsigned long) range->pci_addr.a_mid << 32 | 
-			range->pci_addr.a_lo;
-
-		/* Assume these are both zero */
-		if ((pci_addr != 0) || (isa_addr != 0)) {
-			printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
-					__FUNCTION__);
-			return;
-		}
-		
-		size = PAGE_ALIGN(range->size);
-
-		__ioremap_explicit(phb_io_base_phys, 
-				   (unsigned long) phb_io_base_virt, 
-				   size, _PAGE_NO_CACHE | _PAGE_GUARDED);
-	}
-}
-
 void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
 void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
 					    struct device_node *dev, int prim)
 					    struct device_node *dev, int prim)
 {
 {
@@ -1045,155 +683,122 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
 	}
 	}
 }
 }
 
 
-void __devinit pci_setup_phb_io(struct pci_controller *hose, int primary)
+#ifdef CONFIG_HOTPLUG
+
+int pcibios_unmap_io_space(struct pci_bus *bus)
 {
 {
-	unsigned long size = hose->pci_io_size;
-	unsigned long io_virt_offset;
-	struct resource *res;
-	struct device_node *isa_dn;
+	struct pci_controller *hose;
 
 
-	if (size == 0)
-		return;
+	WARN_ON(bus == NULL);
 
 
-	hose->io_base_virt = reserve_phb_iospace(size);
-	DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
-		hose->global_number, hose->io_base_phys,
-		(unsigned long) hose->io_base_virt);
-
-	if (primary) {
-		pci_io_base = (unsigned long)hose->io_base_virt;
-		isa_dn = of_find_node_by_type(NULL, "isa");
-		if (isa_dn) {
-			isa_io_base = pci_io_base;
-			pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys,
-						hose->io_base_virt);
-			of_node_put(isa_dn);
-		}
-	}
+	/* If this is not a PHB, we only flush the hash table over
+	 * the area mapped by this bridge. We don't play with the PTE
+	 * mappings since we might have to deal with sub-page alignemnts
+	 * so flushing the hash table is the only sane way to make sure
+	 * that no hash entries are covering that removed bridge area
+	 * while still allowing other busses overlapping those pages
+	 */
+	if (bus->self) {
+		struct resource *res = bus->resource[0];
 
 
-	io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
-	res = &hose->io_resource;
-	res->start += io_virt_offset;
-	res->end += io_virt_offset;
+		DBG("IO unmapping for PCI-PCI bridge %s\n",
+		    pci_name(bus->self));
 
 
-	/* If this is called after the initial PCI scan, then we need to
-	 * proceed to IO mappings now
-	 */
-	if (pci_initial_scan_done)
-		__ioremap_explicit(hose->io_base_phys,
-				   (unsigned long)hose->io_base_virt,
-				   hose->pci_io_size,
-				   _PAGE_NO_CACHE | _PAGE_GUARDED);
-}
+		__flush_hash_table_range(&init_mm, res->start + _IO_BASE,
+					 res->end - res->start + 1);
+		return 0;
+	}
 
 
-void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose,
-					int primary)
-{
-	unsigned long size = hose->pci_io_size;
-	unsigned long io_virt_offset;
-	struct resource *res;
+	/* Get the host bridge */
+	hose = pci_bus_to_host(bus);
 
 
-	if (size == 0)
-		return;
+	/* Check if we have IOs allocated */
+	if (hose->io_base_alloc == 0)
+		return 0;
 
 
-	hose->io_base_virt = __ioremap(hose->io_base_phys, size,
-					_PAGE_NO_CACHE | _PAGE_GUARDED);
-	DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
-		hose->global_number, hose->io_base_phys,
-		(unsigned long) hose->io_base_virt);
+	DBG("IO unmapping for PHB %s\n",
+	    ((struct device_node *)hose->arch_data)->full_name);
+	DBG("  alloc=0x%p\n", hose->io_base_alloc);
 
 
-	if (primary)
-		pci_io_base = (unsigned long)hose->io_base_virt;
+	/* This is a PHB, we fully unmap the IO area */
+	vunmap(hose->io_base_alloc);
 
 
-	io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
-	res = &hose->io_resource;
-	res->start += io_virt_offset;
-	res->end += io_virt_offset;
+	return 0;
 }
 }
+EXPORT_SYMBOL_GPL(pcibios_unmap_io_space);
 
 
+#endif /* CONFIG_HOTPLUG */
 
 
-static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
-				unsigned long *start_virt, unsigned long *size)
+int __devinit pcibios_map_io_space(struct pci_bus *bus)
 {
 {
-	struct pci_controller *hose = pci_bus_to_host(bus);
-	struct resource *res;
-
-	if (bus->self)
-		res = bus->resource[0];
-	else
-		/* Root Bus */
-		res = &hose->io_resource;
-
-	if (res->end == 0 && res->start == 0)
-		return 1;
+	struct vm_struct *area;
+	unsigned long phys_page;
+	unsigned long size_page;
+	unsigned long io_virt_offset;
+	struct pci_controller *hose;
 
 
-	*start_virt = pci_io_base + res->start;
-	*start_phys = *start_virt + hose->io_base_phys
-		- (unsigned long) hose->io_base_virt;
+	WARN_ON(bus == NULL);
 
 
-	if (res->end > res->start)
-		*size = res->end - res->start + 1;
-	else {
-		printk("%s(): unexpected region 0x%lx->0x%lx\n",
-		       __FUNCTION__, res->start, res->end);
-		return 1;
+	/* If this not a PHB, nothing to do, page tables still exist and
+	 * thus HPTEs will be faulted in when needed
+	 */
+	if (bus->self) {
+		DBG("IO mapping for PCI-PCI bridge %s\n",
+		    pci_name(bus->self));
+		DBG("  virt=0x%016lx...0x%016lx\n",
+		    bus->resource[0]->start + _IO_BASE,
+		    bus->resource[0]->end + _IO_BASE);
+		return 0;
 	}
 	}
 
 
-	return 0;
-}
-
-int unmap_bus_range(struct pci_bus *bus)
-{
-	unsigned long start_phys;
-	unsigned long start_virt;
-	unsigned long size;
+	/* Get the host bridge */
+	hose = pci_bus_to_host(bus);
+	phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
+	size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
 
 
-	if (!bus) {
-		printk(KERN_ERR "%s() expected bus\n", __FUNCTION__);
-		return 1;
-	}
-	
-	if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
-		return 1;
-	if (__iounmap_explicit((void __iomem *) start_virt, size))
-		return 1;
-
-	return 0;
-}
-EXPORT_SYMBOL(unmap_bus_range);
+	/* Make sure IO area address is clear */
+	hose->io_base_alloc = NULL;
 
 
-int remap_bus_range(struct pci_bus *bus)
-{
-	unsigned long start_phys;
-	unsigned long start_virt;
-	unsigned long size;
+	/* If there's no IO to map on that bus, get away too */
+	if (hose->pci_io_size == 0 || hose->io_base_phys == 0)
+		return 0;
 
 
-	if (!bus) {
-		printk(KERN_ERR "%s() expected bus\n", __FUNCTION__);
-		return 1;
-	}
-	
-	
-	if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
-		return 1;
-	if (start_phys == 0)
-		return 1;
-	printk(KERN_DEBUG "mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size);
-	if (__ioremap_explicit(start_phys, start_virt, size,
-			       _PAGE_NO_CACHE | _PAGE_GUARDED))
-		return 1;
+	/* Let's allocate some IO space for that guy. We don't pass
+	 * VM_IOREMAP because we don't care about alignment tricks that
+	 * the core does in that case. Maybe we should due to stupid card
+	 * with incomplete address decoding but I'd rather not deal with
+	 * those outside of the reserved 64K legacy region.
+	 */
+	area = __get_vm_area(size_page, 0, PHB_IO_BASE, PHB_IO_END);
+	if (area == NULL)
+		return -ENOMEM;
+	hose->io_base_alloc = area->addr;
+	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("  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",
+	    hose->pci_io_size, size_page);
+
+	/* Establish the mapping */
+	if (__ioremap_at(phys_page, area->addr, size_page,
+			 _PAGE_NO_CACHE | _PAGE_GUARDED) == NULL)
+		return -ENOMEM;
+
+	/* Fixup hose IO resource */
+	io_virt_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+	hose->io_resource.start += io_virt_offset;
+	hose->io_resource.end += io_virt_offset;
+
+	DBG("  hose->io_resource=0x%016lx...0x%016lx\n",
+	    hose->io_resource.start, hose->io_resource.end);
 
 
 	return 0;
 	return 0;
 }
 }
-EXPORT_SYMBOL(remap_bus_range);
-
-static void phbs_remap_io(void)
-{
-	struct pci_controller *hose, *tmp;
-
-	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
-		remap_bus_range(hose->bus);
-}
+EXPORT_SYMBOL_GPL(pcibios_map_io_space);
 
 
 static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 {
 {
@@ -1201,8 +806,7 @@ static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 	unsigned long offset;
 	unsigned long offset;
 
 
 	if (res->flags & IORESOURCE_IO) {
 	if (res->flags & IORESOURCE_IO) {
-		offset = (unsigned long)hose->io_base_virt - pci_io_base;
-
+		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
 		res->start += offset;
 		res->start += offset;
 		res->end += offset;
 		res->end += offset;
 	} else if (res->flags & IORESOURCE_MEM) {
 	} else if (res->flags & IORESOURCE_MEM) {
@@ -1217,9 +821,20 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
 	/* Update device resources.  */
 	/* Update device resources.  */
 	int i;
 	int i;
 
 
-	for (i = 0; i < PCI_NUM_RESOURCES; i++)
-		if (dev->resource[i].flags)
-			fixup_resource(&dev->resource[i], dev);
+	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);
 EXPORT_SYMBOL(pcibios_fixup_device_resources);
 
 
@@ -1289,119 +904,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 }
 }
 EXPORT_SYMBOL(pcibios_fixup_bus);
 EXPORT_SYMBOL(pcibios_fixup_bus);
 
 
-/*
- * Reads the interrupt pin to determine if interrupt is use by card.
- * If the interrupt is used, then gets the interrupt line from the 
- * openfirmware and sets it in the pci_dev and pci_config line.
- */
-int pci_read_irq_line(struct pci_dev *pci_dev)
-{
-	struct of_irq oirq;
-	unsigned int virq;
-
-	DBG("Try to map irq for %s...\n", pci_name(pci_dev));
-
-#ifdef DEBUG
-	memset(&oirq, 0xff, sizeof(oirq));
-#endif
-	/* Try to get a mapping from the device-tree */
-	if (of_irq_map_pci(pci_dev, &oirq)) {
-		u8 line, pin;
-
-		/* If that fails, lets fallback to what is in the config
-		 * space and map that through the default controller. We
-		 * also set the type to level low since that's what PCI
-		 * interrupts are. If your platform does differently, then
-		 * either provide a proper interrupt tree or don't use this
-		 * function.
-		 */
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
-			return -1;
-		if (pin == 0)
-			return -1;
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
-		    line == 0xff) {
-			return -1;
-		}
-		DBG(" -> no map ! Using irq line %d from PCI config\n", line);
-
-		virq = irq_create_mapping(NULL, line);
-		if (virq != NO_IRQ)
-			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
-	} else {
-		DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
-		    oirq.size, oirq.specifier[0], oirq.specifier[1],
-		    oirq.controller->full_name);
-
-		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
-					     oirq.size);
-	}
-	if(virq == NO_IRQ) {
-		DBG(" -> failed to map !\n");
-		return -1;
-	}
-
-	DBG(" -> mapped to linux irq %d\n", virq);
-
-	pci_dev->irq = virq;
-
-	return 0;
-}
-EXPORT_SYMBOL(pci_read_irq_line);
-
-void pci_resource_to_user(const struct pci_dev *dev, int bar,
-			  const struct resource *rsrc,
-			  resource_size_t *start, resource_size_t *end)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	resource_size_t offset = 0;
-
-	if (hose == NULL)
-		return;
-
-	if (rsrc->flags & IORESOURCE_IO)
-		offset = (unsigned long)hose->io_base_virt - pci_io_base;
-
-	/* We pass a fully fixed up address to userland for MMIO instead of
-	 * a BAR value because X is lame and expects to be able to use that
-	 * to pass to /dev/mem !
-	 *
-	 * That means that we'll have potentially 64 bits values where some
-	 * userland apps only expect 32 (like X itself since it thinks only
-	 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
-	 * 32 bits CHRPs :-(
-	 *
-	 * Hopefully, the sysfs insterface is immune to that gunk. Once X
-	 * has been fixed (and the fix spread enough), we can re-enable the
-	 * 2 lines below and pass down a BAR value to userland. In that case
-	 * we'll also have to re-enable the matching code in
-	 * __pci_mmap_make_offset().
-	 *
-	 * BenH.
-	 */
-#if 0
-	else if (rsrc->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-#endif
-
-	*start = rsrc->start - offset;
-	*end = rsrc->end - offset;
-}
-
-struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
-{
-	if (!have_of)
-		return NULL;
-	while(node) {
-		struct pci_controller *hose, *tmp;
-		list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
-			if (hose->arch_data == node)
-				return hose;
-		node = node->parent;
-	}
-	return NULL;
-}
-
 unsigned long pci_address_to_pio(phys_addr_t address)
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
 {
 	struct pci_controller *hose, *tmp;
 	struct pci_controller *hose, *tmp;
@@ -1410,7 +912,7 @@ unsigned long pci_address_to_pio(phys_addr_t address)
 		if (address >= hose->io_base_phys &&
 		if (address >= hose->io_base_phys &&
 		    address < (hose->io_base_phys + hose->pci_io_size)) {
 		    address < (hose->io_base_phys + hose->pci_io_size)) {
 			unsigned long base =
 			unsigned long base =
-				(unsigned long)hose->io_base_virt - pci_io_base;
+				(unsigned long)hose->io_base_virt - _IO_BASE;
 			return base + (address - hose->io_base_phys);
 			return base + (address - hose->io_base_phys);
 		}
 		}
 	}
 	}

+ 0 - 5
arch/powerpc/kernel/ppc_ksyms.c

@@ -67,7 +67,6 @@ EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
 EXPORT_SYMBOL(DMA_MODE_READ);
 EXPORT_SYMBOL(DMA_MODE_READ);
 EXPORT_SYMBOL(DMA_MODE_WRITE);
 EXPORT_SYMBOL(DMA_MODE_WRITE);
 
 
-EXPORT_SYMBOL(do_signal);
 EXPORT_SYMBOL(transfer_to_handler);
 EXPORT_SYMBOL(transfer_to_handler);
 EXPORT_SYMBOL(do_IRQ);
 EXPORT_SYMBOL(do_IRQ);
 EXPORT_SYMBOL(machine_check_exception);
 EXPORT_SYMBOL(machine_check_exception);
@@ -106,10 +105,6 @@ EXPORT_SYMBOL(isa_mem_base);
 EXPORT_SYMBOL(pci_dram_offset);
 EXPORT_SYMBOL(pci_dram_offset);
 EXPORT_SYMBOL(pci_alloc_consistent);
 EXPORT_SYMBOL(pci_alloc_consistent);
 EXPORT_SYMBOL(pci_free_consistent);
 EXPORT_SYMBOL(pci_free_consistent);
-EXPORT_SYMBOL(pci_bus_io_base);
-EXPORT_SYMBOL(pci_bus_io_base_phys);
-EXPORT_SYMBOL(pci_bus_mem_base_phys);
-EXPORT_SYMBOL(pci_bus_to_hose);
 #endif /* CONFIG_PCI */
 #endif /* CONFIG_PCI */
 
 
 EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(start_thread);

+ 7 - 7
arch/powerpc/kernel/process.c

@@ -219,22 +219,26 @@ void discard_lazy_cpu_state(void)
 }
 }
 #endif /* CONFIG_SMP */
 #endif /* CONFIG_SMP */
 
 
-#ifdef CONFIG_PPC_MERGE		/* XXX for now */
 int set_dabr(unsigned long dabr)
 int set_dabr(unsigned long dabr)
 {
 {
+#ifdef CONFIG_PPC_MERGE		/* XXX for now */
 	if (ppc_md.set_dabr)
 	if (ppc_md.set_dabr)
 		return ppc_md.set_dabr(dabr);
 		return ppc_md.set_dabr(dabr);
+#endif
 
 
+	/* XXX should we have a CPU_FTR_HAS_DABR ? */
+#if defined(CONFIG_PPC64) || defined(CONFIG_6xx)
 	mtspr(SPRN_DABR, dabr);
 	mtspr(SPRN_DABR, dabr);
+#endif
 	return 0;
 	return 0;
 }
 }
-#endif
 
 
 #ifdef CONFIG_PPC64
 #ifdef CONFIG_PPC64
 DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
 DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
-static DEFINE_PER_CPU(unsigned long, current_dabr);
 #endif
 #endif
 
 
+static DEFINE_PER_CPU(unsigned long, current_dabr);
+
 struct task_struct *__switch_to(struct task_struct *prev,
 struct task_struct *__switch_to(struct task_struct *prev,
 	struct task_struct *new)
 	struct task_struct *new)
 {
 {
@@ -299,12 +303,10 @@ struct task_struct *__switch_to(struct task_struct *prev,
 
 
 #endif /* CONFIG_SMP */
 #endif /* CONFIG_SMP */
 
 
-#ifdef CONFIG_PPC64	/* for now */
 	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
 	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
 		set_dabr(new->thread.dabr);
 		set_dabr(new->thread.dabr);
 		__get_cpu_var(current_dabr) = new->thread.dabr;
 		__get_cpu_var(current_dabr) = new->thread.dabr;
 	}
 	}
-#endif /* CONFIG_PPC64 */
 
 
 	new_thread = &new->thread;
 	new_thread = &new->thread;
 	old_thread = &current->thread;
 	old_thread = &current->thread;
@@ -473,12 +475,10 @@ void flush_thread(void)
 
 
 	discard_lazy_cpu_state();
 	discard_lazy_cpu_state();
 
 
-#ifdef CONFIG_PPC64	/* for now */
 	if (current->thread.dabr) {
 	if (current->thread.dabr) {
 		current->thread.dabr = 0;
 		current->thread.dabr = 0;
 		set_dabr(0);
 		set_dabr(0);
 	}
 	}
-#endif
 }
 }
 
 
 void
 void

+ 19 - 10
arch/powerpc/kernel/prom.c

@@ -52,6 +52,7 @@
 #include <asm/pSeries_reconfig.h>
 #include <asm/pSeries_reconfig.h>
 #include <asm/pci-bridge.h>
 #include <asm/pci-bridge.h>
 #include <asm/kexec.h>
 #include <asm/kexec.h>
+#include <asm/system.h>
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 #define DBG(fmt...) printk(KERN_ERR fmt)
 #define DBG(fmt...) printk(KERN_ERR fmt)
@@ -1005,7 +1006,7 @@ static void __init early_reserve_mem(void)
 
 
 void __init early_init_devtree(void *params)
 void __init early_init_devtree(void *params)
 {
 {
-	DBG(" -> early_init_devtree()\n");
+	DBG(" -> early_init_devtree(%p)\n", params);
 
 
 	/* Setup flat device-tree pointer */
 	/* Setup flat device-tree pointer */
 	initial_boot_params = params;
 	initial_boot_params = params;
@@ -1055,8 +1056,6 @@ void __init early_init_devtree(void *params)
 	DBG(" <- early_init_devtree()\n");
 	DBG(" <- early_init_devtree()\n");
 }
 }
 
 
-#undef printk
-
 int of_n_addr_cells(struct device_node* np)
 int of_n_addr_cells(struct device_node* np)
 {
 {
 	const int *ip;
 	const int *ip;
@@ -1375,8 +1374,17 @@ static void of_node_release(struct kref *kref)
 	struct device_node *node = kref_to_device_node(kref);
 	struct device_node *node = kref_to_device_node(kref);
 	struct property *prop = node->properties;
 	struct property *prop = node->properties;
 
 
-	if (!OF_IS_DYNAMIC(node))
+	/* We should never be releasing nodes that haven't been detached. */
+	if (!of_node_check_flag(node, OF_DETACHED)) {
+		printk("WARNING: Bad of_node_put() on %s\n", node->full_name);
+		dump_stack();
+		kref_init(&node->kref);
+		return;
+	}
+
+	if (!of_node_check_flag(node, OF_DYNAMIC))
 		return;
 		return;
+
 	while (prop) {
 	while (prop) {
 		struct property *next = prop->next;
 		struct property *next = prop->next;
 		kfree(prop->name);
 		kfree(prop->name);
@@ -1432,6 +1440,8 @@ void of_detach_node(const struct device_node *np)
 	write_lock(&devtree_lock);
 	write_lock(&devtree_lock);
 
 
 	parent = np->parent;
 	parent = np->parent;
+	if (!parent)
+		goto out_unlock;
 
 
 	if (allnodes == np)
 	if (allnodes == np)
 		allnodes = np->allnext;
 		allnodes = np->allnext;
@@ -1455,6 +1465,9 @@ void of_detach_node(const struct device_node *np)
 		prevsib->sibling = np->sibling;
 		prevsib->sibling = np->sibling;
 	}
 	}
 
 
+	of_node_set_flag(np, OF_DETACHED);
+
+out_unlock:
 	write_unlock(&devtree_lock);
 	write_unlock(&devtree_lock);
 }
 }
 
 
@@ -1716,22 +1729,18 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
 }
 }
 EXPORT_SYMBOL(of_get_cpu_node);
 EXPORT_SYMBOL(of_get_cpu_node);
 
 
-#ifdef DEBUG
+#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
 static struct debugfs_blob_wrapper flat_dt_blob;
 static struct debugfs_blob_wrapper flat_dt_blob;
 
 
 static int __init export_flat_device_tree(void)
 static int __init export_flat_device_tree(void)
 {
 {
 	struct dentry *d;
 	struct dentry *d;
 
 
-	d = debugfs_create_dir("powerpc", NULL);
-	if (!d)
-		return 1;
-
 	flat_dt_blob.data = initial_boot_params;
 	flat_dt_blob.data = initial_boot_params;
 	flat_dt_blob.size = initial_boot_params->totalsize;
 	flat_dt_blob.size = initial_boot_params->totalsize;
 
 
 	d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
 	d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
-				d, &flat_dt_blob);
+				powerpc_debugfs_root, &flat_dt_blob);
 	if (!d)
 	if (!d)
 		return 1;
 		return 1;
 
 

+ 3 - 1
arch/powerpc/kernel/prom_init.c

@@ -635,6 +635,7 @@ static void __init early_cmdline_parse(void)
 /* ibm,dynamic-reconfiguration-memory property supported */
 /* ibm,dynamic-reconfiguration-memory property supported */
 #define OV5_DRCONF_MEMORY	0x20
 #define OV5_DRCONF_MEMORY	0x20
 #define OV5_LARGE_PAGES		0x10	/* large pages supported */
 #define OV5_LARGE_PAGES		0x10	/* large pages supported */
+#define OV5_DONATE_DEDICATE_CPU 0x02	/* donate dedicated CPU support */
 /* PCIe/MSI support.  Without MSI full PCIe is not supported */
 /* PCIe/MSI support.  Without MSI full PCIe is not supported */
 #ifdef CONFIG_PCI_MSI
 #ifdef CONFIG_PCI_MSI
 #define OV5_MSI			0x01	/* PCIe/MSI support */
 #define OV5_MSI			0x01	/* PCIe/MSI support */
@@ -685,7 +686,8 @@ static unsigned char ibm_architecture_vec[] = {
 	/* option vector 5: PAPR/OF options */
 	/* option vector 5: PAPR/OF options */
 	3 - 2,				/* length */
 	3 - 2,				/* length */
 	0,				/* don't ignore, don't halt */
 	0,				/* don't ignore, don't halt */
-	OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | OV5_MSI,
+	OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
+	OV5_DONATE_DEDICATE_CPU | OV5_MSI,
 };
 };
 
 
 /* Old method - ELF header with PT_NOTE sections */
 /* Old method - ELF header with PT_NOTE sections */

+ 0 - 161
arch/powerpc/kernel/ptrace-common.h

@@ -1,161 +0,0 @@
-/*
- *    Copyright (c) 2002 Stephen Rothwell, IBM Coproration
- *    Extracted from ptrace.c and ptrace32.c
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License.  See the file README.legal in the main directory of
- * this archive for more details.
- */
-
-#ifndef _PPC64_PTRACE_COMMON_H
-#define _PPC64_PTRACE_COMMON_H
-
-#include <asm/system.h>
-
-/*
- * Set of msr bits that gdb can change on behalf of a process.
- */
-#define MSR_DEBUGCHANGE	(MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
-
-/*
- * Get contents of register REGNO in task TASK.
- */
-static inline unsigned long get_reg(struct task_struct *task, int regno)
-{
-	unsigned long tmp = 0;
-
-	/*
-	 * Put the correct FP bits in, they might be wrong as a result
-	 * of our lazy FP restore.
-	 */
-	if (regno == PT_MSR) {
-		tmp = ((unsigned long *)task->thread.regs)[PT_MSR];
-		tmp |= task->thread.fpexc_mode;
-	} else if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) {
-		tmp = ((unsigned long *)task->thread.regs)[regno];
-	}
-
-	return tmp;
-}
-
-/*
- * Write contents of register REGNO in task TASK.
- */
-static inline int put_reg(struct task_struct *task, int regno,
-			  unsigned long data)
-{
-	if (regno < PT_SOFTE) {
-		if (regno == PT_MSR)
-			data = (data & MSR_DEBUGCHANGE)
-				| (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
-		((unsigned long *)task->thread.regs)[regno] = data;
-		return 0;
-	}
-	return -EIO;
-}
-
-static inline void set_single_step(struct task_struct *task)
-{
-	struct pt_regs *regs = task->thread.regs;
-	if (regs != NULL)
-		regs->msr |= MSR_SE;
-	set_tsk_thread_flag(task, TIF_SINGLESTEP);
-}
-
-static inline void clear_single_step(struct task_struct *task)
-{
-	struct pt_regs *regs = task->thread.regs;
-	if (regs != NULL)
-		regs->msr &= ~MSR_SE;
-	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
-}
-
-#ifdef CONFIG_ALTIVEC
-/*
- * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
- * The transfer totals 34 quadword.  Quadwords 0-31 contain the
- * corresponding vector registers.  Quadword 32 contains the vscr as the
- * last word (offset 12) within that quadword.  Quadword 33 contains the
- * vrsave as the first word (offset 0) within the quadword.
- *
- * This definition of the VMX state is compatible with the current PPC32
- * ptrace interface.  This allows signal handling and ptrace to use the
- * same structures.  This also simplifies the implementation of a bi-arch
- * (combined (32- and 64-bit) gdb.
- */
-
-/*
- * Get contents of AltiVec register state in task TASK
- */
-static inline int get_vrregs(unsigned long __user *data,
-			     struct task_struct *task)
-{
-	unsigned long regsize;
-
-	/* copy AltiVec registers VR[0] .. VR[31] */
-	regsize = 32 * sizeof(vector128);
-	if (copy_to_user(data, task->thread.vr, regsize))
-		return -EFAULT;
-	data += (regsize / sizeof(unsigned long));
-
-	/* copy VSCR */
-	regsize = 1 * sizeof(vector128);
-	if (copy_to_user(data, &task->thread.vscr, regsize))
-		return -EFAULT;
-	data += (regsize / sizeof(unsigned long));
-
-	/* copy VRSAVE */
-	if (put_user(task->thread.vrsave, (u32 __user *)data))
-		return -EFAULT;
-
-	return 0;
-}
-
-/*
- * Write contents of AltiVec register state into task TASK.
- */
-static inline int set_vrregs(struct task_struct *task,
-			     unsigned long __user *data)
-{
-	unsigned long regsize;
-
-	/* copy AltiVec registers VR[0] .. VR[31] */
-	regsize = 32 * sizeof(vector128);
-	if (copy_from_user(task->thread.vr, data, regsize))
-		return -EFAULT;
-	data += (regsize / sizeof(unsigned long));
-
-	/* copy VSCR */
-	regsize = 1 * sizeof(vector128);
-	if (copy_from_user(&task->thread.vscr, data, regsize))
-		return -EFAULT;
-	data += (regsize / sizeof(unsigned long));
-
-	/* copy VRSAVE */
-	if (get_user(task->thread.vrsave, (u32 __user *)data))
-		return -EFAULT;
-
-	return 0;
-}
-#endif
-
-static inline int ptrace_set_debugreg(struct task_struct *task,
-				      unsigned long addr, unsigned long data)
-{
-	/* We only support one DABR and no IABRS at the moment */
-	if (addr > 0)
-		return -EINVAL;
-
-	/* The bottom 3 bits are flags */
-	if ((data & ~0x7UL) >= TASK_SIZE)
-		return -EIO;
-
-	/* Ensure translation is on */
-	if (data && !(data & DABR_TRANSLATION))
-		return -EIO;
-
-	task->thread.dabr = data;
-	return 0;
-}
-
-#endif /* _PPC64_PTRACE_COMMON_H */

+ 218 - 107
arch/powerpc/kernel/ptrace.c

@@ -35,11 +35,11 @@
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/system.h>
 
 
-#ifdef CONFIG_PPC64
-#include "ptrace-common.h"
-#endif
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
 
 
-#ifdef CONFIG_PPC32
 /*
 /*
  * Set of msr bits that gdb can change on behalf of a process.
  * Set of msr bits that gdb can change on behalf of a process.
  */
  */
@@ -48,65 +48,117 @@
 #else
 #else
 #define MSR_DEBUGCHANGE	(MSR_SE | MSR_BE)
 #define MSR_DEBUGCHANGE	(MSR_SE | MSR_BE)
 #endif
 #endif
-#endif /* CONFIG_PPC32 */
 
 
 /*
 /*
- * does not yet catch signals sent when the child dies.
- * in exit.c or in signal.c.
+ * Max register writeable via put_reg
  */
  */
-
 #ifdef CONFIG_PPC32
 #ifdef CONFIG_PPC32
+#define PT_MAX_PUT_REG	PT_MQ
+#else
+#define PT_MAX_PUT_REG	PT_CCR
+#endif
+
 /*
 /*
  * Get contents of register REGNO in task TASK.
  * Get contents of register REGNO in task TASK.
  */
  */
-static inline unsigned long get_reg(struct task_struct *task, int regno)
+unsigned long ptrace_get_reg(struct task_struct *task, int regno)
 {
 {
-	if (regno < sizeof(struct pt_regs) / sizeof(unsigned long)
-	    && task->thread.regs != NULL)
+	unsigned long tmp = 0;
+
+	if (task->thread.regs == NULL)
+		return -EIO;
+
+	if (regno == PT_MSR) {
+		tmp = ((unsigned long *)task->thread.regs)[PT_MSR];
+		return tmp | task->thread.fpexc_mode;
+	}
+
+	if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
 		return ((unsigned long *)task->thread.regs)[regno];
 		return ((unsigned long *)task->thread.regs)[regno];
-	return (0);
+
+	return -EIO;
 }
 }
 
 
 /*
 /*
  * Write contents of register REGNO in task TASK.
  * Write contents of register REGNO in task TASK.
  */
  */
-static inline int put_reg(struct task_struct *task, int regno,
-			  unsigned long data)
+int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
 {
 {
-	if (regno <= PT_MQ && task->thread.regs != NULL) {
+	if (task->thread.regs == NULL)
+		return -EIO;
+
+	if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) {
 		if (regno == PT_MSR)
 		if (regno == PT_MSR)
 			data = (data & MSR_DEBUGCHANGE)
 			data = (data & MSR_DEBUGCHANGE)
 				| (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
 				| (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
+		/* We prevent mucking around with the reserved area of trap
+		 * which are used internally by the kernel
+		 */
+		if (regno == PT_TRAP)
+			data &= 0xfff0;
 		((unsigned long *)task->thread.regs)[regno] = data;
 		((unsigned long *)task->thread.regs)[regno] = data;
 		return 0;
 		return 0;
 	}
 	}
 	return -EIO;
 	return -EIO;
 }
 }
 
 
+
+static int get_fpregs(void __user *data, struct task_struct *task,
+		      int has_fpscr)
+{
+	unsigned int count = has_fpscr ? 33 : 32;
+
+	if (copy_to_user(data, task->thread.fpr, count * sizeof(double)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_fpregs(void __user *data, struct task_struct *task,
+		      int has_fpscr)
+{
+	unsigned int count = has_fpscr ? 33 : 32;
+
+	if (copy_from_user(task->thread.fpr, data, count * sizeof(double)))
+		return -EFAULT;
+	return 0;
+}
+
+
 #ifdef CONFIG_ALTIVEC
 #ifdef CONFIG_ALTIVEC
+/*
+ * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
+ * The transfer totals 34 quadword.  Quadwords 0-31 contain the
+ * corresponding vector registers.  Quadword 32 contains the vscr as the
+ * last word (offset 12) within that quadword.  Quadword 33 contains the
+ * vrsave as the first word (offset 0) within the quadword.
+ *
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface.  This allows signal handling and ptrace to use the
+ * same structures.  This also simplifies the implementation of a bi-arch
+ * (combined (32- and 64-bit) gdb.
+ */
+
 /*
 /*
  * Get contents of AltiVec register state in task TASK
  * Get contents of AltiVec register state in task TASK
  */
  */
-static inline int get_vrregs(unsigned long __user *data, struct task_struct *task)
+static int get_vrregs(unsigned long __user *data, struct task_struct *task)
 {
 {
-	int i, j;
-
-	if (!access_ok(VERIFY_WRITE, data, 133 * sizeof(unsigned long)))
-		return -EFAULT;
+	unsigned long regsize;
 
 
 	/* copy AltiVec registers VR[0] .. VR[31] */
 	/* copy AltiVec registers VR[0] .. VR[31] */
-	for (i = 0; i < 32; i++)
-		for (j = 0; j < 4; j++, data++)
-			if (__put_user(task->thread.vr[i].u[j], data))
-				return -EFAULT;
+	regsize = 32 * sizeof(vector128);
+	if (copy_to_user(data, task->thread.vr, regsize))
+		return -EFAULT;
+	data += (regsize / sizeof(unsigned long));
 
 
 	/* copy VSCR */
 	/* copy VSCR */
-	for (i = 0; i < 4; i++, data++)
-		if (__put_user(task->thread.vscr.u[i], data))
-			return -EFAULT;
+	regsize = 1 * sizeof(vector128);
+	if (copy_to_user(data, &task->thread.vscr, regsize))
+		return -EFAULT;
+	data += (regsize / sizeof(unsigned long));
 
 
-        /* copy VRSAVE */
-	if (__put_user(task->thread.vrsave, data))
+	/* copy VRSAVE */
+	if (put_user(task->thread.vrsave, (u32 __user *)data))
 		return -EFAULT;
 		return -EFAULT;
 
 
 	return 0;
 	return 0;
@@ -115,31 +167,29 @@ static inline int get_vrregs(unsigned long __user *data, struct task_struct *tas
 /*
 /*
  * Write contents of AltiVec register state into task TASK.
  * Write contents of AltiVec register state into task TASK.
  */
  */
-static inline int set_vrregs(struct task_struct *task, unsigned long __user *data)
+static int set_vrregs(struct task_struct *task, unsigned long __user *data)
 {
 {
-	int i, j;
-
-	if (!access_ok(VERIFY_READ, data, 133 * sizeof(unsigned long)))
-		return -EFAULT;
+	unsigned long regsize;
 
 
 	/* copy AltiVec registers VR[0] .. VR[31] */
 	/* copy AltiVec registers VR[0] .. VR[31] */
-	for (i = 0; i < 32; i++)
-		for (j = 0; j < 4; j++, data++)
-			if (__get_user(task->thread.vr[i].u[j], data))
-				return -EFAULT;
+	regsize = 32 * sizeof(vector128);
+	if (copy_from_user(task->thread.vr, data, regsize))
+		return -EFAULT;
+	data += (regsize / sizeof(unsigned long));
 
 
 	/* copy VSCR */
 	/* copy VSCR */
-	for (i = 0; i < 4; i++, data++)
-		if (__get_user(task->thread.vscr.u[i], data))
-			return -EFAULT;
+	regsize = 1 * sizeof(vector128);
+	if (copy_from_user(&task->thread.vscr, data, regsize))
+		return -EFAULT;
+	data += (regsize / sizeof(unsigned long));
 
 
 	/* copy VRSAVE */
 	/* copy VRSAVE */
-	if (__get_user(task->thread.vrsave, data))
+	if (get_user(task->thread.vrsave, (u32 __user *)data))
 		return -EFAULT;
 		return -EFAULT;
 
 
 	return 0;
 	return 0;
 }
 }
-#endif
+#endif /* CONFIG_ALTIVEC */
 
 
 #ifdef CONFIG_SPE
 #ifdef CONFIG_SPE
 
 
@@ -156,7 +206,7 @@ static inline int set_vrregs(struct task_struct *task, unsigned long __user *dat
 /*
 /*
  * Get contents of SPE register state in task TASK.
  * Get contents of SPE register state in task TASK.
  */
  */
-static inline int get_evrregs(unsigned long *data, struct task_struct *task)
+static int get_evrregs(unsigned long *data, struct task_struct *task)
 {
 {
 	int i;
 	int i;
 
 
@@ -182,7 +232,7 @@ static inline int get_evrregs(unsigned long *data, struct task_struct *task)
 /*
 /*
  * Write contents of SPE register state into task TASK.
  * Write contents of SPE register state into task TASK.
  */
  */
-static inline int set_evrregs(struct task_struct *task, unsigned long *data)
+static int set_evrregs(struct task_struct *task, unsigned long *data)
 {
 {
 	int i;
 	int i;
 
 
@@ -205,8 +255,8 @@ static inline int set_evrregs(struct task_struct *task, unsigned long *data)
 }
 }
 #endif /* CONFIG_SPE */
 #endif /* CONFIG_SPE */
 
 
-static inline void
-set_single_step(struct task_struct *task)
+
+static void set_single_step(struct task_struct *task)
 {
 {
 	struct pt_regs *regs = task->thread.regs;
 	struct pt_regs *regs = task->thread.regs;
 
 
@@ -221,8 +271,7 @@ set_single_step(struct task_struct *task)
 	set_tsk_thread_flag(task, TIF_SINGLESTEP);
 	set_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 }
 
 
-static inline void
-clear_single_step(struct task_struct *task)
+static void clear_single_step(struct task_struct *task)
 {
 {
 	struct pt_regs *regs = task->thread.regs;
 	struct pt_regs *regs = task->thread.regs;
 
 
@@ -236,7 +285,25 @@ clear_single_step(struct task_struct *task)
 	}
 	}
 	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
 	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 }
-#endif /* CONFIG_PPC32 */
+
+static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
+			       unsigned long data)
+{
+	/* We only support one DABR and no IABRS at the moment */
+	if (addr > 0)
+		return -EINVAL;
+
+	/* The bottom 3 bits are flags */
+	if ((data & ~0x7UL) >= TASK_SIZE)
+		return -EIO;
+
+	/* Ensure translation is on */
+	if (data && !(data & DABR_TRANSLATION))
+		return -EIO;
+
+	task->thread.dabr = data;
+	return 0;
+}
 
 
 /*
 /*
  * Called by kernel/ptrace.c when detaching..
  * Called by kernel/ptrace.c when detaching..
@@ -249,6 +316,62 @@ void ptrace_disable(struct task_struct *child)
 	clear_single_step(child);
 	clear_single_step(child);
 }
 }
 
 
+/*
+ * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
+ * we mark them as obsolete now, they will be removed in a future version
+ */
+static long arch_ptrace_old(struct task_struct *child, long request, long addr,
+			    long data)
+{
+	int ret = -EPERM;
+
+	switch(request) {
+	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
+		int i;
+		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+		unsigned long __user *tmp = (unsigned long __user *)addr;
+
+		for (i = 0; i < 32; i++) {
+			ret = put_user(*reg, tmp);
+			if (ret)
+				break;
+			reg++;
+			tmp++;
+		}
+		break;
+	}
+
+	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
+		int i;
+		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+		unsigned long __user *tmp = (unsigned long __user *)addr;
+
+		for (i = 0; i < 32; i++) {
+			ret = get_user(*reg, tmp);
+			if (ret)
+				break;
+			reg++;
+			tmp++;
+		}
+		break;
+	}
+
+	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
+		flush_fp_to_thread(child);
+		ret = get_fpregs((void __user *)addr, child, 0);
+		break;
+	}
+
+	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
+		flush_fp_to_thread(child);
+		ret = set_fpregs((void __user *)addr, child, 0);
+		break;
+	}
+
+	}
+	return ret;
+}
+
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 {
 	int ret = -EPERM;
 	int ret = -EPERM;
@@ -284,11 +407,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 #endif
 #endif
 			break;
 			break;
 
 
-#ifdef CONFIG_PPC32
 		CHECK_FULL_REGS(child->thread.regs);
 		CHECK_FULL_REGS(child->thread.regs);
-#endif
 		if (index < PT_FPR0) {
 		if (index < PT_FPR0) {
-			tmp = get_reg(child, (int) index);
+			tmp = ptrace_get_reg(child, (int) index);
 		} else {
 		} else {
 			flush_fp_to_thread(child);
 			flush_fp_to_thread(child);
 			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
 			tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
@@ -323,13 +444,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 #endif
 #endif
 			break;
 			break;
 
 
-#ifdef CONFIG_PPC32
 		CHECK_FULL_REGS(child->thread.regs);
 		CHECK_FULL_REGS(child->thread.regs);
-#endif
-		if (index == PT_ORIG_R3)
-			break;
 		if (index < PT_FPR0) {
 		if (index < PT_FPR0) {
-			ret = put_reg(child, index, data);
+			ret = ptrace_put_reg(child, index, data);
 		} else {
 		} else {
 			flush_fp_to_thread(child);
 			flush_fp_to_thread(child);
 			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
 			((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
@@ -384,7 +501,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 		break;
 		break;
 	}
 	}
 
 
-#ifdef CONFIG_PPC64
 	case PTRACE_GET_DEBUGREG: {
 	case PTRACE_GET_DEBUGREG: {
 		ret = -EINVAL;
 		ret = -EINVAL;
 		/* We only support one DABR and no IABRS at the moment */
 		/* We only support one DABR and no IABRS at the moment */
@@ -398,73 +514,61 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 	case PTRACE_SET_DEBUGREG:
 	case PTRACE_SET_DEBUGREG:
 		ret = ptrace_set_debugreg(child, addr, data);
 		ret = ptrace_set_debugreg(child, addr, data);
 		break;
 		break;
-#endif
 
 
 	case PTRACE_DETACH:
 	case PTRACE_DETACH:
 		ret = ptrace_detach(child, data);
 		ret = ptrace_detach(child, data);
 		break;
 		break;
 
 
-	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
-		int i;
-		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
-		unsigned long __user *tmp = (unsigned long __user *)addr;
-
-		for (i = 0; i < 32; i++) {
-			ret = put_user(*reg, tmp);
-			if (ret)
-				break;
-			reg++;
-			tmp++;
+#ifdef CONFIG_PPC64
+	case PTRACE_GETREGS64:
+#endif
+	case PTRACE_GETREGS: { /* Get all pt_regs from the child. */
+		int ui;
+	  	if (!access_ok(VERIFY_WRITE, (void __user *)data,
+			       sizeof(struct pt_regs))) {
+			ret = -EIO;
+			break;
+		}
+		ret = 0;
+		for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
+			ret |= __put_user(ptrace_get_reg(child, ui),
+					  (unsigned long __user *) data);
+			data += sizeof(long);
 		}
 		}
 		break;
 		break;
 	}
 	}
 
 
-	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
-		int i;
-		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
-		unsigned long __user *tmp = (unsigned long __user *)addr;
-
-		for (i = 0; i < 32; i++) {
-			ret = get_user(*reg, tmp);
+#ifdef CONFIG_PPC64
+	case PTRACE_SETREGS64:
+#endif
+	case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+		unsigned long tmp;
+		int ui;
+	  	if (!access_ok(VERIFY_READ, (void __user *)data,
+			       sizeof(struct pt_regs))) {
+			ret = -EIO;
+			break;
+		}
+		ret = 0;
+		for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
+			ret = __get_user(tmp, (unsigned long __user *) data);
 			if (ret)
 			if (ret)
 				break;
 				break;
-			reg++;
-			tmp++;
+			ptrace_put_reg(child, ui, tmp);
+			data += sizeof(long);
 		}
 		}
 		break;
 		break;
 	}
 	}
 
 
-	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
-		int i;
-		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
-		unsigned long __user *tmp = (unsigned long __user *)addr;
-
+	case PTRACE_GETFPREGS: { /* Get the child FPU state (FPR0...31 + FPSCR) */
 		flush_fp_to_thread(child);
 		flush_fp_to_thread(child);
-
-		for (i = 0; i < 32; i++) {
-			ret = put_user(*reg, tmp);
-			if (ret)
-				break;
-			reg++;
-			tmp++;
-		}
+		ret = get_fpregs((void __user *)data, child, 1);
 		break;
 		break;
 	}
 	}
 
 
-	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
-		int i;
-		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
-		unsigned long __user *tmp = (unsigned long __user *)addr;
-
+	case PTRACE_SETFPREGS: { /* Set the child FPU state (FPR0...31 + FPSCR) */
 		flush_fp_to_thread(child);
 		flush_fp_to_thread(child);
-
-		for (i = 0; i < 32; i++) {
-			ret = get_user(*reg, tmp);
-			if (ret)
-				break;
-			reg++;
-			tmp++;
-		}
+		ret = set_fpregs((void __user *)data, child, 1);
 		break;
 		break;
 	}
 	}
 
 
@@ -499,11 +603,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 		break;
 		break;
 #endif
 #endif
 
 
+	/* Old reverse args ptrace callss */
+	case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
+	case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
+	case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
+	case PPC_PTRACE_SETFPREGS: /* Get FPRs 0 - 31. */
+		ret = arch_ptrace_old(child, request, addr, data);
+		break;
+
 	default:
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		ret = ptrace_request(child, request, addr, data);
 		break;
 		break;
 	}
 	}
-
 	return ret;
 	return ret;
 }
 }
 
 

+ 104 - 135
arch/powerpc/kernel/ptrace32.c

@@ -33,13 +33,55 @@
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/system.h>
 
 
-#include "ptrace-common.h"
-
 /*
 /*
  * does not yet catch signals sent when the child dies.
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
  * in exit.c or in signal.c.
  */
  */
 
 
+/*
+ * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
+ * we mark them as obsolete now, they will be removed in a future version
+ */
+static long compat_ptrace_old(struct task_struct *child, long request,
+			      long addr, long data)
+{
+	int ret = -EPERM;
+
+	switch(request) {
+	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
+		int i;
+		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+		unsigned int __user *tmp = (unsigned int __user *)addr;
+
+		for (i = 0; i < 32; i++) {
+			ret = put_user(*reg, tmp);
+			if (ret)
+				break;
+			reg++;
+			tmp++;
+		}
+		break;
+	}
+
+	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
+		int i;
+		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
+		unsigned int __user *tmp = (unsigned int __user *)addr;
+
+		for (i = 0; i < 32; i++) {
+			ret = get_user(*reg, tmp);
+			if (ret)
+				break;
+			reg++;
+			tmp++;
+		}
+		break;
+	}
+
+	}
+	return ret;
+}
+
 long compat_sys_ptrace(int request, int pid, unsigned long addr,
 long compat_sys_ptrace(int request, int pid, unsigned long addr,
 		       unsigned long data)
 		       unsigned long data)
 {
 {
@@ -123,7 +165,7 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
 			break;
 			break;
 
 
 		if (index < PT_FPR0) {
 		if (index < PT_FPR0) {
-			tmp = get_reg(child, index);
+			tmp = ptrace_get_reg(child, index);
 		} else {
 		} else {
 			flush_fp_to_thread(child);
 			flush_fp_to_thread(child);
 			/*
 			/*
@@ -162,7 +204,9 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
 		else
 		else
 			part = 0;  /* want the 1st half of the register (left-most). */
 			part = 0;  /* want the 1st half of the register (left-most). */
 
 
-		/* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */
+		/* Validate the input - check to see if address is on the wrong boundary
+		 * or beyond the end of the user area
+		 */
 		if ((addr & 3) || numReg > PT_FPSCR)
 		if ((addr & 3) || numReg > PT_FPSCR)
 			break;
 			break;
 
 
@@ -170,7 +214,7 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
 			flush_fp_to_thread(child);
 			flush_fp_to_thread(child);
 			tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
 			tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
 		} else { /* register within PT_REGS struct */
 		} else { /* register within PT_REGS struct */
-			tmp = get_reg(child, numReg);
+			tmp = ptrace_get_reg(child, numReg);
 		} 
 		} 
 		reg32bits = ((u32*)&tmp)[part];
 		reg32bits = ((u32*)&tmp)[part];
 		ret = put_user(reg32bits, (u32 __user *)data);
 		ret = put_user(reg32bits, (u32 __user *)data);
@@ -226,10 +270,8 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
 		if ((addr & 3) || (index > PT_FPSCR32))
 		if ((addr & 3) || (index > PT_FPSCR32))
 			break;
 			break;
 
 
-		if (index == PT_ORIG_R3)
-			break;
 		if (index < PT_FPR0) {
 		if (index < PT_FPR0) {
-			ret = put_reg(child, index, data);
+			ret = ptrace_put_reg(child, index, data);
 		} else {
 		} else {
 			flush_fp_to_thread(child);
 			flush_fp_to_thread(child);
 			/*
 			/*
@@ -258,70 +300,25 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
 		/* Determine which register the user wants */
 		/* Determine which register the user wants */
 		index = (u64)addr >> 2;
 		index = (u64)addr >> 2;
 		numReg = index / 2;
 		numReg = index / 2;
+
 		/*
 		/*
 		 * Validate the input - check to see if address is on the
 		 * Validate the input - check to see if address is on the
 		 * wrong boundary or beyond the end of the user area
 		 * wrong boundary or beyond the end of the user area
 		 */
 		 */
 		if ((addr & 3) || (numReg > PT_FPSCR))
 		if ((addr & 3) || (numReg > PT_FPSCR))
 			break;
 			break;
-		/* Insure it is a register we let them change */
-		if ((numReg == PT_ORIG_R3)
-				|| ((numReg > PT_CCR) && (numReg < PT_FPR0)))
-			break;
-		if (numReg >= PT_FPR0) {
+		if (numReg < PT_FPR0) {
+			unsigned long freg = ptrace_get_reg(child, numReg);
+			if (index % 2)
+				freg = (freg & ~0xfffffffful) | (data & 0xfffffffful);
+			else
+				freg = (freg & 0xfffffffful) | (data << 32);
+			ret = ptrace_put_reg(child, numReg, freg);
+		} else {
 			flush_fp_to_thread(child);
 			flush_fp_to_thread(child);
+			((unsigned int *)child->thread.regs)[index] = data;
+			ret = 0;
 		}
 		}
-		if (numReg == PT_MSR)
-			data = (data & MSR_DEBUGCHANGE)
-				| (child->thread.regs->msr & ~MSR_DEBUGCHANGE);
-		((u32*)child->thread.regs)[index] = data;
-		ret = 0;
-		break;
-	}
-
-	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
-	case PTRACE_CONT: { /* restart after signal. */
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		if (request == PTRACE_SYSCALL)
-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		else
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-		/* make sure the single step bit is not set. */
-		clear_single_step(child);
-		wake_up_process(child);
-		ret = 0;
-		break;
-	}
-
-	/*
-	 * make the child exit.  Best I can do is send it a sigkill.
-	 * perhaps it should be put in the status that it wants to
-	 * exit.
-	 */
-	case PTRACE_KILL: {
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
-			break;
-		child->exit_code = SIGKILL;
-		/* make sure the single step bit is not set. */
-		clear_single_step(child);
-		wake_up_process(child);
-		break;
-	}
-
-	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		set_single_step(child);
-		child->exit_code = data;
-		/* give it a chance to run. */
-		wake_up_process(child);
-		ret = 0;
 		break;
 		break;
 	}
 	}
 
 
@@ -334,95 +331,67 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
 		break;
 		break;
 	}
 	}
 
 
-	case PTRACE_SET_DEBUGREG:
-		ret = ptrace_set_debugreg(child, addr, data);
-		break;
-
-	case PTRACE_DETACH:
-		ret = ptrace_detach(child, data);
+	case PTRACE_GETEVENTMSG:
+		ret = put_user(child->ptrace_message, (unsigned int __user *) data);
 		break;
 		break;
 
 
-	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
-		int i;
-		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
-		unsigned int __user *tmp = (unsigned int __user *)addr;
-
-		for (i = 0; i < 32; i++) {
-			ret = put_user(*reg, tmp);
-			if (ret)
-				break;
-			reg++;
-			tmp++;
+	case PTRACE_GETREGS: { /* Get all pt_regs from the child. */
+		int ui;
+	  	if (!access_ok(VERIFY_WRITE, (void __user *)data,
+			       PT_REGS_COUNT * sizeof(int))) {
+			ret = -EIO;
+			break;
 		}
 		}
-		break;
-	}
-
-	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
-		int i;
-		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
-		unsigned int __user *tmp = (unsigned int __user *)addr;
-
-		for (i = 0; i < 32; i++) {
-			ret = get_user(*reg, tmp);
-			if (ret)
-				break;
-			reg++;
-			tmp++;
+		ret = 0;
+		for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
+			ret |= __put_user(ptrace_get_reg(child, ui),
+					  (unsigned int __user *) data);
+			data += sizeof(int);
 		}
 		}
 		break;
 		break;
 	}
 	}
 
 
-	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
-		int i;
-		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
-		unsigned int __user *tmp = (unsigned int __user *)addr;
-
-		flush_fp_to_thread(child);
-
-		for (i = 0; i < 32; i++) {
-			ret = put_user(*reg, tmp);
-			if (ret)
-				break;
-			reg++;
-			tmp++;
+	case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+		unsigned long tmp;
+		int ui;
+	  	if (!access_ok(VERIFY_READ, (void __user *)data,
+			       PT_REGS_COUNT * sizeof(int))) {
+			ret = -EIO;
+			break;
 		}
 		}
-		break;
-	}
-
-	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
-		int i;
-		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
-		unsigned int __user *tmp = (unsigned int __user *)addr;
-
-		flush_fp_to_thread(child);
-
-		for (i = 0; i < 32; i++) {
-			ret = get_user(*reg, tmp);
+		ret = 0;
+		for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
+			ret = __get_user(tmp, (unsigned int __user *) data);
 			if (ret)
 			if (ret)
 				break;
 				break;
-			reg++;
-			tmp++;
+			ptrace_put_reg(child, ui, tmp);
+			data += sizeof(int);
 		}
 		}
 		break;
 		break;
 	}
 	}
 
 
-	case PTRACE_GETEVENTMSG:
-		ret = put_user(child->ptrace_message, (unsigned int __user *) data);
-		break;
-
-#ifdef CONFIG_ALTIVEC
+	case PTRACE_GETFPREGS:
+	case PTRACE_SETFPREGS:
 	case PTRACE_GETVRREGS:
 	case PTRACE_GETVRREGS:
-		/* Get the child altivec register state. */
-		flush_altivec_to_thread(child);
-		ret = get_vrregs((unsigned long __user *)data, child);
+	case PTRACE_SETVRREGS:
+	case PTRACE_GETREGS64:
+	case PTRACE_SETREGS64:
+	case PPC_PTRACE_GETFPREGS:
+	case PPC_PTRACE_SETFPREGS:
+	case PTRACE_KILL:
+	case PTRACE_SINGLESTEP:
+	case PTRACE_DETACH:
+	case PTRACE_SET_DEBUGREG:
+	case PTRACE_SYSCALL:
+	case PTRACE_CONT:
+		ret = arch_ptrace(child, request, addr, data);
 		break;
 		break;
 
 
-	case PTRACE_SETVRREGS:
-		/* Set the child altivec register state. */
-		flush_altivec_to_thread(child);
-		ret = set_vrregs(child, (unsigned long __user *)data);
+	/* Old reverse args ptrace callss */
+	case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
+	case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
+		ret = compat_ptrace_old(child, request, addr, data);
 		break;
 		break;
-#endif
 
 
 	default:
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		ret = ptrace_request(child, request, addr, data);

+ 2 - 5
arch/powerpc/kernel/rtas_pci.c

@@ -278,10 +278,8 @@ void __init find_and_init_phbs(void)
 {
 {
 	struct device_node *node;
 	struct device_node *node;
 	struct pci_controller *phb;
 	struct pci_controller *phb;
-	unsigned int index;
 	struct device_node *root = of_find_node_by_path("/");
 	struct device_node *root = of_find_node_by_path("/");
 
 
-	index = 0;
 	for (node = of_get_next_child(root, NULL);
 	for (node = of_get_next_child(root, NULL);
 	     node != NULL;
 	     node != NULL;
 	     node = of_get_next_child(root, node)) {
 	     node = of_get_next_child(root, node)) {
@@ -295,8 +293,7 @@ void __init find_and_init_phbs(void)
 			continue;
 			continue;
 		rtas_setup_phb(phb);
 		rtas_setup_phb(phb);
 		pci_process_bridge_OF_ranges(phb, node, 0);
 		pci_process_bridge_OF_ranges(phb, node, 0);
-		pci_setup_phb_io(phb, index == 0);
-		index++;
+		isa_bridge_find_early(phb);
 	}
 	}
 
 
 	of_node_put(root);
 	of_node_put(root);
@@ -335,7 +332,7 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
 		return 1;
 		return 1;
 	}
 	}
 
 
-	rc = unmap_bus_range(b);
+	rc = pcibios_unmap_io_space(b);
 	if (rc) {
 	if (rc) {
 		printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
 		printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
 			__FUNCTION__, b->name);
 			__FUNCTION__, b->name);

+ 21 - 0
arch/powerpc/kernel/setup-common.c

@@ -32,6 +32,7 @@
 #include <linux/unistd.h>
 #include <linux/unistd.h>
 #include <linux/serial.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_8250.h>
+#include <linux/debugfs.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
@@ -486,6 +487,14 @@ int check_legacy_ioport(unsigned long base_port)
 
 
 	switch(base_port) {
 	switch(base_port) {
 	case I8042_DATA_REG:
 	case I8042_DATA_REG:
+		if (!(np = of_find_compatible_node(NULL, NULL, "pnpPNP,303")))
+			np = of_find_compatible_node(NULL, NULL, "pnpPNP,f03");
+		if (np) {
+			parent = of_get_parent(np);
+			of_node_put(np);
+			np = parent;
+			break;
+		}
 		np = of_find_node_by_type(NULL, "8042");
 		np = of_find_node_by_type(NULL, "8042");
 		break;
 		break;
 	case FDC_BASE: /* FDC1 */
 	case FDC_BASE: /* FDC1 */
@@ -571,3 +580,15 @@ static int __init check_cache_coherency(void)
 
 
 late_initcall(check_cache_coherency);
 late_initcall(check_cache_coherency);
 #endif /* CONFIG_CHECK_CACHE_COHERENCY */
 #endif /* CONFIG_CHECK_CACHE_COHERENCY */
+
+#ifdef CONFIG_DEBUG_FS
+struct dentry *powerpc_debugfs_root;
+
+static int powerpc_debugfs_init(void)
+{
+	powerpc_debugfs_root = debugfs_create_dir("powerpc", NULL);
+
+	return powerpc_debugfs_root == NULL;
+}
+arch_initcall(powerpc_debugfs_init);
+#endif

+ 5 - 7
arch/powerpc/kernel/setup_32.c

@@ -262,13 +262,11 @@ void __init setup_arch(char **cmdline_p)
 	 * Systems with OF can look in the properties on the cpu node(s)
 	 * Systems with OF can look in the properties on the cpu node(s)
 	 * for a possibly more accurate value.
 	 * for a possibly more accurate value.
 	 */
 	 */
-	if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
-		dcache_bsize = cur_cpu_spec->dcache_bsize;
-		icache_bsize = cur_cpu_spec->icache_bsize;
-		ucache_bsize = 0;
-	} else
-		ucache_bsize = dcache_bsize = icache_bsize
-			= cur_cpu_spec->dcache_bsize;
+	dcache_bsize = cur_cpu_spec->dcache_bsize;
+	icache_bsize = cur_cpu_spec->icache_bsize;
+	ucache_bsize = 0;
+	if (cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE))
+		ucache_bsize = icache_bsize = dcache_bsize;
 
 
 	/* reboot on panic */
 	/* reboot on panic */
 	panic_timeout = 180;
 	panic_timeout = 180;

+ 8 - 4
arch/powerpc/kernel/setup_64.c

@@ -350,13 +350,11 @@ void __init setup_system(void)
 {
 {
 	DBG(" -> setup_system()\n");
 	DBG(" -> setup_system()\n");
 
 
-	/* Apply the CPUs-specific and firmware specific fixups to kernel
-	 * text (nop out sections not relevant to this CPU or this firmware)
+	/* Apply CPUs-specific fixups to kernel text (nop out sections
+	 * not relevant to this CPU)
 	 */
 	 */
 	do_feature_fixups(cur_cpu_spec->cpu_features,
 	do_feature_fixups(cur_cpu_spec->cpu_features,
 			  &__start___ftr_fixup, &__stop___ftr_fixup);
 			  &__start___ftr_fixup, &__stop___ftr_fixup);
-	do_feature_fixups(powerpc_firmware_features,
-			  &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
 
 
 	/*
 	/*
 	 * Unflatten the device-tree passed by prom_init or kexec
 	 * Unflatten the device-tree passed by prom_init or kexec
@@ -394,6 +392,12 @@ void __init setup_system(void)
 	if (ppc_md.init_early)
 	if (ppc_md.init_early)
 		ppc_md.init_early();
 		ppc_md.init_early();
 
 
+	/* Apply firmware specific fixups to kernel text (nop out
+	 * sections not relevant to this firmware)
+	 */
+	do_feature_fixups(powerpc_firmware_features,
+			  &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
+
  	/*
  	/*
 	 * We can discover serial ports now since the above did setup the
 	 * We can discover serial ports now since the above did setup the
 	 * hash table management for us, thus ioremap works. We do that early
 	 * hash table management for us, thus ioremap works. We do that early

+ 180 - 0
arch/powerpc/kernel/signal.c

@@ -0,0 +1,180 @@
+/*
+ * Common signal handling code for both 32 and 64 bits
+ *
+ *    Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
+ *    Extracted from signal_32.c and signal_64.c
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file README.legal in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/ptrace.h>
+#include <linux/signal.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+#include "signal.h"
+
+/*
+ * Allocate space for the signal frame
+ */
+void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+			   size_t frame_size)
+{
+        unsigned long oldsp, newsp;
+
+        /* Default to using normal stack */
+        oldsp = regs->gpr[1];
+
+	/* Check for alt stack */
+	if ((ka->sa.sa_flags & SA_ONSTACK) &&
+	    current->sas_ss_size && !on_sig_stack(oldsp))
+		oldsp = (current->sas_ss_sp + current->sas_ss_size);
+
+	/* Get aligned frame */
+	newsp = (oldsp - frame_size) & ~0xFUL;
+
+	/* Check access */
+	if (!access_ok(VERIFY_WRITE, (void __user *)newsp, oldsp - newsp))
+		return NULL;
+
+        return (void __user *)newsp;
+}
+
+
+/*
+ * Restore the user process's signal mask
+ */
+void restore_sigmask(sigset_t *set)
+{
+	sigdelsetmask(set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = *set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+}
+
+static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
+				  int has_handler)
+{
+	unsigned long ret = regs->gpr[3];
+	int restart = 1;
+
+	/* syscall ? */
+	if (TRAP(regs) != 0x0C00)
+		return;
+
+	/* error signalled ? */
+	if (!(regs->ccr & 0x10000000))
+		return;
+
+	switch (ret) {
+	case ERESTART_RESTARTBLOCK:
+	case ERESTARTNOHAND:
+		/* ERESTARTNOHAND means that the syscall should only be
+		 * restarted if there was no handler for the signal, and since
+		 * we only get here if there is a handler, we dont restart.
+		 */
+		restart = !has_handler;
+		break;
+	case ERESTARTSYS:
+		/* ERESTARTSYS means to restart the syscall if there is no
+		 * handler or the handler was registered with SA_RESTART
+		 */
+		restart = !has_handler || (ka->sa.sa_flags & SA_RESTART) != 0;
+		break;
+	case ERESTARTNOINTR:
+		/* ERESTARTNOINTR means that the syscall should be
+		 * called again after the signal handler returns.
+		 */
+		break;
+	default:
+		return;
+	}
+	if (restart) {
+		if (ret == ERESTART_RESTARTBLOCK)
+			regs->gpr[0] = __NR_restart_syscall;
+		else
+			regs->gpr[3] = regs->orig_gpr3;
+		regs->nip -= 4;
+		regs->result = 0;
+	} else {
+		regs->result = -EINTR;
+		regs->gpr[3] = EINTR;
+		regs->ccr |= 0x10000000;
+	}
+}
+
+int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	siginfo_t info;
+	int signr;
+	struct k_sigaction ka;
+	int ret;
+	int is32 = is_32bit_task();
+
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	/* Is there any syscall restart business here ? */
+	check_syscall_restart(regs, &ka, signr > 0);
+
+	if (signr <= 0) {
+		/* No signal to deliver -- put the saved sigmask back */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+		}
+		return 0;               /* no signals delivered */
+	}
+
+        /*
+	 * Reenable the DABR before delivering the signal to
+	 * user space. The DABR will have been cleared if it
+	 * triggered inside the kernel.
+	 */
+	if (current->thread.dabr)
+		set_dabr(current->thread.dabr);
+
+	if (is32) {
+        	if (ka.sa.sa_flags & SA_SIGINFO)
+			ret = handle_rt_signal32(signr, &ka, &info, oldset,
+					regs);
+		else
+			ret = handle_signal32(signr, &ka, &info, oldset,
+					regs);
+	} else {
+		ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
+	}
+
+	if (ret) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked, &current->blocked,
+			  &ka.sa.sa_mask);
+		if (!(ka.sa.sa_flags & SA_NODEFER))
+			sigaddset(&current->blocked, signr);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+
+		/*
+		 * A signal was successfully delivered; the saved sigmask is in
+		 * its frame, and we can clear the TIF_RESTORE_SIGMASK flag.
+		 */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+	}
+
+	return ret;
+}
+
+long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+		unsigned long r5, unsigned long r6, unsigned long r7,
+		unsigned long r8, struct pt_regs *regs)
+{
+	return do_sigaltstack(uss, uoss, regs->gpr[1]);
+}

+ 55 - 0
arch/powerpc/kernel/signal.h

@@ -0,0 +1,55 @@
+/*
+ *    Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
+ *    Extracted from signal_32.c and signal_64.c
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file README.legal in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _POWERPC_ARCH_SIGNAL_H
+#define _POWERPC_ARCH_SIGNAL_H
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+				  size_t frame_size);
+extern void restore_sigmask(sigset_t *set);
+
+extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
+			   siginfo_t *info, sigset_t *oldset,
+			   struct pt_regs *regs);
+
+extern int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
+			      siginfo_t *info, sigset_t *oldset,
+			      struct pt_regs *regs);
+
+
+#ifdef CONFIG_PPC64
+
+static inline int is_32bit_task(void)
+{
+	return test_thread_flag(TIF_32BIT);
+}
+
+extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
+			      siginfo_t *info, sigset_t *set,
+			      struct pt_regs *regs);
+
+#else /* CONFIG_PPC64 */
+
+static inline int is_32bit_task(void)
+{
+	return 1;
+}
+
+static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
+				     siginfo_t *info, sigset_t *set,
+				     struct pt_regs *regs)
+{
+	return -EFAULT;
+}
+
+#endif /* !defined(CONFIG_PPC64) */
+
+#endif  /* _POWERPC_ARCH_SIGNAL_H */

+ 28 - 163
arch/powerpc/kernel/signal_32.c

@@ -51,12 +51,11 @@
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #endif
 #endif
 
 
-#undef DEBUG_SIG
+#include "signal.h"
 
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+#undef DEBUG_SIG
 
 
 #ifdef CONFIG_PPC64
 #ifdef CONFIG_PPC64
-#define do_signal	do_signal32
 #define sys_sigsuspend	compat_sys_sigsuspend
 #define sys_sigsuspend	compat_sys_sigsuspend
 #define sys_rt_sigsuspend	compat_sys_rt_sigsuspend
 #define sys_rt_sigsuspend	compat_sys_rt_sigsuspend
 #define sys_rt_sigreturn	compat_sys_rt_sigreturn
 #define sys_rt_sigreturn	compat_sys_rt_sigreturn
@@ -231,8 +230,6 @@ static inline int restore_general_regs(struct pt_regs *regs,
 
 
 #endif /* CONFIG_PPC64 */
 #endif /* CONFIG_PPC64 */
 
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs);
-
 /*
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  * Atomically swap in the new signal mask, and wait for a signal.
  */
  */
@@ -251,14 +248,6 @@ long sys_sigsuspend(old_sigset_t mask)
  	return -ERESTARTNOHAND;
  	return -ERESTARTNOHAND;
 }
 }
 
 
-#ifdef CONFIG_PPC32
-long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
-		int r6, int r7, int r8, struct pt_regs *regs)
-{
-	return do_sigaltstack(uss, uoss, regs->gpr[1]);
-}
-#endif
-
 long sys_sigaction(int sig, struct old_sigaction __user *act,
 long sys_sigaction(int sig, struct old_sigaction __user *act,
 		struct old_sigaction __user *oact)
 		struct old_sigaction __user *oact)
 {
 {
@@ -293,14 +282,17 @@ long sys_sigaction(int sig, struct old_sigaction __user *act,
 /*
 /*
  * When we have signals to deliver, we set up on the
  * When we have signals to deliver, we set up on the
  * user stack, going down from the original stack pointer:
  * user stack, going down from the original stack pointer:
- *	a sigregs struct
+ *	an ABI gap of 56 words
+ *	an mcontext struct
  *	a sigcontext struct
  *	a sigcontext struct
  *	a gap of __SIGNAL_FRAMESIZE bytes
  *	a gap of __SIGNAL_FRAMESIZE bytes
  *
  *
- * Each of these things must be a multiple of 16 bytes in size.
+ * Each of these things must be a multiple of 16 bytes in size. The following
+ * structure represent all of this except the __SIGNAL_FRAMESIZE gap
  *
  *
  */
  */
-struct sigregs {
+struct sigframe {
+	struct sigcontext sctx;		/* the sigcontext */
 	struct mcontext	mctx;		/* all the register values */
 	struct mcontext	mctx;		/* all the register values */
 	/*
 	/*
 	 * Programs using the rs6000/xcoff abi can save up to 19 gp
 	 * Programs using the rs6000/xcoff abi can save up to 19 gp
@@ -703,44 +695,22 @@ int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
 }
 }
 #endif /* CONFIG_PPC64 */
 #endif /* CONFIG_PPC64 */
 
 
-
-/*
- * Restore the user process's signal mask
- */
-#ifdef CONFIG_PPC64
-extern void restore_sigmask(sigset_t *set);
-#else /* CONFIG_PPC64 */
-static void restore_sigmask(sigset_t *set)
-{
-	sigdelsetmask(set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = *set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-}
-#endif
-
 /*
 /*
  * Set up a signal frame for a "real-time" signal handler
  * Set up a signal frame for a "real-time" signal handler
  * (one which gets siginfo).
  * (one which gets siginfo).
  */
  */
-static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
+int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
 		siginfo_t *info, sigset_t *oldset,
 		siginfo_t *info, sigset_t *oldset,
-		struct pt_regs *regs, unsigned long newsp)
+		struct pt_regs *regs)
 {
 {
 	struct rt_sigframe __user *rt_sf;
 	struct rt_sigframe __user *rt_sf;
 	struct mcontext __user *frame;
 	struct mcontext __user *frame;
-	unsigned long origsp = newsp;
+	unsigned long newsp = 0;
 
 
 	/* Set up Signal Frame */
 	/* Set up Signal Frame */
 	/* Put a Real Time Context onto stack */
 	/* Put a Real Time Context onto stack */
-	newsp -= sizeof(*rt_sf);
-	rt_sf = (struct rt_sigframe __user *)newsp;
-
-	/* create a stack frame for the caller of the handler */
-	newsp -= __SIGNAL_FRAMESIZE + 16;
-
-	if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
+	rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf));
+	if (unlikely(rt_sf == NULL))
 		goto badframe;
 		goto badframe;
 
 
 	/* Put the siginfo & fill in most of the ucontext */
 	/* Put the siginfo & fill in most of the ucontext */
@@ -770,8 +740,12 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
 
 
 	current->thread.fpscr.val = 0;	/* turn off all fp exceptions */
 	current->thread.fpscr.val = 0;	/* turn off all fp exceptions */
 
 
+	/* create a stack frame for the caller of the handler */
+	newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
 	if (put_user(regs->gpr[1], (u32 __user *)newsp))
 	if (put_user(regs->gpr[1], (u32 __user *)newsp))
 		goto badframe;
 		goto badframe;
+
+	/* Fill registers for signal handler */
 	regs->gpr[1] = newsp;
 	regs->gpr[1] = newsp;
 	regs->gpr[3] = sig;
 	regs->gpr[3] = sig;
 	regs->gpr[4] = (unsigned long) &rt_sf->info;
 	regs->gpr[4] = (unsigned long) &rt_sf->info;
@@ -1015,27 +989,18 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
 /*
 /*
  * OK, we're invoking a handler
  * OK, we're invoking a handler
  */
  */
-static int handle_signal(unsigned long sig, struct k_sigaction *ka,
-		siginfo_t *info, sigset_t *oldset, struct pt_regs *regs,
-		unsigned long newsp)
+int handle_signal32(unsigned long sig, struct k_sigaction *ka,
+		    siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 {
 {
 	struct sigcontext __user *sc;
 	struct sigcontext __user *sc;
-	struct sigregs __user *frame;
-	unsigned long origsp = newsp;
+	struct sigframe __user *frame;
+	unsigned long newsp = 0;
 
 
 	/* Set up Signal Frame */
 	/* Set up Signal Frame */
-	newsp -= sizeof(struct sigregs);
-	frame = (struct sigregs __user *) newsp;
-
-	/* Put a sigcontext on the stack */
-	newsp -= sizeof(*sc);
-	sc = (struct sigcontext __user *) newsp;
-
-	/* create a stack frame for the caller of the handler */
-	newsp -= __SIGNAL_FRAMESIZE;
-
-	if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (unlikely(frame == NULL))
 		goto badframe;
 		goto badframe;
+	sc = (struct sigcontext __user *) &frame->sctx;
 
 
 #if _NSIG != 64
 #if _NSIG != 64
 #error "Please adjust handle_signal()"
 #error "Please adjust handle_signal()"
@@ -1047,7 +1012,7 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
 #else
 #else
 	    || __put_user(oldset->sig[1], &sc->_unused[3])
 	    || __put_user(oldset->sig[1], &sc->_unused[3])
 #endif
 #endif
-	    || __put_user(to_user_ptr(frame), &sc->regs)
+	    || __put_user(to_user_ptr(&frame->mctx), &sc->regs)
 	    || __put_user(sig, &sc->signal))
 	    || __put_user(sig, &sc->signal))
 		goto badframe;
 		goto badframe;
 
 
@@ -1063,8 +1028,11 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
 
 
 	current->thread.fpscr.val = 0;	/* turn off all fp exceptions */
 	current->thread.fpscr.val = 0;	/* turn off all fp exceptions */
 
 
+	/* create a stack frame for the caller of the handler */
+	newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
 	if (put_user(regs->gpr[1], (u32 __user *)newsp))
 	if (put_user(regs->gpr[1], (u32 __user *)newsp))
 		goto badframe;
 		goto badframe;
+
 	regs->gpr[1] = newsp;
 	regs->gpr[1] = newsp;
 	regs->gpr[3] = sig;
 	regs->gpr[3] = sig;
 	regs->gpr[4] = (unsigned long) sc;
 	regs->gpr[4] = (unsigned long) sc;
@@ -1126,106 +1094,3 @@ badframe:
 	force_sig(SIGSEGV, current);
 	force_sig(SIGSEGV, current);
 	return 0;
 	return 0;
 }
 }
-
-/*
- * Note that 'init' is a special process: it doesn't get signals it doesn't
- * want to handle. Thus you cannot kill init even with a SIGKILL even by
- * mistake.
- */
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
-{
-	siginfo_t info;
-	struct k_sigaction ka;
-	unsigned int newsp;
-	int signr, ret;
-
-#ifdef CONFIG_PPC32
-	if (try_to_freeze()) {
-		signr = 0;
-		if (!signal_pending(current))
-			goto no_signal;
-	}
-#endif
-
-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
-		oldset = &current->saved_sigmask;
-	else if (!oldset)
-		oldset = &current->blocked;
-
-	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-#ifdef CONFIG_PPC32
-no_signal:
-#endif
-	if (TRAP(regs) == 0x0C00		/* System Call! */
-	    && regs->ccr & 0x10000000		/* error signalled */
-	    && ((ret = regs->gpr[3]) == ERESTARTSYS
-		|| ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
-		|| ret == ERESTART_RESTARTBLOCK)) {
-
-		if (signr > 0
-		    && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
-			|| (ret == ERESTARTSYS
-			    && !(ka.sa.sa_flags & SA_RESTART)))) {
-			/* make the system call return an EINTR error */
-			regs->result = -EINTR;
-			regs->gpr[3] = EINTR;
-			/* note that the cr0.SO bit is already set */
-		} else {
-			regs->nip -= 4;	/* Back up & retry system call */
-			regs->result = 0;
-			regs->trap = 0;
-			if (ret == ERESTART_RESTARTBLOCK)
-				regs->gpr[0] = __NR_restart_syscall;
-			else
-				regs->gpr[3] = regs->orig_gpr3;
-		}
-	}
-
-	if (signr == 0) {
-		/* No signal to deliver -- put the saved sigmask back */
-		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-			clear_thread_flag(TIF_RESTORE_SIGMASK);
-			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
-		}
-		return 0;		/* no signals delivered */
-	}
-
-	if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
-	    && !on_sig_stack(regs->gpr[1]))
-		newsp = current->sas_ss_sp + current->sas_ss_size;
-	else
-		newsp = regs->gpr[1];
-	newsp &= ~0xfUL;
-
-#ifdef CONFIG_PPC64
-	/*
-	 * Reenable the DABR before delivering the signal to
-	 * user space. The DABR will have been cleared if it
-	 * triggered inside the kernel.
-	 */
-	if (current->thread.dabr)
-		set_dabr(current->thread.dabr);
-#endif
-
-	/* Whee!  Actually deliver the signal.  */
-	if (ka.sa.sa_flags & SA_SIGINFO)
-		ret = handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
-	else
-		ret = handle_signal(signr, &ka, &info, oldset, regs, newsp);
-
-	if (ret) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			  &ka.sa.sa_mask);
-		if (!(ka.sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, signr);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-		/* A signal was successfully delivered; the saved sigmask is in
-		   its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
-		if (test_thread_flag(TIF_RESTORE_SIGMASK))
-			clear_thread_flag(TIF_RESTORE_SIGMASK);
-	}
-
-	return ret;
-}

+ 5 - 177
arch/powerpc/kernel/signal_64.c

@@ -34,9 +34,9 @@
 #include <asm/syscalls.h>
 #include <asm/syscalls.h>
 #include <asm/vdso.h>
 #include <asm/vdso.h>
 
 
-#define DEBUG_SIG 0
+#include "signal.h"
 
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+#define DEBUG_SIG 0
 
 
 #define GP_REGS_SIZE	min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
 #define GP_REGS_SIZE	min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
 #define FP_REGS_SIZE	sizeof(elf_fpregset_t)
 #define FP_REGS_SIZE	sizeof(elf_fpregset_t)
@@ -64,14 +64,6 @@ struct rt_sigframe {
 	char abigap[288];
 	char abigap[288];
 } __attribute__ ((aligned (16)));
 } __attribute__ ((aligned (16)));
 
 
-long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5,
-		     unsigned long r6, unsigned long r7, unsigned long r8,
-		     struct pt_regs *regs)
-{
-	return do_sigaltstack(uss, uoss, regs->gpr[1]);
-}
-
-
 /*
 /*
  * Set up the sigcontext for the signal frame.
  * Set up the sigcontext for the signal frame.
  */
  */
@@ -207,25 +199,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
 	return err;
 	return err;
 }
 }
 
 
-/*
- * Allocate space for the signal frame
- */
-static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-				  size_t frame_size)
-{
-        unsigned long newsp;
-
-        /* Default to using normal stack */
-        newsp = regs->gpr[1];
-
-	if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) {
-		if (! on_sig_stack(regs->gpr[1]))
-			newsp = (current->sas_ss_sp + current->sas_ss_size);
-	}
-
-        return (void __user *)((newsp - frame_size) & -16ul);
-}
-
 /*
 /*
  * Setup the trampoline code on the stack
  * Setup the trampoline code on the stack
  */
  */
@@ -252,19 +225,6 @@ static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
 	return err;
 	return err;
 }
 }
 
 
-/*
- * Restore the user process's signal mask (also used by signal32.c)
- */
-void restore_sigmask(sigset_t *set)
-{
-	sigdelsetmask(set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = *set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-}
-
-
 /*
 /*
  * Handle {get,set,swap}_context operations
  * Handle {get,set,swap}_context operations
  */
  */
@@ -359,7 +319,7 @@ badframe:
 	return 0;
 	return 0;
 }
 }
 
 
-static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
+int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
 		sigset_t *set, struct pt_regs *regs)
 		sigset_t *set, struct pt_regs *regs)
 {
 {
 	/* Handler is *really* a pointer to the function descriptor for
 	/* Handler is *really* a pointer to the function descriptor for
@@ -373,8 +333,7 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
 	long err = 0;
 	long err = 0;
 
 
 	frame = get_sigframe(ka, regs, sizeof(*frame));
 	frame = get_sigframe(ka, regs, sizeof(*frame));
-
-	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+	if (unlikely(frame == NULL))
 		goto badframe;
 		goto badframe;
 
 
 	err |= __put_user(&frame->info, &frame->pinfo);
 	err |= __put_user(&frame->info, &frame->pinfo);
@@ -411,7 +370,7 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
 	funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler;
 	funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler;
 
 
 	/* Allocate a dummy caller frame for the signal handler. */
 	/* Allocate a dummy caller frame for the signal handler. */
-	newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
+	newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
 	err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
 	err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
 
 
 	/* Set up "regs" so we "return" to the signal handler. */
 	/* Set up "regs" so we "return" to the signal handler. */
@@ -442,134 +401,3 @@ badframe:
 	force_sigsegv(signr, current);
 	force_sigsegv(signr, current);
 	return 0;
 	return 0;
 }
 }
-
-
-/*
- * OK, we're invoking a handler
- */
-static int handle_signal(unsigned long sig, struct k_sigaction *ka,
-			 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
-{
-	int ret;
-
-	/* Set up Signal Frame */
-	ret = setup_rt_frame(sig, ka, info, oldset, regs);
-
-	if (ret) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked,sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
-
-	return ret;
-}
-
-static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
-{
-	switch ((int)regs->result) {
-	case -ERESTART_RESTARTBLOCK:
-	case -ERESTARTNOHAND:
-		/* ERESTARTNOHAND means that the syscall should only be
-		 * restarted if there was no handler for the signal, and since
-		 * we only get here if there is a handler, we dont restart.
-		 */
-		regs->result = -EINTR;
-		regs->gpr[3] = EINTR;
-		regs->ccr |= 0x10000000;
-		break;
-	case -ERESTARTSYS:
-		/* ERESTARTSYS means to restart the syscall if there is no
-		 * handler or the handler was registered with SA_RESTART
-		 */
-		if (!(ka->sa.sa_flags & SA_RESTART)) {
-			regs->result = -EINTR;
-			regs->gpr[3] = EINTR;
-			regs->ccr |= 0x10000000;
-			break;
-		}
-		/* fallthrough */
-	case -ERESTARTNOINTR:
-		/* ERESTARTNOINTR means that the syscall should be
-		 * called again after the signal handler returns.
-		 */
-		regs->gpr[3] = regs->orig_gpr3;
-		regs->nip -= 4;
-		regs->result = 0;
-		break;
-	}
-}
-
-/*
- * Note that 'init' is a special process: it doesn't get signals it doesn't
- * want to handle. Thus you cannot kill init even with a SIGKILL even by
- * mistake.
- */
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
-{
-	siginfo_t info;
-	int signr;
-	struct k_sigaction ka;
-
-	/*
-	 * If the current thread is 32 bit - invoke the
-	 * 32 bit signal handling code
-	 */
-	if (test_thread_flag(TIF_32BIT))
-		return do_signal32(oldset, regs);
-
-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
-		oldset = &current->saved_sigmask;
-	else if (!oldset)
-		oldset = &current->blocked;
-
-	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-	if (signr > 0) {
-		int ret;
-
-		/* Whee!  Actually deliver the signal.  */
-		if (TRAP(regs) == 0x0C00)
-			syscall_restart(regs, &ka);
-
-		/*
-		 * Reenable the DABR before delivering the signal to
-		 * user space. The DABR will have been cleared if it
-		 * triggered inside the kernel.
-		 */
-		if (current->thread.dabr)
-			set_dabr(current->thread.dabr);
-
-		ret = handle_signal(signr, &ka, &info, oldset, regs);
-
-		/* If a signal was successfully delivered, the saved sigmask is in
-		   its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
-		if (ret && test_thread_flag(TIF_RESTORE_SIGMASK))
-			clear_thread_flag(TIF_RESTORE_SIGMASK);
-
-		return ret;
-	}
-
-	if (TRAP(regs) == 0x0C00) {	/* System Call! */
-		if ((int)regs->result == -ERESTARTNOHAND ||
-		    (int)regs->result == -ERESTARTSYS ||
-		    (int)regs->result == -ERESTARTNOINTR) {
-			regs->gpr[3] = regs->orig_gpr3;
-			regs->nip -= 4; /* Back up & retry system call */
-			regs->result = 0;
-		} else if ((int)regs->result == -ERESTART_RESTARTBLOCK) {
-			regs->gpr[0] = __NR_restart_syscall;
-			regs->nip -= 4;
-			regs->result = 0;
-		}
-	}
-	/* No signal to deliver -- put the saved sigmask back */
-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
-		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(do_signal);

+ 2 - 3
arch/powerpc/kernel/sysfs.c

@@ -442,12 +442,14 @@ int sysfs_add_device_to_node(struct sys_device *dev, int nid)
 	return sysfs_create_link(&node->sysdev.kobj, &dev->kobj,
 	return sysfs_create_link(&node->sysdev.kobj, &dev->kobj,
 			kobject_name(&dev->kobj));
 			kobject_name(&dev->kobj));
 }
 }
+EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
 
 
 void sysfs_remove_device_from_node(struct sys_device *dev, int nid)
 void sysfs_remove_device_from_node(struct sys_device *dev, int nid)
 {
 {
 	struct node *node = &node_devices[nid];
 	struct node *node = &node_devices[nid];
 	sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj));
 	sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj));
 }
 }
+EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
 
 
 #else
 #else
 static void register_nodes(void)
 static void register_nodes(void)
@@ -457,9 +459,6 @@ static void register_nodes(void)
 
 
 #endif
 #endif
 
 
-EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
-EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
-
 /* Only valid if CPU is present. */
 /* Only valid if CPU is present. */
 static ssize_t show_physical_id(struct sys_device *dev, char *buf)
 static ssize_t show_physical_id(struct sys_device *dev, char *buf)
 {
 {

+ 41 - 24
arch/powerpc/kernel/time.c

@@ -77,9 +77,8 @@
 /* keep track of when we need to update the rtc */
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
 time_t last_rtc_update;
 #ifdef CONFIG_PPC_ISERIES
 #ifdef CONFIG_PPC_ISERIES
-unsigned long iSeries_recal_titan = 0;
-unsigned long iSeries_recal_tb = 0; 
-static unsigned long first_settimeofday = 1;
+static unsigned long __initdata iSeries_recal_titan;
+static signed long __initdata iSeries_recal_tb;
 #endif
 #endif
 
 
 /* The decrementer counts down by 128 every 128ns on a 601. */
 /* The decrementer counts down by 128 every 128ns on a 601. */
@@ -113,8 +112,9 @@ u64 ticklen_to_xs;	/* 0.64 fraction */
 DEFINE_SPINLOCK(rtc_lock);
 DEFINE_SPINLOCK(rtc_lock);
 EXPORT_SYMBOL_GPL(rtc_lock);
 EXPORT_SYMBOL_GPL(rtc_lock);
 
 
-u64 tb_to_ns_scale;
-unsigned tb_to_ns_shift;
+static u64 tb_to_ns_scale __read_mostly;
+static unsigned tb_to_ns_shift __read_mostly;
+static unsigned long boot_tb __read_mostly;
 
 
 struct gettimeofday_struct do_gtod;
 struct gettimeofday_struct do_gtod;
 
 
@@ -214,7 +214,6 @@ static void account_process_time(struct pt_regs *regs)
  	run_posix_cpu_timers(current);
  	run_posix_cpu_timers(current);
 }
 }
 
 
-#ifdef CONFIG_PPC_SPLPAR
 /*
 /*
  * Stuff for accounting stolen time.
  * Stuff for accounting stolen time.
  */
  */
@@ -222,19 +221,28 @@ struct cpu_purr_data {
 	int	initialized;			/* thread is running */
 	int	initialized;			/* thread is running */
 	u64	tb;			/* last TB value read */
 	u64	tb;			/* last TB value read */
 	u64	purr;			/* last PURR value read */
 	u64	purr;			/* last PURR value read */
-	spinlock_t lock;
 };
 };
 
 
+/*
+ * Each entry in the cpu_purr_data array is manipulated only by its
+ * "owner" cpu -- usually in the timer interrupt but also occasionally
+ * in process context for cpu online.  As long as cpus do not touch
+ * each others' cpu_purr_data, disabling local interrupts is
+ * sufficient to serialize accesses.
+ */
 static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data);
 static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data);
 
 
 static void snapshot_tb_and_purr(void *data)
 static void snapshot_tb_and_purr(void *data)
 {
 {
+	unsigned long flags;
 	struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
 	struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
 
 
+	local_irq_save(flags);
 	p->tb = mftb();
 	p->tb = mftb();
 	p->purr = mfspr(SPRN_PURR);
 	p->purr = mfspr(SPRN_PURR);
 	wmb();
 	wmb();
 	p->initialized = 1;
 	p->initialized = 1;
+	local_irq_restore(flags);
 }
 }
 
 
 /*
 /*
@@ -242,15 +250,14 @@ static void snapshot_tb_and_purr(void *data)
  */
  */
 void snapshot_timebases(void)
 void snapshot_timebases(void)
 {
 {
-	int cpu;
-
 	if (!cpu_has_feature(CPU_FTR_PURR))
 	if (!cpu_has_feature(CPU_FTR_PURR))
 		return;
 		return;
-	for_each_possible_cpu(cpu)
-		spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock);
 	on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1);
 	on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1);
 }
 }
 
 
+/*
+ * Must be called with interrupts disabled.
+ */
 void calculate_steal_time(void)
 void calculate_steal_time(void)
 {
 {
 	u64 tb, purr;
 	u64 tb, purr;
@@ -262,7 +269,6 @@ void calculate_steal_time(void)
 	pme = &per_cpu(cpu_purr_data, smp_processor_id());
 	pme = &per_cpu(cpu_purr_data, smp_processor_id());
 	if (!pme->initialized)
 	if (!pme->initialized)
 		return;		/* this can happen in early boot */
 		return;		/* this can happen in early boot */
-	spin_lock(&pme->lock);
 	tb = mftb();
 	tb = mftb();
 	purr = mfspr(SPRN_PURR);
 	purr = mfspr(SPRN_PURR);
 	stolen = (tb - pme->tb) - (purr - pme->purr);
 	stolen = (tb - pme->tb) - (purr - pme->purr);
@@ -270,9 +276,9 @@ void calculate_steal_time(void)
 		account_steal_time(current, stolen);
 		account_steal_time(current, stolen);
 	pme->tb = tb;
 	pme->tb = tb;
 	pme->purr = purr;
 	pme->purr = purr;
-	spin_unlock(&pme->lock);
 }
 }
 
 
+#ifdef CONFIG_PPC_SPLPAR
 /*
 /*
  * Must be called before the cpu is added to the online map when
  * Must be called before the cpu is added to the online map when
  * a cpu is being brought up at runtime.
  * a cpu is being brought up at runtime.
@@ -284,12 +290,12 @@ static void snapshot_purr(void)
 
 
 	if (!cpu_has_feature(CPU_FTR_PURR))
 	if (!cpu_has_feature(CPU_FTR_PURR))
 		return;
 		return;
+	local_irq_save(flags);
 	pme = &per_cpu(cpu_purr_data, smp_processor_id());
 	pme = &per_cpu(cpu_purr_data, smp_processor_id());
-	spin_lock_irqsave(&pme->lock, flags);
 	pme->tb = mftb();
 	pme->tb = mftb();
 	pme->purr = mfspr(SPRN_PURR);
 	pme->purr = mfspr(SPRN_PURR);
 	pme->initialized = 1;
 	pme->initialized = 1;
-	spin_unlock_irqrestore(&pme->lock, flags);
+	local_irq_restore(flags);
 }
 }
 
 
 #endif /* CONFIG_PPC_SPLPAR */
 #endif /* CONFIG_PPC_SPLPAR */
@@ -550,10 +556,15 @@ EXPORT_SYMBOL(profile_pc);
  * returned by the service processor for the timebase frequency.  
  * returned by the service processor for the timebase frequency.  
  */
  */
 
 
-static void iSeries_tb_recal(void)
+static int __init iSeries_tb_recal(void)
 {
 {
 	struct div_result divres;
 	struct div_result divres;
 	unsigned long titan, tb;
 	unsigned long titan, tb;
+
+	/* Make sure we only run on iSeries */
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
 	tb = get_tb();
 	tb = get_tb();
 	titan = HvCallXm_loadTod();
 	titan = HvCallXm_loadTod();
 	if ( iSeries_recal_titan ) {
 	if ( iSeries_recal_titan ) {
@@ -594,8 +605,18 @@ static void iSeries_tb_recal(void)
 	}
 	}
 	iSeries_recal_titan = titan;
 	iSeries_recal_titan = titan;
 	iSeries_recal_tb = tb;
 	iSeries_recal_tb = tb;
+
+	return 0;
 }
 }
-#endif
+late_initcall(iSeries_tb_recal);
+
+/* Called from platform early init */
+void __init iSeries_time_init_early(void)
+{
+	iSeries_recal_tb = get_tb();
+	iSeries_recal_titan = HvCallXm_loadTod();
+}
+#endif /* CONFIG_PPC_ISERIES */
 
 
 /*
 /*
  * For iSeries shared processors, we have to let the hypervisor
  * For iSeries shared processors, we have to let the hypervisor
@@ -735,7 +756,7 @@ unsigned long long sched_clock(void)
 {
 {
 	if (__USE_RTC())
 	if (__USE_RTC())
 		return get_rtc();
 		return get_rtc();
-	return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
+	return mulhdu(get_tb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift;
 }
 }
 
 
 int do_settimeofday(struct timespec *tv)
 int do_settimeofday(struct timespec *tv)
@@ -759,12 +780,6 @@ int do_settimeofday(struct timespec *tv)
 	 * to the RTC again, or write to the RTC but then they don't call
 	 * to the RTC again, or write to the RTC but then they don't call
 	 * settimeofday to perform this operation.
 	 * settimeofday to perform this operation.
 	 */
 	 */
-#ifdef CONFIG_PPC_ISERIES
-	if (firmware_has_feature(FW_FEATURE_ISERIES) && first_settimeofday) {
-		iSeries_tb_recal();
-		first_settimeofday = 0;
-	}
-#endif
 
 
 	/* Make userspace gettimeofday spin until we're done. */
 	/* Make userspace gettimeofday spin until we're done. */
 	++vdso_data->tb_update_count;
 	++vdso_data->tb_update_count;
@@ -960,6 +975,8 @@ void __init time_init(void)
 	}
 	}
 	tb_to_ns_scale = scale;
 	tb_to_ns_scale = scale;
 	tb_to_ns_shift = shift;
 	tb_to_ns_shift = shift;
+	/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
+	boot_tb = get_tb();
 
 
 	tm = get_boot_time();
 	tm = get_boot_time();
 
 

+ 1 - 1
arch/powerpc/kernel/vdso.c

@@ -670,7 +670,7 @@ static int __init vdso_init(void)
 	/*
 	/*
 	 * Fill up the "systemcfg" stuff for backward compatiblity
 	 * Fill up the "systemcfg" stuff for backward compatiblity
 	 */
 	 */
-	strcpy(vdso_data->eye_catcher, "SYSTEMCFG:PPC64");
+	strcpy((char *)vdso_data->eye_catcher, "SYSTEMCFG:PPC64");
 	vdso_data->version.major = SYSTEMCFG_MAJOR;
 	vdso_data->version.major = SYSTEMCFG_MAJOR;
 	vdso_data->version.minor = SYSTEMCFG_MINOR;
 	vdso_data->version.minor = SYSTEMCFG_MINOR;
 	vdso_data->processor = mfspr(SPRN_PVR);
 	vdso_data->processor = mfspr(SPRN_PVR);

+ 6 - 0
arch/powerpc/kernel/vmlinux.lds.S

@@ -7,6 +7,7 @@
 #define PROVIDE32(x)	PROVIDE(x)
 #define PROVIDE32(x)	PROVIDE(x)
 #endif
 #endif
 #include <asm-generic/vmlinux.lds.h>
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
 
 
 ENTRY(_stext)
 ENTRY(_stext)
 
 
@@ -211,6 +212,11 @@ SECTIONS
 		*(.data.cacheline_aligned)
 		*(.data.cacheline_aligned)
 	}
 	}
 
 
+	. = ALIGN(L1_CACHE_BYTES);
+	.data.read_mostly : {
+		*(.data.read_mostly)
+	}
+
 	. = ALIGN(PAGE_SIZE);
 	. = ALIGN(PAGE_SIZE);
 	__data_nosave : {
 	__data_nosave : {
 		__nosave_begin = .;
 		__nosave_begin = .;

+ 0 - 1
arch/powerpc/mm/44x_mmu.c

@@ -12,7 +12,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds

+ 0 - 1
arch/powerpc/mm/4xx_mmu.c

@@ -9,7 +9,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds

+ 1 - 2
arch/powerpc/mm/Makefile

@@ -11,8 +11,7 @@ obj-$(CONFIG_PPC32)		+= init_32.o pgtable_32.o mmu_context_32.o
 hash-$(CONFIG_PPC_NATIVE)	:= hash_native_64.o
 hash-$(CONFIG_PPC_NATIVE)	:= hash_native_64.o
 obj-$(CONFIG_PPC64)		+= init_64.o pgtable_64.o mmu_context_64.o \
 obj-$(CONFIG_PPC64)		+= init_64.o pgtable_64.o mmu_context_64.o \
 				   hash_utils_64.o hash_low_64.o tlb_64.o \
 				   hash_utils_64.o hash_low_64.o tlb_64.o \
-				   slb_low.o slb.o stab.o mmap.o imalloc.o \
-				   $(hash-y)
+				   slb_low.o slb.o stab.o mmap.o $(hash-y)
 obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu_32.o hash_low_32.o tlb_32.o
 obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu_32.o hash_low_32.o tlb_32.o
 obj-$(CONFIG_40x)		+= 4xx_mmu.o
 obj-$(CONFIG_40x)		+= 4xx_mmu.o
 obj-$(CONFIG_44x)		+= 44x_mmu.o
 obj-$(CONFIG_44x)		+= 44x_mmu.o

+ 1 - 1
arch/powerpc/mm/fault.c

@@ -380,7 +380,7 @@ out_of_memory:
 	}
 	}
 	printk("VM: killing process %s\n", current->comm);
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 	if (user_mode(regs))
-		do_exit(SIGKILL);
+		do_group_exit(SIGKILL);
 	return SIGKILL;
 	return SIGKILL;
 
 
 do_sigbus:
 do_sigbus:

+ 0 - 1
arch/powerpc/mm/fsl_booke_mmu.c

@@ -14,7 +14,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds

+ 13 - 14
arch/powerpc/mm/hash_native_64.c

@@ -104,7 +104,7 @@ static inline void tlbie(unsigned long va, int psize, int local)
 		spin_unlock(&native_tlbie_lock);
 		spin_unlock(&native_tlbie_lock);
 }
 }
 
 
-static inline void native_lock_hpte(hpte_t *hptep)
+static inline void native_lock_hpte(struct hash_pte *hptep)
 {
 {
 	unsigned long *word = &hptep->v;
 	unsigned long *word = &hptep->v;
 
 
@@ -116,7 +116,7 @@ static inline void native_lock_hpte(hpte_t *hptep)
 	}
 	}
 }
 }
 
 
-static inline void native_unlock_hpte(hpte_t *hptep)
+static inline void native_unlock_hpte(struct hash_pte *hptep)
 {
 {
 	unsigned long *word = &hptep->v;
 	unsigned long *word = &hptep->v;
 
 
@@ -128,7 +128,7 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
 			unsigned long pa, unsigned long rflags,
 			unsigned long pa, unsigned long rflags,
 			unsigned long vflags, int psize)
 			unsigned long vflags, int psize)
 {
 {
-	hpte_t *hptep = htab_address + hpte_group;
+	struct hash_pte *hptep = htab_address + hpte_group;
 	unsigned long hpte_v, hpte_r;
 	unsigned long hpte_v, hpte_r;
 	int i;
 	int i;
 
 
@@ -163,7 +163,7 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
 
 
 	hptep->r = hpte_r;
 	hptep->r = hpte_r;
 	/* Guarantee the second dword is visible before the valid bit */
 	/* Guarantee the second dword is visible before the valid bit */
-	__asm__ __volatile__ ("eieio" : : : "memory");
+	eieio();
 	/*
 	/*
 	 * Now set the first dword including the valid bit
 	 * Now set the first dword including the valid bit
 	 * NOTE: this also unlocks the hpte
 	 * NOTE: this also unlocks the hpte
@@ -177,7 +177,7 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
 
 
 static long native_hpte_remove(unsigned long hpte_group)
 static long native_hpte_remove(unsigned long hpte_group)
 {
 {
-	hpte_t *hptep;
+	struct hash_pte *hptep;
 	int i;
 	int i;
 	int slot_offset;
 	int slot_offset;
 	unsigned long hpte_v;
 	unsigned long hpte_v;
@@ -217,7 +217,7 @@ static long native_hpte_remove(unsigned long hpte_group)
 static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 				 unsigned long va, int psize, int local)
 				 unsigned long va, int psize, int local)
 {
 {
-	hpte_t *hptep = htab_address + slot;
+	struct hash_pte *hptep = htab_address + slot;
 	unsigned long hpte_v, want_v;
 	unsigned long hpte_v, want_v;
 	int ret = 0;
 	int ret = 0;
 
 
@@ -233,15 +233,14 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 	/* Even if we miss, we need to invalidate the TLB */
 	/* Even if we miss, we need to invalidate the TLB */
 	if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
 	if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
 		DBG_LOW(" -> miss\n");
 		DBG_LOW(" -> miss\n");
-		native_unlock_hpte(hptep);
 		ret = -1;
 		ret = -1;
 	} else {
 	} else {
 		DBG_LOW(" -> hit\n");
 		DBG_LOW(" -> hit\n");
 		/* Update the HPTE */
 		/* Update the HPTE */
 		hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
 		hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
 			(newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C));
 			(newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C));
-		native_unlock_hpte(hptep);
 	}
 	}
+	native_unlock_hpte(hptep);
 
 
 	/* Ensure it is out of the tlb too. */
 	/* Ensure it is out of the tlb too. */
 	tlbie(va, psize, local);
 	tlbie(va, psize, local);
@@ -251,7 +250,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 
 
 static long native_hpte_find(unsigned long va, int psize)
 static long native_hpte_find(unsigned long va, int psize)
 {
 {
-	hpte_t *hptep;
+	struct hash_pte *hptep;
 	unsigned long hash;
 	unsigned long hash;
 	unsigned long i, j;
 	unsigned long i, j;
 	long slot;
 	long slot;
@@ -294,7 +293,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
 {
 {
 	unsigned long vsid, va;
 	unsigned long vsid, va;
 	long slot;
 	long slot;
-	hpte_t *hptep;
+	struct hash_pte *hptep;
 
 
 	vsid = get_kernel_vsid(ea);
 	vsid = get_kernel_vsid(ea);
 	va = (vsid << 28) | (ea & 0x0fffffff);
 	va = (vsid << 28) | (ea & 0x0fffffff);
@@ -315,7 +314,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
 static void native_hpte_invalidate(unsigned long slot, unsigned long va,
 static void native_hpte_invalidate(unsigned long slot, unsigned long va,
 				   int psize, int local)
 				   int psize, int local)
 {
 {
-	hpte_t *hptep = htab_address + slot;
+	struct hash_pte *hptep = htab_address + slot;
 	unsigned long hpte_v;
 	unsigned long hpte_v;
 	unsigned long want_v;
 	unsigned long want_v;
 	unsigned long flags;
 	unsigned long flags;
@@ -345,7 +344,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
 #define LP_BITS		8
 #define LP_BITS		8
 #define LP_MASK(i)	((0xFF >> (i)) << LP_SHIFT)
 #define LP_MASK(i)	((0xFF >> (i)) << LP_SHIFT)
 
 
-static void hpte_decode(hpte_t *hpte, unsigned long slot,
+static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
 			int *psize, unsigned long *va)
 			int *psize, unsigned long *va)
 {
 {
 	unsigned long hpte_r = hpte->r;
 	unsigned long hpte_r = hpte->r;
@@ -415,7 +414,7 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot,
 static void native_hpte_clear(void)
 static void native_hpte_clear(void)
 {
 {
 	unsigned long slot, slots, flags;
 	unsigned long slot, slots, flags;
-	hpte_t *hptep = htab_address;
+	struct hash_pte *hptep = htab_address;
 	unsigned long hpte_v, va;
 	unsigned long hpte_v, va;
 	unsigned long pteg_count;
 	unsigned long pteg_count;
 	int psize;
 	int psize;
@@ -462,7 +461,7 @@ static void native_hpte_clear(void)
 static void native_flush_hash_range(unsigned long number, int local)
 static void native_flush_hash_range(unsigned long number, int local)
 {
 {
 	unsigned long va, hash, index, hidx, shift, slot;
 	unsigned long va, hash, index, hidx, shift, slot;
-	hpte_t *hptep;
+	struct hash_pte *hptep;
 	unsigned long hpte_v;
 	unsigned long hpte_v;
 	unsigned long want_v;
 	unsigned long want_v;
 	unsigned long flags;
 	unsigned long flags;

+ 1 - 1
arch/powerpc/mm/hash_utils_64.c

@@ -87,7 +87,7 @@ extern unsigned long dart_tablebase;
 static unsigned long _SDR1;
 static unsigned long _SDR1;
 struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
 struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
 
 
-hpte_t *htab_address;
+struct hash_pte *htab_address;
 unsigned long htab_size_bytes;
 unsigned long htab_size_bytes;
 unsigned long htab_hash_mask;
 unsigned long htab_hash_mask;
 int mmu_linear_psize = MMU_PAGE_4K;
 int mmu_linear_psize = MMU_PAGE_4K;

+ 0 - 313
arch/powerpc/mm/imalloc.c

@@ -1,313 +0,0 @@
-/*
- * c 2001 PPC 64 Team, 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.
- */
-
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <linux/mutex.h>
-#include <asm/cacheflush.h>
-
-#include "mmu_decl.h"
-
-static DEFINE_MUTEX(imlist_mutex);
-struct vm_struct * imlist = NULL;
-
-static int get_free_im_addr(unsigned long size, unsigned long *im_addr)
-{
-	unsigned long addr;
-	struct vm_struct **p, *tmp;
-
-	addr = ioremap_bot;
-	for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
-		if (size + addr < (unsigned long) tmp->addr)
-			break;
-		if ((unsigned long)tmp->addr >= ioremap_bot)
-			addr = tmp->size + (unsigned long) tmp->addr;
-		if (addr >= IMALLOC_END-size)
-			return 1;
-	}
-	*im_addr = addr;
-
-	return 0;
-}
-
-/* Return whether the region described by v_addr and size is a subset
- * of the region described by parent
- */
-static inline int im_region_is_subset(unsigned long v_addr, unsigned long size,
-			struct vm_struct *parent)
-{
-	return (int) (v_addr >= (unsigned long) parent->addr &&
-	              v_addr < (unsigned long) parent->addr + parent->size &&
-	    	      size < parent->size);
-}
-
-/* Return whether the region described by v_addr and size is a superset
- * of the region described by child
- */
-static int im_region_is_superset(unsigned long v_addr, unsigned long size,
-		struct vm_struct *child)
-{
-	struct vm_struct parent;
-
-	parent.addr = (void *) v_addr;
-	parent.size = size;
-
-	return im_region_is_subset((unsigned long) child->addr, child->size,
-			&parent);
-}
-
-/* Return whether the region described by v_addr and size overlaps
- * the region described by vm.  Overlapping regions meet the
- * following conditions:
- * 1) The regions share some part of the address space
- * 2) The regions aren't identical
- * 3) Neither region is a subset of the other
- */
-static int im_region_overlaps(unsigned long v_addr, unsigned long size,
-		     struct vm_struct *vm)
-{
-	if (im_region_is_superset(v_addr, size, vm))
-		return 0;
-
-	return (v_addr + size > (unsigned long) vm->addr + vm->size &&
-		v_addr < (unsigned long) vm->addr + vm->size) ||
-	       (v_addr < (unsigned long) vm->addr &&
-		v_addr + size > (unsigned long) vm->addr);
-}
-
-/* Determine imalloc status of region described by v_addr and size.
- * Can return one of the following:
- * IM_REGION_UNUSED   -  Entire region is unallocated in imalloc space.
- * IM_REGION_SUBSET -    Region is a subset of a region that is already
- * 			 allocated in imalloc space.
- * 		         vm will be assigned to a ptr to the parent region.
- * IM_REGION_EXISTS -    Exact region already allocated in imalloc space.
- *                       vm will be assigned to a ptr to the existing imlist
- *                       member.
- * IM_REGION_OVERLAPS -  Region overlaps an allocated region in imalloc space.
- * IM_REGION_SUPERSET -  Region is a superset of a region that is already
- *                       allocated in imalloc space.
- */
-static int im_region_status(unsigned long v_addr, unsigned long size,
-		    struct vm_struct **vm)
-{
-	struct vm_struct *tmp;
-
-	for (tmp = imlist; tmp; tmp = tmp->next)
-		if (v_addr < (unsigned long) tmp->addr + tmp->size)
-			break;
-
-	*vm = NULL;
-	if (tmp) {
-		if (im_region_overlaps(v_addr, size, tmp))
-			return IM_REGION_OVERLAP;
-
-		*vm = tmp;
-		if (im_region_is_subset(v_addr, size, tmp)) {
-			/* Return with tmp pointing to superset */
-			return IM_REGION_SUBSET;
-		}
-		if (im_region_is_superset(v_addr, size, tmp)) {
-			/* Return with tmp pointing to first subset */
-			return IM_REGION_SUPERSET;
-		}
-		else if (v_addr == (unsigned long) tmp->addr &&
-		 	 size == tmp->size) {
-			/* Return with tmp pointing to exact region */
-			return IM_REGION_EXISTS;
-		}
-	}
-
-	return IM_REGION_UNUSED;
-}
-
-static struct vm_struct * split_im_region(unsigned long v_addr, 
-		unsigned long size, struct vm_struct *parent)
-{
-	struct vm_struct *vm1 = NULL;
-	struct vm_struct *vm2 = NULL;
-	struct vm_struct *new_vm = NULL;
-	
-	vm1 = kmalloc(sizeof(*vm1), GFP_KERNEL);
-	if (vm1	== NULL) {
-		printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
-		return NULL;
-	}
-
-	if (v_addr == (unsigned long) parent->addr) {
-	        /* Use existing parent vm_struct to represent child, allocate
-		 * new one for the remainder of parent range
-		 */
-		vm1->size = parent->size - size;
-		vm1->addr = (void *) (v_addr + size);
-		vm1->next = parent->next;
-
-		parent->size = size;
-		parent->next = vm1;
-		new_vm = parent;
-	} else if (v_addr + size == (unsigned long) parent->addr + 
-			parent->size) {
-		/* Allocate new vm_struct to represent child, use existing
-		 * parent one for remainder of parent range
-		 */
-		vm1->size = size;
-		vm1->addr = (void *) v_addr;
-		vm1->next = parent->next;
-		new_vm = vm1;
-
-		parent->size -= size;
-		parent->next = vm1;
-	} else {
-	        /* Allocate two new vm_structs for the new child and 
-		 * uppermost remainder, and use existing parent one for the
-		 * lower remainder of parent range
-		 */
-		vm2 = kmalloc(sizeof(*vm2), GFP_KERNEL);
-		if (vm2 == NULL) {
-			printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
-			kfree(vm1);
-			return NULL;
-		}
-
-		vm1->size = size;
-		vm1->addr = (void *) v_addr;
-		vm1->next = vm2;
-		new_vm = vm1;
-
-		vm2->size = ((unsigned long) parent->addr + parent->size) - 
-				(v_addr + size);
-		vm2->addr = (void *) v_addr + size;
-		vm2->next = parent->next;
-
-		parent->size = v_addr - (unsigned long) parent->addr;
-		parent->next = vm1;
-	}
-
-	return new_vm;
-}
-
-static struct vm_struct * __add_new_im_area(unsigned long req_addr, 
-					    unsigned long size)
-{
-	struct vm_struct **p, *tmp, *area;
-		
-	for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
-		if (req_addr + size <= (unsigned long)tmp->addr)
-			break;
-	}
-	
-	area = kmalloc(sizeof(*area), GFP_KERNEL);
-	if (!area)
-		return NULL;
-	area->flags = 0;
-	area->addr = (void *)req_addr;
-	area->size = size;
-	area->next = *p;
-	*p = area;
-
-	return area;
-}
-
-static struct vm_struct * __im_get_area(unsigned long req_addr, 
-					unsigned long size,
-					int criteria)
-{
-	struct vm_struct *tmp;
-	int status;
-
-	status = im_region_status(req_addr, size, &tmp);
-	if ((criteria & status) == 0) {
-		return NULL;
-	}
-	
-	switch (status) {
-	case IM_REGION_UNUSED:
-		tmp = __add_new_im_area(req_addr, size);
-		break;
-	case IM_REGION_SUBSET:
-		tmp = split_im_region(req_addr, size, tmp);
-		break;
-	case IM_REGION_EXISTS:
-		/* Return requested region */
-		break;
-	case IM_REGION_SUPERSET:
-		/* Return first existing subset of requested region */
-		break;
-	default:
-		printk(KERN_ERR "%s() unexpected imalloc region status\n",
-				__FUNCTION__);
-		tmp = NULL;
-	}
-
-	return tmp;
-}
-
-struct vm_struct * im_get_free_area(unsigned long size)
-{
-	struct vm_struct *area;
-	unsigned long addr;
-	
-	mutex_lock(&imlist_mutex);
-	if (get_free_im_addr(size, &addr)) {
-		printk(KERN_ERR "%s() cannot obtain addr for size 0x%lx\n",
-				__FUNCTION__, size);
-		area = NULL;
-		goto next_im_done;
-	}
-
-	area = __im_get_area(addr, size, IM_REGION_UNUSED);
-	if (area == NULL) {
-		printk(KERN_ERR 
-		       "%s() cannot obtain area for addr 0x%lx size 0x%lx\n",
-			__FUNCTION__, addr, size);
-	}
-next_im_done:
-	mutex_unlock(&imlist_mutex);
-	return area;
-}
-
-struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
-		int criteria)
-{
-	struct vm_struct *area;
-
-	mutex_lock(&imlist_mutex);
-	area = __im_get_area(v_addr, size, criteria);
-	mutex_unlock(&imlist_mutex);
-	return area;
-}
-
-void im_free(void * addr)
-{
-	struct vm_struct **p, *tmp;
-  
-	if (!addr)
-		return;
-	if ((unsigned long) addr & ~PAGE_MASK) {
-		printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__,			addr);
-		return;
-	}
-	mutex_lock(&imlist_mutex);
-	for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
-		if (tmp->addr == addr) {
-			*p = tmp->next;
-			unmap_vm_area(tmp);
-			kfree(tmp);
-			mutex_unlock(&imlist_mutex);
-			return;
-		}
-	}
-	mutex_unlock(&imlist_mutex);
-	printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__,
-			addr);
-}

+ 0 - 1
arch/powerpc/mm/init_32.c

@@ -5,7 +5,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *  PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
  *  PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"

+ 0 - 1
arch/powerpc/mm/init_64.c

@@ -5,7 +5,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds

+ 0 - 3
arch/powerpc/mm/mem.c

@@ -5,7 +5,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *  PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
  *  PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
@@ -129,8 +128,6 @@ int __devinit arch_add_memory(int nid, u64 start, u64 size)
 	zone = pgdata->node_zones;
 	zone = pgdata->node_zones;
 
 
 	return __add_pages(zone, start_pfn, nr_pages);
 	return __add_pages(zone, start_pfn, nr_pages);
-
-	return 0;
 }
 }
 
 
 /*
 /*

+ 0 - 1
arch/powerpc/mm/mmu_context_32.c

@@ -11,7 +11,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds

+ 2 - 15
arch/powerpc/mm/mmu_decl.h

@@ -8,7 +8,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
@@ -40,8 +39,8 @@ extern int __map_without_bats;
 extern unsigned long ioremap_base;
 extern unsigned long ioremap_base;
 extern unsigned int rtas_data, rtas_size;
 extern unsigned int rtas_data, rtas_size;
 
 
-struct _PTE;
-extern struct _PTE *Hash, *Hash_end;
+struct hash_pte;
+extern struct hash_pte *Hash, *Hash_end;
 extern unsigned long Hash_size, Hash_mask;
 extern unsigned long Hash_size, Hash_mask;
 
 
 extern unsigned int num_tlbcam_entries;
 extern unsigned int num_tlbcam_entries;
@@ -90,16 +89,4 @@ static inline void flush_HPTE(unsigned context, unsigned long va,
 	else
 	else
 		_tlbie(va);
 		_tlbie(va);
 }
 }
-#else /* CONFIG_PPC64 */
-/* imalloc region types */
-#define IM_REGION_UNUSED	0x1
-#define IM_REGION_SUBSET	0x2
-#define IM_REGION_EXISTS	0x4
-#define IM_REGION_OVERLAP	0x8
-#define IM_REGION_SUPERSET	0x10
-
-extern struct vm_struct * im_get_free_area(unsigned long size);
-extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
-				      int region_type);
-extern void im_free(void *addr);
 #endif
 #endif

+ 0 - 123
arch/powerpc/mm/pgtable_32.c

@@ -8,7 +8,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
@@ -37,7 +36,6 @@
 unsigned long ioremap_base;
 unsigned long ioremap_base;
 unsigned long ioremap_bot;
 unsigned long ioremap_bot;
 EXPORT_SYMBOL(ioremap_bot);	/* aka VMALLOC_END */
 EXPORT_SYMBOL(ioremap_bot);	/* aka VMALLOC_END */
-int io_bat_index;
 
 
 #if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
 #if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
 #define HAVE_BATS	1
 #define HAVE_BATS	1
@@ -300,51 +298,6 @@ void __init mapin_ram(void)
 	}
 	}
 }
 }
 
 
-/* is x a power of 4? */
-#define is_power_of_4(x)	is_power_of_2(x) && (ffs(x) & 1)
-
-/*
- * Set up a mapping for a block of I/O.
- * virt, phys, size must all be page-aligned.
- * This should only be called before ioremap is called.
- */
-void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
-			     unsigned int size, int flags)
-{
-	int i;
-
-	if (virt > KERNELBASE && virt < ioremap_bot)
-		ioremap_bot = ioremap_base = virt;
-
-#ifdef HAVE_BATS
-	/*
-	 * Use a BAT for this if possible...
-	 */
-	if (io_bat_index < 2 && is_power_of_2(size)
-	    && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
-		setbat(io_bat_index, virt, phys, size, flags);
-		++io_bat_index;
-		return;
-	}
-#endif /* HAVE_BATS */
-
-#ifdef HAVE_TLBCAM
-	/*
-	 * Use a CAM for this if possible...
-	 */
-	if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size)
-	    && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
-		settlbcam(tlbcam_index, virt, phys, size, flags, 0);
-		++tlbcam_index;
-		return;
-	}
-#endif /* HAVE_TLBCAM */
-
-	/* No BATs available, put it in the page tables. */
-	for (i = 0; i < size; i += PAGE_SIZE)
-		map_page(virt + i, phys + i, flags);
-}
-
 /* Scan the real Linux page tables and return a PTE pointer for
 /* Scan the real Linux page tables and return a PTE pointer for
  * a virtual address in a context.
  * a virtual address in a context.
  * Returns true (1) if PTE was found, zero otherwise.  The pointer to
  * Returns true (1) if PTE was found, zero otherwise.  The pointer to
@@ -379,82 +332,6 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
         return(retval);
         return(retval);
 }
 }
 
 
-/* Find physical address for this virtual address.  Normally used by
- * I/O functions, but anyone can call it.
- */
-unsigned long iopa(unsigned long addr)
-{
-	unsigned long pa;
-
-	/* I don't know why this won't work on PMacs or CHRP.  It
-	 * appears there is some bug, or there is some implicit
-	 * mapping done not properly represented by BATs or in page
-	 * tables.......I am actively working on resolving this, but
-	 * can't hold up other stuff.  -- Dan
-	 */
-	pte_t *pte;
-	struct mm_struct *mm;
-
-	/* Check the BATs */
-	pa = v_mapped_by_bats(addr);
-	if (pa)
-		return pa;
-
-	/* Allow mapping of user addresses (within the thread)
-	 * for DMA if necessary.
-	 */
-	if (addr < TASK_SIZE)
-		mm = current->mm;
-	else
-		mm = &init_mm;
-
-	pa = 0;
-	if (get_pteptr(mm, addr, &pte, NULL)) {
-		pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
-		pte_unmap(pte);
-	}
-
-	return(pa);
-}
-
-/* This is will find the virtual address for a physical one....
- * Swiped from APUS, could be dangerous :-).
- * This is only a placeholder until I really find a way to make this
- * work.  -- Dan
- */
-unsigned long
-mm_ptov (unsigned long paddr)
-{
-	unsigned long ret;
-#if 0
-	if (paddr < 16*1024*1024)
-		ret = ZTWO_VADDR(paddr);
-	else {
-		int i;
-
-		for (i = 0; i < kmap_chunk_count;){
-			unsigned long phys = kmap_chunks[i++];
-			unsigned long size = kmap_chunks[i++];
-			unsigned long virt = kmap_chunks[i++];
-			if (paddr >= phys
-			    && paddr < (phys + size)){
-				ret = virt + paddr - phys;
-				goto exit;
-			}
-		}
-	
-		ret = (unsigned long) __va(paddr);
-	}
-exit:
-#ifdef DEBUGPV
-	printk ("PTOV(%lx)=%lx\n", paddr, ret);
-#endif
-#else
-	ret = (unsigned long)paddr + KERNELBASE;
-#endif
-	return ret;
-}
-
 #ifdef CONFIG_DEBUG_PAGEALLOC
 #ifdef CONFIG_DEBUG_PAGEALLOC
 
 
 static int __change_page_attr(struct page *page, pgprot_t prot)
 static int __change_page_attr(struct page *page, pgprot_t prot)

+ 49 - 157
arch/powerpc/mm/pgtable_64.c

@@ -7,7 +7,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@samba.org)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@samba.org)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
@@ -34,41 +33,27 @@
 #include <linux/stddef.h>
 #include <linux/stddef.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bootmem.h>
-#include <linux/highmem.h>
-#include <linux/idr.h>
-#include <linux/nodemask.h>
-#include <linux/module.h>
 
 
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/prom.h>
 #include <asm/prom.h>
-#include <asm/lmb.h>
-#include <asm/rtas.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/mmu_context.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 #include <asm/mmu.h>
-#include <asm/uaccess.h>
 #include <asm/smp.h>
 #include <asm/smp.h>
 #include <asm/machdep.h>
 #include <asm/machdep.h>
 #include <asm/tlb.h>
 #include <asm/tlb.h>
-#include <asm/eeh.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
-#include <asm/mmzone.h>
 #include <asm/cputable.h>
 #include <asm/cputable.h>
 #include <asm/sections.h>
 #include <asm/sections.h>
 #include <asm/system.h>
 #include <asm/system.h>
-#include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/abs_addr.h>
-#include <asm/vdso.h>
 #include <asm/firmware.h>
 #include <asm/firmware.h>
 
 
 #include "mmu_decl.h"
 #include "mmu_decl.h"
 
 
-unsigned long ioremap_bot = IMALLOC_BASE;
-static unsigned long phbs_io_bot = PHBS_IO_BASE;
+unsigned long ioremap_bot = IOREMAP_BASE;
 
 
 /*
 /*
  * map_io_page currently only called by __ioremap
  * map_io_page currently only called by __ioremap
@@ -102,8 +87,8 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
 		 * entry in the hardware page table.
 		 * entry in the hardware page table.
 		 *
 		 *
 		 */
 		 */
-		if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
-				      mmu_io_psize)) {
+		if (htab_bolt_mapping(ea, (unsigned long)ea + PAGE_SIZE,
+				      pa, flags, mmu_io_psize)) {
 			printk(KERN_ERR "Failed to do bolted mapping IO "
 			printk(KERN_ERR "Failed to do bolted mapping IO "
 			       "memory at %016lx !\n", pa);
 			       "memory at %016lx !\n", pa);
 			return -ENOMEM;
 			return -ENOMEM;
@@ -113,8 +98,11 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
 }
 }
 
 
 
 
-static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa,
-			    unsigned long ea, unsigned long size,
+/**
+ * __ioremap_at - Low level function to establish the page tables
+ *                for an IO mapping
+ */
+void __iomem * __ioremap_at(phys_addr_t pa, void *ea, unsigned long size,
 			    unsigned long flags)
 			    unsigned long flags)
 {
 {
 	unsigned long i;
 	unsigned long i;
@@ -122,17 +110,35 @@ static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa,
 	if ((flags & _PAGE_PRESENT) == 0)
 	if ((flags & _PAGE_PRESENT) == 0)
 		flags |= pgprot_val(PAGE_KERNEL);
 		flags |= pgprot_val(PAGE_KERNEL);
 
 
+	WARN_ON(pa & ~PAGE_MASK);
+	WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
+	WARN_ON(size & ~PAGE_MASK);
+
 	for (i = 0; i < size; i += PAGE_SIZE)
 	for (i = 0; i < size; i += PAGE_SIZE)
-		if (map_io_page(ea+i, pa+i, flags))
+		if (map_io_page((unsigned long)ea+i, pa+i, flags))
 			return NULL;
 			return NULL;
 
 
-	return (void __iomem *) (ea + (addr & ~PAGE_MASK));
+	return (void __iomem *)ea;
+}
+
+/**
+ * __iounmap_from - Low level function to tear down the page tables
+ *                  for an IO mapping. This is used for mappings that
+ *                  are manipulated manually, like partial unmapping of
+ *                  PCI IOs or ISA space.
+ */
+void __iounmap_at(void *ea, unsigned long size)
+{
+	WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
+	WARN_ON(size & ~PAGE_MASK);
+
+	unmap_kernel_range((unsigned long)ea, size);
 }
 }
 
 
 void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
 void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
 			 unsigned long flags)
 			 unsigned long flags)
 {
 {
-	unsigned long pa, ea;
+	phys_addr_t paligned;
 	void __iomem *ret;
 	void __iomem *ret;
 
 
 	/*
 	/*
@@ -144,27 +150,30 @@ void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
 	 * IMALLOC_END
 	 * IMALLOC_END
 	 * 
 	 * 
 	 */
 	 */
-	pa = addr & PAGE_MASK;
-	size = PAGE_ALIGN(addr + size) - pa;
+	paligned = addr & PAGE_MASK;
+	size = PAGE_ALIGN(addr + size) - paligned;
 
 
-	if ((size == 0) || (pa == 0))
+	if ((size == 0) || (paligned == 0))
 		return NULL;
 		return NULL;
 
 
 	if (mem_init_done) {
 	if (mem_init_done) {
 		struct vm_struct *area;
 		struct vm_struct *area;
-		area = im_get_free_area(size);
+
+		area = __get_vm_area(size, VM_IOREMAP,
+				     ioremap_bot, IOREMAP_END);
 		if (area == NULL)
 		if (area == NULL)
 			return NULL;
 			return NULL;
-		ea = (unsigned long)(area->addr);
-		ret = __ioremap_com(addr, pa, ea, size, flags);
+		ret = __ioremap_at(paligned, area->addr, size, flags);
 		if (!ret)
 		if (!ret)
-			im_free(area->addr);
+			vunmap(area->addr);
 	} else {
 	} else {
-		ea = ioremap_bot;
-		ret = __ioremap_com(addr, pa, ea, size, flags);
+		ret = __ioremap_at(paligned, (void *)ioremap_bot, size, flags);
 		if (ret)
 		if (ret)
 			ioremap_bot += size;
 			ioremap_bot += size;
 	}
 	}
+
+	if (ret)
+		ret += addr & ~PAGE_MASK;
 	return ret;
 	return ret;
 }
 }
 
 
@@ -187,62 +196,9 @@ void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
 }
 }
 
 
 
 
-#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
-
-int __ioremap_explicit(phys_addr_t pa, unsigned long ea,
-		       unsigned long size, unsigned long flags)
-{
-	struct vm_struct *area;
-	void __iomem *ret;
-	
-	/* For now, require page-aligned values for pa, ea, and size */
-	if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
-	    !IS_PAGE_ALIGNED(size)) {
-		printk(KERN_ERR	"unaligned value in %s\n", __FUNCTION__);
-		return 1;
-	}
-	
-	if (!mem_init_done) {
-		/* Two things to consider in this case:
-		 * 1) No records will be kept (imalloc, etc) that the region
-		 *    has been remapped
-		 * 2) It won't be easy to iounmap() the region later (because
-		 *    of 1)
-		 */
-		;
-	} else {
-		area = im_get_area(ea, size,
-			IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
-		if (area == NULL) {
-			/* Expected when PHB-dlpar is in play */
-			return 1;
-		}
-		if (ea != (unsigned long) area->addr) {
-			printk(KERN_ERR "unexpected addr return from "
-			       "im_get_area\n");
-			return 1;
-		}
-	}
-	
-	ret = __ioremap_com(pa, pa, ea, size, flags);
-	if (ret == NULL) {
-		printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
-		return 1;
-	}
-	if (ret != (void *) ea) {
-		printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
-		return 1;
-	}
-
-	return 0;
-}
-
 /*  
 /*  
  * Unmap an IO region and remove it from imalloc'd list.
  * Unmap an IO region and remove it from imalloc'd list.
  * Access to IO memory should be serialized by driver.
  * Access to IO memory should be serialized by driver.
- * This code is modeled after vmalloc code - unmap_vm_area()
- *
- * XXX	what about calls before mem_init_done (ie python_countermeasures())
  */
  */
 void __iounmap(volatile void __iomem *token)
 void __iounmap(volatile void __iomem *token)
 {
 {
@@ -251,9 +207,14 @@ void __iounmap(volatile void __iomem *token)
 	if (!mem_init_done)
 	if (!mem_init_done)
 		return;
 		return;
 	
 	
-	addr = (void *) ((unsigned long __force) token & PAGE_MASK);
-
-	im_free(addr);
+	addr = (void *) ((unsigned long __force)
+			 PCI_FIX_ADDR(token) & PAGE_MASK);
+	if ((unsigned long)addr < ioremap_bot) {
+		printk(KERN_WARNING "Attempt to iounmap early bolted mapping"
+		       " at 0x%p\n", addr);
+		return;
+	}
+	vunmap(addr);
 }
 }
 
 
 void iounmap(volatile void __iomem *token)
 void iounmap(volatile void __iomem *token)
@@ -264,77 +225,8 @@ void iounmap(volatile void __iomem *token)
 		__iounmap(token);
 		__iounmap(token);
 }
 }
 
 
-static int iounmap_subset_regions(unsigned long addr, unsigned long size)
-{
-	struct vm_struct *area;
-
-	/* Check whether subsets of this region exist */
-	area = im_get_area(addr, size, IM_REGION_SUPERSET);
-	if (area == NULL)
-		return 1;
-
-	while (area) {
-		iounmap((void __iomem *) area->addr);
-		area = im_get_area(addr, size,
-				IM_REGION_SUPERSET);
-	}
-
-	return 0;
-}
-
-int __iounmap_explicit(volatile void __iomem *start, unsigned long size)
-{
-	struct vm_struct *area;
-	unsigned long addr;
-	int rc;
-	
-	addr = (unsigned long __force) start & PAGE_MASK;
-
-	/* Verify that the region either exists or is a subset of an existing
-	 * region.  In the latter case, split the parent region to create 
-	 * the exact region 
-	 */
-	area = im_get_area(addr, size, 
-			    IM_REGION_EXISTS | IM_REGION_SUBSET);
-	if (area == NULL) {
-		/* Determine whether subset regions exist.  If so, unmap */
-		rc = iounmap_subset_regions(addr, size);
-		if (rc) {
-			printk(KERN_ERR
-			       "%s() cannot unmap nonexistent range 0x%lx\n",
- 				__FUNCTION__, addr);
-			return 1;
-		}
-	} else {
-		iounmap((void __iomem *) area->addr);
-	}
-	/*
-	 * FIXME! This can't be right:
-	iounmap(area->addr);
-	 * Maybe it should be "iounmap(area);"
-	 */
-	return 0;
-}
-
 EXPORT_SYMBOL(ioremap);
 EXPORT_SYMBOL(ioremap);
 EXPORT_SYMBOL(ioremap_flags);
 EXPORT_SYMBOL(ioremap_flags);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(__iounmap);
 EXPORT_SYMBOL(__iounmap);
-
-static DEFINE_SPINLOCK(phb_io_lock);
-
-void __iomem * reserve_phb_iospace(unsigned long size)
-{
-	void __iomem *virt_addr;
-		
-	if (phbs_io_bot >= IMALLOC_BASE) 
-		panic("reserve_phb_iospace(): phb io space overflow\n");
-			
-	spin_lock(&phb_io_lock);
-	virt_addr = (void __iomem *) phbs_io_bot;
-	phbs_io_bot += size;
-	spin_unlock(&phb_io_lock);
-
-	return virt_addr;
-}

+ 3 - 4
arch/powerpc/mm/ppc_mmu_32.c

@@ -11,7 +11,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *
  *  Derived from "arch/i386/mm/init.c"
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
@@ -35,12 +34,12 @@
 
 
 #include "mmu_decl.h"
 #include "mmu_decl.h"
 
 
-PTE *Hash, *Hash_end;
+struct hash_pte *Hash, *Hash_end;
 unsigned long Hash_size, Hash_mask;
 unsigned long Hash_size, Hash_mask;
 unsigned long _SDR1;
 unsigned long _SDR1;
 
 
 union ubat {			/* BAT register values to be loaded */
 union ubat {			/* BAT register values to be loaded */
-	BAT	bat;
+	struct ppc_bat bat;
 	u32	word[2];
 	u32	word[2];
 } BATS[8][2];			/* 8 pairs of IBAT, DBAT */
 } BATS[8][2];			/* 8 pairs of IBAT, DBAT */
 
 
@@ -245,7 +244,7 @@ void __init MMU_init_hw(void)
 	cacheable_memzero(Hash, Hash_size);
 	cacheable_memzero(Hash, Hash_size);
 	_SDR1 = __pa(Hash) | SDR1_LOW_BITS;
 	_SDR1 = __pa(Hash) | SDR1_LOW_BITS;
 
 
-	Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
+	Hash_end = (struct hash_pte *) ((unsigned long)Hash + Hash_size);
 
 
 	printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
 	printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
 	       total_memory >> 20, Hash_size >> 10, Hash);
 	       total_memory >> 20, Hash_size >> 10, Hash);

部分文件因为文件数量过多而无法显示