LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [Cbe-oss-dev] [patch 02/13] powerpc: add hvc backend for rtas
From: Olof Johansson @ 2006-03-23 22:49 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-kernel, linuxppc-dev, cbe-oss-dev, Arnd Bergmann
In-Reply-To: <200603232336.19683.arnd@arndb.de>

On Thu, Mar 23, 2006 at 11:36:19PM +0100, Arnd Bergmann wrote:
> Am Thursday 23 March 2006 22:32 schrieb Olof Johansson:
> > > +static inline int hvc_rtas_write_console(uint32_t vtermno, const char
> > > *buf, int count) +{
> > > +     int done;
> > > +
> > > +     /* if there is more than one character to be displayed, wait a bit */
> > > +     for (done = 0; done < count; done++) { 
> > > +             int result;
> > > +             result = rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[done]);
> > > +             if (result) 
> > > +                     break;
> >
> > Why introduce a scope-local variable just to check it?
> >                 if(rtas_call(...))   would be cleaner.
> 
> I don't like doing the important stuff inside of another expression,
> and I prefer conditions not to have side-effects.
> If nobody else has a strong opinion on it, I'd prefer to leave it.

Ok. It just looked silly to have the declaration/assignment/test and no
use of result outside of those three lines.

> BTW, who is the current maintainer of hvc_console? Ryan is working on
> glibc nowadays, right?

That's what I think IBM pays him to do, that's never stopped people from
maintaining other code in the past though. :-)


-Olof

^ permalink raw reply

* Re: [PATCH] return to OF via trap, not exit
From: Michael Ellerman @ 2006-03-23 23:11 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20060323210357.GC24667@suse.de>

On Thu, 2006-03-23 at 22:03 +0100, Olaf Hering wrote:
>  On Mon, Mar 06, Segher Boessenkool wrote:
> 
> > That's better than always calling trap, sure.  Is there any reason
> > you can't just do it on Macs though?  Because the problem you're trying
> > to work around only happens there.
> 
> Maybe something like this? Only compile tested
> 
> 
> Do not call prom exit prom_panic. It clears the screen and the exit message is lost.
> On some (or all?) pmacs it causes another crash when OF tries to print the
> date and time in its banner.
> 
> Set of_platform earlier to catch more prom_panic() calls.

Looks reasonable, assuming it works :)

cheers

-- 
Michael Ellerman
IBM OzLabs

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

^ permalink raw reply

* Re: [PATCH] kdump: Fix for machine checkstop on DMA fault
From: Olof Johansson @ 2006-03-23 23:11 UTC (permalink / raw)
  To: Haren Myneni
  Cc: Milton Miller, Michael Ellerman, linuxppc-dev, Paul Mackerras,
	Olaf Hering, ellerman
In-Reply-To: <OF587D6284.5AECD8A6-ON8725713A.007B0F39-8825713A.007E8BA3@us.ibm.com>

Hi,

On Thu, Mar 23, 2006 at 03:06:22PM -0800, Haren Myneni wrote:

> On JS21, immediately after the tce entries are initialized, the machine 
> checkstops with an error "Internal CPU 1 Fault Error" on bladecenter MM. 
> If we do not initialize tce entries for crash kernel, allows the ongoing 
> DMA continue to the old kernel memory. I though that, ongoing DMA will be 

The problem isn't when DMA is going to the old kernel memory. The
problem is when that TCE entry gets reused by the crashdump kernel, and
some other memory gets overwritten instead.

> stopped when the device reset happens later by the drivers. I think, some 
> hardening is already included in some drivers to take care of this 
> behavior. I might be wrong. So far, I had e100 issue after testing on p5, 

What assures that the crash kernel has drivers for all hardware in the
system? If there's no driver, what will then be used to quiesce the
device?

> p4, js20 and js21. Probably, it could be lucky scenario.
> So, will be keeping the same change (posted here) plus your suggestion. 
> Right? Can we apply same approach even for power-4?

What you have now might be a 99%-of-the-time-it-works solution, but is
that really good enough?

The last things you want from a crash kernel is:

1. Have it crash on it's own because of something getting overwritten
(small chance, since most mappings are probably for writing out data
for later analysis)

or:

2. Have it write corrupted data to the crash dump. This makes it more or
less useless, since you can't trust what it wrote out: Did the machine
go down because of the memory corruption you're spotting, or did that
happen after the crash, while dumping it, etc?

Either way, a proper solution is needed, not a 99% one.


-Olof

^ permalink raw reply

* [PATCH] powerpc: Rename and export ppc64_firmware_features
From: Michael Ellerman @ 2006-03-23 23:40 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Stephen Rothwell
In-Reply-To: <20060324001748.5ae0c190.sfr@canb.auug.org.au>

We need to export ppc64_firmware_features for modules. Before we do that
I think we should probably rename it to powerpc_firmware_features.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/firmware.c            |    3 ++-
 arch/powerpc/platforms/iseries/setup.c    |    4 ++--
 arch/powerpc/platforms/pseries/firmware.c |    2 +-
 arch/powerpc/platforms/pseries/setup.c    |    2 +-
 include/asm-powerpc/firmware.h            |    4 ++--
 5 files changed, 8 insertions(+), 7 deletions(-)

Index: to-merge/arch/powerpc/kernel/firmware.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/firmware.c
+++ to-merge/arch/powerpc/kernel/firmware.c
@@ -17,4 +17,5 @@
 
 #include <asm/firmware.h>
 
-unsigned long ppc64_firmware_features;
+unsigned long powerpc_firmware_features;
+EXPORT_SYMBOL_GPL(powerpc_firmware_features);
Index: to-merge/arch/powerpc/platforms/iseries/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/iseries/setup.c
+++ to-merge/arch/powerpc/platforms/iseries/setup.c
@@ -680,8 +680,8 @@ static int __init iseries_probe(int plat
 	if (PLATFORM_ISERIES_LPAR != platform)
 		return 0;
 
-	ppc64_firmware_features |= FW_FEATURE_ISERIES;
-	ppc64_firmware_features |= FW_FEATURE_LPAR;
+	powerpc_firmware_features |= FW_FEATURE_ISERIES;
+	powerpc_firmware_features |= FW_FEATURE_LPAR;
 
 	return 1;
 }
Index: to-merge/arch/powerpc/platforms/pseries/firmware.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/pseries/firmware.c
+++ to-merge/arch/powerpc/platforms/pseries/firmware.c
@@ -91,7 +91,7 @@ void __init fw_feature_init(void)
 				continue;
 
 			/* we have a match */
-			ppc64_firmware_features |=
+			powerpc_firmware_features |=
 				firmware_features_table[i].val;
 			break;
 		}
Index: to-merge/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/pseries/setup.c
+++ to-merge/arch/powerpc/platforms/pseries/setup.c
@@ -386,7 +386,7 @@ static int __init pSeries_probe(int plat
 	 */
 
 	if (platform == PLATFORM_PSERIES_LPAR)
-		ppc64_firmware_features |= FW_FEATURE_LPAR;
+		powerpc_firmware_features |= FW_FEATURE_LPAR;
 
 	return 1;
 }
Index: to-merge/include/asm-powerpc/firmware.h
===================================================================
--- to-merge.orig/include/asm-powerpc/firmware.h
+++ to-merge/include/asm-powerpc/firmware.h
@@ -82,11 +82,11 @@ enum {
 /* This is used to identify firmware features which are available
  * to the kernel.
  */
-extern unsigned long	ppc64_firmware_features;
+extern unsigned long	powerpc_firmware_features;
 
 #define firmware_has_feature(feature)					\
 	((FW_FEATURE_ALWAYS & (feature)) ||				\
-		(FW_FEATURE_POSSIBLE & ppc64_firmware_features & (feature)))
+		(FW_FEATURE_POSSIBLE & powerpc_firmware_features & (feature)))
 
 extern void system_reset_fwnmi(void);
 extern void machine_check_fwnmi(void);

^ permalink raw reply

* pci_dlpar.c & probe mode
From: Benjamin Herrenschmidt @ 2006-03-24  0:36 UTC (permalink / raw)
  To: linuxppc-dev

Hi !

I noticed that pcibios_add_pci_devices() test the platform type to
decide wether to do a device-tree based probe or a direct PCI probe. Why
can't it use ppc_md.probe_mode() like the rest of the PCI code does ?

Ben.

^ permalink raw reply

* why we need gcc-3.3.6 when making gcc-4.1.0-glibc-2.3.6 cross toolchain
From: Gao Bismar @ 2006-03-24  1:14 UTC (permalink / raw)
  To: linuxppc-embedded

In file gcc-4.1.0-glibc-2.3.6.dat:

BINUTILS_DIR=binutils-2.16.1
GCC_CORE_DIR=gcc-3.3.6
GCC_DIR=gcc-4.1.0
GLIBC_DIR=glibc-2.3.6
LINUX_DIR=linux-2.6.15.4
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.6
GDB_DIR=gdb-6.4

but why we need gcc-3.3.6 when making gcc-4.1.0-glibc-2.3.6 cross toolchain 
?

_________________________________________________________________
免费下载 MSN Explorer:   http://explorer.msn.com/lccn/  

^ permalink raw reply

* Re: [PATCH] kdump: Fix for machine checkstop on DMA fault
From: Haren Myneni @ 2006-03-23 23:06 UTC (permalink / raw)
  To: Olof Johansson
  Cc: Milton Miller, Michael Ellerman, linuxppc-dev, Paul Mackerras,
	Olaf Hering, ellerman
In-Reply-To: <20060323201258.GA5538@pb15.lixom.net>

[-- Attachment #1: Type: text/plain, Size: 1733 bytes --]

linuxppc-dev-bounces+hbabu=us.ibm.com@ozlabs.org wrote on 03/23/2006 
12:12:58 PM:

> On Thu, Mar 23, 2006 at 12:19:04AM -0600, Olof Johansson wrote:
> 
> > The crash kernel needs to be even more careful, and instead read out
> > the entries that are mapped and reserve them. This would require a bit
> > more plumbing since there's no way to read an entry right now, but 
it'd
> > remove that hole.
> 
> Actually, what's probably easier is to allocate some entries when the
> purgatory is set up, and make the crash kernel only use those by 
modifying
> the device tree accordingly. Sort of how regular memory is handled right
> now. That'd be a cleaner solution with less changes needed.
> 
> The trick will be to get a decent size contiguous allocation, but the
> same applies for the memory reserve.

Olof, Thanks for your comments/suggestions.

On JS21, immediately after the tce entries are initialized, the machine 
checkstops with an error "Internal CPU 1 Fault Error" on bladecenter MM. 
If we do not initialize tce entries for crash kernel, allows the ongoing 
DMA continue to the old kernel memory. I though that, ongoing DMA will be 
stopped when the device reset happens later by the drivers. I think, some 
hardening is already included in some drivers to take care of this 
behavior. I might be wrong. So far, I had e100 issue after testing on p5, 
p4, js20 and js21. Probably, it could be lucky scenario.
So, will be keeping the same change (posted here) plus your suggestion. 
Right? Can we apply same approach even for power-4?

Thanks
Haren




> 
> 
> -Olof
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

[-- Attachment #2: Type: text/html, Size: 2160 bytes --]

^ permalink raw reply

* memory with __get_free_pages and disabling caching
From: Kallol Biswas @ 2006-03-24  2:15 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 406 bytes --]

Hello,
       Is there an easy way to set page table attributes for the memory returned
by __get_free_pages()?
 
I need to be able to turn off caching and turn on E bit for these pages.
 
I tried to walk through the page tables data structures to get the pte, but it seems
that the pmd is not present for the pages. If someone has done investigation
on this before please send me a reply.
 
Thanks,
Kallol

[-- Attachment #2: Type: text/html, Size: 1656 bytes --]

^ permalink raw reply

* Re: memory with __get_free_pages and disabling caching
From: Benjamin Herrenschmidt @ 2006-03-24  3:05 UTC (permalink / raw)
  To: Kallol Biswas; +Cc: linuxppc-dev
In-Reply-To: <478F19F21671F04298A2116393EEC3D50A9BE2@sjc1exm08.pmc_nt.nt.pmc-sierra.bc.ca>

On Thu, 2006-03-23 at 18:15 -0800, Kallol Biswas wrote:
> Hello,
>        Is there an easy way to set page table attributes for the
> memory returned
> by __get_free_pages()?
>  
> I need to be able to turn off caching and turn on E bit for these
> pages.

The Evil bit ? heh ! what are you trying to do ? here ... you can always
create a virtual mapping to those pages with different attributes but
that's nor recommended as some processors will shoke pretty badly if you
end up with both cacheable and non-cacheable mappings for the same page.
However, it's not always possible to unmap the initial mapping since
it's common to use things like large pages, BATs, large TLB entries
etc... to map kernel memory..

> I tried to walk through the page tables data structures to get the
> pte, but it seems
> that the pmd is not present for the pages. If someone has done
> investigation
> on this before please send me a reply.
>  
Kernel linear memory isn't necessarily mapped by the page tables. What
are you trying to do and with what processor ?

Ben.

^ permalink raw reply

* [PATCH] powerpc: legacy_serial loop cleanup
From: Michael Neuling @ 2006-03-24  4:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: michael

We only ever execute the loop once, so let's move it to a function
making it more readable.  Cleanup patch, no functional change.  

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/kernel/legacy_serial.c |   39 +++++++++++++++++++-----------------
 1 files changed, 21 insertions(+), 18 deletions(-)

Index: linux-2.6-linus/arch/powerpc/kernel/legacy_serial.c
===================================================================
--- linux-2.6-linus.orig/arch/powerpc/kernel/legacy_serial.c
+++ linux-2.6-linus/arch/powerpc/kernel/legacy_serial.c
@@ -236,6 +236,26 @@ static int __init add_legacy_pci_port(st
 }
 #endif
 
+static void __init setup_legacy_serial_console(int console)
+{
+	if (console >= 0) {
+		struct legacy_serial_info *info =
+			&legacy_serial_infos[legacy_serial_console];
+		void __iomem *addr;
+
+		if (info->taddr == 0)
+			return;
+		addr = ioremap(info->taddr, 0x1000);
+		if (addr == NULL)
+			return;
+		if (info->speed == 0)
+			info->speed = udbg_probe_uart_speed(addr, info->clock);
+		DBG("default console speed = %d\n", info->speed);
+		udbg_init_uart(addr, info->speed, info->clock);
+	}
+	return;
+}
+
 /*
  * This is called very early, as part of setup_system() or eventually
  * setup_arch(), basically before anything else in this file. This function
@@ -319,24 +339,7 @@ void __init find_legacy_serial_ports(voi
 
 	DBG("legacy_serial_console = %d\n", legacy_serial_console);
 
-	/* udbg is 64 bits only for now, that will change soon though ... */
-	while (legacy_serial_console >= 0) {
-		struct legacy_serial_info *info =
-			&legacy_serial_infos[legacy_serial_console];
-		void __iomem *addr;
-
-		if (info->taddr == 0)
-			break;
-		addr = ioremap(info->taddr, 0x1000);
-		if (addr == NULL)
-			break;
-		if (info->speed == 0)
-			info->speed = udbg_probe_uart_speed(addr, info->clock);
-		DBG("default console speed = %d\n", info->speed);
-		udbg_init_uart(addr, info->speed, info->clock);
-		break;
-	}
-
+	setup_legacy_serial_console(legacy_serial_console);
 	DBG(" <- find_legacy_serial_port()\n");
 }
 

^ permalink raw reply

* [PATCH] powerpc: Kill machine numbers
From: Benjamin Herrenschmidt @ 2006-03-24  5:42 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev list, Linux Kernel list

This patch removes statically assigned machine numbers and reworks the
powerpc platform probe code to use a better mecanism when board support
files can simply declare a new machine type with a macro and implement a
probe() function that uses the flattened device-tree to detect if they
apply for a given machine.

This patch is tested & booted on 64 bits iseries, pseries and powermac
and builds for cell and 32 bits powermac.

It does break ARCH=ppc at the moment. The fix now will be to remove all
occurences of _machine there and either:
 - make prep a config option of it's own in arch/ppc (easy)
 - move prep over to arch/powerpc and kill completely MULTIPLATFORM for
arch/ppc (harder since prep relies on a lot of cruft in the boot wrapper
that needs to be ported over too, but also the best long term solution) 

I will try to do one of the above asap. Help welcome with the
bootwrapper crud :)

Index: linux-work/arch/powerpc/kernel/prom.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/prom.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/kernel/prom.c	2006-03-24 11:45:28.000000000 +1100
@@ -383,14 +383,14 @@ static int __devinit finish_node_interru
 			/* Apple uses bits in there in a different way, let's
 			 * only keep the real sense bit on macs
 			 */
-			if (_machine == PLATFORM_POWERMAC)
+			if (machine_is(powermac))
 				sense &= 0x1;
 			np->intrs[intrcount].sense = map_mpic_senses[sense];
 		}
 
 #ifdef CONFIG_PPC64
 		/* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
-		if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
+		if (machine_is(powermac) && ic && ic->parent) {
 			char *name = get_property(ic->parent, "name", NULL);
 			if (name && !strcmp(name, "u3"))
 				np->intrs[intrcount].line += 128;
@@ -570,6 +570,18 @@ int __init of_scan_flat_dt(int (*it)(uns
 	return rc;
 }
 
+unsigned long __init of_get_flat_dt_root(void)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		initial_boot_params->off_dt_struct;
+
+	while(*((u32 *)p) == OF_DT_NOP)
+		p += 4;
+	BUG_ON (*((u32 *)p) != OF_DT_BEGIN_NODE);
+	p += 4;
+	return _ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
 /**
  * This  function can be used within scan_flattened_dt callback to get
  * access to properties
@@ -612,6 +624,25 @@ void* __init of_get_flat_dt_prop(unsigne
 	} while(1);
 }
 
+int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
+{
+	const char* cp;
+	unsigned long cplen, l;
+
+	cp = of_get_flat_dt_prop(node, "compatible", &cplen);
+	if (cp == NULL)
+		return 0;
+	while (cplen > 0) {
+		if (strncasecmp(cp, compat, strlen(compat)) == 0)
+			return 1;
+		l = strlen(cp) + 1;
+		cp += l;
+		cplen -= l;
+	}
+
+	return 0;
+}
+
 static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 				       unsigned long align)
 {
@@ -686,7 +717,7 @@ static unsigned long __init unflatten_dt
 #ifdef DEBUG
 				if ((strlen(p) + l + 1) != allocl) {
 					DBG("%s: p: %d, l: %d, a: %d\n",
-					    pathp, strlen(p), l, allocl);
+					    pathp, (int)strlen(p), l, allocl);
 				}
 #endif
 				p += strlen(p);
@@ -919,7 +950,6 @@ static int __init early_init_dt_scan_cpu
 static int __init early_init_dt_scan_chosen(unsigned long node,
 					    const char *uname, int depth, void *data)
 {
-	u32 *prop;
 	unsigned long *lprop;
 	unsigned long l;
 	char *p;
@@ -930,14 +960,6 @@ static int __init early_init_dt_scan_cho
 	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
 		return 0;
 
-	/* get platform type */
-	prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
-	if (prop == NULL)
-		return 0;
-#ifdef CONFIG_PPC_MULTIPLATFORM
-	_machine = *prop;
-#endif
-
 #ifdef CONFIG_PPC64
 	/* check if iommu is forced on or off */
 	if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
@@ -964,15 +986,15 @@ static int __init early_init_dt_scan_cho
 	 * set of RTAS infos now if available
 	 */
 	{
-		u64 *basep, *entryp;
+		u64 *basep, *entryp, *sizep;
 
 		basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
 		entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
-		prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
-		if (basep && entryp && prop) {
+		sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
+		if (basep && entryp && sizep) {
 			rtas.base = *basep;
 			rtas.entry = *entryp;
-			rtas.size = *prop;
+			rtas.size = *sizep;
 		}
 	}
 #endif /* CONFIG_PPC_RTAS */
@@ -1755,7 +1777,7 @@ static int of_finish_dynamic_node(struct
 	/* We don't support that function on PowerMac, at least
 	 * not yet
 	 */
-	if (_machine == PLATFORM_POWERMAC)
+	if (machine_is(powermac))
 		return -ENODEV;
 
 	/* fix up new node's linux_phandle field */
Index: linux-work/arch/powerpc/kernel/setup-common.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/setup-common.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/kernel/setup-common.c	2006-03-24 11:45:28.000000000 +1100
@@ -9,6 +9,9 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
+
+#undef DEBUG
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/string.h>
@@ -41,6 +44,7 @@
 #include <asm/time.h>
 #include <asm/cputable.h>
 #include <asm/sections.h>
+#include <asm/firmware.h>
 #include <asm/btext.h>
 #include <asm/nvram.h>
 #include <asm/setup.h>
@@ -56,8 +60,6 @@
 
 #include "setup.h"
 
-#undef DEBUG
-
 #ifdef DEBUG
 #include <asm/udbg.h>
 #define DBG(fmt...) udbg_printf(fmt)
@@ -65,10 +67,12 @@
 #define DBG(fmt...)
 #endif
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
-int _machine = 0;
-EXPORT_SYMBOL(_machine);
-#endif
+/* The main machine-dep calls structure
+ */
+struct machdep_calls ppc_md;
+EXPORT_SYMBOL(ppc_md);
+struct machdep_calls *machine_id;
+EXPORT_SYMBOL(machine_id);
 
 unsigned long klimit = (unsigned long) _end;
 
@@ -399,7 +403,7 @@ void __init smp_setup_cpu_maps(void)
 	 * On pSeries LPAR, we need to know how many cpus
 	 * could possibly be added to this partition.
 	 */
-	if (_machine == PLATFORM_PSERIES_LPAR &&
+	if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
 	    (dn = of_find_node_by_path("/rtas"))) {
 		int num_addr_cell, num_size_cell, maxcpus;
 		unsigned int *ireg;
@@ -468,3 +472,32 @@ static int __init early_xmon(char *p)
 }
 early_param("xmon", early_xmon);
 #endif
+
+void probe_machine(void)
+{
+	extern struct machdep_calls __machine_desc_start;
+	extern struct machdep_calls __machine_desc_end;
+
+	/*
+	 * Iterate all ppc_md structures until we find the proper
+	 * one for the current machine type
+	 */
+	DBG("Probing machine type ...\n");
+
+	for (machine_id = &__machine_desc_start;
+	     machine_id < &__machine_desc_end;
+	     machine_id++) {
+		DBG("  %s ...", machine_id->name);
+		memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls));
+		if (ppc_md.probe()) {
+			DBG(" match !\n");
+			break;
+		}
+		DBG("\n");
+	}
+	/* What can we do if we didn't find ? */
+	if (machine_id >= &__machine_desc_end) {
+		DBG("No suitable machine found !\n");
+		for (;;);
+	}
+}
Index: linux-work/arch/powerpc/kernel/setup_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/setup_32.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/kernel/setup_32.c	2006-03-24 11:45:28.000000000 +1100
@@ -70,10 +70,6 @@ unsigned int DMA_MODE_WRITE;
 int have_of = 1;
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-extern void prep_init(void);
-extern void pmac_init(void);
-extern void chrp_init(void);
-
 dev_t boot_dev;
 #endif /* CONFIG_PPC_MULTIPLATFORM */
 
@@ -85,9 +81,6 @@ unsigned long SYSRQ_KEY = 0x54;
 unsigned long vgacon_remap_base;
 #endif
 
-struct machdep_calls ppc_md;
-EXPORT_SYMBOL(ppc_md);
-
 /*
  * These are used in binfmt_elf.c to put aux entries on the stack
  * for each elf executable being started.
@@ -123,48 +116,6 @@ unsigned long __init early_init(unsigned
 	return KERNELBASE + offset;
 }
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
-/*
- * The PPC_MULTIPLATFORM version of platform_init...
- */
-void __init platform_init(void)
-{
-	/* if we didn't get any bootinfo telling us what we are... */
-	if (_machine == 0) {
-		/* prep boot loader tells us if we're prep or not */
-		if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
-			_machine = _MACH_prep;
-	}
-
-#ifdef CONFIG_PPC_PREP
-	/* not much more to do here, if prep */
-	if (_machine == _MACH_prep) {
-		prep_init();
-		return;
-	}
-#endif
-
-#ifdef CONFIG_ADB
-	if (strstr(cmd_line, "adb_sync")) {
-		extern int __adb_probe_sync;
-		__adb_probe_sync = 1;
-	}
-#endif /* CONFIG_ADB */
-
-	switch (_machine) {
-#ifdef CONFIG_PPC_PMAC
-	case _MACH_Pmac:
-		pmac_init();
-		break;
-#endif
-#ifdef CONFIG_PPC_CHRP
-	case _MACH_chrp:
-		chrp_init();
-		break;
-#endif
-	}
-}
-#endif
 
 /*
  * Find out what kind of machine we're on and save any data we need
@@ -190,8 +141,12 @@ void __init machine_init(unsigned long d
 		strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
 #endif /* CONFIG_CMDLINE */
 
-	/* Base init based on machine type */
+#ifdef CONFIG_PPC_MULTIPLATFORM
+	probe_machine();
+#else
+	/* Base init based on machine type. Obsoloete, please kill ! */
 	platform_init();
+#endif
 
 #ifdef CONFIG_6xx
 	ppc_md.power_save = ppc6xx_idle;
@@ -366,7 +321,4 @@ void __init setup_arch(char **cmdline_p)
 	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
 	paging_init();
-
-	/* this is for modules since _machine can be a define -- Cort */
-	ppc_md.ppc_machine = _machine;
 }
Index: linux-work/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/setup_64.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/kernel/setup_64.c	2006-03-24 11:45:28.000000000 +1100
@@ -96,11 +96,6 @@ int dcache_bsize;
 int icache_bsize;
 int ucache_bsize;
 
-/* The main machine-dep calls structure
- */
-struct machdep_calls ppc_md;
-EXPORT_SYMBOL(ppc_md);
-
 #ifdef CONFIG_MAGIC_SYSRQ
 unsigned long SYSRQ_KEY;
 #endif /* CONFIG_MAGIC_SYSRQ */
@@ -161,32 +156,6 @@ early_param("smt-enabled", early_smt_ena
 #define check_smt_enabled()
 #endif /* CONFIG_SMP */
 
-extern struct machdep_calls pSeries_md;
-extern struct machdep_calls pmac_md;
-extern struct machdep_calls maple_md;
-extern struct machdep_calls cell_md;
-extern struct machdep_calls iseries_md;
-
-/* Ultimately, stuff them in an elf section like initcalls... */
-static struct machdep_calls __initdata *machines[] = {
-#ifdef CONFIG_PPC_PSERIES
-	&pSeries_md,
-#endif /* CONFIG_PPC_PSERIES */
-#ifdef CONFIG_PPC_PMAC
-	&pmac_md,
-#endif /* CONFIG_PPC_PMAC */
-#ifdef CONFIG_PPC_MAPLE
-	&maple_md,
-#endif /* CONFIG_PPC_MAPLE */
-#ifdef CONFIG_PPC_CELL
-	&cell_md,
-#endif
-#ifdef CONFIG_PPC_ISERIES
-	&iseries_md,
-#endif
-	NULL
-};
-
 /*
  * Early initialization entry point. This is called by head.S
  * with MMU translation disabled. We rely on the "feature" of
@@ -209,12 +178,11 @@ static struct machdep_calls __initdata *
 void __init early_setup(unsigned long dt_ptr)
 {
 	struct paca_struct *lpaca = get_paca();
-	static struct machdep_calls **mach;
 
 	/* Enable early debugging if any specified (see udbg.h) */
 	udbg_early_init();
 
-	DBG(" -> early_setup()\n");
+	DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr);
 
 	/*
 	 * Do early initializations using the flattened device
@@ -223,22 +191,8 @@ void __init early_setup(unsigned long dt
 	 */
 	early_init_devtree(__va(dt_ptr));
 
-	/*
-	 * Iterate all ppc_md structures until we find the proper
-	 * one for the current machine type
-	 */
-	DBG("Probing machine type for platform %x...\n", _machine);
-
-	for (mach = machines; *mach; mach++) {
-		if ((*mach)->probe(_machine))
-			break;
-	}
-	/* What can we do if we didn't find ? */
-	if (*mach == NULL) {
-		DBG("No suitable machine found !\n");
-		for (;;);
-	}
-	ppc_md = **mach;
+	/* Probe the machine type */
+	probe_machine();
 
 #ifdef CONFIG_CRASH_DUMP
 	kdump_setup();
@@ -340,7 +294,7 @@ static void __init initialize_cache_info
 			const char *dc, *ic;
 
 			/* Then read cache informations */
-			if (_machine == PLATFORM_POWERMAC) {
+			if (machine_is(powermac)) {
 				dc = "d-cache-block-size";
 				ic = "i-cache-block-size";
 			} else {
@@ -484,7 +438,6 @@ void __init setup_system(void)
 	printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
 	printk("ppc64_interrupt_controller    = 0x%ld\n",
 	       ppc64_interrupt_controller);
-	printk("platform                      = 0x%x\n", _machine);
 	printk("physicalMemorySize            = 0x%lx\n", lmb_phys_mem_size());
 	printk("ppc64_caches.dcache_line_size = 0x%x\n",
 	       ppc64_caches.dline_size);
Index: linux-work/arch/powerpc/kernel/vmlinux.lds.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vmlinux.lds.S	2006-01-14 14:43:22.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vmlinux.lds.S	2006-03-24 11:45:28.000000000 +1100
@@ -1,9 +1,11 @@
 #include <linux/config.h>
 #ifdef CONFIG_PPC64
 #include <asm/page.h>
+#define PROVIDE32(x)	PROVIDE(__unused__##x)
 #else
 #define PAGE_SIZE	4096
 #define KERNELBASE	CONFIG_KERNEL_START
+#define PROVIDE32(x)	PROVIDE(x)
 #endif
 #include <asm-generic/vmlinux.lds.h>
 
@@ -18,43 +20,42 @@ jiffies = jiffies_64 + 4;
 #endif
 SECTIONS
 {
-  /* Sections to be discarded. */
-  /DISCARD/ : {
-    *(.exitcall.exit)
-    *(.exit.data)
-  }
-
-  . = KERNELBASE;
-
-  /* Read-only sections, merged into text segment: */
-  .text : {
-    *(.text .text.*)
-    SCHED_TEXT
-    LOCK_TEXT
-    KPROBES_TEXT
-    *(.fixup)
-#ifdef CONFIG_PPC32
-    *(.got1)
-    __got2_start = .;
-    *(.got2)
-    __got2_end = .;
-#else
-    . = ALIGN(PAGE_SIZE);
-    _etext = .;
-#endif
-  }
-#ifdef CONFIG_PPC32
-  _etext = .;
-  PROVIDE (etext = .);
+	/* Sections to be discarded. */
+	/DISCARD/ : {
+	*(.exitcall.exit)
+	*(.exit.data)
+	}
 
-  RODATA
-  .fini      : { *(.fini)    } =0
-  .ctors     : { *(.ctors)   }
-  .dtors     : { *(.dtors)   }
+	. = KERNELBASE;
 
-  .fixup   : { *(.fixup) }
-#endif
+/*
+ * Text, read only data and other permanent read-only sections
+ */
+
+	/* Text and gots */
+	.text : {
+		*(.text .text.*)
+		SCHED_TEXT
+		LOCK_TEXT
+		KPROBES_TEXT
+		*(.fixup)
+
+#ifdef CONFIG_PPC32
+		*(.got1)
+		__got2_start = .;
+		*(.got2)
+		__got2_end = .;
+#endif /* CONFIG_PPC32 */
+
+		. = ALIGN(PAGE_SIZE);
+		_etext = .;
+		PROVIDE32 (etext = .);
+	}
+
+	/* Read-only data */
+	RODATA
 
+	/* Exception & bug tables */
 	__ex_table : {
 		__start___ex_table = .;
 		*(__ex_table)
@@ -67,192 +68,172 @@ SECTIONS
 		__stop___bug_table = .;
 	}
 
-#ifdef CONFIG_PPC64
+/*
+ * Init sections discarded at runtime
+ */
+	. = ALIGN(PAGE_SIZE);
+	__init_begin = .;
+
+	.init.text : {
+		_sinittext = .;
+		*(.init.text)
+		_einittext = .;
+	}
+
+	/* .exit.text is discarded at runtime, not link time,
+	 * to deal with references from __bug_table
+	 */
+	.exit.text : { *(.exit.text) }
+
+	.init.data : {
+		*(.init.data);
+		__vtop_table_begin = .;
+		*(.vtop_fixup);
+		__vtop_table_end = .;
+		__ptov_table_begin = .;
+		*(.ptov_fixup);
+		__ptov_table_end = .;
+	}
+
+	. = ALIGN(16);
+	.init.setup : {
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+	}
+
+	.initcall.init : {
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		}
+
+	.con_initcall.init : {
+		__con_initcall_start = .;
+		*(.con_initcall.init)
+		__con_initcall_end = .;
+	}
+
+	SECURITY_INIT
+
+	. = ALIGN(8);
 	__ftr_fixup : {
 		__start___ftr_fixup = .;
 		*(__ftr_fixup)
 		__stop___ftr_fixup = .;
 	}
 
-  RODATA
-#endif
+	. = ALIGN(PAGE_SIZE);
+	.init.ramfs : {
+		__initramfs_start = .;
+		*(.init.ramfs)
+		__initramfs_end = .;
+	}
 
 #ifdef CONFIG_PPC32
-  /* Read-write section, merged into data segment: */
-  . = ALIGN(PAGE_SIZE);
-  _sdata = .;
-  .data    :
-  {
-    *(.data)
-    *(.data1)
-    *(.sdata)
-    *(.sdata2)
-    *(.got.plt) *(.got)
-    *(.dynamic)
-    CONSTRUCTORS
-  }
-
-  . = ALIGN(PAGE_SIZE);
-  __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
-  . = ALIGN(PAGE_SIZE);
-  __nosave_end = .;
+	. = ALIGN(32);
+#else
+	. = ALIGN(128);
+#endif
+	.data.percpu : {
+		__per_cpu_start = .;
+		*(.data.percpu)
+		__per_cpu_end = .;
+	}
 
-  . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+	. = ALIGN(8);
+	.machine.desc : {
+		__machine_desc_start = . ;
+		*(.machine.desc)
+		__machine_desc_end = . ;
+	}
 
-  _edata  =  .;
-  PROVIDE (edata = .);
+	/* freed after init ends here */
+	. = ALIGN(PAGE_SIZE);
+	__init_end = .;
+
+/*
+ * And now the various read/write data
+ */
+
+	. = ALIGN(PAGE_SIZE);
+	_sdata = .;
+
+#ifdef CONFIG_PPC32
+	.data    :
+	{
+		*(.data)
+		*(.sdata)
+		*(.got.plt) *(.got)
+	}
+#else
+	.data : {
+		*(.data .data.rel* .toc1)
+		*(.branch_lt)
+	}
 
-  . = ALIGN(8192);
-  .data.init_task : { *(.data.init_task) }
-#endif
+	.opd : {
+		*(.opd)
+	}
 
-  /* will be freed after init */
-  . = ALIGN(PAGE_SIZE);
-  __init_begin = .;
-  .init.text : {
-	_sinittext = .;
-	*(.init.text)
-	_einittext = .;
-  }
-#ifdef CONFIG_PPC32
-  /* .exit.text is discarded at runtime, not link time,
-     to deal with references from __bug_table */
-  .exit.text : { *(.exit.text) }
+	.got : {
+		__toc_start = .;
+		*(.got)
+		*(.toc)
+	}
 #endif
-  .init.data : {
-    *(.init.data);
-    __vtop_table_begin = .;
-    *(.vtop_fixup);
-    __vtop_table_end = .;
-    __ptov_table_begin = .;
-    *(.ptov_fixup);
-    __ptov_table_end = .;
-  }
-
-  . = ALIGN(16);
-  .init.setup : {
-    __setup_start = .;
-    *(.init.setup)
-    __setup_end = .;
-  }
-
-  .initcall.init : {
-	__initcall_start = .;
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
-	__initcall_end = .;
-  }
-
-  .con_initcall.init : {
-    __con_initcall_start = .;
-    *(.con_initcall.init)
-    __con_initcall_end = .;
-  }
 
-  SECURITY_INIT
+	. = ALIGN(PAGE_SIZE);
+	_edata  =  .;
+	PROVIDE32 (edata = .);
 
+	/* The initial task and kernel stack */
 #ifdef CONFIG_PPC32
-  __start___ftr_fixup = .;
-  __ftr_fixup : { *(__ftr_fixup) }
-  __stop___ftr_fixup = .;
+	. = ALIGN(8192);
 #else
-  . = ALIGN(PAGE_SIZE);
-  .init.ramfs : {
-    __initramfs_start = .;
-    *(.init.ramfs)
-    __initramfs_end = .;
-  }
-#endif
-
-#ifdef CONFIG_PPC32
-  . = ALIGN(32);
+	. = ALIGN(16384);
 #endif
-  .data.percpu : {
-    __per_cpu_start = .;
-    *(.data.percpu)
-    __per_cpu_end = .;
-  }
+	.data.init_task : {
+		*(.data.init_task)
+	}
 
- . = ALIGN(PAGE_SIZE);
-#ifdef CONFIG_PPC64
- . = ALIGN(16384);
- __init_end = .;
- /* freed after init ends here */
-
- /* Read/write sections */
- . = ALIGN(PAGE_SIZE);
- . = ALIGN(16384);
- _sdata = .;
- /* The initial task and kernel stack */
- .data.init_task : {
-      *(.data.init_task)
-      }
-
- . = ALIGN(PAGE_SIZE);
- .data.page_aligned : {
-      *(.data.page_aligned)
-      }
-
- .data.cacheline_aligned : {
-      *(.data.cacheline_aligned)
-      }
-
- .data : {
-      *(.data .data.rel* .toc1)
-      *(.branch_lt)
-      }
-
- .opd : {
-      *(.opd)
-      }
-
- .got : {
-      __toc_start = .;
-      *(.got)
-      *(.toc)
-      . = ALIGN(PAGE_SIZE);
-      _edata = .;
-      }
+	. = ALIGN(PAGE_SIZE);
+	.data.page_aligned : {
+		*(.data.page_aligned)
+	}
 
-  . = ALIGN(PAGE_SIZE);
-#else
-  __initramfs_start = .;
-  .init.ramfs : {
-    *(.init.ramfs)
-  }
-  __initramfs_end = .;
-
-  . = ALIGN(4096);
-  __init_end = .;
-
-  . = ALIGN(4096);
-  _sextratext = .;
-  _eextratext = .;
+	.data.cacheline_aligned : {
+		*(.data.cacheline_aligned)
+	}
 
-  __bss_start = .;
-#endif
+	. = ALIGN(PAGE_SIZE);
+	__data_nosave : {
+		__nosave_begin = .;
+		*(.data.nosave)
+		. = ALIGN(PAGE_SIZE);
+		__nosave_end = .;
+	}
 
-  .bss : {
-    __bss_start = .;
-   *(.sbss) *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-  __bss_stop = .;
-  }
+/*
+ * And finally the bss
+ */
+
+	.bss : {
+		__bss_start = .;
+		*(.sbss) *(.scommon)
+		*(.dynbss)
+		*(.bss)
+		*(COMMON)
+		__bss_stop = .;
+	}
 
-#ifdef CONFIG_PPC64
-  . = ALIGN(PAGE_SIZE);
-#endif
-  _end = . ;
-#ifdef CONFIG_PPC32
-  PROVIDE (end = .);
-#endif
+	. = ALIGN(PAGE_SIZE);
+	_end = . ;
+	PROVIDE32 (end = .);
 }
Index: linux-work/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/cell/setup.c	2006-03-23 14:26:08.000000000 +1100
+++ linux-work/arch/powerpc/platforms/cell/setup.c	2006-03-24 11:45:28.000000000 +1100
@@ -195,9 +195,10 @@ static void __init cell_init_early(void)
 }
 
 
-static int __init cell_probe(int platform)
+static int __init cell_probe(void)
 {
-	if (platform != PLATFORM_CELL)
+	unsigned long root = of_get_flat_dt_root();
+	if (!of_flat_dt_is_compatible(root, "IBM,CPB"))
 		return 0;
 
 	return 1;
@@ -212,7 +213,7 @@ static int cell_check_legacy_ioport(unsi
 	return -ENODEV;
 }
 
-struct machdep_calls __initdata cell_md = {
+define_machine(cell) {
 	.probe			= cell_probe,
 	.setup_arch		= cell_setup_arch,
 	.init_early		= cell_init_early,
Index: linux-work/arch/powerpc/platforms/iseries/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/iseries/setup.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/platforms/iseries/setup.c	2006-03-24 11:45:28.000000000 +1100
@@ -675,9 +675,10 @@ static void iseries_dedicated_idle(void)
 void __init iSeries_init_IRQ(void) { }
 #endif
 
-static int __init iseries_probe(int platform)
+static int __init iseries_probe(void)
 {
-	if (PLATFORM_ISERIES_LPAR != platform)
+	unsigned long root = of_get_flat_dt_root();
+	if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
 		return 0;
 
 	ppc64_firmware_features |= FW_FEATURE_ISERIES;
@@ -686,7 +687,8 @@ static int __init iseries_probe(int plat
 	return 1;
 }
 
-struct machdep_calls __initdata iseries_md = {
+define_machine(iseries) {
+	.name		= "iSeries",
 	.setup_arch	= iSeries_setup_arch,
 	.show_cpuinfo	= iSeries_show_cpuinfo,
 	.init_IRQ	= iSeries_init_IRQ,
@@ -930,7 +932,6 @@ void build_flat_dt(struct iseries_flat_d
 
 	/* /chosen */
 	dt_start_node(dt, "chosen");
-	dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
 	dt_prop_str(dt, "bootargs", cmd_line);
 	if (cmd_mem_limit)
 		dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit);
Index: linux-work/arch/powerpc/platforms/maple/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/maple/setup.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/platforms/maple/setup.c	2006-03-24 11:45:28.000000000 +1100
@@ -259,9 +259,10 @@ static void __init maple_progress(char *
 /*
  * Called very early, MMU is off, device-tree isn't unflattened
  */
-static int __init maple_probe(int platform)
+static int __init maple_probe(void)
 {
-	if (platform != PLATFORM_MAPLE)
+	unsigned long root = of_get_flat_dt_root();
+	if (!of_flat_dt_is_compatible(root, "Momentum,Maple"))
 		return 0;
 	/*
 	 * On U3, the DART (iommu) must be allocated now since it
@@ -274,7 +275,8 @@ static int __init maple_probe(int platfo
 	return 1;
 }
 
-struct machdep_calls __initdata maple_md = {
+define_machine(maple_md) {
+	.name			= "Maple",
 	.probe			= maple_probe,
 	.setup_arch		= maple_setup_arch,
 	.init_early		= maple_init_early,
Index: linux-work/arch/powerpc/platforms/powermac/pci.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/pci.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/platforms/powermac/pci.c	2006-03-24 11:45:28.000000000 +1100
@@ -1201,7 +1201,7 @@ void __init pmac_pcibios_after_init(void
 #ifdef CONFIG_PPC32
 void pmac_pci_fixup_cardbus(struct pci_dev* dev)
 {
-	if (_machine != _MACH_Pmac)
+	if (!machine_is(powermac))
 		return;
 	/*
 	 * Fix the interrupt routing on the various cardbus bridges
@@ -1244,8 +1244,9 @@ void pmac_pci_fixup_pciata(struct pci_de
         * On PowerMacs, we try to switch any PCI ATA controller to
 	* fully native mode
         */
-	if (_machine != _MACH_Pmac)
+	if (!machine_is(powermac))
 		return;
+
 	/* Some controllers don't have the class IDE */
 	if (dev->vendor == PCI_VENDOR_ID_PROMISE)
 		switch(dev->device) {
Index: linux-work/arch/powerpc/platforms/powermac/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/setup.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/platforms/powermac/setup.c	2006-03-24 11:45:28.000000000 +1100
@@ -350,6 +350,13 @@ static void __init pmac_setup_arch(void)
 		smp_ops = &psurge_smp_ops;
 #endif
 #endif /* CONFIG_SMP */
+
+#ifdef CONFIG_ADB
+	if (strstr(cmd_line, "adb_sync")) {
+		extern int __adb_probe_sync;
+		__adb_probe_sync = 1;
+	}
+#endif /* CONFIG_ADB */
 }
 
 char *bootpath;
@@ -576,30 +583,6 @@ pmac_halt(void)
 	pmac_power_off();
 }
 
-#ifdef CONFIG_PPC32
-void __init pmac_init(void)
-{
-	/* isa_io_base gets set in pmac_pci_init */
-	isa_mem_base = PMAC_ISA_MEM_BASE;
-	pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
-	ISA_DMA_THRESHOLD = ~0L;
-	DMA_MODE_READ = 1;
-	DMA_MODE_WRITE = 2;
-
-	ppc_md = pmac_md;
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-        ppc_ide_md.ide_init_hwif	= pmac_ide_init_hwif_ports;
-        ppc_ide_md.default_io_base	= pmac_ide_get_base;
-#endif /* CONFIG_BLK_DEV_IDE_PMAC */
-#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
-
-	if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
-
-}
-#endif
-
 /* 
  * Early initialization.
  */
@@ -646,6 +629,12 @@ static int __init pmac_declare_of_platfo
 {
 	struct device_node *np;
 
+	if (machine_is(chrp))
+		return -1;
+
+	if (!machine_is(powermac))
+		return 0;
+
 	np = of_find_node_by_name(NULL, "valkyrie");
 	if (np)
 		of_platform_device_create(np, "valkyrie", NULL);
@@ -666,12 +655,15 @@ device_initcall(pmac_declare_of_platform
 /*
  * Called very early, MMU is off, device-tree isn't unflattened
  */
-static int __init pmac_probe(int platform)
+static int __init pmac_probe(void)
 {
-#ifdef CONFIG_PPC64
-	if (platform != PLATFORM_POWERMAC)
+	unsigned long root = of_get_flat_dt_root();
+
+	if (!of_flat_dt_is_compatible(root, "Power Macintosh") &&
+	    !of_flat_dt_is_compatible(root, "MacRISC"))
 		return 0;
 
+#ifdef CONFIG_PPC64
 	/*
 	 * On U3, the DART (iommu) must be allocated now since it
 	 * has an impact on htab_initialize (due to the large page it
@@ -681,6 +673,23 @@ static int __init pmac_probe(int platfor
 	alloc_dart_table();
 #endif
 
+#ifdef CONFIG_PPC32
+	/* isa_io_base gets set in pmac_pci_init */
+	isa_mem_base = PMAC_ISA_MEM_BASE;
+	pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
+	ISA_DMA_THRESHOLD = ~0L;
+	DMA_MODE_READ = 1;
+	DMA_MODE_WRITE = 2;
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+        ppc_ide_md.ide_init_hwif	= pmac_ide_init_hwif_ports;
+        ppc_ide_md.default_io_base	= pmac_ide_get_base;
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
+#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
+
+#endif /* CONFIG_PPC32 */
+
 #ifdef CONFIG_PMAC_SMU
 	/*
 	 * SMU based G5s need some memory below 2Gb, at least the current
@@ -709,10 +718,8 @@ static int pmac_pci_probe_mode(struct pc
 }
 #endif
 
-struct machdep_calls __initdata pmac_md = {
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
-	.cpu_die		= generic_mach_cpu_die,
-#endif
+define_machine(powermac) {
+	.name			= "PowerMac",
 	.probe			= pmac_probe,
 	.setup_arch		= pmac_setup_arch,
 	.init_early		= pmac_init_early,
@@ -746,4 +753,7 @@ struct machdep_calls __initdata pmac_md 
 	.pcibios_after_init	= pmac_pcibios_after_init,
 	.phys_mem_access_prot	= pci_phys_mem_access_prot,
 #endif
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
+	.cpu_die		= generic_mach_cpu_die,
+#endif
 };
Index: linux-work/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/setup.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/setup.c	2006-03-24 11:45:28.000000000 +1100
@@ -375,18 +375,36 @@ static int pSeries_check_legacy_ioport(u
  */
 extern struct machdep_calls pSeries_md;
 
-static int __init pSeries_probe(int platform)
+static int __init pSeries_probe_hypertas(unsigned long node,
+					 const char *uname, int depth,
+					 void *data)
 {
-	if (platform != PLATFORM_PSERIES &&
-	    platform != PLATFORM_PSERIES_LPAR)
+	if (depth != 1 ||
+	    (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0))
+ 		return 0;
+
+	if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL)
+ 		ppc64_firmware_features |= FW_FEATURE_LPAR;
+
+ 	return 1;
+}
+
+static int __init pSeries_probe(void)
+{
+ 	char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
+ 					  "device_type", NULL);
+ 	if (dtype == NULL)
+ 		return 0;
+ 	if (strcmp(dtype, "chrp"))
 		return 0;
 
-	/* if we have some ppc_md fixups for LPAR to do, do
-	 * it here ...
-	 */
+	DBG("pSeries detected, looking for LPAR capability...\n");
+
+	/* Now try to figure out if we are running on LPAR */
+	of_scan_flat_dt(pSeries_probe_hypertas, NULL);
 
-	if (platform == PLATFORM_PSERIES_LPAR)
-		ppc64_firmware_features |= FW_FEATURE_LPAR;
+	DBG("Machine is%s LPAR !\n",
+	    (ppc64_firmware_features & FW_FEATURE_LPAR) ? "" : " not");
 
 	return 1;
 }
@@ -553,7 +571,8 @@ static void pseries_kexec_cpu_down(int c
 }
 #endif
 
-struct machdep_calls __initdata pSeries_md = {
+define_machine(pseries) {
+	.name			= "pSeries",
 	.probe			= pSeries_probe,
 	.setup_arch		= pSeries_setup_arch,
 	.init_early		= pSeries_init_early,
Index: linux-work/include/asm-powerpc/machdep.h
===================================================================
--- linux-work.orig/include/asm-powerpc/machdep.h	2006-01-14 14:43:33.000000000 +1100
+++ linux-work/include/asm-powerpc/machdep.h	2006-03-24 11:45:28.000000000 +1100
@@ -47,6 +47,7 @@ struct smp_ops_t {
 #endif
 
 struct machdep_calls {
+	char		*name;
 #ifdef CONFIG_PPC64
 	void            (*hpte_invalidate)(unsigned long slot,
 					   unsigned long va,
@@ -85,9 +86,9 @@ struct machdep_calls {
 	void		(*iommu_dev_setup)(struct pci_dev *dev);
 	void		(*iommu_bus_setup)(struct pci_bus *bus);
 	void		(*irq_bus_setup)(struct pci_bus *bus);
-#endif
+#endif /* CONFIG_PPC64 */
 
-	int		(*probe)(int platform);
+	int		(*probe)(void);
 	void		(*setup_arch)(void);
 	void		(*init_early)(void);
 	/* Optional, may be NULL. */
@@ -208,8 +209,6 @@ struct machdep_calls {
 	/* Called at then very end of pcibios_init() */
 	void (*pcibios_after_init)(void);
 
-	/* this is for modules, since _machine can be a define -- Cort */
-	int ppc_machine;
 #endif /* CONFIG_PPC32 */
 
 	/* Called to shutdown machine specific hardware not already controlled
@@ -245,7 +244,26 @@ struct machdep_calls {
 extern void default_idle(void);
 extern void native_idle(void);
 
+/*
+ * ppc_md contains a copy of the machine description structure for the
+ * current platform. machine_id contains the initial address where the
+ * description was found during boot.
+ */
 extern struct machdep_calls ppc_md;
+extern struct machdep_calls *machine_id;
+
+#define __machine_desc __attribute__ ((__section__ (".machine.desc")))
+
+#define define_machine(name) struct machdep_calls mach_##name __machine_desc =
+#define machine_is(name) \
+	({ \
+		extern struct machdep_calls mach_##name \
+			__attribute__((weak));		 \
+		machine_id == &mach_##name; \
+	})
+
+extern void probe_machine(void);
+
 extern char cmd_line[COMMAND_LINE_SIZE];
 
 #ifdef CONFIG_PPC_PMAC
Index: linux-work/include/asm-powerpc/processor.h
===================================================================
--- linux-work.orig/include/asm-powerpc/processor.h	2006-03-24 11:42:14.000000000 +1100
+++ linux-work/include/asm-powerpc/processor.h	2006-03-24 11:45:28.000000000 +1100
@@ -22,22 +22,6 @@
  * -- BenH.
  */
 
-/* Platforms codes (to be obsoleted) */
-#define PLATFORM_PSERIES	0x0100
-#define PLATFORM_PSERIES_LPAR	0x0101
-#define PLATFORM_ISERIES_LPAR	0x0201
-#define PLATFORM_LPAR		0x0001
-#define PLATFORM_POWERMAC	0x0400
-#define PLATFORM_MAPLE		0x0500
-#define PLATFORM_PREP		0x0600
-#define PLATFORM_CHRP		0x0700
-#define PLATFORM_CELL		0x1000
-
-/* Compat platform codes for 32 bits */
-#define _MACH_prep	PLATFORM_PREP
-#define _MACH_Pmac	PLATFORM_POWERMAC
-#define _MACH_chrp	PLATFORM_CHRP
-
 /* PREP sub-platform types see residual.h for these */
 #define _PREP_Motorola	0x01	/* motorola prep */
 #define _PREP_Firm	0x02	/* firmworks prep */
@@ -49,14 +33,7 @@
 #define _CHRP_IBM	0x05	/* IBM chrp, the longtrail and longtrail 2 */
 #define _CHRP_Pegasos	0x06	/* Genesi/bplan's Pegasos and Pegasos2 */
 
-#ifdef __KERNEL__
-#define platform_is_pseries()	(_machine == PLATFORM_PSERIES || \
-				 _machine == PLATFORM_PSERIES_LPAR)
-
-#if defined(CONFIG_PPC_MULTIPLATFORM)
-extern int _machine;
-
-#ifdef CONFIG_PPC32
+#if defined(__KERNEL__) && defined(CONFIG_PPC32)
 
 /* what kind of prep workstation we are */
 extern int _prep_type;
@@ -70,17 +47,8 @@ extern int _chrp_type;
 extern unsigned char ucBoardRev;
 extern unsigned char ucBoardRevMaj, ucBoardRevMin;
 
-#endif /* CONFIG_PPC32 */
+#endif /* __KERNEL__ && CONFIG_PPC32 */
 
-#elif defined(CONFIG_PPC_ISERIES)
-/*
- * iSeries is soon to become MULTIPLATFORM hopefully ...
- */
-#define _machine PLATFORM_ISERIES_LPAR
-#else
-#define _machine 0
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-#endif /* __KERNEL__ */
 /*
  * Default implementation of macro that returns current
  * instruction pointer ("program counter").
Index: linux-work/include/asm-powerpc/prom.h
===================================================================
--- linux-work.orig/include/asm-powerpc/prom.h	2006-03-24 11:42:14.000000000 +1100
+++ linux-work/include/asm-powerpc/prom.h	2006-03-24 11:45:28.000000000 +1100
@@ -149,12 +149,14 @@ extern struct device_node *of_node_get(s
 extern void of_node_put(struct device_node *node);
 
 /* For scanning the flat device-tree at boot time */
-int __init of_scan_flat_dt(int (*it)(unsigned long node,
-				     const char *uname, int depth,
-				     void *data),
-			   void *data);
-void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
-				 unsigned long *size);
+extern int __init of_scan_flat_dt(int (*it)(unsigned long node,
+					    const char *uname, int depth,
+					    void *data),
+				  void *data);
+extern void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
+					unsigned long *size);
+extern int __init of_flat_dt_is_compatible(unsigned long node, const char *name);
+extern unsigned long __init of_get_flat_dt_root(void);
 
 /* For updating the device tree at runtime */
 extern void of_attach_node(struct device_node *);
Index: linux-work/arch/powerpc/kernel/nvram_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/nvram_64.c	2006-01-14 14:43:22.000000000 +1100
+++ linux-work/arch/powerpc/kernel/nvram_64.c	2006-03-24 11:45:28.000000000 +1100
@@ -160,7 +160,7 @@ static int dev_nvram_ioctl(struct inode 
 	case IOC_NVRAM_GET_OFFSET: {
 		int part, offset;
 
-		if (_machine != PLATFORM_POWERMAC)
+		if (!machine_is(powermac))
 			return -EINVAL;
 		if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
 			return -EFAULT;
@@ -443,7 +443,7 @@ static int nvram_setup_partition(void)
 	 * in our nvram, as Apple defined partitions use pretty much
 	 * all of the space
 	 */
-	if (_machine == PLATFORM_POWERMAC)
+	if (machine_is(powermac))
 		return -ENOSPC;
 
 	/* see if we have an OS partition that meets our needs.
Index: linux-work/arch/powerpc/kernel/proc_ppc64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/proc_ppc64.c	2006-01-14 14:43:22.000000000 +1100
+++ linux-work/arch/powerpc/kernel/proc_ppc64.c	2006-03-24 11:45:28.000000000 +1100
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 
+#include <asm/machdep.h>
 #include <asm/vdso_datapage.h>
 #include <asm/rtas.h>
 #include <asm/uaccess.h>
@@ -51,7 +52,7 @@ static int __init proc_ppc64_create(void
 	if (!root)
 		return 1;
 
-	if (!(platform_is_pseries() || _machine == PLATFORM_CELL))
+	if (!machine_is(pseries) && !machine_is(cell))
 		return 0;
 
 	if (!proc_mkdir("rtas", root))
Index: linux-work/arch/powerpc/kernel/rtas-proc.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/rtas-proc.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/kernel/rtas-proc.c	2006-03-24 11:45:28.000000000 +1100
@@ -257,7 +257,7 @@ static int __init proc_rtas_init(void)
 {
 	struct proc_dir_entry *entry;
 
-	if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR)
+	if (!machine_is(pseries))
 		return 1;
 
 	rtas_node = of_find_node_by_name(NULL, "rtas");
Index: linux-work/arch/powerpc/kernel/rtas.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/rtas.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/kernel/rtas.c	2006-03-24 11:45:28.000000000 +1100
@@ -25,6 +25,7 @@
 #include <asm/hvcall.h>
 #include <asm/semaphore.h>
 #include <asm/machdep.h>
+#include <asm/firmware.h>
 #include <asm/page.h>
 #include <asm/param.h>
 #include <asm/system.h>
@@ -767,7 +768,7 @@ void __init rtas_initialize(void)
 	 * the stop-self token if any
 	 */
 #ifdef CONFIG_PPC64
-	if (_machine == PLATFORM_PSERIES_LPAR) {
+	if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) {
 		rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
 		ibm_suspend_me_token = rtas_token("ibm,suspend-me");
 	}
Index: linux-work/arch/powerpc/kernel/traps.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/traps.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/kernel/traps.c	2006-03-24 11:45:28.000000000 +1100
@@ -97,7 +97,6 @@ static DEFINE_SPINLOCK(die_lock);
 int die(const char *str, struct pt_regs *regs, long err)
 {
 	static int die_counter, crash_dump_start = 0;
-	int nl = 0;
 
 	if (debugger(regs))
 		return 1;
@@ -106,7 +105,7 @@ int die(const char *str, struct pt_regs 
 	spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if (_machine == _MACH_Pmac) {
+	if (machine_is(powermac)) {
 		set_backlight_enable(1);
 		set_backlight_level(BACKLIGHT_MAX);
 	}
@@ -114,46 +113,18 @@ int die(const char *str, struct pt_regs 
 	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
 #ifdef CONFIG_PREEMPT
 	printk("PREEMPT ");
-	nl = 1;
 #endif
 #ifdef CONFIG_SMP
 	printk("SMP NR_CPUS=%d ", NR_CPUS);
-	nl = 1;
 #endif
 #ifdef CONFIG_DEBUG_PAGEALLOC
 	printk("DEBUG_PAGEALLOC ");
-	nl = 1;
 #endif
 #ifdef CONFIG_NUMA
 	printk("NUMA ");
-	nl = 1;
 #endif
-#ifdef CONFIG_PPC64
-	switch (_machine) {
-	case PLATFORM_PSERIES:
-		printk("PSERIES ");
-		nl = 1;
-		break;
-	case PLATFORM_PSERIES_LPAR:
-		printk("PSERIES LPAR ");
-		nl = 1;
-		break;
-	case PLATFORM_ISERIES_LPAR:
-		printk("ISERIES LPAR ");
-		nl = 1;
-		break;
-	case PLATFORM_POWERMAC:
-		printk("POWERMAC ");
-		nl = 1;
-		break;
-	case PLATFORM_CELL:
-		printk("CELL ");
-		nl = 1;
-		break;
-	}
-#endif
-	if (nl)
-		printk("\n");
+	printk("%s\n", ppc_md.name ? "" : ppc_md.name);
+
 	print_modules();
 	show_regs(regs);
 	bust_spinlocks(0);
Index: linux-work/arch/powerpc/platforms/powermac/feature.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/feature.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/platforms/powermac/feature.c	2006-03-24 11:45:28.000000000 +1100
@@ -2951,7 +2951,7 @@ static void *pmac_early_vresume_data;
 
 void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
 {
-	if (_machine != _MACH_Pmac)
+	if (!machine_is(powermac))
 		return;
 	preempt_disable();
 	pmac_early_vresume_proc = proc;
Index: linux-work/arch/powerpc/platforms/powermac/nvram.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/nvram.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/platforms/powermac/nvram.c	2006-03-24 11:45:28.000000000 +1100
@@ -597,7 +597,7 @@ int __init pmac_nvram_init(void)
 	}
 
 #ifdef CONFIG_PPC32
-	if (_machine == _MACH_chrp && nvram_naddrs == 1) {
+	if (machine_is(chrp) && nvram_naddrs == 1) {
 		nvram_data = ioremap(r1.start, s1);
 		nvram_mult = 1;
 		ppc_md.nvram_read_val	= direct_nvram_read_byte;
Index: linux-work/arch/powerpc/platforms/pseries/eeh.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/eeh.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/eeh.c	2006-03-24 11:45:28.000000000 +1100
@@ -1018,7 +1018,7 @@ static int __init eeh_init_proc(void)
 {
 	struct proc_dir_entry *e;
 
-	if (platform_is_pseries()) {
+	if (machine_is(pseries)) {
 		e = create_proc_entry("ppc64/eeh", 0, NULL);
 		if (e)
 			e->proc_fops = &proc_eeh_operations;
Index: linux-work/arch/powerpc/platforms/pseries/pci.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/pci.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/pci.c	2006-03-24 11:45:28.000000000 +1100
@@ -120,7 +120,7 @@ static void fixup_winbond_82c105(struct 
 	int i;
 	unsigned int reg;
 
-	if (!platform_is_pseries())
+	if (!machine_is(pseries))
 		return;
 
 	printk("Using INTC for W82c105 IDE controller.\n");
Index: linux-work/arch/powerpc/platforms/pseries/reconfig.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/reconfig.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/reconfig.c	2006-03-24 11:45:28.000000000 +1100
@@ -17,8 +17,9 @@
 #include <linux/proc_fs.h>
 
 #include <asm/prom.h>
-#include <asm/pSeries_reconfig.h>
+#include <asm/machdep.h>
 #include <asm/uaccess.h>
+#include <asm/pSeries_reconfig.h>
 
 
 
@@ -508,7 +509,7 @@ static int proc_ppc64_create_ofdt(void)
 {
 	struct proc_dir_entry *ent;
 
-	if (!platform_is_pseries())
+	if (!machine_is(pseries))
 		return 0;
 
 	ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
Index: linux-work/arch/powerpc/platforms/pseries/rtasd.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/rtasd.c	2006-01-14 14:43:22.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/rtasd.c	2006-03-24 11:45:28.000000000 +1100
@@ -27,6 +27,7 @@
 #include <asm/prom.h>
 #include <asm/nvram.h>
 #include <asm/atomic.h>
+#include <asm/machdep.h>
 
 #if 0
 #define DEBUG(A...)	printk(KERN_ERR A)
@@ -481,7 +482,7 @@ static int __init rtas_init(void)
 {
 	struct proc_dir_entry *entry;
 
-	if (!platform_is_pseries())
+	if (!machine_is(pseries))
 		return 0;
 
 	/* No RTAS */
Index: linux-work/include/asm-powerpc/vdso_datapage.h
===================================================================
--- linux-work.orig/include/asm-powerpc/vdso_datapage.h	2006-01-14 14:43:33.000000000 +1100
+++ linux-work/include/asm-powerpc/vdso_datapage.h	2006-03-24 11:45:28.000000000 +1100
@@ -55,6 +55,9 @@ struct vdso_data {
 		__u32 minor;		/* Minor number			0x14 */
 	} version;
 
+	/* Note about the platform flags: it now only contains the lpar
+	 * bit. The actual platform number is dead and burried
+	 */
 	__u32 platform;			/* Platform flags		0x18 */
 	__u32 processor;		/* Processor type		0x1C */
 	__u64 processorCount;		/* # of physical processors	0x20 */
Index: linux-work/arch/powerpc/kernel/vdso.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso.c	2006-03-24 11:45:28.000000000 +1100
@@ -33,6 +33,7 @@
 #include <asm/machdep.h>
 #include <asm/cputable.h>
 #include <asm/sections.h>
+#include <asm/firmware.h>
 #include <asm/vdso.h>
 #include <asm/vdso_datapage.h>
 
@@ -667,7 +668,13 @@ void __init vdso_init(void)
 	vdso_data->version.major = SYSTEMCFG_MAJOR;
 	vdso_data->version.minor = SYSTEMCFG_MINOR;
 	vdso_data->processor = mfspr(SPRN_PVR);
-	vdso_data->platform = _machine;
+	/*
+	 * Fake the old platform number for pSeries and iSeries and add
+	 * in LPAR bit if necessary
+	 */
+	vdso_data->platform = machine_is(iseries) ? 0x200 : 0x100;
+	if (firmware_has_feature(FW_FEATURE_LPAR))
+		vdso_data->platform |= 1;
 	vdso_data->physicalMemorySize = lmb_phys_mem_size();
 	vdso_data->dcache_size = ppc64_caches.dsize;
 	vdso_data->dcache_line_size = ppc64_caches.dline_size;
Index: linux-work/arch/powerpc/kernel/asm-offsets.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/asm-offsets.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/kernel/asm-offsets.c	2006-03-24 11:45:28.000000000 +1100
@@ -105,8 +105,6 @@ int main(void)
 	DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
 	DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
 	DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
-	DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
-
 	/* paca */
 	DEFINE(PACA_SIZE, sizeof(struct paca_struct));
 	DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
Index: linux-work/arch/powerpc/kernel/prom_init.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/prom_init.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/kernel/prom_init.c	2006-03-24 14:41:14.000000000 +1100
@@ -180,6 +180,16 @@ static unsigned long __initdata prom_tce
 static unsigned long __initdata prom_tce_alloc_end;
 #endif
 
+/* Platforms codes are now obsolete in the kernel. Now only used within this
+ * file and ultimately gone too. Feel free to change them if you need, they
+ * are not shared with anything outside of this file anymore
+ */
+#define PLATFORM_PSERIES	0x0100
+#define PLATFORM_PSERIES_LPAR	0x0101
+#define PLATFORM_LPAR		0x0001
+#define PLATFORM_POWERMAC	0x0400
+#define PLATFORM_GENERIC	0x0500
+
 static int __initdata of_platform;
 
 static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
@@ -1487,7 +1497,10 @@ static int __init prom_find_machine_type
 	int len, i = 0;
 #ifdef CONFIG_PPC64
 	phandle rtas;
+	int x;
 #endif
+
+	/* Look for a PowerMac */
 	len = prom_getprop(_prom->root, "compatible",
 			   compat, sizeof(compat)-1);
 	if (len > 0) {
@@ -1500,28 +1513,36 @@ static int __init prom_find_machine_type
 			if (strstr(p, RELOC("Power Macintosh")) ||
 			    strstr(p, RELOC("MacRISC")))
 				return PLATFORM_POWERMAC;
-#ifdef CONFIG_PPC64
-			if (strstr(p, RELOC("Momentum,Maple")))
-				return PLATFORM_MAPLE;
-			if (strstr(p, RELOC("IBM,CPB")))
-				return PLATFORM_CELL;
-#endif
 			i += sl + 1;
 		}
 	}
 #ifdef CONFIG_PPC64
+	/* If not a mac, try to figure out if it's an IBM pSeries. We assume
+	 * it is if :
+	 *  - /device_type is "chrp" (please, do NOT use that for future
+	 *    non-IBM designs !
+	 *  - it has /rtas
+	 */
+	len = prom_getprop(_prom->root, "model",
+			   compat, sizeof(compat)-1);
+	if (len <= 0)
+		return PLATFORM_GENERIC;
+	compat[len] = 0;
+	if (strcmp(compat, "chrp"))
+		return PLATFORM_GENERIC;
+
 	/* Default to pSeries. We need to know if we are running LPAR */
 	rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-	if (PHANDLE_VALID(rtas)) {
-		int x = prom_getproplen(rtas, "ibm,hypertas-functions");
-		if (x != PROM_ERROR) {
-			prom_printf("Hypertas detected, assuming LPAR !\n");
-			return PLATFORM_PSERIES_LPAR;
-		}
+	if (!PHANDLE_VALID(rtas))
+		return PLATFORM_GENERIC;
+	x = prom_getproplen(rtas, "ibm,hypertas-functions");
+	if (x != PROM_ERROR) {
+		prom_printf("Hypertas detected, assuming LPAR !\n");
+		return PLATFORM_PSERIES_LPAR;
 	}
 	return PLATFORM_PSERIES;
 #else
-	return PLATFORM_CHRP;
+	return PLATFORM_GENERIC;
 #endif
 }
 
@@ -2029,7 +2050,6 @@ unsigned long __init prom_init(unsigned 
 {	
        	struct prom_t *_prom;
 	unsigned long hdr;
-	u32 getprop_rval;
 	unsigned long offset = reloc_offset();
 
 #ifdef CONFIG_PPC32
@@ -2074,9 +2094,6 @@ unsigned long __init prom_init(unsigned 
 	 * between pSeries SMP and pSeries LPAR
 	 */
 	RELOC(of_platform) = prom_find_machine_type();
-	getprop_rval = RELOC(of_platform);
-	prom_setprop(_prom->chosen, "/chosen", "linux,platform",
-		     &getprop_rval, sizeof(getprop_rval));
 
 #ifdef CONFIG_PPC_PSERIES
 	/*
Index: linux-work/arch/powerpc/mm/hash_utils_64.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/hash_utils_64.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/mm/hash_utils_64.c	2006-03-24 11:45:28.000000000 +1100
@@ -167,7 +167,7 @@ int htab_bolt_mapping(unsigned long vsta
 		 * normal insert callback here.
 		 */
 #ifdef CONFIG_PPC_ISERIES
-		if (_machine == PLATFORM_ISERIES_LPAR)
+		if (machine_is(iseries))
 			ret = iSeries_hpte_insert(hpteg, va,
 						  paddr,
 						  tmp_mode,
@@ -176,7 +176,7 @@ int htab_bolt_mapping(unsigned long vsta
 		else
 #endif
 #ifdef CONFIG_PPC_PSERIES
-		if (_machine & PLATFORM_LPAR)
+		if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR))
 			ret = pSeries_lpar_hpte_insert(hpteg, va,
 						       paddr,
 						       tmp_mode,
@@ -295,8 +295,7 @@ static void __init htab_init_page_sizes(
 	 * Not in the device-tree, let's fallback on known size
 	 * list for 16M capable GP & GR
 	 */
-	if ((_machine != PLATFORM_ISERIES_LPAR) &&
-	    cpu_has_feature(CPU_FTR_16M_PAGE))
+	if (cpu_has_feature(CPU_FTR_16M_PAGE) && !machine_is(iseries))
 		memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
 		       sizeof(mmu_psize_defaults_gp));
  found:
Index: linux-work/drivers/char/generic_nvram.c
===================================================================
--- linux-work.orig/drivers/char/generic_nvram.c	2006-01-14 14:43:23.000000000 +1100
+++ linux-work/drivers/char/generic_nvram.c	2006-03-24 11:45:28.000000000 +1100
@@ -22,6 +22,9 @@
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
+#ifdef CONFIG_PPC_PMAC
+#include <asm/machdep.h>
+#endif
 
 #define NVRAM_SIZE	8192
 
@@ -92,7 +95,7 @@ static int nvram_ioctl(struct inode *ino
 	case IOC_NVRAM_GET_OFFSET: {
 		int part, offset;
 
-		if (_machine != _MACH_Pmac)
+		if (!machine_is(powermac))
 			return -EINVAL;
 		if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
 			return -EFAULT;
Index: linux-work/drivers/ide/pci/via82cxxx.c
===================================================================
--- linux-work.orig/drivers/ide/pci/via82cxxx.c	2006-01-14 14:43:23.000000000 +1100
+++ linux-work/drivers/ide/pci/via82cxxx.c	2006-03-24 11:45:28.000000000 +1100
@@ -440,7 +440,7 @@ static void __devinit init_hwif_via82cxx
 
 
 #if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32)
-	if(_machine == _MACH_chrp && _chrp_type == _CHRP_Pegasos) {
+	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
 		hwif->irq = hwif->channel ? 15 : 14;
 	}
 #endif
Index: linux-work/drivers/ide/ppc/pmac.c
===================================================================
--- linux-work.orig/drivers/ide/ppc/pmac.c	2006-01-14 14:43:23.000000000 +1100
+++ linux-work/drivers/ide/ppc/pmac.c	2006-03-24 11:45:28.000000000 +1100
@@ -1677,7 +1677,7 @@ MODULE_DEVICE_TABLE(pci, pmac_ide_pci_ma
 void __init
 pmac_ide_probe(void)
 {
-	if (_machine != _MACH_Pmac)
+	if (!machine_is(powermac))
 		return;
 
 #ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST
Index: linux-work/drivers/ieee1394/ohci1394.c
===================================================================
--- linux-work.orig/drivers/ieee1394/ohci1394.c	2006-01-14 14:43:23.000000000 +1100
+++ linux-work/drivers/ieee1394/ohci1394.c	2006-03-24 11:45:28.000000000 +1100
@@ -3526,7 +3526,7 @@ static void ohci1394_pci_remove(struct p
 static int ohci1394_pci_resume (struct pci_dev *pdev)
 {
 #ifdef CONFIG_PPC_PMAC
-	if (_machine == _MACH_Pmac) {
+	if (machine_is(powermac)) {
 		struct device_node *of_node;
 
 		/* Re-enable 1394 */
@@ -3545,7 +3545,7 @@ static int ohci1394_pci_resume (struct p
 static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
 {
 #ifdef CONFIG_PPC_PMAC
-	if (_machine == _MACH_Pmac) {
+	if (machine_is(powermac)) {
 		struct device_node *of_node;
 
 		/* Disable 1394 */
Index: linux-work/drivers/macintosh/adb.c
===================================================================
--- linux-work.orig/drivers/macintosh/adb.c	2006-01-14 14:43:23.000000000 +1100
+++ linux-work/drivers/macintosh/adb.c	2006-03-24 11:45:28.000000000 +1100
@@ -42,6 +42,7 @@
 #include <asm/semaphore.h>
 #ifdef CONFIG_PPC
 #include <asm/prom.h>
+#include <asm/machdep.h>
 #endif
 
 
@@ -294,7 +295,7 @@ int __init adb_init(void)
 	int i;
 
 #ifdef CONFIG_PPC32
-	if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
+	if (!machine_is(chrp) && !machine_is(powermac))
 		return 0;
 #endif
 #ifdef CONFIG_MAC
Index: linux-work/drivers/macintosh/adbhid.c
===================================================================
--- linux-work.orig/drivers/macintosh/adbhid.c	2006-01-14 14:43:23.000000000 +1100
+++ linux-work/drivers/macintosh/adbhid.c	2006-03-24 11:45:28.000000000 +1100
@@ -1206,8 +1206,8 @@ init_ms_a3(int id)
 static int __init adbhid_init(void)
 {
 #ifndef CONFIG_MAC
-	if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
-	    return 0;
+	if (!machine_is(chrp) && !machine_is(powermac))
+		return 0;
 #endif
 
 	led_request.complete = 1;
Index: linux-work/drivers/macintosh/mediabay.c
===================================================================
--- linux-work.orig/drivers/macintosh/mediabay.c	2006-01-14 14:43:23.000000000 +1100
+++ linux-work/drivers/macintosh/mediabay.c	2006-03-24 11:45:28.000000000 +1100
@@ -839,8 +839,8 @@ static int __init media_bay_init(void)
 		media_bays[i].cd_index		= -1;
 #endif
 	}
-	if (_machine != _MACH_Pmac)
-		return -ENODEV;
+	if (!machine_is(powermac))
+		return 0;
 
 	macio_register_driver(&media_bay_driver);	
 
Index: linux-work/drivers/media/video/planb.c
===================================================================
--- linux-work.orig/drivers/media/video/planb.c	2006-03-23 14:26:09.000000000 +1100
+++ linux-work/drivers/media/video/planb.c	2006-03-24 11:45:28.000000000 +1100
@@ -2156,7 +2156,7 @@ static int find_planb(void)
 	struct pci_dev 		*pdev;
 	int rc;
 
-	if (_machine != _MACH_Pmac)
+	if (!machine_is(powermac))
 		return 0;
 
 	planb_devices = find_devices("planb");
Index: linux-work/drivers/scsi/mesh.c
===================================================================
--- linux-work.orig/drivers/scsi/mesh.c	2006-01-14 14:43:31.000000000 +1100
+++ linux-work/drivers/scsi/mesh.c	2006-03-24 11:45:28.000000000 +1100
@@ -1748,7 +1748,7 @@ static int mesh_host_reset(struct scsi_c
 
 static void set_mesh_power(struct mesh_state *ms, int state)
 {
-	if (_machine != _MACH_Pmac)
+	if (!machine_is(powermac))
 		return;
 	if (state) {
 		pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 1);
Index: linux-work/drivers/usb/core/hcd-pci.c
===================================================================
--- linux-work.orig/drivers/usb/core/hcd-pci.c	2006-03-23 14:26:11.000000000 +1100
+++ linux-work/drivers/usb/core/hcd-pci.c	2006-03-24 11:45:28.000000000 +1100
@@ -296,7 +296,7 @@ done:
 
 #ifdef CONFIG_PPC_PMAC
 		/* Disable ASIC clocks for USB */
-		if (_machine == _MACH_Pmac) {
+		if (machine_is(powermac)) {
 			struct device_node	*of_node;
 
 			of_node = pci_device_to_OF_node (dev);
@@ -331,7 +331,7 @@ int usb_hcd_pci_resume (struct pci_dev *
 
 #ifdef CONFIG_PPC_PMAC
 	/* Reenable ASIC clocks for USB */
-	if (_machine == _MACH_Pmac) {
+	if (machine_is(powermac)) {
 		struct device_node *of_node;
 
 		of_node = pci_device_to_OF_node (dev);
Index: linux-work/drivers/video/aty/aty128fb.c
===================================================================
--- linux-work.orig/drivers/video/aty/aty128fb.c	2006-03-23 14:26:11.000000000 +1100
+++ linux-work/drivers/video/aty/aty128fb.c	2006-03-24 11:45:28.000000000 +1100
@@ -67,6 +67,7 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_PPC_PMAC
+#include <asm/machdep.h>
 #include <asm/pmac_feature.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
@@ -1748,7 +1749,7 @@ static int __init aty128_init(struct pci
 
 	var = default_var;
 #ifdef CONFIG_PPC_PMAC
-	if (_machine == _MACH_Pmac) {
+	if (machine_is(powermac)) {
 		/* Indicate sleep capability */
 		if (par->chip_gen == rage_M3) {
 			pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1);
@@ -2011,7 +2012,7 @@ static int aty128fb_blank(int blank, str
 		return 0;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if ((_machine == _MACH_Pmac) && blank)
+	if (machine_is(powermac) && blank)
 		set_backlight_enable(0);
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
@@ -2029,7 +2030,7 @@ static int aty128fb_blank(int blank, str
 		aty128_set_lcd_enable(par, par->lcd_on && !blank);
 	}
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if ((_machine == _MACH_Pmac) && !blank)
+	if (machine_is(powermac) && !blank)
 		set_backlight_enable(1);
 #endif /* CONFIG_PMAC_BACKLIGHT */
 	return 0;
Index: linux-work/drivers/video/aty/atyfb_base.c
===================================================================
--- linux-work.orig/drivers/video/aty/atyfb_base.c	2006-03-10 15:58:20.000000000 +1100
+++ linux-work/drivers/video/aty/atyfb_base.c	2006-03-24 11:45:28.000000000 +1100
@@ -75,6 +75,7 @@
 #include "ati_ids.h"
 
 #ifdef __powerpc__
+#include <asm/machdep.h>
 #include <asm/prom.h>
 #include "../macmodes.h"
 #endif
@@ -2516,7 +2517,7 @@ static int __init aty_init(struct fb_inf
 
 	memset(&var, 0, sizeof(var));
 #ifdef CONFIG_PPC
-	if (_machine == _MACH_Pmac) {
+	if (machine_is(powermac)) {
 		/*
 		 *  FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
 		 *         applies to all Mac video cards
@@ -2671,7 +2672,7 @@ static int atyfb_blank(int blank, struct
 		return 0;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if ((_machine == _MACH_Pmac) && blank > FB_BLANK_NORMAL)
+	if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
 		set_backlight_enable(0);
 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
 	if (par->lcd_table && blank > FB_BLANK_NORMAL &&
@@ -2703,7 +2704,7 @@ static int atyfb_blank(int blank, struct
 	aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if ((_machine == _MACH_Pmac) && blank <= FB_BLANK_NORMAL)
+	if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
 		set_backlight_enable(1);
 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
 	if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
Index: linux-work/drivers/video/aty/radeon_pm.c
===================================================================
--- linux-work.orig/drivers/video/aty/radeon_pm.c	2006-03-10 15:58:20.000000000 +1100
+++ linux-work/drivers/video/aty/radeon_pm.c	2006-03-24 14:41:02.000000000 +1100
@@ -20,7 +20,7 @@
 #include <linux/agp_backend.h>
 
 #ifdef CONFIG_PPC_PMAC
-#include <asm/processor.h>
+#include <asm/machdep.h>
 #include <asm/prom.h>
 #include <asm/pmac_feature.h>
 #endif
@@ -2745,7 +2745,7 @@ void radeonfb_pm_init(struct radeonfb_in
 		rinfo->pm_mode |= radeon_pm_off;
 	}
 #if defined(CONFIG_PPC_PMAC)
-	if (_machine == _MACH_Pmac && rinfo->of_node) {
+	if (machine_is(powermac) && rinfo->of_node) {
 		if (rinfo->is_mobility && rinfo->pm_reg &&
 		    rinfo->family <= CHIP_FAMILY_RV250)
 			rinfo->pm_mode |= radeon_pm_d2;
Index: linux-work/drivers/video/cirrusfb.c
===================================================================
--- linux-work.orig/drivers/video/cirrusfb.c	2006-01-14 14:43:31.000000000 +1100
+++ linux-work/drivers/video/cirrusfb.c	2006-03-24 11:45:28.000000000 +1100
@@ -60,8 +60,8 @@
 #include <asm/amigahw.h>
 #endif
 #ifdef CONFIG_PPC_PREP
-#include <asm/processor.h>
-#define isPReP (_machine == _MACH_prep)
+#include <asm/machdep.h>
+#define isPReP (machine_is(prep))
 #else
 #define isPReP 0
 #endif
Index: linux-work/drivers/video/matrox/matroxfb_base.c
===================================================================
--- linux-work.orig/drivers/video/matrox/matroxfb_base.c	2006-03-10 15:58:20.000000000 +1100
+++ linux-work/drivers/video/matrox/matroxfb_base.c	2006-03-24 11:45:28.000000000 +1100
@@ -116,6 +116,7 @@
 #include <asm/uaccess.h>
 
 #ifdef CONFIG_PPC_PMAC
+#include <asm/machdep.h>
 unsigned char nvram_read_byte(int);
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
@@ -1834,7 +1835,7 @@ static int initMatrox2(WPMINFO struct bo
 	/* FIXME: Where to move this?! */
 #if defined(CONFIG_PPC_PMAC)
 #ifndef MODULE
-	if (_machine == _MACH_Pmac) {
+	if (machine_is(powermac)) {
 		struct fb_var_screeninfo var;
 		if (default_vmode <= 0 || default_vmode > VMODE_MAX)
 			default_vmode = VMODE_640_480_60;
Index: linux-work/drivers/video/nvidia/nvidia.c
===================================================================
--- linux-work.orig/drivers/video/nvidia/nvidia.c	2006-03-10 15:58:20.000000000 +1100
+++ linux-work/drivers/video/nvidia/nvidia.c	2006-03-24 11:45:28.000000000 +1100
@@ -29,6 +29,7 @@
 #include <asm/pci-bridge.h>
 #endif
 #ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/machdep.h>
 #include <asm/backlight.h>
 #endif
 
@@ -1353,7 +1354,7 @@ static int nvidiafb_blank(int blank, str
 	NVWriteCrtc(par, 0x1a, vesa);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if (par->FlatPanel && _machine == _MACH_Pmac) {
+	if (par->FlatPanel && machine_is(powermac)) {
 		set_backlight_enable(!blank);
 	}
 #endif
@@ -1688,7 +1689,7 @@ static int __devinit nvidiafb_probe(stru
 	       info->fix.id,
 	       par->FbMapSize / (1024 * 1024), info->fix.smem_start);
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if (par->FlatPanel && _machine == _MACH_Pmac)
+	if (par->FlatPanel && machine_is(powermac))
 		register_backlight_controller(&nvidia_backlight_controller,
 					      par, "mnca");
 #endif
Index: linux-work/drivers/video/radeonfb.c
===================================================================
--- linux-work.orig/drivers/video/radeonfb.c	2006-03-10 15:58:20.000000000 +1100
+++ linux-work/drivers/video/radeonfb.c	2006-03-24 11:45:28.000000000 +1100
@@ -1596,7 +1596,7 @@ static int radeonfb_blank (int blank, st
 		return 0;
 		
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
+	if (rinfo->dviDisp_type == MT_LCD && machine_is(powermac)) {
 		set_backlight_enable(!blank);
 		return 0;
 	}
Index: linux-work/drivers/video/riva/fbdev.c
===================================================================
--- linux-work.orig/drivers/video/riva/fbdev.c	2006-01-14 14:43:32.000000000 +1100
+++ linux-work/drivers/video/riva/fbdev.c	2006-03-24 11:45:28.000000000 +1100
@@ -49,6 +49,7 @@
 #include <asm/pci-bridge.h>
 #endif
 #ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/machdep.h>
 #include <asm/backlight.h>
 #endif
 
@@ -1247,7 +1248,7 @@ static int rivafb_blank(int blank, struc
 	CRTCout(par, 0x1a, vesa);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if ( par->FlatPanel && _machine == _MACH_Pmac) {
+	if ( par->FlatPanel && machine_is(powermac)) {
 		set_backlight_enable(!blank);
 	}
 #endif
@@ -2037,9 +2038,9 @@ static int __devinit rivafb_probe(struct
 		info->fix.smem_len / (1024 * 1024),
 		info->fix.smem_start);
 #ifdef CONFIG_PMAC_BACKLIGHT
-	if (default_par->FlatPanel && _machine == _MACH_Pmac)
-	register_backlight_controller(&riva_backlight_controller,
-						default_par, "mnca");
+	if (default_par->FlatPanel && machine_is(powermac))
+		register_backlight_controller(&riva_backlight_controller,
+					      default_par, "mnca");
 #endif
 	NVTRACE_LEAVE();
 	return 0;
Index: linux-work/include/asm-powerpc/pmac_feature.h
===================================================================
--- linux-work.orig/include/asm-powerpc/pmac_feature.h	2006-01-14 14:43:33.000000000 +1100
+++ linux-work/include/asm-powerpc/pmac_feature.h	2006-03-24 11:45:28.000000000 +1100
@@ -305,7 +305,7 @@ extern void pmac_feature_init(void);
 extern void pmac_set_early_video_resume(void (*proc)(void *data), void *data);
 extern void pmac_call_early_video_resume(void);
 
-#define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x))
+#define PMAC_FTR_DEF(x) ((0x6660000) | (x))
 
 /* The AGP driver registers itself here */
 extern void pmac_register_agp_pm(struct pci_dev *bridge,
Index: linux-work/arch/powerpc/platforms/powermac/low_i2c.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/low_i2c.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/platforms/powermac/low_i2c.c	2006-03-24 11:45:28.000000000 +1100
@@ -1457,6 +1457,9 @@ int __init pmac_i2c_init(void)
 		return 0;
 	i2c_inited = 1;
 
+	if (!machine_is(powermac))
+		return 0;
+
 	/* Probe keywest-i2c busses */
 	kw_i2c_probe();
 
Index: linux-work/arch/powerpc/platforms/powermac/pfunc_base.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/pfunc_base.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/platforms/powermac/pfunc_base.c	2006-03-24 11:45:28.000000000 +1100
@@ -336,6 +336,8 @@ int __init pmac_pfunc_base_install(void)
 		return 0;
 	pfbase_inited = 1;
 
+	if (!machine_is(powermac))
+		return 0;
 
 	DBG("Installing base platform functions...\n");
 
Index: linux-work/fs/partitions/mac.c
===================================================================
--- linux-work.orig/fs/partitions/mac.c	2006-01-14 14:43:32.000000000 +1100
+++ linux-work/fs/partitions/mac.c	2006-03-24 11:45:28.000000000 +1100
@@ -12,6 +12,7 @@
 #include "mac.h"
 
 #ifdef CONFIG_PPC_PMAC
+#include <asm/machdep.h>
 extern void note_bootable_part(dev_t dev, int part, int goodness);
 #endif
 
@@ -79,7 +80,7 @@ int mac_partition(struct parsed_partitio
 		 * If this is the first bootable partition, tell the
 		 * setup code, in case it wants to make this the root.
 		 */
-		if (_machine == _MACH_Pmac) {
+		if (machine_is(powermac)) {
 			int goodness = 0;
 
 			mac_fix_string(part->processor, 16);
Index: linux-work/sound/oss/dmasound/dmasound_awacs.c
===================================================================
--- linux-work.orig/sound/oss/dmasound/dmasound_awacs.c	2006-03-24 11:42:14.000000000 +1100
+++ linux-work/sound/oss/dmasound/dmasound_awacs.c	2006-03-24 11:45:28.000000000 +1100
@@ -2814,7 +2814,7 @@ int __init dmasound_awacs_init(void)
 	struct device_node *io = NULL, *info = NULL;
 	int vol, res;
 
-	if (_machine != _MACH_Pmac)
+	if (!machine_is(powermac))
 		return -ENODEV;
 
 	awacs_subframe = 0;
Index: linux-work/sound/ppc/pmac.c
===================================================================
--- linux-work.orig/sound/ppc/pmac.c	2006-03-10 15:58:21.000000000 +1100
+++ linux-work/sound/ppc/pmac.c	2006-03-24 11:45:28.000000000 +1100
@@ -869,7 +869,7 @@ static int __init snd_pmac_detect(struct
 
 	u32 layout_id = 0;
 
-	if (_machine != _MACH_Pmac)
+	if (!machine_is(powermac))
 		return -ENODEV;
 
 	chip->subframe = 0;
Index: linux-work/arch/powerpc/platforms/chrp/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/chrp/setup.c	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/arch/powerpc/platforms/chrp/setup.c	2006-03-24 11:45:28.000000000 +1100
@@ -304,6 +304,10 @@ void __init chrp_setup_arch(void)
 
 	pci_create_OF_bus_map();
 
+#ifdef CONFIG_SMP
+	smp_ops = &chrp_smp_ops;
+#endif /* CONFIG_SMP */
+
 	/*
 	 * Print the banner, then scroll down so boot progress
 	 * can be printed.  -- Cort
@@ -480,8 +484,15 @@ chrp_init2(void)
 		ppc_md.progress("  Have fun!    ", 0x7777);
 }
 
-void __init chrp_init(void)
+static int __init chrp_probe(void)
 {
+ 	char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
+ 					  "device_type", NULL);
+ 	if (dtype == NULL)
+ 		return 0;
+ 	if (strcmp(dtype, "chrp"))
+		return 0;
+
 	ISA_DMA_THRESHOLD = ~0L;
 	DMA_MODE_READ = 0x44;
 	DMA_MODE_WRITE = 0x48;
Index: linux-work/arch/powerpc/platforms/powermac/bootx_init.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/bootx_init.c	2006-01-14 14:43:22.000000000 +1100
+++ linux-work/arch/powerpc/platforms/powermac/bootx_init.c	2006-03-24 11:45:28.000000000 +1100
@@ -161,9 +161,7 @@ static void __init bootx_dt_add_prop(cha
 static void __init bootx_add_chosen_props(unsigned long base,
 					  unsigned long *mem_end)
 {
-	u32 val = _MACH_Pmac;
-
-	bootx_dt_add_prop("linux,platform", &val, 4, mem_end);
+	u32 val;
 
 	if (bootx_info->kernelParamsOffset) {
 		char *args = (char *)((unsigned long)bootx_info) +
Index: linux-work/arch/powerpc/platforms/powermac/time.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/time.c	2006-01-14 14:43:22.000000000 +1100
+++ linux-work/arch/powerpc/platforms/powermac/time.c	2006-03-24 11:45:28.000000000 +1100
@@ -336,10 +336,10 @@ static struct pmu_sleep_notifier time_sl
  */
 void __init pmac_calibrate_decr(void)
 {
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && defined(CONFIG_ADB_PMU)
 	/* XXX why here? */
 	pmu_register_sleep_notifier(&time_sleep_notifier);
-#endif /* CONFIG_PM */
+#endif
 
 	generic_calibrate_decr();
 
Index: linux-work/drivers/net/tulip/de4x5.c
===================================================================
--- linux-work.orig/drivers/net/tulip/de4x5.c	2006-01-14 14:43:28.000000000 +1100
+++ linux-work/drivers/net/tulip/de4x5.c	2006-03-24 11:45:28.000000000 +1100
@@ -4160,7 +4160,7 @@ get_hw_addr(struct net_device *dev)
     ** If the address starts with 00 a0, we have to bit-reverse
     ** each byte of the address.
     */
-    if ( (_machine & _MACH_Pmac) &&
+    if ( machine_is(powermac) &&
 	 (dev->dev_addr[0] == 0) &&
 	 (dev->dev_addr[1] == 0xa0) )
     {
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c	2006-03-24 11:45:28.000000000 +1100
@@ -787,7 +787,7 @@ pci_busdev_to_OF_node(struct pci_bus *bu
 	 * fix has to be done by making the remapping per-host and always
 	 * filling the pci_to_OF map. --BenH
 	 */
-	if (_machine == _MACH_Pmac && busnr >= 0xf0)
+	if (machine_is(powermac) && busnr >= 0xf0)
 		busnr -= 0xf0;
 	else
 #endif
@@ -1728,7 +1728,7 @@ long sys_pciconfig_iobase(long which, un
 	 * (bus 0 is HT root), we return the AGP one instead.
 	 */
 #ifdef CONFIG_PPC_PMAC
-	if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4"))
+	if (machine_is(powermac) && machine_is_compatible("MacRISC4"))
 		if (bus == 0)
 			bus = 0xf0;
 #endif /* CONFIG_PPC_PMAC */
Index: linux-work/arch/powerpc/platforms/pseries/pci_dlpar.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/pci_dlpar.c	2006-03-23 14:26:08.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/pci_dlpar.c	2006-03-24 11:45:28.000000000 +1100
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppc-pci.h>
+#include <asm/firmware.h>
 
 static struct pci_bus *
 find_bus_among_children(struct pci_bus *bus,
@@ -158,7 +159,7 @@ pcibios_add_pci_devices(struct pci_bus *
 
 	eeh_add_device_tree_early(dn);
 
-	if (_machine == PLATFORM_PSERIES_LPAR) {
+	if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) {
 		/* use ofdt-based probe */
 		of_scan_bus(dn, bus);
 		if (!list_empty(&bus->devices)) {
Index: linux-work/Documentation/powerpc/booting-without-of.txt
===================================================================
--- linux-work.orig/Documentation/powerpc/booting-without-of.txt	2006-03-24 11:42:13.000000000 +1100
+++ linux-work/Documentation/powerpc/booting-without-of.txt	2006-03-24 14:28:27.000000000 +1100
@@ -719,6 +719,10 @@ address which can extend beyond that lim
     - model : this is your board name/model
     - #address-cells : address representation for "root" devices
     - #size-cells: the size representation for "root" devices
+    - device_type : This property shouldn't be necessary. However, if
+      device to create a device_type for your root node, make sure it
+      is _not_ "chrp" as this will be matched by the kernel to be a
+      CHRP machine on 32 bits kernel or a pSeries on 64 bits kernels
 
   Additionally, some recommended properties are:
 

^ permalink raw reply

* "transmit timed out" on FCC in MPC8260 as well as MPC8247
From: Siju Viswanath K E @ 2006-03-24  5:20 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: siju

Hi,
	I am using denk's linuxppc-2.4.20 . I am getting this problem of
"transmit timed out" on FCC in MPC8260 as well as MPC8247. It seems to
be a case of late collision. I checked out earlier posts similar to this
also. The problem occurs if I attempt to transfer large files and is not
seen on all systems.

	The messages on console are given below. I am seeing the
same 5th BD reporting LC. FCC_PSMR_LPB is already set in
arch/ppc/8260_io/fcc_enet.c .

	Can the 8247 errata CPM119 or some other errata be the cause ? What is
the solution for this ?
 
console messages:
 
NETDEV WATCHDOG: eth0: transmit timed out
 
eth0: transmit timed out.
 
 Ring data dump: cur_tx c01ef560 (full) cur_rx c01ef4d0.
 
 Tx @base c01ef508 :
 
5c00 0036 016d7da2
 
1c00 003e 00c25892
 
5c00 0036 00c2529a
 
1c00 0121 066b489a
 
1c00 05ea 0652e89a
 
1c80 01f0 0652e09a
 
9c00 0056 00c25c7a
 
9c00 003e 00c25e92
 
9c00 0056 00ad527a
 
9c00 003e 00ad5092
 
dc00 0036 00ad549a
 
9c00 004e 00c25682
 
1c00 003e 00c25492
 
5c00 0036 00c25a9a
 
1c00 0123 065c009a
 
3c00 040d 066b409a
 
 Rx @base c01ef408 :
 
9c00 0040 07b34000
 
<deleted>
 
bc00 0040 07b25800
 
 
+++++++++++++++++ similar problems ++++++++++++++++++++
 
1. http://patchwork.ozlabs.org/linuxppc/patch?id=1853
 
2. From: hubert loewenguth <hubert.loewenguth@thales-bm.com>
To: linuxppc-embedded@ozlabs.org
Subject: MPC8260 fcc_enet transmit timed out
Date: Mon, 14 Nov 2005 18:34:32 +0100

<deleted>
I have found some personns in this mailling list who has encounter a
problem wich seems similar:
 
http://ozlabs.org/pipermail/linuxppc-embedded/2005-January/016539.html
http://ozlabs.org/pipermail/linuxppc-embedded/2001-December/005714.html
<deleted>
+++++++++++++++++ similar problems ++++++++++++++++++++
 
Thanks,
Siju Viswanath K E
Tejas Networks

^ permalink raw reply

* Re: [PATCH] powerpc: Kill machine numbers
From: Olof Johansson @ 2006-03-24  6:26 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Paul Mackerras, Linux Kernel list
In-Reply-To: <1143178947.4257.78.camel@localhost.localdomain>

Hi,

A few comments below, I've cut out most of the patch to save
bandwidth...

On Fri, Mar 24, 2006 at 04:42:26PM +1100, Benjamin Herrenschmidt wrote:

> Index: linux-work/arch/powerpc/kernel/setup-common.c
> ===================================================================
> --- linux-work.orig/arch/powerpc/kernel/setup-common.c	2006-03-24 11:42:13.000000000 +1100
> +++ linux-work/arch/powerpc/kernel/setup-common.c	2006-03-24 11:45:28.000000000 +1100
> +void probe_machine(void)
> +{
> +	extern struct machdep_calls __machine_desc_start;
> +	extern struct machdep_calls __machine_desc_end;
> +
> +	/*
> +	 * Iterate all ppc_md structures until we find the proper
> +	 * one for the current machine type
> +	 */
> +	DBG("Probing machine type ...\n");
> +
> +	for (machine_id = &__machine_desc_start;
> +	     machine_id < &__machine_desc_end;
> +	     machine_id++) {
> +		DBG("  %s ...", machine_id->name);
> +		memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls));
> +		if (ppc_md.probe()) {
> +			DBG(" match !\n");
> +			break;
> +		}
> +		DBG("\n");
> +	}

It would be very useful to print the ppc_md.name of the found machine
here, even without debugging enabled.

> +	/* What can we do if we didn't find ? */
> +	if (machine_id >= &__machine_desc_end) {
> +		DBG("No suitable machine found !\n");
> +		for (;;);
> +	}
> +}


> Index: linux-work/arch/powerpc/platforms/cell/setup.c
> ===================================================================
> --- linux-work.orig/arch/powerpc/platforms/cell/setup.c	2006-03-23 14:26:08.000000000 +1100
> +++ linux-work/arch/powerpc/platforms/cell/setup.c	2006-03-24 11:45:28.000000000 +1100
> @@ -195,9 +195,10 @@ static void __init cell_init_early(void)
>  }
>  
>  
> -static int __init cell_probe(int platform)
> +static int __init cell_probe(void)
>  {
> -	if (platform != PLATFORM_CELL)
> +	unsigned long root = of_get_flat_dt_root();
> +	if (!of_flat_dt_is_compatible(root, "IBM,CPB"))
>  		return 0;
>  
>  	return 1;
> @@ -212,7 +213,7 @@ static int cell_check_legacy_ioport(unsi
>  	return -ENODEV;
>  }
>  
> -struct machdep_calls __initdata cell_md = {
> +define_machine(cell) {
>  	.probe			= cell_probe,
>  	.setup_arch		= cell_setup_arch,
>  	.init_early		= cell_init_early,

You forgot to add a .name value here.

> Index: linux-work/arch/powerpc/kernel/prom_init.c
> ===================================================================
> --- linux-work.orig/arch/powerpc/kernel/prom_init.c	2006-03-10 15:58:17.000000000 +1100
> +++ linux-work/arch/powerpc/kernel/prom_init.c	2006-03-24 14:41:14.000000000 +1100
[...]
> +	/* If not a mac, try to figure out if it's an IBM pSeries. We assume
> +	 * it is if :
> +	 *  - /device_type is "chrp" (please, do NOT use that for future
> +	 *    non-IBM designs !
> +	 *  - it has /rtas
> +	 */

It's really weird that IBM chose to use "chrp" to describe a
PAPR-compliant platform. I guess it's for historical reasons, but it
sure isn't CHRP any more.

Also, please change the wording. With power.org, there will likely be
non-IBM PAPR-compliant platforms at some point. "non-PAPR-compliant
designs" is a better term to use.

> Index: linux-work/Documentation/powerpc/booting-without-of.txt
> ===================================================================
> --- linux-work.orig/Documentation/powerpc/booting-without-of.txt	2006-03-24 11:42:13.000000000 +1100
> +++ linux-work/Documentation/powerpc/booting-without-of.txt	2006-03-24 14:28:27.000000000 +1100
> @@ -719,6 +719,10 @@ address which can extend beyond that lim
>      - model : this is your board name/model
>      - #address-cells : address representation for "root" devices
>      - #size-cells: the size representation for "root" devices
> +    - device_type : This property shouldn't be necessary. However, if
> +      device to create a device_type for your root node, make sure it

if you device to create... ?

> +      is _not_ "chrp" as this will be matched by the kernel to be a
> +      CHRP machine on 32 bits kernel or a pSeries on 64 bits kernels

...or a PAPR-compliant machine on 64-bit kernels.

(Also, "xx-bit kernels", not "xx bits kernels").


-Olof

^ permalink raw reply

* Re: "transmit timed out" on FCC in MPC8260 as well as MPC8247
From: Wolfgang Denk @ 2006-03-24  7:51 UTC (permalink / raw)
  To: Siju Viswanath K E; +Cc: linuxppc-embedded
In-Reply-To: <1143177651.22246.3.camel@Blaze>

In message <1143177651.22246.3.camel@Blaze> you wrote:
>
> 	I am using denk's linuxppc-2.4.20 . I am getting this problem of

Why don't you try using a more current version of the code? 2.4.20 is
*very* old, and *lots* of bugs and problems have been fixed since.

It really does not make sense to spend effort on such old code.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Those who do not  understand  Unix  are  condemned  to  reinvent  it,
poorly.              - Henry Spencer, University of Toronto Unix hack

^ permalink raw reply

* Re: [PATCH] powerpc: Kill machine numbers
From: Benjamin Herrenschmidt @ 2006-03-24  8:01 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev list, Paul Mackerras, Linux Kernel list
In-Reply-To: <20060324062624.GA16815@pb15.lixom.net>


> It would be very useful to print the ppc_md.name of the found machine
> here, even without debugging enabled.

Not sure ... without debugging enabled, it's likely that you won't see
anything that early anyway :)

> > -struct machdep_calls __initdata cell_md = {
> > +define_machine(cell) {
> >  	.probe			= cell_probe,
> >  	.setup_arch		= cell_setup_arch,
> >  	.init_early		= cell_init_early,
> 
> You forgot to add a .name value here.

Yup, thanks. I think this should become cpb instead of cell, other cell
based boards would then have different ppc_md's though they could share
various routines.

> > Index: linux-work/arch/powerpc/kernel/prom_init.c
> > ===================================================================
> > --- linux-work.orig/arch/powerpc/kernel/prom_init.c	2006-03-10 15:58:17.000000000 +1100
> > +++ linux-work/arch/powerpc/kernel/prom_init.c	2006-03-24 14:41:14.000000000 +1100
> [...]
> > +	/* If not a mac, try to figure out if it's an IBM pSeries. We assume
> > +	 * it is if :
> > +	 *  - /device_type is "chrp" (please, do NOT use that for future
> > +	 *    non-IBM designs !
> > +	 *  - it has /rtas
> > +	 */
> 
> It's really weird that IBM chose to use "chrp" to describe a
> PAPR-compliant platform. I guess it's for historical reasons, but it
> sure isn't CHRP any more.

Yup, I'm trying to get that changed in the architecture but even if I'm
successful, we'll have to deal with existing machines.

> Also, please change the wording. With power.org, there will likely be
> non-IBM PAPR-compliant platforms at some point. "non-PAPR-compliant
> designs" is a better term to use.

Ok.

> > Index: linux-work/Documentation/powerpc/booting-without-of.txt
> > ===================================================================
> > --- linux-work.orig/Documentation/powerpc/booting-without-of.txt	2006-03-24 11:42:13.000000000 +1100
> > +++ linux-work/Documentation/powerpc/booting-without-of.txt	2006-03-24 14:28:27.000000000 +1100
> > @@ -719,6 +719,10 @@ address which can extend beyond that lim
> >      - model : this is your board name/model
> >      - #address-cells : address representation for "root" devices
> >      - #size-cells: the size representation for "root" devices
> > +    - device_type : This property shouldn't be necessary. However, if
> > +      device to create a device_type for your root node, make sure it
> 
> if you device to create... ?

I was tired :) If you "decide" to create.. will fix, thanks.

> > +      is _not_ "chrp" as this will be matched by the kernel to be a
> > +      CHRP machine on 32 bits kernel or a pSeries on 64 bits kernels
> 
> ...or a PAPR-compliant machine on 64-bit kernels.
> 
> (Also, "xx-bit kernels", not "xx bits kernels").

yeah yeah :) Thanks for the review anyway !

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] powerpc: Kill machine numbers
From: Arnd Bergmann @ 2006-03-24  8:46 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras, Linux Kernel list, cbe-oss-dev
In-Reply-To: <1143187298.3710.3.camel@localhost.localdomain>

On Friday 24 March 2006 09:01, Benjamin Herrenschmidt wrote:
> > > -struct machdep_calls __initdata cell_md = {
> > > +define_machine(cell) {
> > >     .probe                  = cell_probe,
> > >     .setup_arch             = cell_setup_arch,
> > >     .init_early             = cell_init_early,
> > 
> > You forgot to add a .name value here.
> 
> Yup, thanks. I think this should become cpb instead of cell, other cell
> based boards would then have different ppc_md's though they could share
> various routines.

The cpb name come from an outdated code name for what we currently
call the cell blade. My current understanding is that we try to keep
a common machine description for at least those machines that are
running without a hypervisor underneath them but based on rtas,
while then adding new machine descriptions for others.

However I really want to avoid having to add a new machine description
every time a company comes up with a new board design. As long
as they get everything right in the device tree, it should just
work (as long as all device drivers are there).

One thing I have been wondering about is what should be the right way
to check whether we're running on something based on the
Cell Broadband Engine Architecture, if that is needed somewhere.
My original idea was to make this the platform number, but this
seems impractical now.

	Arnd <><

^ permalink raw reply

* Re: [PATCH] powerpc: Kill machine numbers
From: Arnd Bergmann @ 2006-03-24  9:27 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras, Linux Kernel list, cbe-oss-dev
In-Reply-To: <1143178947.4257.78.camel@localhost.localdomain>

On Friday 24 March 2006 06:42, Benjamin Herrenschmidt wrote:
> -                       if (strstr(p, RELOC("IBM,CPB")))
> -                               return PLATFORM_CELL;

> +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
> +{
> +       const char* cp;
> +       unsigned long cplen, l;
> +
> +       cp = of_get_flat_dt_prop(node, "compatible", &cplen);
> +       if (cp == NULL)
> +               return 0;
> +       while (cplen > 0) {
> +               if (strncasecmp(cp, compat, strlen(compat)) == 0)
> +                       return 1;
> +               l = strlen(cp) + 1;
> +               cp += l;
> +               cplen -= l;
> +       }
> +
> +       return 0;
> +}

> +static int __init cell_probe(void)
>  {
> -       if (platform != PLATFORM_CELL)
> +       unsigned long root = of_get_flat_dt_root();
> +       if (!of_flat_dt_is_compatible(root, "IBM,CPB"))
>                 return 0;
>  

Unfortunately, this breaks cell detection. The string in our current
hardware is 'IBM,CPBW-1.0', for reasons you don't want to know.
We just relied on strstr being able to scan for everything starting
with 'IBM,CPB'.

For even more obscure reasons, our future firmware is planned
to no no longer claim compatibility with that but rather with
'CBEA' _and_ 'IBM,CBEA'.

At this point, the issue is getting really complicated, as CBEA
was meant to be a generic identifier for all systems based on
that architecture extension, but we probably want to have different
machine_description data for e.g. IBM and Sony hardware, so they
should check for different values.

As soon as I get to the office, I'll try to do a patch that at
least 

- restores the current functionality by checking for 'IBM,CPBW-1.0'
- also checks for 'IBM,CBEA' so we don't break on future IBM systems

but we should make sure we come to a solution that is practical
to all system vendors that are participating in Linux support.

	Arnd <><

^ permalink raw reply

* [PATCH] powerpc: Unify the 32 and 64 bit idle loops
From: Paul Mackerras @ 2006-03-24  9:54 UTC (permalink / raw)
  To: linuxppc-dev

This unifies the 32-bit (ARCH=ppc and ARCH=powerpc) and 64-bit idle
loops.  It brings over the concept of having a ppc_md.power_save
function from 32-bit to ARCH=powerpc, which lets us get rid of
native_idle().  With that, we can also reduce the amount of special
code for pSeries and cell because the special code has only to do what
needs to be done when there is no work to do, rather than being a
complete idle loop.

iSeries still has its own idle loops because it wants to test
hvlpevents_pending() as well as need_resched() etc.  I don't know if
that is essential but I have left it as-is for now.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 80e9fe2..f2c47e9 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -10,16 +10,16 @@ CFLAGS_prom_init.o      += -fPIC
 CFLAGS_btext.o		+= -fPIC
 endif
 
 obj-y				:= semaphore.o cputable.o ptrace.o syscalls.o \
 				   irq.o align.o signal_32.o pmc.o vdso.o \
-				   init_task.o process.o systbl.o
+				   init_task.o process.o systbl.o idle.o
 obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 				   signal_64.o ptrace32.o \
 				   paca.o cpu_setup_power4.o \
-				   firmware.o sysfs.o idle_64.o
+				   firmware.o sysfs.o
 obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
 obj-$(CONFIG_POWER4)		+= idle_power4.o
 obj-$(CONFIG_PPC_OF)		+= of_device.o prom_parse.o
 procfs-$(CONFIG_PPC64)		:= proc_ppc64.o
@@ -32,10 +32,11 @@ obj-$(CONFIG_LPARCFG)		+= lparcfg.o
 obj-$(CONFIG_IBMVIO)		+= vio.o
 obj-$(CONFIG_IBMEBUS)           += ibmebus.o
 obj-$(CONFIG_GENERIC_TBSYNC)	+= smp-tbsync.o
 obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
+obj-$(CONFIG_6xx)		+= idle_6xx.o
 
 ifeq ($(CONFIG_PPC_MERGE),y)
 
 extra-$(CONFIG_PPC_STD_MMU)	:= head_32.o
 extra-$(CONFIG_PPC64)		:= head_64.o
@@ -49,11 +50,10 @@ obj-y				+= time.o prom.o traps.o setup-
 obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o misc_32.o
 obj-$(CONFIG_PPC64)		+= misc_64.o dma_64.o iommu.o
 obj-$(CONFIG_PPC_MULTIPLATFORM)	+= prom_init.o
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
-obj-$(CONFIG_6xx)		+= idle_6xx.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_PPC_UDBG_16550)	+= legacy_serial.o udbg_16550.o
 module-$(CONFIG_PPC64)		+= module_64.o
 obj-$(CONFIG_MODULES)		+= $(module-y)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 4827ca1..b3a9794 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -133,14 +133,14 @@ transfer_to_handler:
          */
 #ifdef CONFIG_6xx
 	mfspr	r11,SPRN_HID0
 	mtcr	r11
 BEGIN_FTR_SECTION
-	bt-	8,power_save_6xx_restore	/* Check DOZE */
+	bt-	8,4f			/* Check DOZE */
 END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
 BEGIN_FTR_SECTION
-	bt-	9,power_save_6xx_restore	/* Check NAP */
+	bt-	9,4f			/* Check NAP */
 END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 #endif /* CONFIG_6xx */
 	.globl transfer_to_handler_cont
 transfer_to_handler_cont:
 	lwz	r11,THREAD_INFO-THREAD(r12)
@@ -155,10 +155,14 @@ transfer_to_handler_cont:
 	mtspr	SPRN_SRR1,r10
 	mtlr	r9
 	SYNC
 	RFI				/* jump to handler, enable MMU */
 
+#ifdef CONFIG_6xx	
+4:	b	power_save_6xx_restore
+#endif
+
 /*
  * On kernel stack overflow, load up an initial stack pointer
  * and call StackOverflow(regs), which should not return.
  */
 stack_ovf:
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
new file mode 100644
index 0000000..e9f321d
--- /dev/null
+++ b/arch/powerpc/kernel/idle.c
@@ -0,0 +1,122 @@
+/*
+ * Idle daemon for PowerPC.  Idle daemon will handle any action
+ * that needs to be taken when the system becomes idle.
+ *
+ * Originally written by Cort Dougan (cort@cs.nmt.edu).
+ * Subsequent 32-bit hacking by Tom Rini, Armin Kuster,
+ * Paul Mackerras and others.
+ *
+ * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
+ *
+ * Additional shared processor, SMT, and firmware support
+ *    Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
+ *
+ * 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/cpu.h>
+#include <linux/sysctl.h>
+
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/smp.h>
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define cpu_should_die()	(cpu_is_offline(smp_processor_id()) && \
+				 system_state == SYSTEM_RUNNING)
+#else
+#define cpu_should_die()	0
+#endif
+
+/*
+ * The body of the idle task.
+ */
+void cpu_idle(void)
+{
+	if (ppc_md.idle_loop)
+		ppc_md.idle_loop();	/* doesn't return */
+
+	set_thread_flag(TIF_POLLING_NRFLAG);
+	while (1) {
+		ppc64_runlatch_off();
+
+		while (!need_resched() && !cpu_should_die()) {
+			if (ppc_md.power_save) {
+				clear_thread_flag(TIF_POLLING_NRFLAG);
+				/*
+				 * smp_mb is so clearing of TIF_POLLING_NRFLAG
+				 * is ordered w.r.t. need_resched() test.
+				 */
+				smp_mb();
+				local_irq_disable();
+
+				/* check again after disabling irqs */
+				if (!need_resched() && !cpu_should_die())
+					ppc_md.power_save();
+
+				local_irq_enable();
+				set_thread_flag(TIF_POLLING_NRFLAG);
+
+			} else {
+				/*
+				 * Go into low thread priority and possibly
+				 * low power mode.
+				 */
+				HMT_low();
+				HMT_very_low();
+			}
+		}
+
+		HMT_medium();
+		ppc64_runlatch_on();
+		if (cpu_should_die())
+			cpu_die();
+		preempt_enable_no_resched();
+		schedule();
+		preempt_disable();
+	}
+}
+
+int powersave_nap;
+
+#ifdef CONFIG_SYSCTL
+/*
+ * Register the sysctl to set/clear powersave_nap.
+ */
+static ctl_table powersave_nap_ctl_table[]={
+	{
+		.ctl_name	= KERN_PPC_POWERSAVE_NAP,
+		.procname	= "powersave-nap",
+		.data		= &powersave_nap,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{ 0, },
+};
+static ctl_table powersave_nap_sysctl_root[] = {
+	{ 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, },
+ 	{ 0,},
+};
+
+static int __init
+register_powersave_nap_sysctl(void)
+{
+	register_sysctl_table(powersave_nap_sysctl_root, 0);
+
+	return 0;
+}
+__initcall(register_powersave_nap_sysctl);
+#endif
diff --git a/arch/powerpc/kernel/idle_64.c b/arch/powerpc/kernel/idle_64.c
deleted file mode 100644
index b879d30..0000000
--- a/arch/powerpc/kernel/idle_64.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Idle daemon for PowerPC.  Idle daemon will handle any action
- * that needs to be taken when the system becomes idle.
- *
- * Originally Written by Cort Dougan (cort@cs.nmt.edu)
- *
- * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
- *
- * Additional shared processor, SMT, and firmware support
- *    Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/cpu.h>
-#include <linux/sysctl.h>
-
-#include <asm/system.h>
-#include <asm/processor.h>
-#include <asm/cputable.h>
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/smp.h>
-
-extern void power4_idle(void);
-
-void default_idle(void)
-{
-	unsigned int cpu = smp_processor_id();
-	set_thread_flag(TIF_POLLING_NRFLAG);
-
-	while (1) {
-		if (!need_resched()) {
-			while (!need_resched() && !cpu_is_offline(cpu)) {
-				ppc64_runlatch_off();
-
-				/*
-				 * Go into low thread priority and possibly
-				 * low power mode.
-				 */
-				HMT_low();
-				HMT_very_low();
-			}
-
-			HMT_medium();
-		}
-
-		ppc64_runlatch_on();
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
-			cpu_die();
-	}
-}
-
-void native_idle(void)
-{
-	while (1) {
-		ppc64_runlatch_off();
-
-		if (!need_resched())
-			power4_idle();
-
-		if (need_resched()) {
-			ppc64_runlatch_on();
-			preempt_enable_no_resched();
-			schedule();
-			preempt_disable();
-		}
-
-		if (cpu_is_offline(smp_processor_id()) &&
-		    system_state == SYSTEM_RUNNING)
-			cpu_die();
-	}
-}
-
-void cpu_idle(void)
-{
-	BUG_ON(NULL == ppc_md.idle_loop);
-	ppc_md.idle_loop();
-}
-
-int powersave_nap;
-
-#ifdef CONFIG_SYSCTL
-/*
- * Register the sysctl to set/clear powersave_nap.
- */
-static ctl_table powersave_nap_ctl_table[]={
-	{
-		.ctl_name	= KERN_PPC_POWERSAVE_NAP,
-		.procname	= "powersave-nap",
-		.data		= &powersave_nap,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{ 0, },
-};
-static ctl_table powersave_nap_sysctl_root[] = {
-	{ 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, },
- 	{ 0,},
-};
-
-static int __init
-register_powersave_nap_sysctl(void)
-{
-	register_sysctl_table(powersave_nap_sysctl_root, 0);
-
-	return 0;
-}
-__initcall(register_powersave_nap_sysctl);
-#endif
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
index 444fdcc..1647ea3 100644
--- a/arch/powerpc/kernel/idle_6xx.S
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -85,23 +85,10 @@ BEGIN_FTR_SECTION
 1:	
 END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 	cmpwi	0,r3,0
 	beqlr
 
-	/* Clear MSR:EE */
-	mfmsr	r7
-	rlwinm	r0,r7,0,17,15
-	mtmsr	r0
-
-	/* Check current_thread_info()->flags */
-	rlwinm	r4,r1,0,0,18
-	lwz	r4,TI_FLAGS(r4)
-	andi.	r0,r4,_TIF_NEED_RESCHED
-	beq	1f
-	mtmsr	r7	/* out of line this ? */
-	blr
-1:	
 	/* Some pre-nap cleanups needed on some CPUs */
 	andis.	r0,r3,HID0_NAP@h
 	beq	2f
 BEGIN_FTR_SECTION
 	/* Disable L2 prefetch on some 745x and try to ensure
@@ -218,12 +205,10 @@ _GLOBAL(nap_save_msscr0)
 	.space	4*NR_CPUS
 
 _GLOBAL(nap_save_hid1)
 	.space	4*NR_CPUS
 
-_GLOBAL(powersave_nap)
-	.long	0
 _GLOBAL(powersave_lowspeed)
 	.long	0
 
 #ifdef DEBUG
 _GLOBAL(nap_enter_count)
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index c16b4af..692cf2e 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -47,25 +47,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
 	LOAD_REG_ADDRBASE(r3,powersave_nap)
 	lwz	r4,ADDROFF(powersave_nap)(r3)
 	cmpwi	0,r4,0
 	beqlr
 
-	/* Clear MSR:EE */
-	mfmsr	r7
-	li	r4,0
-	ori	r4,r4,MSR_EE
-	andc	r0,r7,r4
-	mtmsrd	r0
-
-	/* Check current_thread_info()->flags */
-	clrrdi	r4,r1,THREAD_SHIFT
-	ld	r4,TI_FLAGS(r4)
-	andi.	r0,r4,_TIF_NEED_RESCHED
-	beq	1f
-	mtmsrd	r7	/* out of line this ? */
-	blr
-1:
 	/* Go to NAP now */
 BEGIN_FTR_SECTION
 	DSSALL
 	sync
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index db72a92..791edcd 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -51,13 +51,10 @@
 #endif
 
 extern void platform_init(void);
 extern void bootx_init(unsigned long r4, unsigned long phys);
 
-extern void ppc6xx_idle(void);
-extern void power4_idle(void);
-
 boot_infos_t *boot_infos;
 struct ide_machdep_calls ppc_ide_md;
 
 int boot_cpuid;
 EXPORT_SYMBOL_GPL(boot_cpuid);
@@ -192,11 +189,13 @@ void __init machine_init(unsigned long d
 
 	/* Base init based on machine type */
 	platform_init();
 
 #ifdef CONFIG_6xx
-	ppc_md.power_save = ppc6xx_idle;
+	if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
+	    cpu_has_feature(CPU_FTR_CAN_NAP))
+		ppc_md.power_save = ppc6xx_idle;
 #endif
 
 	if (ppc_md.progress)
 		ppc_md.progress("id mach(): done", 0x200);
 }
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 2f3fdad..f47b3cc 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -599,16 +599,10 @@ void __init setup_arch(char **cmdline_p)
 	conswitchp = &dummy_con;
 #endif
 
 	ppc_md.setup_arch();
 
-	/* Use the default idle loop if the platform hasn't provided one. */
-	if (NULL == ppc_md.idle_loop) {
-		ppc_md.idle_loop = default_idle;
-		printk(KERN_INFO "Using default idle loop\n");
-	}
-
 	paging_init();
 	ppc64_boot_msg(0x15, "Setup Done");
 }
 
 
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index e0e051c..07f0c33 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -98,50 +98,33 @@ static void __init cbe_enable_pause_zero
 
 out:
 	spin_unlock_irq(&cbe_pervasive_lock);
 }
 
-static void cbe_idle(void)
+static void cbe_idle_sleep(void)
 {
 	unsigned long ctrl;
 
 	cbe_enable_pause_zero();
 
-	while (1) {
-		if (!need_resched()) {
-			local_irq_disable();
-			while (!need_resched()) {
-				/* go into low thread priority */
-				HMT_low();
-
-				/*
-				 * atomically disable thread execution
-				 * and runlatch.
-				 * External and Decrementer exceptions
-				 * are still handled when the thread
-				 * is disabled but now enter in
-				 * cbe_system_reset_exception()
-				 */
-				ctrl = mfspr(SPRN_CTRLF);
-				ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);
-				mtspr(SPRN_CTRLT, ctrl);
-			}
-			/* restore thread prio */
-			HMT_medium();
-			local_irq_enable();
-		}
+	/* go into low thread priority */
+	HMT_low();
 
-		/*
-		 * turn runlatch on again before scheduling the
-		 * process we just woke up
-		 */
-		ppc64_runlatch_on();
-
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
+	/*
+	 * atomically disable thread execution
+	 * and runlatch.
+	 * External and Decrementer exceptions
+	 * are still handled when the thread
+	 * is disabled but now enter in
+	 * cbe_system_reset_exception()
+	 */
+	ctrl = mfspr(SPRN_CTRLF);
+	ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);
+	mtspr(SPRN_CTRLT, ctrl);
+
+	/* restore thread prio */
+	HMT_medium();
 }
 
 static int cbe_system_reset_exception(struct pt_regs *regs)
 {
 	switch (regs->msr & SRR1_WAKEMASK) {
@@ -222,8 +205,8 @@ void __init cell_pervasive_init(void)
 		ret = cbe_find_pmd_mmio(cpu, p);
 		if (ret)
 			return;
 	}
 
-	ppc_md.idle_loop = cbe_idle;
+	ppc_md.power_save = cbe_idle_sleep;
 	ppc_md.system_reset_exception = cbe_system_reset_exception;
 }
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index ec5c1e1..137d606 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -288,11 +288,11 @@ struct machdep_calls __initdata maple_md
        	.get_boot_time		= maple_get_boot_time,
        	.set_rtc_time		= maple_set_rtc_time,
        	.get_rtc_time		= maple_get_rtc_time,
       	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= maple_progress,
-	.idle_loop		= native_idle,
+	.power_save		= power4_idle,
 #ifdef CONFIG_KEXEC
 	.machine_kexec		= default_machine_kexec,
 	.machine_kexec_prepare	= default_machine_kexec_prepare,
 	.machine_crash_shutdown	= default_machine_crash_shutdown,
 #endif
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 385aab9..c2696d0 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -731,11 +731,11 @@ struct machdep_calls __initdata pmac_md 
 	.feature_call		= pmac_do_feature_call,
 	.check_legacy_ioport	= pmac_check_legacy_ioport,
 	.progress		= udbg_progress,
 #ifdef CONFIG_PPC64
 	.pci_probe_mode		= pmac_pci_probe_mode,
-	.idle_loop		= native_idle,
+	.power_save		= power4_idle,
 	.enable_pmcs		= power4_enable_pmcs,
 #ifdef CONFIG_KEXEC
 	.machine_kexec		= default_machine_kexec,
 	.machine_kexec_prepare	= default_machine_kexec_prepare,
 	.machine_crash_shutdown	= default_machine_crash_shutdown,
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 44d5c7f..213bf98 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -79,12 +79,12 @@
 
 extern void find_udbg_vterm(void);
 
 int fwnmi_active;  /* TRUE if an FWNMI handler is present */
 
-static void pseries_shared_idle(void);
-static void pseries_dedicated_idle(void);
+static void pseries_shared_idle_sleep(void);
+static void pseries_dedicated_idle_sleep(void);
 
 struct mpic *pSeries_mpic;
 
 static void pSeries_show_cpuinfo(struct seq_file *m)
 {
@@ -234,18 +234,17 @@ static void __init pSeries_setup_arch(vo
 	/* Choose an idle loop */
 	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
 		vpa_init(boot_cpuid);
 		if (get_lppaca()->shared_proc) {
 			printk(KERN_INFO "Using shared processor idle loop\n");
-			ppc_md.idle_loop = pseries_shared_idle;
+			ppc_md.power_save = pseries_shared_idle_sleep;
 		} else {
 			printk(KERN_INFO "Using dedicated idle loop\n");
-			ppc_md.idle_loop = pseries_dedicated_idle;
+			ppc_md.power_save = pseries_dedicated_idle_sleep;
 		}
 	} else {
 		printk(KERN_INFO "Using default idle loop\n");
-		ppc_md.idle_loop = default_idle;
 	}
 
 	if (firmware_has_feature(FW_FEATURE_LPAR))
 		ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
 	else
@@ -391,140 +390,91 @@ static int __init pSeries_probe(int plat
 	return 1;
 }
 
 DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
 
-static inline void dedicated_idle_sleep(unsigned int cpu)
-{
-	struct lppaca *plppaca = &lppaca[cpu ^ 1];
-
-	/* Only sleep if the other thread is not idle */
-	if (!(plppaca->idle)) {
-		local_irq_disable();
-
-		/*
-		 * We are about to sleep the thread and so wont be polling any
-		 * more.
-		 */
-		clear_thread_flag(TIF_POLLING_NRFLAG);
-		smp_mb__after_clear_bit();
-
-		/*
-		 * SMT dynamic mode. Cede will result in this thread going
-		 * dormant, if the partner thread is still doing work.  Thread
-		 * wakes up if partner goes idle, an interrupt is presented, or
-		 * a prod occurs.  Returning from the cede enables external
-		 * interrupts.
-		 */
-		if (!need_resched())
-			cede_processor();
-		else
-			local_irq_enable();
-		set_thread_flag(TIF_POLLING_NRFLAG);
-	} else {
-		/*
-		 * Give the HV an opportunity at the processor, since we are
-		 * not doing any work.
-		 */
-		poll_pending();
-	}
-}
-
-static void pseries_dedicated_idle(void)
+static void pseries_dedicated_idle_sleep(void)
 { 
 	unsigned int cpu = smp_processor_id();
 	unsigned long start_snooze;
 	unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
-	set_thread_flag(TIF_POLLING_NRFLAG);
 
-	while (1) {
-		/*
-		 * Indicate to the HV that we are idle. Now would be
-		 * a good time to find other work to dispatch.
-		 */
-		get_lppaca()->idle = 1;
-
-		if (!need_resched()) {
-			start_snooze = get_tb() +
-				*smt_snooze_delay * tb_ticks_per_usec;
-
-			while (!need_resched() && !cpu_is_offline(cpu)) {
-				ppc64_runlatch_off();
-
-				/*
-				 * Go into low thread priority and possibly
-				 * low power mode.
-				 */
-				HMT_low();
-				HMT_very_low();
-
-				if (*smt_snooze_delay != 0 &&
-				    get_tb() > start_snooze) {
-					HMT_medium();
-					dedicated_idle_sleep(cpu);
-				}
+	/*
+	 * Indicate to the HV that we are idle. Now would be
+	 * a good time to find other work to dispatch.
+	 */
+	get_lppaca()->idle = 1;
 
-			}
+	/*
+	 * We come in with interrupts disabled, and need_resched()
+	 * has been checked recently.  If we should poll for a little
+	 * while, do so.
+	 */
+	if (*smt_snooze_delay) {
+		start_snooze = get_tb() +
+			*smt_snooze_delay * tb_ticks_per_usec;
+		local_irq_enable();
+		set_thread_flag(TIF_POLLING_NRFLAG);
 
-			HMT_medium();
+		while (get_tb() < start_snooze) {
+			if (need_resched() || cpu_is_offline(cpu))
+				goto out;
+			ppc64_runlatch_off();
+			HMT_low();
+			HMT_very_low();
 		}
 
-		get_lppaca()->idle = 0;
-		ppc64_runlatch_on();
+		HMT_medium();
+		clear_thread_flag(TIF_POLLING_NRFLAG);
+		smp_mb();
+		local_irq_disable();
+		if (need_resched() || cpu_is_offline(cpu))
+			goto out;
+	}
 
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
+	/*
+	 * Cede if the other thread is not idle, so that it can
+	 * go single-threaded.  If the other thread is idle,
+	 * we ask the hypervisor if it has pending work it
+	 * wants to do and cede if it does.  Otherwise we keep
+	 * polling in order to reduce interrupt latency.
+	 *
+	 * Doing the cede when the other thread is active will
+	 * result in this thread going dormant, meaning the other
+	 * thread gets to run in single-threaded (ST) mode, which
+	 * is slightly faster than SMT mode with this thread at
+	 * very low priority.  The cede enables interrupts, which
+	 * doesn't matter here.
+	 */
+	if (!lppaca[cpu ^ 1].idle || poll_pending() == H_Pending)
+		cede_processor();
 
-		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
-			cpu_die();
-	}
+out:
+	HMT_medium();
+	get_lppaca()->idle = 0;
 }
 
-static void pseries_shared_idle(void)
+static void pseries_shared_idle_sleep(void)
 {
 	unsigned int cpu = smp_processor_id();
 
-	while (1) {
-		/*
-		 * Indicate to the HV that we are idle. Now would be
-		 * a good time to find other work to dispatch.
-		 */
-		get_lppaca()->idle = 1;
-
-		while (!need_resched() && !cpu_is_offline(cpu)) {
-			local_irq_disable();
-			ppc64_runlatch_off();
-
-			/*
-			 * Yield the processor to the hypervisor.  We return if
-			 * an external interrupt occurs (which are driven prior
-			 * to returning here) or if a prod occurs from another
-			 * processor. When returning here, external interrupts
-			 * are enabled.
-			 *
-			 * Check need_resched() again with interrupts disabled
-			 * to avoid a race.
-			 */
-			if (!need_resched())
-				cede_processor();
-			else
-				local_irq_enable();
-
-			HMT_medium();
-		}
-
-		get_lppaca()->idle = 0;
-		ppc64_runlatch_on();
+	/*
+	 * Indicate to the HV that we are idle. Now would be
+	 * a good time to find other work to dispatch.
+	 */
+	get_lppaca()->idle = 1;
 
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
+	/*
+	 * Yield the processor to the hypervisor.  We return if
+	 * an external interrupt occurs (which are driven prior
+	 * to returning here) or if a prod occurs from another
+	 * processor. When returning here, external interrupts
+	 * are enabled.
+	 */
+	cede_processor();
 
-		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
-			cpu_die();
-	}
+	get_lppaca()->idle = 0;
 }
 
 static int pSeries_pci_probe_mode(struct pci_bus *bus)
 {
 	if (firmware_has_feature(FW_FEATURE_LPAR))
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 98e940b..e6154b6 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -57,12 +57,10 @@ head-y				:= arch/ppc/kernel/head.o
 head-$(CONFIG_8xx)		:= arch/ppc/kernel/head_8xx.o
 head-$(CONFIG_4xx)		:= arch/ppc/kernel/head_4xx.o
 head-$(CONFIG_44x)		:= arch/ppc/kernel/head_44x.o
 head-$(CONFIG_FSL_BOOKE)	:= arch/ppc/kernel/head_fsl_booke.o
 
-head-$(CONFIG_6xx)		+= arch/ppc/kernel/idle_6xx.o
-head-$(CONFIG_POWER4)		+= arch/ppc/kernel/idle_power4.o
 head-$(CONFIG_PPC_FPU)		+= arch/powerpc/kernel/fpu.o
 
 core-y				+= arch/ppc/kernel/ arch/powerpc/kernel/ \
 				   arch/ppc/platforms/ \
 				   arch/ppc/mm/ arch/ppc/lib/ \
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index e399bbb..1b2c745 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -6,14 +6,13 @@ ifneq ($(CONFIG_PPC_MERGE),y)
 extra-$(CONFIG_PPC_STD_MMU)	:= head.o
 extra-$(CONFIG_40x)		:= head_4xx.o
 extra-$(CONFIG_44x)		:= head_44x.o
 extra-$(CONFIG_FSL_BOOKE)	:= head_fsl_booke.o
 extra-$(CONFIG_8xx)		:= head_8xx.o
-extra-$(CONFIG_6xx)		+= idle_6xx.o
 extra-y				+= vmlinux.lds
 
-obj-y				:= entry.o traps.o idle.o time.o misc.o \
+obj-y				:= entry.o traps.o time.o misc.o \
 					setup.o \
 					ppc_htab.o
 obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
 obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
@@ -33,11 +32,10 @@ obj-$(CONFIG_8xx)		+= softemu8xx.o
 endif
 
 # These are here while we do the architecture merge
 
 else
-obj-y				:= idle.o
 obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
 obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_NOT_COHERENT_CACHE)	+= dma-mapping.o
 obj-$(CONFIG_KGDB)		+= ppc-stub.o
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 3a28159..fa8d497 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -133,14 +133,14 @@ transfer_to_handler:
          */
 #ifdef CONFIG_6xx
 	mfspr	r11,SPRN_HID0
 	mtcr	r11
 BEGIN_FTR_SECTION
-	bt-	8,power_save_6xx_restore	/* Check DOZE */
+	bt-	8,4f			/* Check DOZE */
 END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
 BEGIN_FTR_SECTION
-	bt-	9,power_save_6xx_restore	/* Check NAP */
+	bt-	9,4f			/* Check NAP */
 END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 #endif /* CONFIG_6xx */
 	.globl transfer_to_handler_cont
 transfer_to_handler_cont:
 	lwz	r11,THREAD_INFO-THREAD(r12)
@@ -155,10 +155,14 @@ transfer_to_handler_cont:
 	mtspr	SPRN_SRR1,r10
 	mtlr	r9
 	SYNC
 	RFI				/* jump to handler, enable MMU */
 
+#ifdef CONFIG_6xx
+4:	b	power_save_6xx_restore
+#endif
+
 /*
  * On kernel stack overflow, load up an initial stack pointer
  * and call StackOverflow(regs), which should not return.
  */
 stack_ovf:
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
deleted file mode 100644
index 1be3ca5..0000000
--- a/arch/ppc/kernel/idle.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Idle daemon for PowerPC.  Idle daemon will handle any action
- * that needs to be taken when the system becomes idle.
- *
- * Written by Cort Dougan (cort@cs.nmt.edu).  Subsequently hacked
- * on by Tom Rini, Armin Kuster, Paul Mackerras and others.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/sysctl.h>
-#include <linux/cpu.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/mmu.h>
-#include <asm/cache.h>
-#include <asm/cputable.h>
-#include <asm/machdep.h>
-#include <asm/smp.h>
-
-void default_idle(void)
-{
-	void (*powersave)(void);
-
-	powersave = ppc_md.power_save;
-
-	if (!need_resched()) {
-		if (powersave != NULL)
-			powersave();
-#ifdef CONFIG_SMP
-		else {
-			set_thread_flag(TIF_POLLING_NRFLAG);
-			while (!need_resched() &&
-					!cpu_is_offline(smp_processor_id()))
-				barrier();
-			clear_thread_flag(TIF_POLLING_NRFLAG);
-		}
-#endif
-	}
-}
-
-/*
- * The body of the idle task.
- */
-void cpu_idle(void)
-{
-	int cpu = smp_processor_id();
-
-	for (;;) {
-		while (!need_resched()) {
-			if (ppc_md.idle != NULL)
-				ppc_md.idle();
-			else
-				default_idle();
-		}
-
-		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
-			cpu_die();
-		preempt_enable_no_resched();
-		schedule();
-		preempt_disable();
-	}
-}
-
-#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx)
-/*
- * Register the sysctl to set/clear powersave_nap.
- */
-extern int powersave_nap;
-
-static ctl_table powersave_nap_ctl_table[]={
-	{
-		.ctl_name	= KERN_PPC_POWERSAVE_NAP,
-		.procname	= "powersave-nap",
-		.data		= &powersave_nap,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{ 0, },
-};
-static ctl_table powersave_nap_sysctl_root[] = {
-	{ 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, },
- 	{ 0,},
-};
-
-static int __init
-register_powersave_nap_sysctl(void)
-{
-	register_sysctl_table(powersave_nap_sysctl_root, 0);
-
-	return 0;
-}
-
-__initcall(register_powersave_nap_sysctl);
-#endif
diff --git a/arch/ppc/kernel/idle_6xx.S b/arch/ppc/kernel/idle_6xx.S
deleted file mode 100644
index 1a2194c..0000000
--- a/arch/ppc/kernel/idle_6xx.S
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- *  This file contains the power_save function for 6xx & 7xxx CPUs
- *  rewritten in assembler
- *
- *  Warning ! This code assumes that if your machine has a 750fx
- *  it will have PLL 1 set to low speed mode (used during NAP/DOZE).
- *  if this is not the case some additional changes will have to
- *  be done to check a runtime var (a bit like powersave-nap)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/threads.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/thread_info.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-
-#undef DEBUG
-
-	.text
-
-/*
- * Init idle, called at early CPU setup time from head.S for each CPU
- * Make sure no rest of NAP mode remains in HID0, save default
- * values for some CPU specific registers. Called with r24
- * containing CPU number and r3 reloc offset
- */
-_GLOBAL(init_idle_6xx)
-BEGIN_FTR_SECTION
-	mfspr	r4,SPRN_HID0
-	rlwinm	r4,r4,0,10,8	/* Clear NAP */
-	mtspr	SPRN_HID0, r4
-	b	1f
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
-	blr
-1:
-	slwi	r5,r24,2
-	add	r5,r5,r3
-BEGIN_FTR_SECTION
-	mfspr	r4,SPRN_MSSCR0
-	addis	r6,r5, nap_save_msscr0@ha
-	stw	r4,nap_save_msscr0@l(r6)
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-BEGIN_FTR_SECTION
-	mfspr	r4,SPRN_HID1
-	addis	r6,r5,nap_save_hid1@ha
-	stw	r4,nap_save_hid1@l(r6)
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
-	blr
-
-/*
- * Here is the power_save_6xx function. This could eventually be
- * split into several functions & changing the function pointer
- * depending on the various features.
- */
-_GLOBAL(ppc6xx_idle)
-	/* Check if we can nap or doze, put HID0 mask in r3
-	 */
-	lis	r3, 0
-BEGIN_FTR_SECTION
-	lis	r3,HID0_DOZE@h
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
-BEGIN_FTR_SECTION
-	/* We must dynamically check for the NAP feature as it
-	 * can be cleared by CPU init after the fixups are done
-	 */
-	lis	r4,cur_cpu_spec@ha
-	lwz	r4,cur_cpu_spec@l(r4)
-	lwz	r4,CPU_SPEC_FEATURES(r4)
-	andi.	r0,r4,CPU_FTR_CAN_NAP
-	beq	1f
-	/* Now check if user or arch enabled NAP mode */
-	lis	r4,powersave_nap@ha
-	lwz	r4,powersave_nap@l(r4)
-	cmpwi	0,r4,0
-	beq	1f
-	lis	r3,HID0_NAP@h
-1:	
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
-	cmpwi	0,r3,0
-	beqlr
-
-	/* Clear MSR:EE */
-	mfmsr	r7
-	rlwinm	r0,r7,0,17,15
-	mtmsr	r0
-
-	/* Check current_thread_info()->flags */
-	rlwinm	r4,r1,0,0,18
-	lwz	r4,TI_FLAGS(r4)
-	andi.	r0,r4,_TIF_NEED_RESCHED
-	beq	1f
-	mtmsr	r7	/* out of line this ? */
-	blr
-1:	
-	/* Some pre-nap cleanups needed on some CPUs */
-	andis.	r0,r3,HID0_NAP@h
-	beq	2f
-BEGIN_FTR_SECTION
-	/* Disable L2 prefetch on some 745x and try to ensure
-	 * L2 prefetch engines are idle. As explained by errata
-	 * text, we can't be sure they are, we just hope very hard
-	 * that well be enough (sic !). At least I noticed Apple
-	 * doesn't even bother doing the dcbf's here...
-	 */
-	mfspr	r4,SPRN_MSSCR0
-	rlwinm	r4,r4,0,0,29
-	sync
-	mtspr	SPRN_MSSCR0,r4
-	sync
-	isync
-	lis	r4,KERNELBASE@h
-	dcbf	0,r4
-	dcbf	0,r4
-	dcbf	0,r4
-	dcbf	0,r4
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-#ifdef DEBUG
-	lis	r6,nap_enter_count@ha
-	lwz	r4,nap_enter_count@l(r6)
-	addi	r4,r4,1
-	stw	r4,nap_enter_count@l(r6)
-#endif	
-2:
-BEGIN_FTR_SECTION
-	/* Go to low speed mode on some 750FX */
-	lis	r4,powersave_lowspeed@ha
-	lwz	r4,powersave_lowspeed@l(r4)
-	cmpwi	0,r4,0
-	beq	1f
-	mfspr	r4,SPRN_HID1
-	oris	r4,r4,0x0001
-	mtspr	SPRN_HID1,r4
-1:	
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
-
-	/* Go to NAP or DOZE now */	
-	mfspr	r4,SPRN_HID0
-	lis	r5,(HID0_NAP|HID0_SLEEP)@h
-BEGIN_FTR_SECTION
-	oris	r5,r5,HID0_DOZE@h
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
-	andc	r4,r4,r5
-	or	r4,r4,r3
-BEGIN_FTR_SECTION
-	oris	r4,r4,HID0_DPM@h	/* that should be done once for all  */
-END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
-	mtspr	SPRN_HID0,r4
-BEGIN_FTR_SECTION
-	DSSALL
-	sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-	ori	r7,r7,MSR_EE /* Could be ommited (already set) */
-	oris	r7,r7,MSR_POW@h
-	sync
-	isync
-	mtmsr	r7
-	isync
-	sync
-	blr
-	
-/*
- * Return from NAP/DOZE mode, restore some CPU specific registers,
- * we are called with DR/IR still off and r2 containing physical
- * address of current.
- */
-_GLOBAL(power_save_6xx_restore)
-	mfspr	r11,SPRN_HID0
-	rlwinm.	r11,r11,0,10,8	/* Clear NAP & copy NAP bit !state to cr1 EQ */
-	cror	4*cr1+eq,4*cr0+eq,4*cr0+eq
-BEGIN_FTR_SECTION
-	rlwinm	r11,r11,0,9,7	/* Clear DOZE */
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
-	mtspr	SPRN_HID0, r11
-
-#ifdef DEBUG
-	beq	cr1,1f
-	lis	r11,(nap_return_count-KERNELBASE)@ha
-	lwz	r9,nap_return_count@l(r11)
-	addi	r9,r9,1
-	stw	r9,nap_return_count@l(r11)
-1:
-#endif
-	
-	rlwinm	r9,r1,0,0,18
-	tophys(r9,r9)
-	lwz	r11,TI_CPU(r9)
-	slwi	r11,r11,2
-	/* Todo make sure all these are in the same page
-	 * and load r22 (@ha part + CPU offset) only once
-	 */
-BEGIN_FTR_SECTION
-	beq	cr1,1f
-	addis	r9,r11,(nap_save_msscr0-KERNELBASE)@ha
-	lwz	r9,nap_save_msscr0@l(r9)
-	mtspr	SPRN_MSSCR0, r9
-	sync
-	isync
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-BEGIN_FTR_SECTION
-	addis	r9,r11,(nap_save_hid1-KERNELBASE)@ha
-	lwz	r9,nap_save_hid1@l(r9)
-	mtspr	SPRN_HID1, r9
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
-	b	transfer_to_handler_cont
-
-	.data
-
-_GLOBAL(nap_save_msscr0)
-	.space	4*NR_CPUS
-
-_GLOBAL(nap_save_hid1)
-	.space	4*NR_CPUS
-
-_GLOBAL(powersave_nap)
-	.long	0
-_GLOBAL(powersave_lowspeed)
-	.long	0
-
-#ifdef DEBUG
-_GLOBAL(nap_enter_count)
-	.space	4
-_GLOBAL(nap_return_count)
-	.space	4
-#endif
diff --git a/arch/ppc/kernel/idle_power4.S b/arch/ppc/kernel/idle_power4.S
deleted file mode 100644
index cc0d535..0000000
--- a/arch/ppc/kernel/idle_power4.S
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *  This file contains the power_save function for 6xx & 7xxx CPUs
- *  rewritten in assembler
- *
- *  Warning ! This code assumes that if your machine has a 750fx
- *  it will have PLL 1 set to low speed mode (used during NAP/DOZE).
- *  if this is not the case some additional changes will have to
- *  be done to check a runtime var (a bit like powersave-nap)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/threads.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/thread_info.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-
-#undef DEBUG
-
-	.text
-
-/*
- * Init idle, called at early CPU setup time from head.S for each CPU
- * So nothing for now. Called with r24 containing CPU number and r3
- * reloc offset
- */
- 	.globl	init_idle_power4
-init_idle_power4:
-	blr
-
-/*
- * Here is the power_save_6xx function. This could eventually be
- * split into several functions & changing the function pointer
- * depending on the various features.
- */
-	.globl	power4_idle
-power4_idle:
-BEGIN_FTR_SECTION
-	blr
-END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
-	/* We must dynamically check for the NAP feature as it
-	 * can be cleared by CPU init after the fixups are done
-	 */
-	lis	r4,cur_cpu_spec@ha
-	lwz	r4,cur_cpu_spec@l(r4)
-	lwz	r4,CPU_SPEC_FEATURES(r4)
-	andi.	r0,r4,CPU_FTR_CAN_NAP
-	beqlr
-	/* Now check if user or arch enabled NAP mode */
-	lis	r4,powersave_nap@ha
-	lwz	r4,powersave_nap@l(r4)
-	cmpwi	0,r4,0
-	beqlr
-
-	/* Clear MSR:EE */
-	mfmsr	r7
-	rlwinm	r0,r7,0,17,15
-	mtmsr	r0
-
-	/* Check current_thread_info()->flags */
-	rlwinm	r4,r1,0,0,18
-	lwz	r4,TI_FLAGS(r4)
-	andi.	r0,r4,_TIF_NEED_RESCHED
-	beq	1f
-	mtmsr	r7	/* out of line this ? */
-	blr
-1:	
-	/* Go to NAP now */	
-BEGIN_FTR_SECTION
-	DSSALL
-	sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-	ori	r7,r7,MSR_EE /* Could be ommited (already set) */
-	oris	r7,r7,MSR_POW@h
-	sync
-	isync
-	mtmsr	r7
-	isync
-	sync
-	blr
-	
-	.globl powersave_nap
-powersave_nap:
-	.long	0
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
index 38ca9ad..b72c04f 100644
--- a/include/asm-powerpc/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -7,10 +7,11 @@
 #define H_Success	0
 #define H_Busy		1	/* Hardware busy -- retry later */
 #define H_Closed	2	/* Resource closed */
 #define H_Constrained	4	/* Resource request constrained to max allowed */
 #define H_InProgress   14	/* Kind of like busy */
+#define H_Pending      17	/* returned from H_POLL_PENDING */
 #define H_Continue     18	/* Returned from H_Join on success */
 #define H_LongBusyStartRange   9900  /* Start of long busy range */
 #define H_LongBusyOrder1msec   9900  /* Long busy, hint that 1msec is a good time to retry */
 #define H_LongBusyOrder10msec  9901  /* Long busy, hint that 10msec is a good time to retry */
 #define H_LongBusyOrder100msec 9902  /* Long busy, hint that 100msec is a good time to retry */
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 5348b82..21c8dc9 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -156,10 +156,16 @@ struct machdep_calls {
 						pgprot_t vma_prot);
 
 	/* Idle loop for this platform, leave empty for default idle loop */
 	void		(*idle_loop)(void);
 
+	/*
+	 * Function for waiting for work with reduced power in idle loop;
+	 * called with interrupts disabled.
+	 */
+	void		(*power_save)(void);
+
 	/* Function to enable performance monitor counters for this
 	   platform, called once per cpu. */
 	void		(*enable_pmcs)(void);
 
 	/* Set DABR for this platform, leave empty for default implemenation */
@@ -168,13 +174,10 @@ struct machdep_calls {
 #ifdef CONFIG_PPC32	/* XXX for now */
 	/* A general init function, called by ppc_init in init/main.c.
 	   May be NULL. */
 	void		(*init)(void);
 
-	void		(*idle)(void);
-	void		(*power_save)(void);
-
 	void		(*heartbeat)(void);
 	unsigned long	heartbeat_reset;
 	unsigned long	heartbeat_count;
 
 	void		(*setup_io_mappings)(void);
@@ -240,12 +243,12 @@ struct machdep_calls {
 	 */
 	void (*machine_kexec)(struct kimage *image);
 #endif /* CONFIG_KEXEC */
 };
 
-extern void default_idle(void);
-extern void native_idle(void);
+extern void power4_idle(void);
+extern void ppc6xx_idle(void);
 
 extern struct machdep_calls ppc_md;
 extern char cmd_line[COMMAND_LINE_SIZE];
 
 #ifdef CONFIG_PPC_PMAC
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 72bfe3a..bd467bf 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -620,10 +620,14 @@ extern void ppc64_runlatch_on(void);
 extern void ppc64_runlatch_off(void);
 
 extern unsigned long scom970_read(unsigned int address);
 extern void scom970_write(unsigned int address, unsigned long value);
 
+#else
+#define ppc64_runlatch_on()
+#define ppc64_runlatch_off()
+
 #endif /* CONFIG_PPC64 */
 
 #define __get_SP()	({unsigned long sp; \
 			asm volatile("mr %0,1": "=r" (sp)); sp;})
 
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index a3e8a45..ebbef64 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -42,11 +42,11 @@ struct machdep_calls {
 
 	void		(*restart)(char *cmd);
 	void		(*power_off)(void);
 	void		(*halt)(void);
 
-	void		(*idle)(void);
+	void		(*idle_loop)(void);
 	void		(*power_save)(void);
 
 	long		(*time_init)(void); /* Optional, may be NULL */
 	int		(*set_rtc_time)(unsigned long nowtime);
 	unsigned long	(*get_rtc_time)(void);

^ permalink raw reply related

* Re: [BULK]  Re: "transmit timed out" on FCC in MPC8260 as well as MPC8247
From: Siju Viswanath K E @ 2006-03-24  9:47 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-embedded
In-Reply-To: <20060324075148.4C106353BFB@atlas.denx.de>

Hi Denk,
	Thanks for the suggestion. I had a look at the source repository
at projects/linuxppc_2_4_devel.git site. Outdated code doesnt seem to be
the issue. My repository is patched upto 
"Patch by Wojciech Kromer, 06 Jan 2004" and later changes are only
adding extra board support. 

regards,
Siju Viswanath

On Fri, 2006-03-24 at 13:21, Wolfgang Denk wrote:
> In message <1143177651.22246.3.camel@Blaze> you wrote:
> >
> > 	I am using denk's linuxppc-2.4.20 . I am getting this problem of
> 
> Why don't you try using a more current version of the code? 2.4.20 is
> *very* old, and *lots* of bugs and problems have been fixed since.
> 
> It really does not make sense to spend effort on such old code.
> 
> Best regards,
> 
> Wolfgang Denk

^ permalink raw reply

* Re: pci-x
From: Carlos Mitidieri @ 2006-03-24 11:21 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <AD260576-EB34-4B56-9FB7-CE3A2DAEBFE7@kernel.crashing.org>


On Thursday 23 March 2006 16:41, Kumar Gala wrote:
> > Is there PCI-X support for the mpc8540ads?
>
> Yes.  You have to make sure the board is setup (switches in the right
> place) properly for it.

Thank you for answering.

Looking the manuals and schematics,  I have changed the "config" switch in 
SW1, and now the PCI-X support is activated in the kernel at the system 
initialization. Nevertheless,  when I plug a bridge board to the slot 0, I 
get the following messages:

PCI: Probing PCI hardware
PCI: Cannot allocate resource region 1 of PCI bridge 1
PCI: bridge 1 resource 1 moved to 9ff00000..9fffffff
PCI: Cannot allocate resource region 2 of PCI bridge 1
PCI: bridge 1 resource 2 moved to 9fe00000..9fefffff

Would you guess that this is a driver problem, or that my board setup is still 
incorrect?

-- 
Carlos Mitidieri
SYSGO AG - Office Ulm

^ permalink raw reply

* Re: new sound driver
From: Johannes Berg @ 2006-03-24 11:37 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1143020119.11724.41.camel@localhost>

[-- Attachment #1: Type: text/plain, Size: 428 bytes --]

On Wed, 2006-03-22 at 10:35 +0100, Johannes Berg wrote:

> So I started to rewrite snd-powermac as snd-aoa, which I currently keep
> in a git tree at http://johannes.sipsolutions.net/snd-aoa.git/

It's a bit hacky (but hopefully those hacks can be removed rather
easily) but it works now for the onyx based machines (powermac8,1, quad
powermac, last 15" powerbook and probably more if you add the layout id)

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* Re: "transmit timed out" on FCC in MPC8260 => bug corrected
From: hubert.loewenguth @ 2006-03-24 11:44 UTC (permalink / raw)
  To: Siju Viswanath K E; +Cc: Hunter, David, linuxppc-embedded
In-Reply-To: <1143193658.22246.20.camel@Blaze>


[-- Attachment #1.1: Type: text/plain, Size: 5744 bytes --]

Hi to the community.

I'm the man who has posted numerous questions about this problem of 
fcc_enet timeout in ppc8260.
I just want to say that the 2.6 kernel doesn't solve the problem if you 
have it on your board (I tried it,  normally I have a 2.4-20 linux too).
I have search for this bug during a long time, and fortunatly, I 'm 
happy to say you that finally, it is corrected since few days.
Special thanks to "Hunter, David" for having take in consideration my 
problem, and proposing me some way of invastigations in this thread:

http://ozlabs.org/pipermail/linuxppc-embedded/2006-January/021842.html

In fact the solution comes from the new "MPC8260 PowerQUICC II Family 
Reference Manual"   fresescale has delivered 01/19/2006.
http://www.freescale.com/files/product/doc/MPC8260UM.pdf

They have added a very interesting paragraph about error handling in 
ethernet mode:

/29.10.1.3 Adjusting Transmitter BD Handling
When a TXE event occurs, the TBPTR may already point beyond BDs still 
marked as ready due to internal
pipelining. If the TBPTR is not adjusted, these BDs would be skipped 
while still being marked as ready.
Software must determine if these BDs should be retransmitted or if they 
should be skipped, depending on
the protocol and application needs. This requires the following steps:
1. From the current TBPTR value, search backwards over all (if any) BDs 
still marked as ready to
find the first BD that has not been closed by the CPM. The search 
process should stop if the BD to
be checked next is not ready or if it is the most recent BD marked as 
ready by the CPU transmit
software. This is to avoid an endless loop in case the CPU software 
fills the BD ring completely.
2. A) For skipping BDs, manually close all BDs from the BD just found up 
to and including the BD
just before TBPTR. Leave the TBPTR value untouched.
B) For retransmitting BDs, change the TBPTR value to point to the BD 
just found.
/
So, here is the correction  I have done to the fcc-enet.c driver, and 
wich I'am very satsify
I have tested it on my platform which was always entering in this 
infernal timeout loop when there was successive plug/unplug during 
important data transfert.
Thanks to some trace, I have seen that, as it is said in the new manual, 
the error comes from the pipelining and a bad restart procedure in the 
driver.
(I think it is the same restart procedure in the 2.6 kernel ??? to 
verify ...)
With this correction, I have no more infernal timeout  loop.
In fact, I replace the restart procedure in the fcc_enet_interrupt 
method by this one, which respect the MPC8260 manual restart procedure:

if (must_restart) {
        volatile cpm8260_t *cp;

        /* Some transmit errors cause the transmitter to shut
         * down.  We now issue a restart transmit.  Since the
         * errors close the BD and update the pointers, the restart
         * _should_ pick up without having to reset any of our
         * pointers either.  Also, To workaround 8260 device erratum
         * CPM37, we must disable and then re-enable the transmitter
         * following a Late Collision, Underrun, or Retry Limit error.
         */
         
         // disable Transmitter
        cep->fccp->fcc_gfmr &= ~FCC_GFMR_ENT;
        udelay(10); /* wait a few microseconds just on principle */
   
        #ifdef THALES_DEBUG_TRACE
        printk("Thales restart debug trace :\n");
        printk("first dirty tx %d, final dirty_tx %d, tbptr 
%d\n",cbt_ptr2index(dev,first_bdp_dirty_tx),cbt_ptr2index(dev,cep->dirty_tx),tbptr_ptr2index(dev,ep->fen_genfcc.fcc_tbptr));
        #endif
                                   
        // RESTART TX command to the cpm
        cp = cpmp;
        cp->cp_cpcr = mk_cr_cmd(cep->fip->fc_cpmpage, 
cep->fip->fc_cpmblock,0x0c, CPM_CR_RESTART_TX) | CPM_CR_FLG;
        while (cp->cp_cpcr & CPM_CR_FLG);
       
        // Adjusting Transmitter BD Handling
        /* HLO : I do not search backwards from the current TBPTR value 
to found skip BDs, but I directly
         * adjust the tbptr value to the dirty_tx current value.
         * In case of problemes occuring, change it and do like 
indicated in 29.10.3 of MPC8260 manual
         */
        ep->fen_genfcc.fcc_tbptr = __pa(cep->dirty_tx);
       
        #ifdef THALES_DEBUG_TRACE
        printk(" Thales workaround tbptr value adjusted : 
%d\n",tbptr_ptr2index(dev,ep->fen_genfcc.fcc_tbptr));
        #endif
       
        // re-enable Transmitter       
        cep->fccp->fcc_gfmr |=  FCC_GFMR_ENT;

        }

I hope this correction will help you and the community.

Best regards


Siju Viswanath K E a écrit :

>Hi Denk,
>	Thanks for the suggestion. I had a look at the source repository
>at projects/linuxppc_2_4_devel.git site. Outdated code doesnt seem to be
>the issue. My repository is patched upto 
>"Patch by Wojciech Kromer, 06 Jan 2004" and later changes are only
>adding extra board support. 
>
>regards,
>Siju Viswanath
>
>On Fri, 2006-03-24 at 13:21, Wolfgang Denk wrote:
>  
>
>>In message <1143177651.22246.3.camel@Blaze> you wrote:
>>    
>>
>>>	I am using denk's linuxppc-2.4.20 . I am getting this problem of
>>>      
>>>
>>Why don't you try using a more current version of the code? 2.4.20 is
>>*very* old, and *lots* of bugs and problems have been fixed since.
>>
>>It really does not make sense to spend effort on such old code.
>>
>>Best regards,
>>
>>Wolfgang Denk
>>    
>>
>
>_______________________________________________
>Linuxppc-embedded mailing list
>Linuxppc-embedded@ozlabs.org
>https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>  
>

[-- Attachment #1.2: Type: text/html, Size: 8250 bytes --]

[-- Attachment #2: hubert.loewenguth.vcf --]
[-- Type: text/x-vcard, Size: 285 bytes --]

begin:vcard
fn:Hubert Loewenguth
n:Loewenguth;Hubert
org:Thales Broadcast & Multimedia
adr:;;1 rue de l'hautil;Conflans Ste Honorine;;78700;France
email;internet:hubert.loewenguth@thales-bm.com
title:Software Engineer
tel;work:01-34-90-37-56
x-mozilla-html:TRUE
version:2.1
end:vcard


^ permalink raw reply

* Re: [PATCH] return to OF via trap, not exit
From: Segher Boessenkool @ 2006-03-24 12:13 UTC (permalink / raw)
  To: Olaf Hering; +Cc: Michael Ellerman, linuxppc-dev
In-Reply-To: <20060323210357.GC24667@suse.de>

On 23-mrt-2006, at 22:03, Olaf Hering wrote:
>  On Mon, Mar 06, Segher Boessenkool wrote:
>> That's better than always calling trap, sure.  Is there any reason
>> you can't just do it on Macs though?  Because the problem you're  
>> trying
>> to work around only happens there.
>
> Maybe something like this? Only compile tested

That looks fine yes (if it runs ;-) ), thanks!

> Do not call prom exit prom_panic. It clears the screen and the exit  
> message is lost.
> On some (or all?) pmacs it causes another crash when OF tries to  
> print the
> date and time in its banner.
>
> Set of_platform earlier to catch more prom_panic() calls.
>
> Signed-off-by: Olaf Hering <olh@suse.de>

Acked-by: Segher Boessenkool <segher@kernel.crashing.org>

^ permalink raw reply

* Re: [PATCH] powerpc: Kill machine numbers
From: Segher Boessenkool @ 2006-03-24 12:23 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linuxppc-dev, Paul Mackerras, Linux Kernel list, cbe-oss-dev
In-Reply-To: <200603240946.51793.arnd@arndb.de>

> One thing I have been wondering about is what should be the right way
> to check whether we're running on something based on the
> Cell Broadband Engine Architecture, if that is needed somewhere.
> My original idea was to make this the platform number, but this
> seems impractical now.

Just check the PVR?  Either directly, or in the device tree.
It's not likely that there will be a million different CBEA
compliant CPUs any time soon ;-)

There really should be some other OF property in the CPU nodes
that tells us the CPU is CBEA, but I don't think we have one
right now :-(


Segher

^ permalink raw reply

* MTD physmap issues trying to map flash
From: Randy Smith @ 2006-03-24 13:32 UTC (permalink / raw)
  To: linuxppc-embedded

Hello everyone,

I have been trying to get my flash memory to show up as an mtd device in 
my 2.4.25 kernel and I get the following error:

physmap flash device: 0 at 0
__ioremap(): phys addr 00000000 is RAM lr c000f67c
Failed to ioremap

My hardware is based on the Icecube reference design but uses one 
Spansion S29G128M-R2 16 MByte flash chip at physical address 0xff00000.  
I am using u-boot 1.1.4 and the flash operates correctly in that 
environment (after some tweaking).  I am using a vanilla 2.4.25 linux 
kernel from DENX's ELDK 3.1 and I have tried almost every incantation 
regarding MTD configuration but no joy.

Some questions:

1.  Does 2.4.25 expect the physmap_map structure to be populated by 
u-boot and if so, where should I look in u-boot to make that happen?

2.  I am assuming that this chip is CFI compliant and should show up 
with that probing (and AMD support) enabled.  Does it matter if turn on 
both CFI and JEDEC probes?  Or put another way, why should I have to 
probe if this information is passed by u-boot, if it is?

3.  How does the partitioning (command line) of the chip effect the 
recognition of the chip?

4.  What should I put in the physmap menuconfig line for the physical 
address and size of the chip?  I am using 0xff000000 and 0x01000000.  Is 
this correct and something else is broken?

5.  Is there a patch to the kernel or u-boot that addresses this type of 
failure?


Thanks,

Randy Smith
Software Engineer
ImageMap, Inc.

^ permalink raw reply


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