LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] Fix Tsi108 ethernet driver performance
From: Scott Wood @ 2007-07-13 20:32 UTC (permalink / raw)
  To: Scott Wood; +Cc: Alexandre Bounine, linuxppc-dev
In-Reply-To: <4697E08B.6080700@freescale.com>

Scott Wood wrote:
> Wouldn't this cause latencies of up to a second in responding to 
> received packets?  I'd think that would be considered excessive.
> 
> And shouldn't NAPI be reducing the RX interrupt load anyway?

Sorry, I missed that you reduced the interval to 20 ms.  Still, a bit on 
the high side, and a source of wasted CPU cycles when the network isn't 
heavily loaded.  How much of a difference in CPU usage did you see with 
this patch?

-Scott

^ permalink raw reply

* Re: [PATCH] Fix Tsi108 ethernet driver performance
From: Scott Wood @ 2007-07-13 20:28 UTC (permalink / raw)
  To: Alexandre Bounine; +Cc: linuxppc-dev
In-Reply-To: <1B5F013528140F45B5C671039279CA5701F8314C@NANUK.pc.tundra.com>

Alexandre Bounine wrote:
> -/* If the RX ring has run out of memory, try periodically
> - * to allocate some more, as otherwise poll would never
> - * get called (apart from the initial end-of-queue condition).
> - *
> - * This is called once per second (by default) from the thread.
> +/* tsi108_check_rxring() is used to periodically check if the RX ring
> has
> + * pending frames that have not been reported by RX interrupt (due to
> interrupt
> + * moderation). It is called with CHECK_RX_INTERVAL timer interval.

Wouldn't this cause latencies of up to a second in responding to 
received packets?  I'd think that would be considered excessive.

And shouldn't NAPI be reducing the RX interrupt load anyway?

-Scott

^ permalink raw reply

* Re: Help required for porting ISP1362 usb device driver
From: Clemens Koller @ 2007-07-13 20:27 UTC (permalink / raw)
  To: Vikram Kone; +Cc: linuxppc-embedded
In-Reply-To: <003901c7c585$24fe3430$66dd47ab@cisco.com>

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

Don't remove the list, use "reply-to-all".

Vikram Kone schrieb:
> Hi Clemens..
> Thanks for replying..
> 
> The problem that I actually have is..
> The documentation that I got with the device and host controller drivers is
> based on kernel 2.6.6 so I'm not sure whther it works for 2.6.22 or not....
> I followed the instructions in that document and was able to compile to
> modules by running 'make' command in the folder. That's all fine. 
> But the problem is....as I said I'm working on the MPC8548 board by free
> scale and as you know its based on power pc architecture.

> I have attched the device driver files that I got from sourceforge.net

You don't need to attach drivers, when they are somewhere in the
web. Linking to it is fine.
I don't have the hardware and such an old kernel.
(I am using the ISP1563 on PCI and that works just fine.)

The driver is not in the kernel tree. There is no real support
for out of kernel drivers, so these drivers just get old and broken.
Contact the driver author mentioned in the code (Marlon Jose Masbad)
and tell him to push the code into the latest kernel.

> What I did was... Unzipped them and copied the folders in
> /usr/src/linux-2.6.10/drivers/usb 

I prefer not riding dead horses. ;-)

> As you can see the two folders that I have got are ISP1362_Device and
> ISP1362_Host
 >
> When I run 'make' in the Device folder I get the following error
> 
> bash-2.05b$ make
> make -C
> /ws/vkone/usb/Vendor/linux-2.6.10/drivers/usb/ISP1362_Device/device/diskemu
> make[1]: Entering directory
> `/auto/wsvkone/usb/Vendor/linux-2.6.10/drivers/usb/ISP1362_Device/device/dis
> kemu'
> make[1]: Nothing to be done for `all'.
> make[1]: Leaving directory
> `/auto/wsvkone/usb/Vendor/linux-2.6.10/drivers/usb/ISP1362_Device/device/dis
> kemu'
> make -C /ws/vkone/usb/Vendor/linux-2.6.10
> M=/ws/vkone/usb/Vendor/linux-2.6.10/drivers/usb/ISP1362_Device
> make[1]: Entering directory `/auto/wsvkone/usb/Vendor/linux-2.6.10'
> Makefile:531: /auto/wsvkone/usb/Vendor/linux-2.6.10/arch/i386/Makefile: No
> such file or directory
> make[1]: *** No rule to make target
> `/auto/wsvkone/usb/Vendor/linux-2.6.10/arch/i386/Makefile'.  Stop.
> make[1]: Leaving directory `/auto/wsvkone/usb/Vendor/linux-2.6.10'
> make: *** [all] Error 2
> bash-2.05b$
> 
> 
> I guess this is due to the 'arch' problem. I mean since there is no i386
> folder in the arch directory I guess its messing up. 
> 
> Can you help me now

Have you tried
$ export ARCH=ppc
or something similar?
(powerpc is current)

On my MPC8540 and the latest tools (than one still on ARCH=ppc), I ran into some crap:

/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/devmscd.c:35:26: error: linux/config.h: No such file or directory
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/devmscd.c:61:25: error: asm/segment.h: No such file or directory

So, well, just out of curiosity, I just killed some of the bad stuff and got it to build... :-)

$ make
make -C /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/diskemu
make[1]: Entering directory `/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/diskemu'
cc  -I../devmscd -D_8MB_SIZE_ -c disk_emu.c
cc -g -s -o msdisk disk_emu.o
make[1]: Leaving directory `/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/diskemu'
make -C /usr/src/linux-2.6.21.5 M=/usr/src/linux-2.6.21.5/drivers/ISP1362_Device
make[1]: Entering directory `/usr/src/linux-2.6.21.5'
   LD      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/built-in.o
   CC [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/devmscd.o
   CC [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/msbridge.o
   LD [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/mscd.o
   LD      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/built-in.o
   CC [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/usb_pdc.o
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/usb_pdc.c: In function 'pdc_dev_control':
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/usb_pdc.c:313: warning: format '%d' expects type 'int', but argument 2 has type 'long unsigned int'
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/usb_pdc.c: In function 'rx_command':
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/usb_pdc.c:647: warning: format '%d' expects type 'int', but argument 2 has type 'long unsigned int'
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/usb_pdc.c: In function 'pdc_get_frame_number':
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/usb_pdc.c:851: warning: format '%d' expects type 'int', but argument 2 has type 'long unsigned int'
   CC [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/pdc_bus.o
   LD [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/pdc.o
   LD      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/built-in.o
   CC [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.o
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.c: In function 'isp1362_request_irq':
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.c:724: warning: passing argument 2 of 'request_irq' from incompatible pointer type
   Building modules, stage 2.
   MODPOST 3 modules
   CC      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/mscd.mod.o
   LD [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/mscd.ko
   CC      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/pdc.mod.o
   LD [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/pdc.ko
   CC      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.mod.o
   LD [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.ko
make[1]: Leaving directory `/usr/src/linux-2.6.21.5'
root@fox:/usr/src/linux-2.6.21.5/drivers/ISP1362_Device$ make
make -C /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/diskemu
make[1]: Entering directory `/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/diskemu'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/diskemu'
make -C /usr/src/linux-2.6.21.5 M=/usr/src/linux-2.6.21.5/drivers/ISP1362_Device
make[1]: Entering directory `/usr/src/linux-2.6.21.5'
   CC [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.o
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.c: In function 'isp1362_request_irq':
/usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.c:724: warning: passing argument 2 of 'request_irq' from incompatible pointer type
   Building modules, stage 2.
   MODPOST 3 modules
   CC      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/mscd.mod.o
   LD [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/devmscd/mscd.ko
   CC      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/pdc.mod.o
   LD [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/device/pdc/pdc.ko
   CC      /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.mod.o
   LD [M]  /usr/src/linux-2.6.21.5/drivers/ISP1362_Device/x86pci/hal_pci.ko
make[1]: Leaving directory `/usr/src/linux-2.6.21.5'

Quick and dirty patch attached below...
Give it a try and publish your results (also to the list!)

Anybody who wants to see this in mainline?
It would be good to pick up *now*!
For sure it needs more clean up...

Regards,
-- 
Clemens Koller
__________________________________
R&D Imaging Devices
Anagramm GmbH
Rupert-Mayer-Straße 45/1
Linhof Werksgelände
D-81379 München
Tel.089-741518-50
Fax 089-741518-19
http://www.anagramm-technology.com

[-- Attachment #2: ISP1362_Device-2.6.21.5-fix.patch --]
[-- Type: text/plain, Size: 4459 bytes --]

diff -Nurp ISP1362_Device/Makefile ISP1362_Device.fixed/Makefile
--- ISP1362_Device/Makefile	2006-09-25 11:37:29.000000000 +0200
+++ ISP1362_Device.fixed/Makefile	2007-07-13 22:04:53.000000000 +0200
@@ -1,5 +1,5 @@
 TOPDIR=$(shell pwd)
-KERNEL_DIR=/usr/src/linux-2.6.6
+KERNEL_DIR=/usr/src/linux-2.6.21.5
 export $(KERNEL_DIR)
 
 obj-m += x86pci/
diff -Nurp ISP1362_Device/device/devmscd/devmscd.c ISP1362_Device.fixed/device/devmscd/devmscd.c
--- ISP1362_Device/device/devmscd/devmscd.c	2006-09-25 11:32:21.000000000 +0200
+++ ISP1362_Device.fixed/device/devmscd/devmscd.c	2007-07-13 22:08:48.000000000 +0200
@@ -32,10 +32,6 @@
  *
  ***********************************************************************/
 
-#include <linux/config.h>
-#ifdef LINUX_24
-#define	MODULE
-#endif
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
@@ -50,20 +46,14 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#ifdef LINUX_24
-#include <linux/tqueue.h>
-#else
 #include <linux/workqueue.h>
-#endif
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <linux/proc_fs.h>
 #include <linux/poll.h>
 
-
 #include "pdc_intf.h"
 #include "devmscd.h"
 #include "mscdbridge.h"
diff -Nurp ISP1362_Device/device/devmscd/msbridge.c ISP1362_Device.fixed/device/devmscd/msbridge.c
--- ISP1362_Device/device/devmscd/msbridge.c	2006-09-25 11:32:21.000000000 +0200
+++ ISP1362_Device.fixed/device/devmscd/msbridge.c	2007-07-13 22:09:46.000000000 +0200
@@ -30,17 +30,12 @@
  * 09/25/06		MMASBAD					Released with GPL
  * 
  ***********************************************************************/
-#include <linux/config.h>
-#ifdef LINUX_24
-#define	MODULE
-#endif
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/errno.h>
Binary files ISP1362_Device/device/diskemu/msdisk and ISP1362_Device.fixed/device/diskemu/msdisk differ
diff -Nurp ISP1362_Device/device/pdc/pdc_bus.c ISP1362_Device.fixed/device/pdc/pdc_bus.c
--- ISP1362_Device/device/pdc/pdc_bus.c	2006-09-25 11:32:22.000000000 +0200
+++ ISP1362_Device.fixed/device/pdc/pdc_bus.c	2007-07-13 22:11:04.000000000 +0200
@@ -31,10 +31,6 @@
  * 09/20/06		MMASBAD					Added Interface-based debugging options
  * 09/25/06		MMASBAD					Released with GPL
  ***********************************************************************/
-#include <linux/config.h>
-#ifdef LINUX_24
-#define MODULE
-#endif
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
@@ -49,15 +45,10 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#ifdef LINUX_24
-#include <linux/tqueue.h>
-#else
 #include <linux/workqueue.h>
-#endif
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <linux/proc_fs.h>
 #include <linux/poll.h>
diff -Nurp ISP1362_Device/device/pdc/usb_pdc.c ISP1362_Device.fixed/device/pdc/usb_pdc.c
--- ISP1362_Device/device/pdc/usb_pdc.c	2006-09-25 11:44:02.000000000 +0200
+++ ISP1362_Device.fixed/device/pdc/usb_pdc.c	2007-07-13 22:10:29.000000000 +0200
@@ -52,10 +52,6 @@
  *
  */
 
-#include <linux/config.h>
-#ifdef LINUX_24
-#define MODULE
-#endif
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
@@ -70,14 +66,9 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#ifdef LINUX_24
-#include <linux/tqueue.h>
-#else
 #include <linux/workqueue.h>
-#endif
 #include <asm/byteorder.h>
 #include <asm/irq.h>
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <linux/proc_fs.h>
 #include <linux/poll.h>
diff -Nurp ISP1362_Device/x86pci/hal_pci.c ISP1362_Device.fixed/x86pci/hal_pci.c
--- ISP1362_Device/x86pci/hal_pci.c	2006-09-25 11:32:22.000000000 +0200
+++ ISP1362_Device.fixed/x86pci/hal_pci.c	2007-07-13 22:11:32.000000000 +0200
@@ -30,10 +30,6 @@
  * 09/25/06		MMASBAD					Released with GPL
  *
  ***********************************************************************/
-#include <linux/config.h>
-#ifdef LINUX_24
-#define	MODULE
-#endif
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>

^ permalink raw reply

* Re: Weird oopses with 2.6.22-rc7 [SOLVED]
From: Christian Kujau @ 2007-07-13 20:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nathan Lynch, linux-kernel
In-Reply-To: <alpine.DEB.0.99.0707130840470.18512@sheep.housecafe.de>

On Fri, 13 Jul 2007, Christian Kujau wrote:
> Ah, this seem to have fixed http://lkml.org/lkml/2007/7/8/21 and really
> looks promising, I'll try 2.6.22-git2 now.

for the record: running 2.6.22-git3 now and the Oopses went away ;)

thanks,
Christian.
-- 
BOFH excuse #352:

The cables are not the same length.

^ permalink raw reply

* [PATCH] Fix Tsi108 ethernet driver performance
From: Alexandre Bounine @ 2007-07-13 20:00 UTC (permalink / raw)
  To: Zang Roy-r61911; +Cc: linuxppc-dev

From: Alexandre Bounine <alexandreb@tundra.com>

This patch improves performance of the Tsi108 Ethernet driver by
changing interrupt handling
for frame receive path. It reduces number of interrupts generated for
received frames and therefore lowers CPU utilization by the device
driver.
=20=20=20
Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>

---

diff -Nurp linux-2.6.22-hpc2/drivers/net/tsi108_eth.c
linux-2.6.22-tun/drivers/net/tsi108_eth.c
--- linux-2.6.22-hpc2/drivers/net/tsi108_eth.c	2007-07-08
19:32:17.000000000 -0400
+++ linux-2.6.22-tun/drivers/net/tsi108_eth.c	2007-07-12
16:55:50.000000000 -0400
@@ -58,6 +58,7 @@
 #define MII_READ_DELAY 10000	/* max link wait time in msec */
=20
 #define TSI108_RXRING_LEN     256
+#define TSI108_RX_INT_FREQ    32
=20
 /* NOTE: The driver currently does not support receiving packets
  * larger than the buffer size, so don't decrease this (unless you
@@ -69,8 +70,10 @@
=20
 #define TSI108_TX_INT_FREQ    64
=20
-/* Check the phy status every half a second. */
-#define CHECK_PHY_INTERVAL (HZ/2)
+/* Timer interval to check the RX queue status */
+#define CHECK_RX_INTERVAL	(HZ/50)
+/* Timer interval to check the PHY status */
+#define CHECK_PHY_INTERVAL	(CHECK_RX_INTERVAL * 10)
=20
 static int tsi108_init_one(struct platform_device *pdev);
 static int tsi108_ether_remove(struct platform_device *pdev);
@@ -104,6 +107,7 @@ struct tsi108_prv_data {
 	unsigned int txfree;
=20
 	unsigned int phy_ok;		/* The PHY is currently powered
on. */
+	unsigned int phy_chk_count;
=20
 	/* PHY status (duplex is 1 for half, 2 for full,
 	 * so that the default 0 indicates that neither has
@@ -823,7 +827,10 @@ static int tsi108_refill_rx(struct net_d
 		 */
=20
 		data->rxring[rx].blen =3D TSI108_RX_SKB_SIZE;
-		data->rxring[rx].misc =3D TSI108_RX_OWN | TSI108_RX_INT;
+		if (rx % TSI108_RX_INT_FREQ)
+			data->rxring[rx].misc =3D TSI108_RX_OWN;
+		else
+			data->rxring[rx].misc =3D TSI108_RX_OWN |
TSI108_RX_INT;
=20
 		data->rxhead =3D (data->rxhead + 1) % TSI108_RXRING_LEN;
 		data->rxfree++;
@@ -973,24 +980,22 @@ static void tsi108_rx_int(struct net_dev
 	}
 }
=20
-/* If the RX ring has run out of memory, try periodically
- * to allocate some more, as otherwise poll would never
- * get called (apart from the initial end-of-queue condition).
- *
- * This is called once per second (by default) from the thread.
+/* tsi108_check_rxring() is used to periodically check if the RX ring
has
+ * pending frames that have not been reported by RX interrupt (due to
interrupt
+ * moderation). It is called with CHECK_RX_INTERVAL timer interval.
  */
=20
 static void tsi108_check_rxring(struct net_device *dev)
 {
 	struct tsi108_prv_data *data =3D netdev_priv(dev);
+	unsigned int rx =3D data->rxtail;
=20
-	/* A poll is scheduled, as opposed to caling tsi108_refill_rx
-	 * directly, so as to keep the receive path single-threaded
-	 * (and thus not needing a lock).
-	 */
-
-	if (netif_running(dev) && data->rxfree < TSI108_RXRING_LEN / 4)
+	/* Schedule a poll (if required) */
+	if (netif_running(dev) &&
+	    0 =3D=3D (data->rxring[rx].misc & TSI108_RX_OWN)) {
+		data->rxpending =3D 1;
 		tsi108_rx_int(dev);
+	}
 }
=20
 static void tsi108_tx_int(struct net_device *dev)
@@ -1295,6 +1300,7 @@ static void tsi108_init_phy(struct net_d
=20
 	printk(KERN_DEBUG "PHY_STAT reg contains %08x\n", phyval);
 	data->phy_ok =3D 1;
+	data->phy_chk_count =3D 0;
 	data->init_media =3D 1;
 	spin_unlock_irqrestore(&phy_lock, flags);
 }
@@ -1664,9 +1670,12 @@ static void tsi108_timed_checker(unsigne
 	struct net_device *dev =3D (struct net_device *)dev_ptr;
 	struct tsi108_prv_data *data =3D netdev_priv(dev);
=20
-	tsi108_check_phy(dev);
+	/* We assume that RX queue is checked more often than PHY status
*/
+	if (data->phy_chk_count++ =3D=3D 0)
+		tsi108_check_phy(dev);
 	tsi108_check_rxring(dev);
-	mod_timer(&data->timer, jiffies + CHECK_PHY_INTERVAL);
+	data->phy_chk_count %=3D (CHECK_PHY_INTERVAL/CHECK_RX_INTERVAL);
+	mod_timer(&data->timer, jiffies + CHECK_RX_INTERVAL);
 }
=20
 static int tsi108_ether_init(void)


---=0D
=0D
Important Notice: This message is intended for the use of the individual to=
 whom it is addressed and may contain information which is privileged, conf=
idential and/or exempt from disclosure under applicable law. If the reader =
of this message is not the intended recipient, or is not the employee or ag=
ent responsible for delivering the message to the intended recipient, you a=
re hereby notified that any dissemination, distribution, or copying of this=
 communication is strictly prohibited. If you have received this communicat=
ion in error, please notify the sender immediately by telephone or return e=
-mail and delete the original message from your systems. Thank you. =0D

^ permalink raw reply

* Re: [patch 5/6] ps3: BD/DVD/CD-ROM Storage Driver
From: Geert Uytterhoeven @ 2007-07-13 20:13 UTC (permalink / raw)
  To: James Bottomley
  Cc: Arnd Bergmann, linux-scsi, linux-kernel, Alessandro Rubini,
	linuxppc-dev, Paul Mackerras, Jens Axboe
In-Reply-To: <1184340528.3402.32.camel@localhost.localdomain>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2859 bytes --]

On Fri, 13 Jul 2007, James Bottomley wrote:
> On Fri, 2007-07-13 at 17:10 +0200, Geert Uytterhoeven wrote:
> > On Fri, 13 Jul 2007, Arnd Bergmann wrote:
> > > On Friday 13 July 2007, James Bottomley wrote:
> > > > > IC.
> > > > > 
> > > > >  - flush_kernel_dcache_page() is a no-op on ppc64
> > > > >   (ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE is defined on parisc only).
> > > > > 
> > > > >  - For reference, drivers/scsi/ipr.c (another ppc64 driver) just uses a plain
> > > > >   kmap/memcpy/kunmap sequence
> > > > > 
> > > > > So what should I do?
> > > > 
> > > > Ask someone who knows the architecture ... Anton, Paulus or Benh ... I'm
> > > > fairly certain PPC is VIPT and will need some kind of alias
> > > > resolution ... perhaps its associative enough not to let the aliases be
> > > > a problem.
> > > 
> > > I'm pretty sure that no ppc64 machine needs alias resolution in the kernel,
> > > although some are VIPT. Last time we discussed this, Segher explained it
> > > to me, but I don't remember which way Cell does it. IIRC, it automatically
> > > flushes cache lines that are accessed through aliases.
> > 
> > Thanks for confirming!
> > 
> > > It's probably a good idea to have the flush_kernel_dcache_page() in there
> > > anyway, if only to serve as an example for people that copy it into
> > > architecture-independent drivers, same as what we do for the
> > > k{,un}map_atomic() that is also not required on ppc64.
> > 
> > Now my next question: why should I add it, if currently no single driver in
> > mainline calls flush_kernel_dcache_page()? 
> > 
> > `git grep' finds it in the following files only:
> >     Documentation/cachetlb.txt
> >     arch/parisc/kernel/cache.c
> >     arch/parisc/kernel/pacache.S
> >     include/asm-parisc/cacheflush.h
> >     include/linux/highmem.h
> 
> It's a recent addition to the API ... the previous way of doing it was
> flush_dcache_page() but that's expensive and flushes all the user
> aliases.  Since you know in this case there are no current user aliases
> and you only need to flush the kernel alias, flush_kernel_dcache_page()
> was introduced as the cheaper alternative.

Ah, that explains it. flush_dcache_page() is used in some drivers.
I'll update my patches. Thanks for the comments!

With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [PATCH] crash in 2.6.22-git2 sysctl_set_parent()
From: Linas Vepstas @ 2007-07-13 20:05 UTC (permalink / raw)
  To: Eric W. Biederman, linux-kernel; +Cc: linuxppc-dev, netdev


This is a patch (& bug report) for a crash in sysctl_set_parent() 
in 2.6.22-git2. 

Problem: 2.6.22-git2 crashes with a stack trace 
[c000000001d0fb00] c000000000067b4c .sysctl_set_parent+0x48/0x7c
[c000000001d0fb90] c000000000069b40 .register_sysctl_table+0x7c/0xf4
[c000000001d0fc30] c00000000065e710 .devinet_init+0x88/0xb0
[c000000001d0fcc0] c00000000065db74 .ip_rt_init+0x17c/0x32c
[c000000001d0fd70] c00000000065deec .ip_init+0x10/0x34
[c000000001d0fdf0] c00000000065e898 .inet_init+0x160/0x3dc
[c000000001d0fea0] c000000000630bc4 .kernel_init+0x204/0x3c8

A bit of poking around makes it clear what the problem is:
In sysctl_set_parent(), the for loop 

   for (; table->ctl_name || table->procname; table++) {

walks off the end of the table, and into garbage.  Basically,
this for-loop iterator expects all table arrays to be 
"null terminated".  However, net/ipv4/devinet.c statically 
declares an array that is not null-terminated.  The patch 
below fixes that; it works for me.  Its somewhat conservative;
if one wishes to assume that the compiler will always zero out
the empty parts of the structure, then this pach can be shrunk 
to one line: +	ctl_table		devinet_root_dir[3];

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>

----
I tried to audit some of the code to see where else there 
might be similar badly-formed static declarations.  This is hard,
as there's a lot of code. Most seems fine.


 net/core/neighbour.c |    4 ++++
 net/ipv4/devinet.c   |    7 ++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

Index: linux-2.6.22-git2/net/ipv4/devinet.c
===================================================================
--- linux-2.6.22-git2.orig/net/ipv4/devinet.c	2007-07-13 14:23:21.000000000 -0500
+++ linux-2.6.22-git2/net/ipv4/devinet.c	2007-07-13 14:24:15.000000000 -0500
@@ -1424,7 +1424,7 @@ static struct devinet_sysctl_table {
 	ctl_table		devinet_dev[2];
 	ctl_table		devinet_conf_dir[2];
 	ctl_table		devinet_proto_dir[2];
-	ctl_table		devinet_root_dir[2];
+	ctl_table		devinet_root_dir[3];
 } devinet_sysctl = {
 	.devinet_vars = {
 		DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
@@ -1493,8 +1493,13 @@ static struct devinet_sysctl_table {
 			.data		= &ipv4_devconf.loop,
 			.maxlen		= sizeof(int),
 			.mode		= 0644,
+			.child	= 0x0,
 			.proc_handler	= &proc_dointvec,
 		},
+		{
+			.ctl_name	= 0,
+			.procname	= 0,
+		},
 	},
 };
 

^ permalink raw reply

* Re: 2.6.22 flash boot
From: Sergei Shtylyov @ 2007-07-13 19:48 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linuxppc-dev
In-Reply-To: <20070713194013.GU2660@chiana.homelinux.org>

Hello.

Marc Leeman wrote:

> With the release of the 2.6.22, our boards didn't boot anymore. I traced
> the change back to 2.6.21-git10/2.6.21-git11. 

> The reason they didn't boot was that the kernel  didn't detect the flash
> where the root filesystem is stored on. The boards boot without an
> initrd, directly from flash.

> A file was removed (rom.c) and mentioned as obsolete in the ChangeLog.

[...]

> Am I missing something here?

    It's been removed as conflicting with the new of_device probing code.
You can either register the "rom" device explicitly in your platform code, or 
put it on some bus below the ones specified to of_platform_device_probe() -- 
by your platform code again...

WBR, Sergei

^ permalink raw reply

* [PATCH 0/5] Kconfig cleanup
From: Arnd Bergmann @ 2007-07-13 18:44 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev@ozlabs.org

Jon Loeliger <jdl@freescale.com> wrote:
X-Provags-ID: V01U2FsdGVkX18a539ZiXmAXeY+eK9MdUjOkwfvlvR4PUC8vLN
 hv7FFOkt1BgOy18T2Tf8fQgBcT+SMke7QjZMwzOtjX3HPEZzfI
 I86h59GhTM7GU39vE50ww==

> Hmmm... Shouldn't this sort of change come
> with an update to the 8641 defconfig too?

Yes, good point. This updates the various defconfig files
that are impacted by the changes, and applied cleanly
against the latest powerpc.git again.

	Arnd <><

^ permalink raw reply

* [PATCH 2/5] move embedded6xx into multiplatform
From: Arnd Bergmann @ 2007-07-13 18:44 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20070713184452.466490031@arndb.de>

Jon Loeliger <jdl@freescale.com> wrote:
X-Provags-ID: V01U2FsdGVkX1+SaCCegn5lQjYmfKX51SjCTUcB54DR70XKrhI
 hmGM1tKApkuJUhU1N/m27xBNFkgSrryBjxIoSP8aSjI4iolGnU
 P+lfBacQBsWXTPdYoWsBw==

> Hmmm... Shouldn't this sort of change come
> with an update to the 8641 defconfig too?
Content-Disposition: inline; filename=embedded6xx-multi.diff

The various embedded 6xx systems can easily coexist
in one kernel together with the other 6xx based systems,
so there is no strict reason to keep them separate.

This also fixes a problem introduced in one earlier
patch, where the embedded 74xx based systems could
not automatically select altivec any more.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---

Index: linux-2.6/arch/powerpc/platforms/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/Kconfig
+++ linux-2.6/arch/powerpc/platforms/Kconfig
@@ -12,10 +12,6 @@ config PPC_MULTIPLATFORM
 	  RS/6000 machine, an Apple machine, or a PReP, CHRP,
 	  Maple or Cell-based machine.
 
-config EMBEDDED6xx
-	bool "Embedded 6xx/7xx/7xxx-based board"
-	depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
-
 config PPC_82xx
 	bool "Freescale 82xx"
 	depends on 6xx
Index: linux-2.6/arch/powerpc/platforms/embedded6xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/embedded6xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -1,9 +1,10 @@
-choice
-	prompt "Machine Type"
-	depends on EMBEDDED6xx
+config EMBEDDED6xx
+	bool "Embedded 6xx/7xx/7xxx-based boards"
+	depends on PPC32 && (BROKEN||BROKEN_ON_SMP) && PPC_MULTIPLATFORM
 
 config LINKSTATION
 	bool "Linkstation / Kurobox(HG) from Buffalo"
+	depends on EMBEDDED6xx
 	select MPIC
 	select FSL_SOC
 	select PPC_UDBG_16550 if SERIAL_8250
@@ -18,6 +19,7 @@ config LINKSTATION
 
 config MPC7448HPC2
 	bool "Freescale MPC7448HPC2(Taiga)"
+	depends on EMBEDDED6xx
 	select TSI108_BRIDGE
 	select DEFAULT_UIMAGE
 	select PPC_UDBG_16550
@@ -28,6 +30,7 @@ config MPC7448HPC2
 
 config PPC_HOLLY
 	bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)"
+	depends on EMBEDDED6xx
 	select TSI108_BRIDGE
 	select PPC_UDBG_16550
 	select WANT_DEVICE_TREE
@@ -38,13 +41,13 @@ config PPC_HOLLY
 
 config PPC_PRPMC2800
 	bool "Motorola-PrPMC2800"
+	depends on EMBEDDED6xx
 	select MV64X60
 	select NOT_COHERENT_CACHE
 	select WANT_DEVICE_TREE
 	select CPU_7450
 	help
 	  This option enables support for the Motorola PrPMC2800 board
-endchoice
 
 config TSI108_BRIDGE
 	bool
Index: linux-2.6/arch/powerpc/configs/holly_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/holly_defconfig
+++ linux-2.6/arch/powerpc/configs/holly_defconfig
@@ -1,9 +1,32 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22-rc2
-# Thu May 31 11:25:44 2007
+# Linux kernel version: 2.6.22-rc7
+# Fri Jul 13 20:05:39 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+# CONFIG_CPU_603e is not set
+CONFIG_CPU_750=y
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=750"
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +48,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 # CONFIG_DEFAULT_UIMAGE is not set
-
-#
-# Processor support
-#
-CONFIG_CLASSIC32=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-# CONFIG_ALTIVEC is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -136,14 +139,21 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-# CONFIG_PPC_MULTIPLATFORM is not set
-CONFIG_EMBEDDED6xx=y
-# CONFIG_APUS is not set
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_EMBEDDED6xx=y
 # CONFIG_LINKSTATION is not set
 # CONFIG_MPC7448HPC2 is not set
 CONFIG_PPC_HOLLY=y
@@ -177,6 +187,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -590,6 +601,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_TSI108_ETH=y
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
@@ -600,10 +612,6 @@ CONFIG_NETDEV_10000=y
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_MLX4_CORE is not set
-
-#
-# Token Ring devices
-#
 # CONFIG_TR is not set
 
 #
Index: linux-2.6/arch/powerpc/configs/linkstation_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/linkstation_defconfig
+++ linux-2.6/arch/powerpc/configs/linkstation_defconfig
@@ -1,9 +1,32 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22-rc6
-# Tue Jun 26 13:25:19 2007
+# Linux kernel version: 2.6.22-rc7
+# Fri Jul 13 20:05:40 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+CONFIG_CPU_603e=y
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=603e"
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +48,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-CONFIG_CLASSIC32=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-# CONFIG_ALTIVEC is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -138,14 +141,21 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-# CONFIG_PPC_MULTIPLATFORM is not set
-CONFIG_EMBEDDED6xx=y
-# CONFIG_APUS is not set
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_EMBEDDED6xx=y
 CONFIG_LINKSTATION=y
 # CONFIG_MPC7448HPC2 is not set
 # CONFIG_PPC_HOLLY is not set
@@ -181,6 +191,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -774,6 +785,7 @@ CONFIG_R8169=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
Index: linux-2.6/arch/powerpc/configs/mpc7448_hpc2_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc7448_hpc2_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc7448_hpc2_defconfig
@@ -1,9 +1,32 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:56:54 2007
+# Fri Jul 13 20:05:41 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+# CONFIG_CPU_603e is not set
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+CONFIG_CPU_7450=y
+CONFIG_PPC_MCPU="-mcpu=7450"
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +48,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-CONFIG_CLASSIC32=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-# CONFIG_ALTIVEC is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -131,14 +134,21 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-# CONFIG_PPC_MULTIPLATFORM is not set
-CONFIG_EMBEDDED6xx=y
-# CONFIG_APUS is not set
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_EMBEDDED6xx=y
 # CONFIG_LINKSTATION is not set
 CONFIG_MPC7448HPC2=y
 # CONFIG_PPC_HOLLY is not set
@@ -172,6 +182,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -600,6 +611,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_TSI108_ETH=y
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
Index: linux-2.6/arch/powerpc/configs/prpmc2800_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/prpmc2800_defconfig
+++ linux-2.6/arch/powerpc/configs/prpmc2800_defconfig
@@ -1,9 +1,34 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22-rc6
-# Tue Jun 26 14:15:11 2007
+# Linux kernel version: 2.6.22-rc7
+# Fri Jul 13 20:05:42 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+# CONFIG_CPU_603e is not set
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+CONFIG_CPU_7450=y
+CONFIG_PPC_MCPU="-mcpu=7450"
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_CONFIG_CHECK_CACHE_COHERENCY=y
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,30 +50,8 @@ CONFIG_PPC_OF=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 # CONFIG_DEFAULT_UIMAGE is not set
-
-#
-# Processor support
-#
-CONFIG_CLASSIC32=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_ALTIVEC=y
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
-CONFIG_NOT_COHERENT_CACHE=y
-CONFIG_CONFIG_CHECK_CACHE_COHERENCY=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -133,14 +136,21 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-# CONFIG_PPC_MULTIPLATFORM is not set
-CONFIG_EMBEDDED6xx=y
-# CONFIG_APUS is not set
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_EMBEDDED6xx=y
 # CONFIG_LINKSTATION is not set
 # CONFIG_MPC7448HPC2 is not set
 # CONFIG_PPC_HOLLY is not set

--

^ permalink raw reply

* [PATCH 5/5] move 83xx into multiplatform
From: Arnd Bergmann @ 2007-07-13 18:44 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20070713184452.466490031@arndb.de>

Jon Loeliger <jdl@freescale.com> wrote:
X-Provags-ID: V01U2FsdGVkX183KEAUKHXvruCYhaaV52OzolDzOwR8U/cVbZz
 RqqlZgNmQVzTnk6PKfA2exuU2PW9QK2JcOV9grQhnden9S/eQ3
 4u2xKjwqyFO/YMrW3bvyA==

> Hmmm... Shouldn't this sort of change come
> with an update to the 8641 defconfig too?
Content-Disposition: inline; filename=83xx-multi.diff

MPC83xx based machines don't need their own kernel,
but can run one that is shared with the other 6xx
compatible machines, so we should allow that
in Kconfig.

Cc: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
Index: linux-2.6/arch/powerpc/platforms/83xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/83xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/83xx/Kconfig
@@ -1,10 +1,13 @@
-choice
-	prompt "83xx Board Type"
-	depends on PPC_83xx
-	default MPC834x_MDS
+config PPC_83xx
+	bool "Freescale 83xx based boards"
+	depends on 6xx
+	select FSL_SOC
+	select 83xx
+	select WANT_DEVICE_TREE
 
 config MPC8313_RDB
 	bool "Freescale MPC8313 RDB"
+	depends on PPC_83xx
 	select DEFAULT_UIMAGE
 	select CPU_603e
 	help
@@ -12,6 +15,7 @@ config MPC8313_RDB
 
 config MPC832x_MDS
 	bool "Freescale MPC832x MDS"
+	depends on PPC_83xx
 	select DEFAULT_UIMAGE
 	select QUICC_ENGINE
 	select CPU_603e
@@ -20,6 +24,7 @@ config MPC832x_MDS
 
 config MPC832x_RDB
 	bool "Freescale MPC832x RDB"
+	depends on PPC_83xx
 	select DEFAULT_UIMAGE
 	select QUICC_ENGINE
 	select CPU_603e
@@ -28,6 +33,7 @@ config MPC832x_RDB
 
 config MPC834x_MDS
 	bool "Freescale MPC834x MDS"
+	depends on PPC_83xx
 	select DEFAULT_UIMAGE
 	select CPU_603e
 	help
@@ -40,6 +46,7 @@ config MPC834x_MDS
 
 config MPC834x_ITX
 	bool "Freescale MPC834x ITX"
+	depends on PPC_83xx
 	select DEFAULT_UIMAGE
 	select CPU_603e
 	help
@@ -50,14 +57,13 @@ config MPC834x_ITX
 
 config MPC836x_MDS
 	bool "Freescale MPC836x MDS"
+	depends on PPC_83xx
 	select DEFAULT_UIMAGE
 	select QUICC_ENGINE
 	select CPU_603e
 	help
 	  This option enables support for the MPC836x MDS Processor Board.
 
-endchoice
-
 config PPC_MPC831x
 	bool
 	select PPC_UDBG_16550
Index: linux-2.6/arch/powerpc/platforms/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/Kconfig
+++ linux-2.6/arch/powerpc/platforms/Kconfig
@@ -16,13 +16,6 @@ config PPC_82xx
 	bool "Freescale 82xx"
 	depends on 6xx
 
-config PPC_83xx
-	bool "Freescale 83xx"
-	depends on 6xx
-	select FSL_SOC
-	select 83xx
-	select WANT_DEVICE_TREE
-
 endchoice
 
 config CLASSIC32
Index: linux-2.6/arch/powerpc/configs/mpc8313_rdb_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc8313_rdb_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc8313_rdb_defconfig
@@ -1,9 +1,33 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:56:55 2007
+# Fri Jul 13 20:00:52 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+CONFIG_CPU_603e=y
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=603e"
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +49,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-# CONFIG_CLASSIC32 is not set
-# CONFIG_PPC_82xx is not set
-CONFIG_PPC_83xx=y
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_83xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -135,11 +139,19 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_PPC_83xx=y
 CONFIG_MPC8313_RDB=y
 # CONFIG_MPC832x_MDS is not set
 # CONFIG_MPC832x_RDB is not set
@@ -147,6 +159,8 @@ CONFIG_MPC8313_RDB=y
 # CONFIG_MPC834x_ITX is not set
 # CONFIG_MPC836x_MDS is not set
 CONFIG_PPC_MPC831x=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -157,6 +171,7 @@ CONFIG_PPC_MPC831x=y
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
 # CONFIG_CPM2 is not set
 
 #
@@ -174,6 +189,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -638,6 +654,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_BNX2 is not set
 CONFIG_GIANFAR=y
 CONFIG_GFAR_NAPI=y
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
Index: linux-2.6/arch/powerpc/configs/mpc832x_mds_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc832x_mds_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc832x_mds_defconfig
@@ -1,9 +1,33 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:56:55 2007
+# Fri Jul 13 20:00:53 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+CONFIG_CPU_603e=y
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=603e"
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +49,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-# CONFIG_CLASSIC32 is not set
-# CONFIG_PPC_82xx is not set
-CONFIG_PPC_83xx=y
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_83xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -135,11 +139,19 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_PPC_83xx=y
 # CONFIG_MPC8313_RDB is not set
 CONFIG_MPC832x_MDS=y
 # CONFIG_MPC832x_RDB is not set
@@ -147,6 +159,8 @@ CONFIG_MPC832x_MDS=y
 # CONFIG_MPC834x_ITX is not set
 # CONFIG_MPC836x_MDS is not set
 CONFIG_PPC_MPC832x=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -157,6 +171,7 @@ CONFIG_PPC_MPC832x=y
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
 CONFIG_QUICC_ENGINE=y
 # CONFIG_CPM2 is not set
 
@@ -176,6 +191,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -535,6 +551,7 @@ CONFIG_UCC_GETH=y
 # CONFIG_UGETH_MAGIC_PACKET is not set
 # CONFIG_UGETH_FILTERING is not set
 # CONFIG_UGETH_TX_ON_DEMAND is not set
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
Index: linux-2.6/arch/powerpc/configs/mpc832x_rdb_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc832x_rdb_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc832x_rdb_defconfig
@@ -1,9 +1,33 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:56:56 2007
+# Fri Jul 13 20:00:54 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+CONFIG_CPU_603e=y
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=603e"
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +49,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-# CONFIG_CLASSIC32 is not set
-# CONFIG_PPC_82xx is not set
-CONFIG_PPC_83xx=y
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_83xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -135,11 +139,19 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_PPC_83xx=y
 # CONFIG_MPC8313_RDB is not set
 # CONFIG_MPC832x_MDS is not set
 CONFIG_MPC832x_RDB=y
@@ -147,6 +159,8 @@ CONFIG_MPC832x_RDB=y
 # CONFIG_MPC834x_ITX is not set
 # CONFIG_MPC836x_MDS is not set
 CONFIG_PPC_MPC832x=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -157,6 +171,7 @@ CONFIG_PPC_MPC832x=y
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
 CONFIG_QUICC_ENGINE=y
 # CONFIG_CPM2 is not set
 
@@ -176,6 +191,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -538,6 +554,7 @@ CONFIG_UGETH_NAPI=y
 # CONFIG_UGETH_MAGIC_PACKET is not set
 # CONFIG_UGETH_FILTERING is not set
 # CONFIG_UGETH_TX_ON_DEMAND is not set
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
Index: linux-2.6/arch/powerpc/configs/mpc834x_itx_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc834x_itx_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc834x_itx_defconfig
@@ -1,9 +1,33 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:56:56 2007
+# Fri Jul 13 20:01:04 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+CONFIG_CPU_603e=y
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=603e"
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +49,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-# CONFIG_CLASSIC32 is not set
-# CONFIG_PPC_82xx is not set
-CONFIG_PPC_83xx=y
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_83xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -135,11 +139,19 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_PPC_83xx=y
 # CONFIG_MPC8313_RDB is not set
 # CONFIG_MPC832x_MDS is not set
 # CONFIG_MPC832x_RDB is not set
@@ -147,6 +159,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_MPC834x_ITX=y
 # CONFIG_MPC836x_MDS is not set
 CONFIG_MPC834x=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -157,6 +171,7 @@ CONFIG_MPC834x=y
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
 # CONFIG_CPM2 is not set
 
 #
@@ -174,6 +189,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -663,6 +679,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_BNX2 is not set
 CONFIG_GIANFAR=y
 CONFIG_GFAR_NAPI=y
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
Index: linux-2.6/arch/powerpc/configs/mpc834x_itxgp_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc834x_itxgp_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc834x_itxgp_defconfig
@@ -1,9 +1,33 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:56:56 2007
+# Fri Jul 13 20:01:05 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+CONFIG_CPU_603e=y
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=603e"
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +49,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-# CONFIG_CLASSIC32 is not set
-# CONFIG_PPC_82xx is not set
-CONFIG_PPC_83xx=y
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_83xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -135,11 +139,19 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_PPC_83xx=y
 # CONFIG_MPC8313_RDB is not set
 # CONFIG_MPC832x_MDS is not set
 # CONFIG_MPC832x_RDB is not set
@@ -147,6 +159,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_MPC834x_ITX=y
 # CONFIG_MPC836x_MDS is not set
 CONFIG_MPC834x=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -157,6 +171,7 @@ CONFIG_MPC834x=y
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
 # CONFIG_CPM2 is not set
 
 #
@@ -174,6 +189,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -594,6 +610,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_BNX2 is not set
 CONFIG_GIANFAR=y
 CONFIG_GFAR_NAPI=y
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
Index: linux-2.6/arch/powerpc/configs/mpc834x_mds_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc834x_mds_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc834x_mds_defconfig
@@ -1,9 +1,33 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:56:57 2007
+# Fri Jul 13 20:01:05 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+CONFIG_CPU_603e=y
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=603e"
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +49,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-# CONFIG_CLASSIC32 is not set
-# CONFIG_PPC_82xx is not set
-CONFIG_PPC_83xx=y
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_83xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -135,11 +139,19 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_PPC_83xx=y
 # CONFIG_MPC8313_RDB is not set
 # CONFIG_MPC832x_MDS is not set
 # CONFIG_MPC832x_RDB is not set
@@ -147,6 +159,8 @@ CONFIG_MPC834x_MDS=y
 # CONFIG_MPC834x_ITX is not set
 # CONFIG_MPC836x_MDS is not set
 CONFIG_MPC834x=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -157,6 +171,7 @@ CONFIG_MPC834x=y
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
 # CONFIG_CPM2 is not set
 
 #
@@ -174,6 +189,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -477,6 +493,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_BNX2 is not set
 CONFIG_GIANFAR=y
 # CONFIG_GFAR_NAPI is not set
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y
Index: linux-2.6/arch/powerpc/configs/mpc836x_mds_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc836x_mds_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc836x_mds_defconfig
@@ -1,9 +1,33 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:56:57 2007
+# Fri Jul 13 20:01:07 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+CONFIG_CPU_603e=y
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+# CONFIG_CPU_7450 is not set
+CONFIG_PPC_MCPU="-mcpu=603e"
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,28 +49,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-# CONFIG_CLASSIC32 is not set
-# CONFIG_PPC_82xx is not set
-CONFIG_PPC_83xx=y
-# CONFIG_PPC_85xx is not set
-# CONFIG_PPC_86xx is not set
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_83xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -135,11 +139,19 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_PPC_83xx=y
 # CONFIG_MPC8313_RDB is not set
 # CONFIG_MPC832x_MDS is not set
 # CONFIG_MPC832x_RDB is not set
@@ -147,6 +159,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_MPC834x_ITX is not set
 CONFIG_MPC836x_MDS=y
 CONFIG_PPC_MPC836x=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -157,6 +171,7 @@ CONFIG_PPC_MPC836x=y
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
 CONFIG_QUICC_ENGINE=y
 # CONFIG_CPM2 is not set
 
@@ -175,6 +190,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -534,6 +550,7 @@ CONFIG_UCC_GETH=y
 # CONFIG_UGETH_MAGIC_PACKET is not set
 # CONFIG_UGETH_FILTERING is not set
 # CONFIG_UGETH_TX_ON_DEMAND is not set
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y

--

^ permalink raw reply

* [PATCH 1/5] autoselect optimal -mcpu= flag by platform
From: Arnd Bergmann @ 2007-07-13 18:44 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20070713184452.466490031@arndb.de>

Jon Loeliger <jdl@freescale.com> wrote:
X-Provags-ID: V01U2FsdGVkX1+BoY6XjUrGly1rWyOZxsXD2wcNMyeBnkUMy7/
 aE+cggJKYpJ3rKZ1wc9pqTY5IFAoNnY8dtj7q9qT51Y7DKTlnv
 RU/QVHeYEEj4zJk1aarlw==

> Hmmm... Shouldn't this sort of change come
> with an update to the 8641 defconfig too?
Content-Disposition: inline; filename=advanced-cpusel.diff

We can choose the -mcpu= gcc flags for compiling the kernel
based on the platform that we build for. In case of multiplatform
kernels, this chooses a setting for a common subset.

When using a platform type that can use different CPUs, a
new option CONFIG_PPC_CPU_SELECTION can be enabled to select
more specifically which CPUs the kernel will be able to
run on.

This replaces the CONFIG_POWER4_ONLY option with an much more
generic approach.

Also, when CONFIG_PPC_CPU_SELECTION is set, it is now possible
to select a CPU to tune for by means of the -mtune= option.

I tried to be very careful when coding the specific rules into
the Kconfig language, but it would be good to have a few
people sanity-checking them.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Index: linux-2.6/arch/powerpc/platforms/4xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/4xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/4xx/Kconfig
@@ -87,6 +87,7 @@ endmenu
 # 40x specific CPU modules, selected based on the board above.
 config NP405H
 	bool
+	select CPU_405
 	#depends on ASH
 
 # OAK doesn't exist but wanted to keep this around for any future 403GCX boards
@@ -94,6 +95,7 @@ config 403GCX
 	bool
 	#depends on OAK
 	select IBM405_ERR51
+	select CPU_403
 
 config 405GP
 	bool
@@ -102,19 +104,23 @@ config 405GP
 
 config 405EP
 	bool
+	select CPU_405
 
 config 405GPR
 	bool
+	select CPU_405
 
 config VIRTEX_II_PRO
 	bool
 	select IBM405_ERR77
 	select IBM405_ERR51
+	select CPU_405
 
 config STB03xxx
 	bool
 	select IBM405_ERR77
 	select IBM405_ERR51
+	select CPU_405
 
 # 40x errata/workaround config symbols, selected by the CPU models above
 
@@ -168,20 +174,25 @@ config 440EP
 	bool
 	select PPC_FPU
 	select IBM440EP_ERR42
+	select CPU_440
 
 config 440GP
 	bool
 	select IBM_NEW_EMAC_ZMII
+	select CPU_440
 
 config 440GX
 	bool
+	select CPU_440
 
 config 440SP
 	bool
+	select CPU_440
 
 config 440A
 	bool
 	depends on 440GX
+	select CPU_440
 	default y
 
 # 44x errata/workaround config symbols, selected by the CPU models above
Index: linux-2.6/arch/powerpc/platforms/52xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/52xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/52xx/Kconfig
@@ -25,12 +25,14 @@ config PPC_EFIKA
 	select RTAS_PROC
 	select PPC_MPC52xx
 	select PPC_NATIVE
+	select CPU_603e
 	default n
 
 config PPC_LITE5200
 	bool "Freescale Lite5200 Eval Board"
 	depends on PPC_MULTIPLATFORM && PPC32
 	select PPC_MPC5200
+	select CPU_603e
 	default n
 
 
Index: linux-2.6/arch/powerpc/platforms/82xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/82xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/82xx/Kconfig
@@ -10,6 +10,7 @@ config MPC82xx_ADS
 	select 8272
 	select 8260
 	select FSL_SOC
+	select CPU_603e
 	help
 	This option enables support for the MPC8272 ADS board
 
Index: linux-2.6/arch/powerpc/platforms/83xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/83xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/83xx/Kconfig
@@ -6,6 +6,7 @@ choice
 config MPC8313_RDB
 	bool "Freescale MPC8313 RDB"
 	select DEFAULT_UIMAGE
+	select CPU_603e
 	help
 	  This option enables support for the MPC8313 RDB board.
 
@@ -13,6 +14,7 @@ config MPC832x_MDS
 	bool "Freescale MPC832x MDS"
 	select DEFAULT_UIMAGE
 	select QUICC_ENGINE
+	select CPU_603e
 	help
 	  This option enables support for the MPC832x MDS evaluation board.
 
@@ -20,12 +22,14 @@ config MPC832x_RDB
 	bool "Freescale MPC832x RDB"
 	select DEFAULT_UIMAGE
 	select QUICC_ENGINE
+	select CPU_603e
 	help
 	  This option enables support for the MPC8323 RDB board.
 
 config MPC834x_MDS
 	bool "Freescale MPC834x MDS"
 	select DEFAULT_UIMAGE
+	select CPU_603e
 	help
 	  This option enables support for the MPC 834x MDS evaluation board.
 
@@ -37,6 +41,7 @@ config MPC834x_MDS
 config MPC834x_ITX
 	bool "Freescale MPC834x ITX"
 	select DEFAULT_UIMAGE
+	select CPU_603e
 	help
 	  This option enables support for the MPC 834x ITX evaluation board.
 
@@ -47,6 +52,7 @@ config MPC836x_MDS
 	bool "Freescale MPC836x MDS"
 	select DEFAULT_UIMAGE
 	select QUICC_ENGINE
+	select CPU_603e
 	help
 	  This option enables support for the MPC836x MDS Processor Board.
 
Index: linux-2.6/arch/powerpc/platforms/86xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/86xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/86xx/Kconfig
@@ -7,6 +7,7 @@ config MPC8641_HPCN
 	bool "Freescale MPC8641 HPCN"
 	select PPC_I8259
 	select DEFAULT_UIMAGE
+	select CPU_7450
 	help
 	  This option enables support for the MPC8641 HPCN board.
 
Index: linux-2.6/arch/powerpc/platforms/Kconfig.cputype
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/Kconfig.cputype
+++ linux-2.6/arch/powerpc/platforms/Kconfig.cputype
@@ -51,14 +51,352 @@ config E200
 
 endchoice
 
-config POWER4_ONLY
-	bool "Optimize for POWER4"
+config PPC_CPU_SELECTION
+	bool "Advanced CPU selection"
+	help
+	  The kernel can be built for a range of CPU types, which it
+	  normally determines automatically from the platform types that
+	  have been enabled.  In order to optimized leaving out support
+	  for the older CPUs or selecting the exact -mtune= option that
+	  is passed to gcc, you can further optimize the kernel for a
+	  particular system.
+
+	  Selecting this option will not cause changes directly, but will
+	  reveal further options.
+
+	  If unsure, say N.
+
+config CPU_DEFAULT
+	bool "Don't specify -mcpu= to gcc" if PPC_CPU_SELECTION
+	help
+	  When this option is selected, gcc is called without
+	  any specific -mcpu= argument, regardless of which
+	  CPUs are enabled in the next options.
+
+config CPU_RS64
+	bool "RS64" if PPC_CPU_SELECTION
 	depends on PPC64
-	default n
-	---help---
-	  Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
-	  The resulting binary will not work on POWER3 or RS64 processors
-	  when compiled with binutils 2.15 or later.
+	default y if PPC_PSERIES || PPC_ISERIES
+	help
+	  Select this if you want to have support for the first
+	  generation of 64 bit PowerPC CPUs used in the late
+	  1990s in IBM RS/6000 and AS/400 machines.
+
+config CPU_POWER3
+	bool "IBM Power3" if PPC_CPU_SELECTION
+	depends on PPC64
+	default y if PPC_PSERIES
+	help
+	  Select this if you want to have support for the
+	  Power3 chip used in IBM RS/6000 and early pSeries
+	  machines.
+
+config CPU_POWER4
+	bool "IBM Power4" if PPC_CPU_SELECTION
+	depends on PPC64
+	default y if PPC_PSERIES || PPC_ISERIES
+	help
+	  Select this if you want to have support for the Power 4
+	  processor used in IBM pSeries and iSeries machines.
+
+config CPU_POWER5
+	bool "IBM Power5" if PPC_CPU_SELECTION
+	depends on PPC64
+	default y if PPC_PSERIES
+	help
+	  Select this if you want to have support for the Power 5
+	  processor used in IBM System p and System i machines.
+
+config CPU_POWER6
+	bool "IBM Power6" if PPC_CPU_SELECTION
+	depends on PPC64
+	default y if PPC_PSERIES
+	select ALTIVEC
+	help
+	  Select this if you want to have support for the Power 6
+	  processor used in the latest IBM System p and System i
+	  machines.
+
+config CPU_970
+	bool "IBM PowerPC 970 (G5)" if PPC_CPU_SELECTION
+	depends on PPC64
+	default y if PPC_PSERIES
+	select ALTIVEC
+	help
+	  Select this if you want to have support for the PowerPC 970
+	  processor used in Apple Power Macintosh G5 and IBM JS2x blade
+	  servers and other systems.
+
+config CPU_CELL
+	bool "Sony/Toshiba/IBM Cell Broadband Engine" if PPC_CPU_SELECTION
+	depends on PPC64
+	select ALTIVEC
+	help
+	  Select this if you want to have support for the Cell Broadband
+	  Engine processor used the Sony Playstation 3, the IBM QS2x
+	  blade servers and other systems.
+
+config CPU_PA6T
+	bool "PA Semi PA6T-1682M" if PPC_CPU_SELECTION
+	depends on PPC64
+	select ALTIVEC
+	help
+	  Select this if you want to have support for the PA6T-1682M
+	  processor from  PA Semi.
+
+config CPU_601
+	bool "PowerPC 601 (G1)" if PPC_CPU_SELECTION
+	depends on 6xx
+	default PPC_CHRP || PPC_PREP
+	help
+	  Select this if you really wish to have support for ancient PowerPC
+	  601 processors used in very early Power Macintosh machines and
+	  some CHRP boards.
+	  Most people will want to disable this option to get better
+	  performance on modern machines.
+
+config CPU_603e
+	bool "PowerPC 603e, 604, 604e, 52xx, 82xx, 83xx (G2)" if PPC_CPU_SELECTION
+	depends on 6xx
+	default PPC_CHRP || PPC_PREP || PPC_PMAC
+	help
+	  The 603e processor line is the most widespread implementation of
+	  the PowerPC ISA, so you most likely want to enable this if you are
+	  building a kernel for multiple platforms.
+
+config CPU_750
+	bool "PowerPC 740, 750 (G3)" if PPC_CPU_SELECTION
+	depends on 6xx
+	default PPC_PMAC
+	help
+	  Select this for the G3 PowerPC 750 processor used in Apple
+	  Power Macintosh and a number of embedded boards.
+
+config CPU_7400
+	bool "PowerPC 7400, 7410 (G4)" if PPC_CPU_SELECTION
+	depends on 6xx
+	default PPC_PMAC
+	select ALTIVEC
+	help
+	  Select this for the early G4 PowerPC 7400 processor used in
+	  a few Apple Power Macintosh and other machines.
+
+config CPU_7450
+	bool "PowerPC 744x, 745x, 86xx (G4)" if PPC_CPU_SELECTION
+	depends on 6xx
+	default PPC_PMAC
+	select ALTIVEC
+	help
+	  Select this for the later G4 PowerPC 7450 processor and its
+	  derivatives used in most of the late Apple Power Macintosh
+	  machines and some high-performance embedded boards.
+
+config CPU_8540
+	bool "Freescale e500v1 (MPC8540 compatible)" if PPC_CPU_SELECTION
+	depends on PPC_85xx
+	help
+	  Select this for the older version 1 of the e500 core used in
+	  the earlier MPC85xx processors.
+
+config CPU_8548
+	bool "Freescale e500v2 (MPC8548 compatible)" if PPC_CPU_SELECTION
+	depends on PPC_85xx
+	help
+	  Select this for the newer version 2 of the e500 core that was
+	  first used in the MPC8548 processor.
+	  Some versions of gcc don't know about this yet, so you may
+	  also have to enable 8540 to get the best performance with
+	  your compiler.
+
+config CPU_403
+	bool "IBM 403" if PPC_CPU_SELECTION
+	depends on 40x
+	help
+	  The PowerPC 403 core is used in the first generation Tivo and
+	  some other old machines. Select this only if you are sure that
+	  you want to run your kernel on one of these machines.
+
+config CPU_405
+	bool "IBM/AMCC 405" if PPC_CPU_SELECTION
+	depends on 40x
+	default y
+	help
+	  Practically all PowerPC 40x based platforms supported by Linux use
+	  a 405 core, so you should enable this option.
+
+config CPU_440
+	bool "IBM/AMCC 440" if PPC_CPU_SELECTION
+	depends on 44x
+	default y
+	help
+	  If you are building for a PowerPC 440 based, you don't really
+	  have a choice here, say Y.
+
+choice
+	prompt "Tune for processor type" if PPC_CPU_SELECTION
+	default TUNE_POWER4 if PPC64
+	default TUNE_DEFAULT
+	help
+	  This will choose the gcc flag to use for the -mtune= parameter.
+	  See the above list for a description of the invidual options.
+
+	  If unsure, select TUNE_DEFAULT, gcc will tune for the oldest
+	  CPU that the kernel supports in that case, which usually
+	  gives reasonable results on newer CPUs as well.
+
+config TUNE_DEFAULT
+	bool "Don't specify -mtune= to gcc"
+
+config TUNE_RS64
+	bool "RS64"
+	depends on CPU_RS64
+
+config TUNE_POWER3
+	bool "IBM Power3"
+	depends on CPU_POWER3
+
+config TUNE_POWER4
+	bool "IBM Power4"
+	depends on CPU_POWER4
+
+config TUNE_POWER5
+	bool "IBM Power5"
+	depends on CPU_POWER5
+
+config TUNE_POWER6
+	bool "IBM Power6"
+	depends on CPU_POWER6
+
+config TUNE_970
+	bool "IBM PowerPC 970 (G5)"
+	depends on CPU_970
+
+config TUNE_CELL
+	bool "Sony/Toshiba/IBM Cell Broadband Engine"
+	depends on CPU_CELL
+
+config TUNE_PA6T
+	bool "PA Semi PA6T-1682M"
+	depends on CPU_PA6T
+
+config TUNE_601
+	bool "PowerPC 601 (G1)"
+	depends on CPU_601
+
+config TUNE_603e
+	bool "PowerPC 603e, 604, 604e, 52xx, 82xx, 83xx (G2)"
+	depends on CPU_603e
+
+config TUNE_750
+	bool "PowerPC 740/750 (G3)"
+	depends on CPU_750
+
+config TUNE_7400
+	bool "PowerPC 7400, 7410 (G4)"
+	depends on CPU_7400
+
+config TUNE_7450
+	bool "PowerPC 744x, 745x, 86xx (G4)"
+	depends on CPU_7450
+
+config TUNE_821
+	bool "Freescale MPC821"
+	depends on 8xx
+
+config TUNE_823
+	bool "Freescale MPC823"
+	depends on 8xx
+
+config TUNE_860
+	bool "Freescale MPC860"
+	depends on 8xx
+
+config TUNE_403
+	bool "IBM 403"
+	depends on CPU_403
+
+config TUNE_405
+	bool "IBM/AMCC 405"
+	depends on CPU_405
+
+config TUNE_440
+	bool "IBM/AMCC 440"
+	depends on CPU_440
+
+config TUNE_8540
+	bool "Freescale e500v1"
+	depends on CPU_8540
+
+config TUNE_8548
+	bool "Freescale e500v2"
+	depends on CPU_8548
+
+config TUNE_E200
+	bool "Freescale e200"
+	depends on E200
+
+endchoice
+
+config PPC_MCPU
+	string
+	default "" if CPU_DEFAULT
+	default "-mcpu=power3" if CPU_POWER3 || CPU_RS64
+	default "-mcpu=power4" if (CPU_POWER5 || CPU_POWER6) && (CPU_970 || CPU_CELL || CPU_PA6T)
+	default "-mcpu=power4" if CPU_POWER4
+	default "-mcpu=power5" if CPU_POWER5
+	default "-mcpu=power6" if CPU_POWER6
+	default "-mcpu=970" if CPU_970
+	default "-mcpu=cell" if CPU_CELL
+	default "-mcpu=pa6t" if CPU_PA6T
+	default "-mcpu=power3" if PPC64
+	default "-mcpu=powerpc" if CPU_601 && (CPU_603e || CPU_750 || CPU_7400 || CPU_7450)
+	default "-mcpu=601" if CPU_601
+	default "-mcpu=603e" if CPU_603e
+	default "-mcpu=750" if CPU_750
+	default "-mcpu=7400" if CPU_7400
+	default "-mcpu=7450" if CPU_7450
+	default "-mcpu=8540" if CPU_8540
+	default "-mcpu=8548" if CPU_8548
+	default "-mcpu=powerpc" if (CPU_403 && CPU_405)
+	default "-mcpu=powerpc" if (CPU_403 || CPU_405) && CPU_440
+	default "-mcpu=403" if CPU_403
+	default "-mcpu=405" if CPU_405
+	default "-mcpu=440" if CPU_440
+	default "-mcpu=860" if PPC_8xx
+	default "-mcpu=e200" if E200
+	default "-mcpu=powerpc"
+
+config PPC_MTUNE
+	string
+	default "" if TUNE_DEFAULT
+	default "-mtune=power3" if TUNE_POWER3
+	default "-mtune=rs64a" if TUNE_RS64
+	default "-mtune=power4" if TUNE_POWER4
+	default "-mtune=power5" if TUNE_POWER5
+	default "-mtune=power6" if TUNE_POWER6
+	default "-mtune=970" if TUNE_970
+	default "-mtune=cell" if TUNE_CELL
+	default "-mtune=pa6t" if TUNE_PA6T
+	default "-mtune=601" if TUNE_601
+	default "-mtune=603e" if TUNE_603e
+	default "-mtune=750" if TUNE_750
+	default "-mtune=7400" if TUNE_7400
+	default "-mtune=7450" if TUNE_7450
+	default "-mtune=8540" if TUNE_8540
+	default "-mtune=8548" if TUNE_8548
+	default "-mtune=403" if TUNE_403
+	default "-mtune=405" if TUNE_405
+	default "-mtune=440" if TUNE_440
+	default "-mtune=821" if TUNE_821
+	default "-mtune=823" if TUNE_823
+	default "-mtune=860" if TUNE_860
+	default "-mtune=e200" if TUNE_E200
+	default "-mtune=power4" if PPC64
+
+# The next three options should probably go away
+config POWER4_ONLY
+	def_bool y
+	depends on PPC64 && !CPU_POWER3 && !CPU_RS64
 
 config POWER3
 	bool
Index: linux-2.6/arch/powerpc/platforms/cell/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/Kconfig
+++ linux-2.6/arch/powerpc/platforms/cell/Kconfig
@@ -20,6 +20,7 @@ config PPC_IBM_CELL_BLADE
 	select MMIO_NVRAM
 	select PPC_UDBG_16550
 	select UDBG_RTAS_CONSOLE
+	select CPU_CELL
 
 menu "Cell Broadband Engine options"
 	depends on PPC_CELL
Index: linux-2.6/arch/powerpc/platforms/celleb/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/celleb/Kconfig
+++ linux-2.6/arch/powerpc/platforms/celleb/Kconfig
@@ -2,6 +2,7 @@ config PPC_CELLEB
 	bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
 	depends on PPC_MULTIPLATFORM && PPC64
 	select PPC_CELL
+	select CPU_CELL
 	select PPC_OF_PLATFORM_PCI
 	select HAS_TXX9_SERIAL
 	select PPC_UDBG_BEAT
Index: linux-2.6/arch/powerpc/platforms/embedded6xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/embedded6xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -8,6 +8,7 @@ config LINKSTATION
 	select FSL_SOC
 	select PPC_UDBG_16550 if SERIAL_8250
 	select DEFAULT_UIMAGE
+	select CPU_603e
 	help
 	  Select LINKSTATION if configuring for one of PPC- (MPC8241)
 	  based NAS systems from Buffalo Technology. So far only
@@ -20,6 +21,7 @@ config MPC7448HPC2
 	select TSI108_BRIDGE
 	select DEFAULT_UIMAGE
 	select PPC_UDBG_16550
+	select CPU_7450
 	help
 	  Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
 	  platform
@@ -29,6 +31,7 @@ config PPC_HOLLY
 	select TSI108_BRIDGE
 	select PPC_UDBG_16550
 	select WANT_DEVICE_TREE
+	select CPU_750
 	help
 	  Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
 	  Board with TSI108/9 bridge (Hickory/Holly)
@@ -38,6 +41,7 @@ config PPC_PRPMC2800
 	select MV64X60
 	select NOT_COHERENT_CACHE
 	select WANT_DEVICE_TREE
+	select CPU_7450
 	help
 	  This option enables support for the Motorola PrPMC2800 board
 endchoice
Index: linux-2.6/arch/powerpc/platforms/maple/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/maple/Kconfig
+++ linux-2.6/arch/powerpc/platforms/maple/Kconfig
@@ -11,6 +11,7 @@ config PPC_MAPLE
 	select PPC_RTAS
 	select MMIO_NVRAM
 	select ATA_NONSTANDARD if ATA
+	select CPU_970
 	default n
 	help
           This option enables support for the Maple 970FX Evaluation Board.
Index: linux-2.6/arch/powerpc/platforms/pasemi/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/pasemi/Kconfig
+++ linux-2.6/arch/powerpc/platforms/pasemi/Kconfig
@@ -2,6 +2,7 @@ config PPC_PASEMI
 	depends on PPC_MULTIPLATFORM && PPC64
 	bool "PA Semi SoC-based platforms"
 	default n
+	select CPU_PA6T
 	select MPIC
 	select PPC_UDBG_16550
 	select PPC_NATIVE
Index: linux-2.6/arch/powerpc/platforms/powermac/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/powermac/Kconfig
+++ linux-2.6/arch/powerpc/platforms/powermac/Kconfig
@@ -16,6 +16,7 @@ config PPC_PMAC64
 	select MPIC_U3_HT_IRQS
 	select GENERIC_TBSYNC
 	select PPC_970_NAP
+	select CPU_970
 	default y
 
 
Index: linux-2.6/arch/powerpc/platforms/ps3/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/ps3/Kconfig
+++ linux-2.6/arch/powerpc/platforms/ps3/Kconfig
@@ -2,6 +2,7 @@ config PPC_PS3
 	bool "Sony PS3 (incomplete)"
 	depends on PPC_MULTIPLATFORM && PPC64
 	select PPC_CELL
+	select CPU_CELL
 	select USB_ARCH_HAS_OHCI
 	select USB_OHCI_LITTLE_ENDIAN
 	select USB_OHCI_BIG_ENDIAN_MMIO
Index: linux-2.6/arch/powerpc/Makefile
===================================================================
--- linux-2.6.orig/arch/powerpc/Makefile
+++ linux-2.6/arch/powerpc/Makefile
@@ -78,24 +78,23 @@ LINUXINCLUDE    += $(LINUXINCLUDE-y)
 
 CHECKFLAGS	+= -m$(SZ) -D__powerpc__ -D__powerpc$(SZ)__
 
+OPTFLAGS := $(call cc-option,$(CONFIG_PPC_MCPU)) $(call cc-option,$(CONFIG_PPC_MTUNE))
+
+# compilers older than 4.0.0 can only set -maltivec in 64 bit mode
+# when compiling for 970
 ifeq ($(CONFIG_PPC64),y)
 GCC_BROKEN_VEC	:= $(shell if [ $(call cc-version) -lt 0400 ] ; then echo "y"; fi)
-
 ifeq ($(CONFIG_POWER4_ONLY),y)
 ifeq ($(CONFIG_ALTIVEC),y)
 ifeq ($(GCC_BROKEN_VEC),y)
-	CFLAGS += $(call cc-option,-mcpu=970)
-else
-	CFLAGS += $(call cc-option,-mcpu=power4)
+	OPTFLAGS := $(call cc-option,-mcpu=970) $(call cc-option,$(CONFIG_PPC_MTUNE))
 endif
-else
-	CFLAGS += $(call cc-option,-mcpu=power4)
 endif
-else
-	CFLAGS += $(call cc-option,-mtune=power4)
 endif
 endif
 
+CFLAGS += $(OPTFLAGS)
+
 # No AltiVec instruction when building kernel
 CFLAGS += $(call cc-option,-mno-altivec)
 
@@ -107,10 +106,6 @@ CFLAGS += $(call cc-option,-funit-at-a-t
 # often slow when they are implemented at all
 CFLAGS		+= -mno-string
 
-ifeq ($(CONFIG_6xx),y)
-CFLAGS		+= -mcpu=powerpc
-endif
-
 cpu-as-$(CONFIG_4xx)		+= -Wa,-m405
 cpu-as-$(CONFIG_6xx)		+= -Wa,-maltivec
 cpu-as-$(CONFIG_POWER4)		+= -Wa,-maltivec
Index: linux-2.6/arch/powerpc/platforms/85xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/85xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/85xx/Kconfig
@@ -6,24 +6,28 @@ choice
 config MPC8540_ADS
 	bool "Freescale MPC8540 ADS"
 	select DEFAULT_UIMAGE
+	select CPU_8540
 	help
 	  This option enables support for the MPC 8540 ADS board
 
 config MPC8560_ADS
 	bool "Freescale MPC8560 ADS"
 	select DEFAULT_UIMAGE
+	select CPU_8540
 	help
 	  This option enables support for the MPC 8560 ADS board
 
 config MPC85xx_CDS
 	bool "Freescale MPC85xx CDS"
 	select DEFAULT_UIMAGE
+	select CPU_8548
 	help
 	  This option enables support for the MPC85xx CDS board
 
 config MPC85xx_MDS
 	bool "Freescale MPC85xx MDS"
 	select DEFAULT_UIMAGE
+	select CPU_8548
 #	select QUICC_ENGINE
 	help
 	  This option enables support for the MPC85xx MDS board
@@ -31,6 +35,7 @@ config MPC85xx_MDS
 config MPC8544_DS
 	bool "Freescale MPC8544 DS"
 	select DEFAULT_UIMAGE
+	select CPU_8548
 	help
 	  This option enables support for the MPC8544 DS board
 

--

^ permalink raw reply

* [PATCH 4/5] linkstation: fix multiplatform build
From: Arnd Bergmann @ 2007-07-13 18:44 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20070713184452.466490031@arndb.de>

Jon Loeliger <jdl@freescale.com> wrote:
X-Provags-ID: V01U2FsdGVkX19mfbfAMECjK3Yc4qnJalet5VRz84KpvPei34h
 Js67aIi1Jyt+C01bLuMxs+l5L4KLJuYYiIXI6fjXdktExWZ2WR
 fI/xi0tOHQX8AN87t62WA==

> Hmmm... Shouldn't this sort of change come
> with an update to the 8641 defconfig too?
Content-Disposition: inline; filename=ls-fix-uart.diff

The ls_uart file accidentally includes two headers from asm-ppc that
are no longer needed but cause a broken build in some configurations.
Kill the includes to fix the build.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c
index d0bee9f..3b023b0 100644
--- a/arch/powerpc/platforms/embedded6xx/ls_uart.c
+++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c
@@ -4,8 +4,6 @@
 #include <linux/serial_reg.h>
 #include <linux/serial_8250.h>
 #include <asm/io.h>
-#include <asm/mpc10x.h>
-#include <asm/ppc_sys.h>
 #include <asm/prom.h>
 #include <asm/termbits.h>
 

--

^ permalink raw reply related

* [PATCH 3/5] move 86xx into multiplatform
From: Arnd Bergmann @ 2007-07-13 18:44 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20070713184452.466490031@arndb.de>

Jon Loeliger <jdl@freescale.com> wrote:
X-Provags-ID: V01U2FsdGVkX18q0hUeUuMqOEeLWhKFlJn74HxEidaqOcemeHV
 ERKD3Oa64b/U3Jbpg7ScqVjTea/vrQYQQ9h6BX663cqWFlw9cZ
 acZ0zSjq49Kqfby7nRUgQ==

> Hmmm... Shouldn't this sort of change come
> with an update to the 8641 defconfig too?
Content-Disposition: inline; filename=86xx-multi.diff

MPC86xx based machines don't need their own kernel,
but can run one that is shared with the other 6xx
compatible machines, so we should allow that
in Kconfig.

Cc: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---

Kumar, I don't remember if you still had objections
to merging 86xx annd 83xx into multiplatform after
our last discussion.
Please Ack or Nack the two patches.

Index: linux-2.6/arch/powerpc/platforms/86xx/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/86xx/Kconfig
+++ linux-2.6/arch/powerpc/platforms/86xx/Kconfig
@@ -1,18 +1,20 @@
-choice
-	prompt "86xx Board Type"
-	depends on PPC_86xx
-	default MPC8641_HPCN
+config PPC_86xx
+	bool "Freescale 86xx based boards"
+	depends on 6xx
+	select FSL_SOC
+	select ALTIVEC
+	help
+	  The Freescale E600 SoCs have 74xx cores.
 
 config MPC8641_HPCN
 	bool "Freescale MPC8641 HPCN"
+	depends on PPC_86xx
 	select PPC_I8259
 	select DEFAULT_UIMAGE
 	select CPU_7450
 	help
 	  This option enables support for the MPC8641 HPCN board.
 
-endchoice
-
 config MPC8641
 	bool
 	select PPC_INDIRECT_PCI
Index: linux-2.6/arch/powerpc/platforms/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/Kconfig
+++ linux-2.6/arch/powerpc/platforms/Kconfig
@@ -23,13 +23,6 @@ config PPC_83xx
 	select 83xx
 	select WANT_DEVICE_TREE
 
-config PPC_86xx
-	bool "Freescale 86xx"
-	depends on 6xx
-	select FSL_SOC
-	select ALTIVEC
-	help
-	  The Freescale E600 SoCs have 74xx cores.
 endchoice
 
 config CLASSIC32
Index: linux-2.6/arch/powerpc/configs/mpc8641_hpcn_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/mpc8641_hpcn_defconfig
+++ linux-2.6/arch/powerpc/configs/mpc8641_hpcn_defconfig
@@ -1,9 +1,33 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.22-rc7
-# Sun Jul  1 23:57:00 2007
+# Fri Jul 13 20:08:07 2007
 #
 # CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+# CONFIG_PPC_CPU_SELECTION is not set
+# CONFIG_CPU_601 is not set
+# CONFIG_CPU_603e is not set
+# CONFIG_CPU_750 is not set
+# CONFIG_CPU_7400 is not set
+CONFIG_CPU_7450=y
+CONFIG_PPC_MCPU="-mcpu=7450"
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
 CONFIG_PPC32=y
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
@@ -25,29 +49,8 @@ CONFIG_GENERIC_TBSYNC=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
-
-#
-# Processor support
-#
-# CONFIG_CLASSIC32 is not set
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_85xx is not set
-CONFIG_PPC_86xx=y
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_6xx=y
-CONFIG_PPC_FPU=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
-CONFIG_ALTIVEC=y
-CONFIG_PPC_STD_MMU=y
-CONFIG_PPC_STD_MMU_32=y
-# CONFIG_PPC_MM_SLICES is not set
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -133,11 +136,20 @@ CONFIG_DEFAULT_IOSCHED="deadline"
 #
 # Platform support
 #
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_MPC52xx is not set
 # CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+CONFIG_PPC_86xx=y
 CONFIG_MPC8641_HPCN=y
 CONFIG_MPC8641=y
 CONFIG_MPIC=y
@@ -150,6 +162,7 @@ CONFIG_PPC_I8259=y
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
 # CONFIG_CPM2 is not set
 
 #
@@ -168,6 +181,7 @@ CONFIG_PREEMPT_BKL=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
 # CONFIG_IRQ_ALL_CPUS is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -196,7 +210,6 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 CONFIG_FSL_SOC=y
-CONFIG_FSL_PCIE=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
@@ -469,6 +482,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_BNX2 is not set
 CONFIG_GIANFAR=y
 # CONFIG_GFAR_NAPI is not set
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 CONFIG_NETDEV_10000=y

--

^ permalink raw reply

* 2.6.22 flash boot
From: Marc Leeman @ 2007-07-13 19:40 UTC (permalink / raw)
  To: linuxppc-dev


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

With the release of the 2.6.22, our boards didn't boot anymore. I traced
the change back to 2.6.21-git10/2.6.21-git11. 

The reason they didn't boot was that the kernel  didn't detect the flash
where the root filesystem is stored on. The boards boot without an
initrd, directly from flash.

A file was removed (rom.c) and mentioned as obsolete in the ChangeLog.

att'd is the patch to restore the file against 2.6.22 since restoring
this file allow the boards to boot again (i.e. detect mtdblocks as
rootfilesystem).

Am I missing something here?

Judging by the dts files, a number of other boards seem to be using a
similar flash configuration as I do.

-- 
  greetz, marc
That's your plan? Wile E. Coyote would come up with a better plan
than that!
	Crichton - Throne for a Loss
chiana 2.6.18-4-ixp4xx #1 Tue Mar 27 18:01:56 BST 2007 GNU/Linux

[-- Attachment #1.2: fix-boot.diff --]
[-- Type: text/x-diff, Size: 1707 bytes --]

---
 arch/powerpc/sysdev/Makefile |    1 +
 arch/powerpc/sysdev/rom.c    |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

Index: linux-2.6.22/arch/powerpc/sysdev/Makefile
===================================================================
--- linux-2.6.22.orig/arch/powerpc/sysdev/Makefile
+++ linux-2.6.22/arch/powerpc/sysdev/Makefile
@@ -30,6 +30,7 @@
 
 # Temporary hack until we have migrated to asm-powerpc
 ifeq ($(ARCH),powerpc)
+obj-$(CONFIG_MTD)		+= rom.o
 obj-$(CONFIG_CPM2)		+= cpm2_common.o cpm2_pic.o
 obj-$(CONFIG_8xx)		+= mpc8xx_pic.o commproc.o
 obj-$(CONFIG_UCODE_PATCH)	+= micropatch.o
Index: linux-2.6.22/arch/powerpc/sysdev/rom.c
===================================================================
--- /dev/null
+++ linux-2.6.22/arch/powerpc/sysdev/rom.c
@@ -0,0 +1,32 @@
+/*
+ * ROM device registration
+ *
+ * (C) 2006 MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/kernel.h>
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
+
+static int __init powerpc_flash_init(void)
+{
+	struct device_node *node = NULL;
+
+	/*
+	 * Register all the devices which type is "rom"
+	 */
+	while ((node = of_find_node_by_type(node, "rom")) != NULL) {
+		if (node->name == NULL) {
+			printk(KERN_WARNING "powerpc_flash_init: found 'rom' "
+				"device, but with no name, skipping...\n");
+			continue;
+		}
+		of_platform_device_create(node, node->name, NULL);
+	}
+	return 0;
+}
+
+arch_initcall(powerpc_flash_init);

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: Help required for porting ISP1362 usb device driver
From: Sonny Rao @ 2007-07-13 19:10 UTC (permalink / raw)
  To: Vikram Kone; +Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <003d01c7c4d8$07ea3cc0$66dd47ab@cisco.com>

On Thu, Jul 12, 2007 at 03:57:32PM -0700, Vikram Kone wrote:
> 
>    Hi..
>    I'm a linux newbie and im working on porting the USB driver ISP1362 by
>    Philips on to my Freescale ppc board.
>    I dont know how to do this... so if any of you can tell me how to do this
>    step by step, i would be very grateful to you

Try posting this question on the kernel newbies mailing list

http://kernelnewbies.org/MailingList

^ permalink raw reply

* Re: [PATCH] Use resource_size_t for serial port IO addresses
From: Josh Boyer @ 2007-07-13 19:24 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, paulus, rmk, david
In-Reply-To: <20070713120226.797117e2.akpm@linux-foundation.org>

On Fri, 2007-07-13 at 12:02 -0700, Andrew Morton wrote:
> On Fri, 13 Jul 2007 09:02:16 -0500
> Josh Boyer <jwboyer@linux.vnet.ibm.com> wrote:
> 
> > This is a resend of a patch David sent out on May 7.  Without it, the
> > PowerPC 44x port in 2.6.22 and on is broken.  I've rebased it off of
> > Linus' current tree.  Please consider pushing this soon.
> > 
> > josh
> > 
> > 
> > At present, various parts of the serial code use unsigned long to
> > define resource addresses.  This is a problem, because some 32-bit
> > platforms have physical addresses larger than 32-bits, and have mmio
> > serial uarts located above the 4GB point.
> > 
> > This patch changes the type of mapbase in both struct uart_port and
> > struct plat_serial8250_port to resource_size_t, which can be
> > configured to be 64 bits on such platforms.  The mapbase in
> > serial_struct can't safely be changed, because that structure is user
> > visible.
> 
> This is something we should do, but I have recollections of Russell
> identifying problems with this patch, or at least an earlier version of it?

I can't recall myself if there were problems or not.  I thought David
had worked that out with Russell, but I could be mistaken.

> > Signed-off-by: David Gibson <dwg@au1.ibm.com>
> 
> This should have had Signed-off-by:you as well.

Oops, for the rebase I suppose, yes.  Is the one below enough or do you
want me to resubmit?

Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>

josh

^ permalink raw reply

* Re: Help required for porting ISP1362 usb device driver
From: Clemens Koller @ 2007-07-13 19:17 UTC (permalink / raw)
  To: Vikram Kone; +Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <003d01c7c4d8$07ea3cc0$66dd47ab@cisco.com>

Hello, Vikram!

Vikram Kone schrieb:
> Hi..
> I'm a linux newbie and im working on porting the USB driver ISP1362 by 
> Philips on to my Freescale ppc board.

Please don't crosspost.
Please don't write HTML.

> I dont know how to do this... so if any of you can tell me how to do 
> this step by step, i would be very grateful to you
>  
> Few details..
> I'm running RHEL with kernel 2.4.21 on a PC (i386 machine)
> Target Machine is MPC8548 CDS by Free scale (ppc architecture) running 
> kernel version 2.6.11

Did you try something like:
http://www.freescale.com/files/32bit/doc/app_note/AN3094.pdf?fsrch=1
I think it's one of these "step by step" things.

(You should consider moving up to the latest Kernel which is 2.6.22.1
as of today. Nobody fixes bugs on that old kernel.)

> I do have a ppc tool chain, if that helps.....

What tool chain?

 > but i dont know how to use it

Did you read the documentation?
What problem do you have?

> P.S. I downloaded the deive driver and host controller drivers from 
> sourceforge.net and both of them seem to work for 2.6.6 kernel for i386 
> arch ..

Fine!

> P.P.S : Wolfgang ??!1 Can you help me out... I went through the archives 
> on the list and seems thatu answered many Qs on this driver. But i didnt 
> find any post specifcally for my problem..so

Sorry, my crystal ball is broken.
You didn't tell us any details about your problem.

  > This e-mail may contain confidential and privileged material for the
> sole use of the intended recipient. Any review, use, distribution or 
> disclosure by others is strictly prohibited. If you are not the intended 
> recipient (or authorized to receive for the recipient), please contact 
> the sender by reply e-mail and delete all copies of this message.

Oops... If I am not the intended recipient, please: > /dev/null my mail.

Regards,
-- 
Clemens Koller
__________________________________
R&D Imaging Devices
Anagramm GmbH
Rupert-Mayer-Straße 45/1
Linhof Werksgelände
D-81379 München
Tel.089-741518-50
Fax 089-741518-19
http://www.anagramm-technology.com

^ permalink raw reply

* Re: Help required for porting ISP1362 usb device driver
From: Clemens Koller @ 2007-07-13 19:17 UTC (permalink / raw)
  To: Vikram Kone; +Cc: linuxppc-embedded
In-Reply-To: <003d01c7c4d8$07ea3cc0$66dd47ab@cisco.com>

Hello, Vikram!

Vikram Kone schrieb:
> Hi..
> I'm a linux newbie and im working on porting the USB driver ISP1362 by 
> Philips on to my Freescale ppc board.

Please don't crosspost.
Please don't write HTML.

> I dont know how to do this... so if any of you can tell me how to do 
> this step by step, i would be very grateful to you
>  
> Few details..
> I'm running RHEL with kernel 2.4.21 on a PC (i386 machine)
> Target Machine is MPC8548 CDS by Free scale (ppc architecture) running 
> kernel version 2.6.11

Did you try something like:
http://www.freescale.com/files/32bit/doc/app_note/AN3094.pdf?fsrch=1
I think it's one of these "step by step" things.

(You should consider moving up to the latest Kernel which is 2.6.22.1
as of today. Nobody fixes bugs on that old kernel.)

> I do have a ppc tool chain, if that helps.....

What tool chain?

 > but i dont know how to use it

Did you read the documentation?
What problem do you have?

> P.S. I downloaded the deive driver and host controller drivers from 
> sourceforge.net and both of them seem to work for 2.6.6 kernel for i386 
> arch ..

Fine!

> P.P.S : Wolfgang ??!1 Can you help me out... I went through the archives 
> on the list and seems thatu answered many Qs on this driver. But i didnt 
> find any post specifcally for my problem..so

Sorry, my crystal ball is broken.
You didn't tell us any details about your problem.

  > This e-mail may contain confidential and privileged material for the
> sole use of the intended recipient. Any review, use, distribution or 
> disclosure by others is strictly prohibited. If you are not the intended 
> recipient (or authorized to receive for the recipient), please contact 
> the sender by reply e-mail and delete all copies of this message.

Oops... If I am not the intended recipient, please: > /dev/null my mail.

Regards,
-- 
Clemens Koller
__________________________________
R&D Imaging Devices
Anagramm GmbH
Rupert-Mayer-Straße 45/1
Linhof Werksgelände
D-81379 München
Tel.089-741518-50
Fax 089-741518-19
http://www.anagramm-technology.com

^ permalink raw reply

* Re: [PATCH] Use resource_size_t for serial port IO addresses
From: Andrew Morton @ 2007-07-13 19:02 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev, paulus, rmk, david
In-Reply-To: <1184335336.6456.17.camel@weaponx.rchland.ibm.com>

On Fri, 13 Jul 2007 09:02:16 -0500
Josh Boyer <jwboyer@linux.vnet.ibm.com> wrote:

> This is a resend of a patch David sent out on May 7.  Without it, the
> PowerPC 44x port in 2.6.22 and on is broken.  I've rebased it off of
> Linus' current tree.  Please consider pushing this soon.
> 
> josh
> 
> 
> At present, various parts of the serial code use unsigned long to
> define resource addresses.  This is a problem, because some 32-bit
> platforms have physical addresses larger than 32-bits, and have mmio
> serial uarts located above the 4GB point.
> 
> This patch changes the type of mapbase in both struct uart_port and
> struct plat_serial8250_port to resource_size_t, which can be
> configured to be 64 bits on such platforms.  The mapbase in
> serial_struct can't safely be changed, because that structure is user
> visible.

This is something we should do, but I have recollections of Russell
identifying problems with this patch, or at least an earlier version of it?

> Signed-off-by: David Gibson <dwg@au1.ibm.com>

This should have had Signed-off-by:you as well.

^ permalink raw reply

* [PATCH 2/2] OProfile - Add support to OProfile for profiling CELL BE SPUs
From: Bob Nelson @ 2007-07-13 18:29 UTC (permalink / raw)
  To: Andrew Morton, Philippe Elie, linuxppc, oprofile

From: Maynard Johnson <mpjohn@us.ibm.com>

This patch updates the existing arch/powerpc/oprofile/op_model_cell.c
to add in the SPU profiling capabilities.  In addition, a 'cell' subdirectory
was added to arch/powerpc/oprofile to hold Cell-specific SPU profiling code.

Also incorporated several fixes from other patches (rrn).  Check pointer
returned from kzalloc.  Eliminated unnecessary cast.  Better error
handling and cleanup in the related area.  64-bit unsigned long parameter
was being demoted to 32-bit unsigned int and eventually promoted back to
unsigned long.

Signed-off-by: Carl Love <carll@us.ibm.com>
Signed-off-by: Maynard Johnson <mpjohn@us.ibm.com>
Signed-off-by: Bob Nelson <rrnelson@us.ibm.com>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>

---

We would like to include this patch in -mm and 2.6.23

Index: powerpc.git/arch/powerpc/configs/cell_defconfig
===================================================================
--- powerpc.git.orig/arch/powerpc/configs/cell_defconfig
+++ powerpc.git/arch/powerpc/configs/cell_defconfig
@@ -1455,7 +1455,8 @@ CONFIG_HAS_DMA=y
 # Instrumentation Support
 #
 CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
+CONFIG_OPROFILE=m
+CONFIG_OPROFILE_CELL=y
 # CONFIG_KPROBES is not set
 
 #
Index: powerpc.git/arch/powerpc/oprofile/cell/pr_util.h
===================================================================
--- /dev/null
+++ powerpc.git/arch/powerpc/oprofile/cell/pr_util.h
@@ -0,0 +1,90 @@
+ /*
+ * Cell Broadband Engine OProfile Support
+ *
+ * (C) Copyright IBM Corporation 2006
+ *
+ * Author: Maynard Johnson <maynardj@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.
+ */
+
+#ifndef PR_UTIL_H
+#define PR_UTIL_H
+
+#include <linux/cpumask.h>
+#include <linux/oprofile.h>
+#include <asm/cell-pmu.h>
+#include <asm/spu.h>
+
+#include "../../platforms/cell/cbe_regs.h"
+
+static inline int number_of_online_nodes(void)
+{
+	u32 cpu; u32 tmp;
+	int nodes = 0;
+	for_each_online_cpu(cpu) {
+		tmp = cbe_cpu_to_node(cpu) + 1;
+		if (tmp > nodes)
+			nodes++;
+	}
+	return nodes;
+}
+
+/* Defines used for sync_start */
+#define SKIP_GENERIC_SYNC 0
+#define SYNC_START_ERROR -1
+#define DO_GENERIC_SYNC 1
+
+struct	spu_overlay_info
+{
+	unsigned int vma;
+	unsigned int size;
+	unsigned int offset;
+	unsigned int buf;
+};
+
+struct vma_to_fileoffset_map
+{
+	struct vma_to_fileoffset_map *next;
+	unsigned int vma;
+	unsigned int size;
+	unsigned int offset;
+	unsigned int guard_ptr;
+	unsigned int guard_val;
+};
+
+/* The three functions below are for maintaining and accessing
+ * the vma-to-fileoffset map.
+ */
+struct vma_to_fileoffset_map *create_vma_map(const struct spu *spu,
+					     u64 objectid);
+unsigned int vma_map_lookup(struct vma_to_fileoffset_map *map,
+			    unsigned int vma, const struct spu *aSpu,
+			    int *grd_val);
+void vma_map_free(struct vma_to_fileoffset_map *map);
+
+/*
+ * Entry point for SPU profiling.
+ * cycles_reset is the SPU_CYCLES count value specified by the user.
+ */
+int start_spu_profiling(unsigned int cycles_reset);
+
+void stop_spu_profiling(void);
+
+
+/* add the necessary profiling hooks */
+int spu_sync_start(void);
+
+/* remove the hooks */
+int spu_sync_stop(void);
+
+/* Record SPU program counter samples to the oprofile event buffer. */
+void spu_sync_buffer(int spu_num, unsigned int *samples,
+		     int num_samples);
+
+void set_profiling_frequency(unsigned int freq_khz, unsigned int 
cycles_reset);
+
+#endif	  /* PR_UTIL_H */
Index: powerpc.git/arch/powerpc/oprofile/cell/spu_profiler.c
===================================================================
--- /dev/null
+++ powerpc.git/arch/powerpc/oprofile/cell/spu_profiler.c
@@ -0,0 +1,223 @@
+/*
+ * Cell Broadband Engine OProfile Support
+ *
+ * (C) Copyright IBM Corporation 2006
+ *
+ * Authors: Maynard Johnson <maynardj@us.ibm.com>
+ *	    Carl Love <carll@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/hrtimer.h>
+#include <linux/smp.h>
+#include <linux/slab.h>
+#include <asm/cell-pmu.h>
+/*#include <linux/time.h>*/
+#include "pr_util.h"
+
+#define TRACE_ARRAY_SIZE 1024
+#define SCALE_SHIFT 14
+
+static u32 *samples;
+
+static int spu_prof_running;
+static unsigned int profiling_interval;
+
+extern int spu_prof_num_nodes;
+
+
+#define NUM_SPU_BITS_TRBUF 16
+#define SPUS_PER_TB_ENTRY   4
+#define SPUS_PER_NODE	     8
+
+#define SPU_PC_MASK	     0xFFFF
+
+static DEFINE_SPINLOCK(sample_array_lock);
+unsigned long sample_array_lock_flags;
+
+void set_profiling_frequency(unsigned int freq_khz, unsigned int 
cycles_reset)
+{
+	unsigned long ns_per_cyc;
+	if (!freq_khz)
+		freq_khz = ppc_proc_freq/1000;
+
+	/* To calculate a timeout in nanoseconds, the basic
+	 * formula is ns = cycles_reset * (NSEC_PER_SEC / cpu frequency).
+	 * To avoid floating point math, we use the scale math
+	 * technique as described in linux/jiffies.h.  We use
+	 * a scale factor of SCALE_SHIFT, which provides 4 decimal places
+	 * of precision.  This is close enough for the purpose at hand.
+	 *
+	 * The value of the timeout should be small enough that the hw
+	 * trace buffer will not get more then about 1/3 full for the
+	 * maximum user specified (the LFSR value) hw sampling frequency.
+	 * This is to ensure the trace buffer will never fill even if the
+	 * kernel thread scheduling varies under a heavy system load.
+	 */
+
+	ns_per_cyc = (USEC_PER_SEC << SCALE_SHIFT)/freq_khz;
+	profiling_interval = (ns_per_cyc * cycles_reset) >> SCALE_SHIFT;
+
+}
+
+/*
+ * Extract SPU PC from trace buffer entry
+ */
+static void spu_pc_extract(int cpu, int entry)
+{
+	/* the trace buffer is 128 bits */
+	u64 trace_buffer[2];
+	u64 spu_mask;
+	int spu;
+
+	spu_mask = SPU_PC_MASK;
+
+	/* Each SPU PC is 16 bits; hence, four spus in each of
+	 * the two 64-bit buffer entries that make up the
+	 * 128-bit trace_buffer entry.	Process two 64-bit values
+	 * simultaneously.
+	 * trace[0] SPU PC contents are: 0 1 2 3
+	 * trace[1] SPU PC contents are: 4 5 6 7
+	 */
+
+	cbe_read_trace_buffer(cpu, trace_buffer);
+
+	for (spu = SPUS_PER_TB_ENTRY-1; spu >= 0; spu--) {
+		/* spu PC trace entry is upper 16 bits of the
+		 * 18 bit SPU program counter
+		 */
+		samples[spu * TRACE_ARRAY_SIZE + entry]
+			= (spu_mask & trace_buffer[0]) << 2;
+		samples[(spu + SPUS_PER_TB_ENTRY) * TRACE_ARRAY_SIZE + entry]
+			= (spu_mask & trace_buffer[1]) << 2;
+
+		trace_buffer[0] = trace_buffer[0] >> NUM_SPU_BITS_TRBUF;
+		trace_buffer[1] = trace_buffer[1] >> NUM_SPU_BITS_TRBUF;
+	}
+}
+
+static int cell_spu_pc_collection(int cpu)
+{
+	u32 trace_addr;
+	int entry;
+
+	/* process the collected SPU PC for the node */
+
+	entry = 0;
+
+	trace_addr = cbe_read_pm(cpu, trace_address);
+	while (!(trace_addr & CBE_PM_TRACE_BUF_EMPTY)) {
+		/* there is data in the trace buffer to process */
+		spu_pc_extract(cpu, entry);
+
+		entry++;
+
+		if (entry >= TRACE_ARRAY_SIZE)
+			/* spu_samples is full */
+			break;
+
+		trace_addr = cbe_read_pm(cpu, trace_address);
+	}
+
+	return(entry);
+}
+
+
+static enum hrtimer_restart profile_spus(struct hrtimer *timer)
+{
+	ktime_t kt;
+	int cpu, node, k, num_samples, spu_num;
+
+	if (!spu_prof_running)
+		goto stop;
+
+	for_each_online_cpu(cpu) {
+		if (cbe_get_hw_thread_id(cpu))
+			continue;
+
+		node = cbe_cpu_to_node(cpu);
+
+		/* There should only be one kernel thread at a time processing
+		 * the samples.	 In the very unlikely case that the processing
+		 * is taking a very long time and multiple kernel threads are
+		 * started to process the samples.  Make sure only one kernel
+		 * thread is working on the samples array at a time.  The
+		 * sample array must be loaded and then processed for a given
+		 * cpu.	 The sample array is not per cpu.
+		 */
+		spin_lock_irqsave(&sample_array_lock,
+				  sample_array_lock_flags);
+		num_samples = cell_spu_pc_collection(cpu);
+
+		if (num_samples == 0) {
+			spin_unlock_irqrestore(&sample_array_lock,
+					       sample_array_lock_flags);
+			continue;
+		}
+
+		for (k = 0; k < SPUS_PER_NODE; k++) {
+			spu_num = k + (node * SPUS_PER_NODE);
+			spu_sync_buffer(spu_num,
+					samples + (k * TRACE_ARRAY_SIZE),
+					num_samples);
+		}
+
+		spin_unlock_irqrestore(&sample_array_lock,
+				       sample_array_lock_flags);
+
+	}
+	smp_wmb();
+
+	kt = ktime_set(0, profiling_interval);
+	if (!spu_prof_running)
+		goto stop;
+	hrtimer_forward(timer, timer->base->get_time(), kt);
+	return HRTIMER_RESTART;
+
+ stop:
+	printk(KERN_INFO "SPU_PROF: spu-prof timer ending\n");
+	return HRTIMER_NORESTART;
+}
+
+static struct hrtimer timer;
+/*
+ * Entry point for SPU profiling.
+ * NOTE:  SPU profiling is done system-wide, not per-CPU.
+ *
+ * cycles_reset is the count value specified by the user when
+ * setting up OProfile to count SPU_CYCLES.
+ */
+int start_spu_profiling(unsigned int cycles_reset)
+{
+	ktime_t kt;
+
+	pr_debug("timer resolution: %lu\n", TICK_NSEC);
+	kt = ktime_set(0, profiling_interval);
+	hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	timer.expires = kt;
+	timer.function = profile_spus;
+
+	/* Allocate arrays for collecting SPU PC samples */
+	samples = kzalloc(SPUS_PER_NODE *
+			  TRACE_ARRAY_SIZE * sizeof(u32), GFP_KERNEL);
+
+	if (!samples)
+		return -ENOMEM;
+
+	spu_prof_running = 1;
+	hrtimer_start(&timer, kt, HRTIMER_MODE_REL);
+
+	return 0;
+}
+
+void stop_spu_profiling(void)
+{
+	spu_prof_running = 0;
+	hrtimer_cancel(&timer);
+	kfree(samples);
+	pr_debug("SPU_PROF: stop_spu_profiling issued\n");
+}
Index: powerpc.git/arch/powerpc/oprofile/cell/spu_task_sync.c
===================================================================
--- /dev/null
+++ powerpc.git/arch/powerpc/oprofile/cell/spu_task_sync.c
@@ -0,0 +1,465 @@
+/*
+ * Cell Broadband Engine OProfile Support
+ *
+ * (C) Copyright IBM Corporation 2006
+ *
+ * Author: Maynard Johnson <maynardj@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.
+ */
+
+/* The purpose of this file is to handle SPU event task switching
+ * and to record SPU context information into the OProfile
+ * event buffer.
+ *
+ * Additionally, the spu_sync_buffer function is provided as a helper
+ * for recoding actual SPU program counter samples to the event buffer.
+ */
+#include <linux/dcookies.h>
+#include <linux/kref.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/numa.h>
+#include <linux/oprofile.h>
+#include <linux/spinlock.h>
+#include "pr_util.h"
+
+#define RELEASE_ALL 9999
+
+static DEFINE_SPINLOCK(buffer_lock);
+static DEFINE_SPINLOCK(cache_lock);
+static int num_spu_nodes;
+int spu_prof_num_nodes;
+int last_guard_val[MAX_NUMNODES * 8];
+
+/* Container for caching information about an active SPU task. */
+struct cached_info {
+	struct vma_to_fileoffset_map *map;
+	struct spu *the_spu;	/* needed to access pointer to local_store */
+	struct kref cache_ref;
+};
+
+static struct cached_info *spu_info[MAX_NUMNODES * 8];
+
+static void destroy_cached_info(struct kref *kref)
+{
+	struct cached_info *info;
+
+	info = container_of(kref, struct cached_info, cache_ref);
+	vma_map_free(info->map);
+	kfree(info);
+	module_put(THIS_MODULE);
+}
+
+/* Return the cached_info for the passed SPU number.
+ * ATTENTION:  Callers are responsible for obtaining the
+ *	       cache_lock if needed prior to invoking this function.
+ */
+static struct cached_info *get_cached_info(struct spu *the_spu, int spu_num)
+{
+	struct kref *ref;
+	struct cached_info *ret_info;
+
+	if (spu_num >= num_spu_nodes) {
+		printk(KERN_ERR "SPU_PROF: "
+		       "%s, line %d: Invalid index %d into spu info cache\n",
+		       __FUNCTION__, __LINE__, spu_num);
+		ret_info = NULL;
+		goto out;
+	}
+	if (!spu_info[spu_num] && the_spu) {
+		ref = spu_get_profile_private_kref(the_spu->ctx);
+		if (ref) {
+			spu_info[spu_num] = container_of(ref, struct cached_info, cache_ref);
+			kref_get(&spu_info[spu_num]->cache_ref);
+		}
+	}
+
+	ret_info = spu_info[spu_num];
+ out:
+	return ret_info;
+}
+
+
+/* Looks for cached info for the passed spu.  If not found, the
+ * cached info is created for the passed spu.
+ * Returns 0 for success; otherwise, -1 for error.
+ */
+static int
+prepare_cached_spu_info(struct spu *spu, unsigned long objectId)
+{
+	unsigned long flags;
+	struct vma_to_fileoffset_map *new_map;
+	int retval = 0;
+	struct cached_info *info;
+
+	/* We won't bother getting cache_lock here since
+	 * don't do anything with the cached_info that's returned.
+	 */
+	info = get_cached_info(spu, spu->number);
+
+	if (info) {
+		pr_debug("Found cached SPU info.\n");
+		goto out;
+	}
+
+	/* Create cached_info and set spu_info[spu->number] to point to it.
+	 * spu->number is a system-wide value, not a per-node value.
+	 */
+	info = kzalloc(sizeof(struct cached_info), GFP_KERNEL);
+	if (!info) {
+		printk(KERN_ERR "SPU_PROF: "
+		       "%s, line %d: create vma_map failed\n",
+		       __FUNCTION__, __LINE__);
+		retval = -ENOMEM;
+		goto err_alloc;
+	}
+	new_map = create_vma_map(spu, objectId);
+	if (!new_map) {
+		printk(KERN_ERR "SPU_PROF: "
+		       "%s, line %d: create vma_map failed\n",
+		       __FUNCTION__, __LINE__);
+		retval = -ENOMEM;
+		goto err_alloc;
+	}
+
+	pr_debug("Created vma_map\n");
+	info->map = new_map;
+	info->the_spu = spu;
+	kref_init(&info->cache_ref);
+	spin_lock_irqsave(&cache_lock, flags);
+	spu_info[spu->number] = info;
+	/* Increment count before passing off ref to SPUFS. */
+	kref_get(&info->cache_ref);
+
+	/* We increment the module refcount here since SPUFS is
+	 * responsible for the final destruction of the cached_info,
+	 * and it must be able to access the destroy_cached_info()
+	 * function defined in the OProfile module.  We decrement
+	 * the module refcount in destroy_cached_info.
+	 */
+	try_module_get(THIS_MODULE);
+	spu_set_profile_private_kref(spu->ctx, &info->cache_ref,
+				destroy_cached_info);
+	spin_unlock_irqrestore(&cache_lock, flags);
+	goto out;
+
+err_alloc:
+	kfree(info);
+out:
+	return retval;
+}
+
+/*
+ * NOTE:  The caller is responsible for locking the
+ *	  cache_lock prior to calling this function.
+ */
+static int release_cached_info(int spu_index)
+{
+	int index, end;
+
+	if (spu_index == RELEASE_ALL) {
+		end = num_spu_nodes;
+		index = 0;
+	} else {
+		if (spu_index >= num_spu_nodes) {
+			printk(KERN_ERR "SPU_PROF: "
+				"%s, line %d: "
+				"Invalid index %d into spu info cache\n",
+				__FUNCTION__, __LINE__, spu_index);
+			goto out;
+		}
+		end = spu_index + 1;
+		index = spu_index;
+	}
+	for (; index < end; index++) {
+		if (spu_info[index]) {
+			kref_put(&spu_info[index]->cache_ref,
+				 destroy_cached_info);
+			spu_info[index] = NULL;
+		}
+	}
+
+out:
+	return 0;
+}
+
+/* The source code for fast_get_dcookie was "borrowed"
+ * from drivers/oprofile/buffer_sync.c.
+ */
+
+/* Optimisation. We can manage without taking the dcookie sem
+ * because we cannot reach this code without at least one
+ * dcookie user still being registered (namely, the reader
+ * of the event buffer).
+ */
+static inline unsigned long fast_get_dcookie(struct dentry *dentry,
+					     struct vfsmount *vfsmnt)
+{
+	unsigned long cookie;
+
+	if (dentry->d_cookie)
+		return (unsigned long)dentry;
+	get_dcookie(dentry, vfsmnt, &cookie);
+	return cookie;
+}
+
+/* Look up the dcookie for the task's first VM_EXECUTABLE mapping,
+ * which corresponds loosely to "application name". Also, determine
+ * the offset for the SPU ELF object.  If computed offset is
+ * non-zero, it implies an embedded SPU object; otherwise, it's a
+ * separate SPU binary, in which case we retrieve it's dcookie.
+ * For the embedded case, we must determine if SPU ELF is embedded
+ * in the executable application or another file (i.e., shared lib).
+ * If embedded in a shared lib, we must get the dcookie and return
+ * that to the caller.
+ */
+static unsigned long
+get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp,
+			    unsigned long *spu_bin_dcookie,
+			    unsigned long spu_ref)
+{
+	unsigned long app_cookie = 0;
+	unsigned int my_offset = 0;
+	struct file *app = NULL;
+	struct vm_area_struct *vma;
+	struct mm_struct *mm = spu->mm;
+
+	if (!mm)
+		goto out;
+
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		if (!vma->vm_file)
+			continue;
+		if (!(vma->vm_flags & VM_EXECUTABLE))
+			continue;
+		app_cookie = fast_get_dcookie(vma->vm_file->f_dentry,
+					  vma->vm_file->f_vfsmnt);
+		pr_debug("got dcookie for %s\n",
+			 vma->vm_file->f_dentry->d_name.name);
+		app = vma->vm_file;
+		break;
+	}
+
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		if (vma->vm_start > spu_ref || vma->vm_end <= spu_ref)
+			continue;
+		my_offset = spu_ref - vma->vm_start;
+		if (!vma->vm_file)
+			goto fail_no_image_cookie;
+
+		pr_debug("Found spu ELF at %X(object-id:%lx) for file %s\n",
+			 my_offset, spu_ref,
+			 vma->vm_file->f_dentry->d_name.name);
+		*offsetp = my_offset;
+		break;
+	}
+
+	*spu_bin_dcookie = fast_get_dcookie(vma->vm_file->f_dentry,
+						 vma->vm_file->f_vfsmnt);
+	pr_debug("got dcookie for %s\n", vma->vm_file->f_dentry->d_name.name);
+
+out:
+	return app_cookie;
+
+fail_no_image_cookie:
+	printk(KERN_ERR "SPU_PROF: "
+		"%s, line %d: Cannot find dcookie for SPU binary\n",
+		__FUNCTION__, __LINE__);
+	goto out;
+}
+
+
+
+/* This function finds or creates cached context information for the
+ * passed SPU and records SPU context information into the OProfile
+ * event buffer.
+ */
+static int process_context_switch(struct spu *spu, unsigned long objectId)
+{
+	unsigned long flags;
+	int retval;
+	unsigned int offset = 0;
+	unsigned long spu_cookie = 0, app_dcookie;
+
+	retval = prepare_cached_spu_info(spu, objectId);
+	if (retval)
+		goto out;
+
+	/* Get dcookie first because a mutex_lock is taken in that
+	 * code path, so interrupts must not be disabled.
+	 */
+	app_dcookie = get_exec_dcookie_and_offset(spu, &offset, &spu_cookie, 
objectId);
+	if (!app_dcookie || !spu_cookie) {
+		retval  = -ENOENT;
+		goto out;
+	}
+
+	/* Record context info in event buffer */
+	spin_lock_irqsave(&buffer_lock, flags);
+	add_event_entry(ESCAPE_CODE);
+	add_event_entry(SPU_CTX_SWITCH_CODE);
+	add_event_entry(spu->number);
+	add_event_entry(spu->pid);
+	add_event_entry(spu->tgid);
+	add_event_entry(app_dcookie);
+	add_event_entry(spu_cookie);
+	add_event_entry(offset);
+	spin_unlock_irqrestore(&buffer_lock, flags);
+	smp_wmb();
+out:
+	return retval;
+}
+
+/*
+ * This function is invoked on either a bind_context or unbind_context.
+ * If called for an unbind_context, the val arg is 0; otherwise,
+ * it is the object-id value for the spu context.
+ * The data arg is of type 'struct spu *'.
+ */
+static int spu_active_notify(struct notifier_block *self, unsigned long val,
+				void *data)
+{
+	int retval;
+	unsigned long flags;
+	struct spu *the_spu = data;
+
+	pr_debug("SPU event notification arrived\n");
+	if (!val) {
+		spin_lock_irqsave(&cache_lock, flags);
+		retval = release_cached_info(the_spu->number);
+		spin_unlock_irqrestore(&cache_lock, flags);
+	} else {
+		retval = process_context_switch(the_spu, val);
+	}
+	return retval;
+}
+
+static struct notifier_block spu_active = {
+	.notifier_call = spu_active_notify,
+};
+
+/* The main purpose of this function is to synchronize
+ * OProfile with SPUFS by registering to be notified of
+ * SPU task switches.
+ *
+ * NOTE: When profiling SPUs, we must ensure that only
+ * spu_sync_start is invoked and not the generic sync_start
+ * in drivers/oprofile/oprof.c.	 A return value of
+ * SKIP_GENERIC_SYNC or SYNC_START_ERROR will
+ * accomplish this.
+ */
+int spu_sync_start(void)
+{
+	int k;
+	int ret = SKIP_GENERIC_SYNC;
+	int register_ret;
+	unsigned long flags = 0;
+
+	spu_prof_num_nodes = number_of_online_nodes();
+	num_spu_nodes = spu_prof_num_nodes * 8;
+
+	spin_lock_irqsave(&buffer_lock, flags);
+	add_event_entry(ESCAPE_CODE);
+	add_event_entry(SPU_PROFILING_CODE);
+	add_event_entry(num_spu_nodes);
+	spin_unlock_irqrestore(&buffer_lock, flags);
+
+	/* Register for SPU events  */
+	register_ret = spu_switch_event_register(&spu_active);
+	if (register_ret) {
+		ret = SYNC_START_ERROR;
+		goto out;
+	}
+
+	for (k = 0; k < (MAX_NUMNODES * 8); k++)
+		last_guard_val[k] = 0;
+	pr_debug("spu_sync_start -- running.\n");
+out:
+	return ret;
+}
+
+/* Record SPU program counter samples to the oprofile event buffer. */
+void spu_sync_buffer(int spu_num, unsigned int *samples,
+		     int num_samples)
+{
+	unsigned long long file_offset;
+	unsigned long flags;
+	int i;
+	struct vma_to_fileoffset_map *map;
+	struct spu *the_spu;
+	unsigned long long spu_num_ll = spu_num;
+	unsigned long long spu_num_shifted = spu_num_ll << 32;
+	struct cached_info *c_info;
+
+	/* We need to obtain the cache_lock here because it's
+	 * possible that after getting the cached_info, the SPU job
+	 * corresponding to this cached_info may end, thus resulting
+	 * in the destruction of the cached_info.
+	 */
+	spin_lock_irqsave(&cache_lock, flags);
+	c_info = get_cached_info(NULL, spu_num);
+	if (!c_info) {
+		/* This legitimately happens when the SPU task ends before all
+		 * samples are recorded.
+		 * No big deal -- so we just drop a few samples.
+		 */
+		pr_debug("SPU_PROF: No cached SPU contex "
+			  "for SPU #%d. Dropping samples.\n", spu_num);
+		goto out;
+	}
+
+	map = c_info->map;
+	the_spu = c_info->the_spu;
+	spin_lock(&buffer_lock);
+	for (i = 0; i < num_samples; i++) {
+		unsigned int sample = *(samples+i);
+		int grd_val = 0;
+		file_offset = 0;
+		if (sample == 0)
+			continue;
+		file_offset = vma_map_lookup( map, sample, the_spu, &grd_val);
+
+		/* If overlays are used by this SPU application, the guard
+		 * value is non-zero, indicating which overlay section is in
+		 * use.	 We need to discard samples taken during the time
+		 * period which an overlay occurs (i.e., guard value changes).
+		 */
+		if (grd_val && grd_val != last_guard_val[spu_num]) {
+			last_guard_val[spu_num] = grd_val;
+			/* Drop the rest of the samples. */
+			break;
+		}
+
+		add_event_entry(file_offset | spu_num_shifted);
+	}
+	spin_unlock(&buffer_lock);
+out:
+	spin_unlock_irqrestore(&cache_lock, flags);
+}
+
+
+int spu_sync_stop(void)
+{
+	unsigned long flags = 0;
+	int ret = spu_switch_event_unregister(&spu_active);
+	if (ret) {
+		printk(KERN_ERR "SPU_PROF: "
+			"%s, line %d: spu_switch_event_unregister returned %d\n",
+			__FUNCTION__, __LINE__, ret);
+		goto out;
+	}
+
+	spin_lock_irqsave(&cache_lock, flags);
+	ret = release_cached_info(RELEASE_ALL);
+	spin_unlock_irqrestore(&cache_lock, flags);
+out:
+	pr_debug("spu_sync_stop -- done.\n");
+	return ret;
+}
+
+
Index: powerpc.git/arch/powerpc/oprofile/cell/vma_map.c
===================================================================
--- /dev/null
+++ powerpc.git/arch/powerpc/oprofile/cell/vma_map.c
@@ -0,0 +1,287 @@
+/*
+ * Cell Broadband Engine OProfile Support
+ *
+ * (C) Copyright IBM Corporation 2006
+ *
+ * Author: Maynard Johnson <maynardj@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.
+ */
+
+/* The code in this source file is responsible for generating
+ * vma-to-fileOffset maps for both overlay and non-overlay SPU
+ * applications.
+ */
+
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/elf.h>
+#include "pr_util.h"
+
+
+void vma_map_free(struct vma_to_fileoffset_map *map)
+{
+	while (map) {
+		struct vma_to_fileoffset_map *next = map->next;
+		kfree(map);
+		map = next;
+	}
+}
+
+unsigned int
+vma_map_lookup(struct vma_to_fileoffset_map *map, unsigned int vma,
+	       const struct spu *aSpu, int *grd_val)
+{
+	/*
+	 * Default the offset to the physical address + a flag value.
+	 * Addresses of dynamically generated code can't be found in the vma
+	 * map.  For those addresses the flagged value will be sent on to
+	 * the user space tools so they can be reported rather than just
+	 * thrown away.
+	 */
+	u32 offset = 0x10000000 + vma;
+	u32 ovly_grd;
+
+	for (; map; map = map->next) {
+		if (vma < map->vma || vma >= map->vma + map->size)
+			continue;
+
+		if (map->guard_ptr) {
+			ovly_grd = *(u32 *)(aSpu->local_store + map->guard_ptr);
+			if (ovly_grd != map->guard_val)
+				continue;
+			*grd_val = ovly_grd;
+		}
+		offset = vma - map->vma + map->offset;
+		break;
+	}
+
+	return offset;
+}
+
+static struct vma_to_fileoffset_map *
+vma_map_add(struct vma_to_fileoffset_map *map, unsigned int vma,
+	    unsigned int size, unsigned int offset, unsigned int guard_ptr,
+	    unsigned int guard_val)
+{
+	struct vma_to_fileoffset_map *new =
+		kzalloc(sizeof(struct vma_to_fileoffset_map), GFP_KERNEL);
+	if (!new) {
+		printk(KERN_ERR "SPU_PROF: %s, line %d: malloc failed\n",
+		       __FUNCTION__, __LINE__);
+		vma_map_free(map);
+		return NULL;
+	}
+
+	new->next = map;
+	new->vma = vma;
+	new->size = size;
+	new->offset = offset;
+	new->guard_ptr = guard_ptr;
+	new->guard_val = guard_val;
+
+	return new;
+}
+
+
+/* Parse SPE ELF header and generate a list of vma_maps.
+ * A pointer to the first vma_map in the generated list
+ * of vma_maps is returned.  */
+struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
+					     unsigned long spu_elf_start)
+{
+	static const unsigned char expected[EI_PAD] = {
+		[EI_MAG0] = ELFMAG0,
+		[EI_MAG1] = ELFMAG1,
+		[EI_MAG2] = ELFMAG2,
+		[EI_MAG3] = ELFMAG3,
+		[EI_CLASS] = ELFCLASS32,
+		[EI_DATA] = ELFDATA2MSB,
+		[EI_VERSION] = EV_CURRENT,
+		[EI_OSABI] = ELFOSABI_NONE
+	};
+
+	int grd_val;
+	struct vma_to_fileoffset_map *map = NULL;
+	struct spu_overlay_info ovly;
+	unsigned int overlay_tbl_offset = -1;
+	unsigned long phdr_start, shdr_start;
+	Elf32_Ehdr ehdr;
+	Elf32_Phdr phdr;
+	Elf32_Shdr shdr, shdr_str;
+	Elf32_Sym sym;
+	int i, j;
+	char name[32];
+
+	unsigned int ovly_table_sym = 0;
+	unsigned int ovly_buf_table_sym = 0;
+	unsigned int ovly_table_end_sym = 0;
+	unsigned int ovly_buf_table_end_sym = 0;
+	unsigned long ovly_table;
+	unsigned int n_ovlys;
+
+	/* Get and validate ELF header.	 */
+
+	if (copy_from_user(&ehdr, (void *) spu_elf_start, sizeof (ehdr)))
+		goto fail;
+
+	if (memcmp(ehdr.e_ident, expected, EI_PAD) != 0) {
+		printk(KERN_ERR "SPU_PROF: "
+		       "%s, line %d: Unexpected e_ident parsing SPU ELF\n",
+		       __FUNCTION__, __LINE__);
+		goto fail;
+	}
+	if (ehdr.e_machine != EM_SPU) {
+		printk(KERN_ERR "SPU_PROF: "
+		       "%s, line %d: Unexpected e_machine parsing SPU ELF\n",
+		       __FUNCTION__,  __LINE__);
+		goto fail;
+	}
+	if (ehdr.e_type != ET_EXEC) {
+		printk(KERN_ERR "SPU_PROF: "
+		       "%s, line %d: Unexpected e_type parsing SPU ELF\n",
+		       __FUNCTION__, __LINE__);
+		goto fail;
+	}
+	phdr_start = spu_elf_start + ehdr.e_phoff;
+	shdr_start = spu_elf_start + ehdr.e_shoff;
+
+	/* Traverse program headers.  */
+	for (i = 0; i < ehdr.e_phnum; i++) {
+		if (copy_from_user(&phdr,
+				   (void *) (phdr_start + i * sizeof(phdr)),
+				   sizeof(phdr)))
+			goto fail;
+
+		if (phdr.p_type != PT_LOAD)
+			continue;
+		if (phdr.p_flags & (1 << 27))
+			continue;
+
+		map = vma_map_add(map, phdr.p_vaddr, phdr.p_memsz,
+				  phdr.p_offset, 0, 0);
+		if (!map)
+			goto fail;
+	}
+
+	pr_debug("SPU_PROF: Created non-overlay maps\n");
+	/* Traverse section table and search for overlay-related symbols.  */
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		if (copy_from_user(&shdr,
+				   (void *) (shdr_start + i * sizeof(shdr)),
+				   sizeof(shdr)))
+			goto fail;
+
+		if (shdr.sh_type != SHT_SYMTAB)
+			continue;
+		if (shdr.sh_entsize != sizeof (sym))
+			continue;
+
+		if (copy_from_user(&shdr_str,
+				   (void *) (shdr_start + shdr.sh_link *
+					     sizeof(shdr)),
+				   sizeof(shdr)))
+			goto fail;
+
+		if (shdr_str.sh_type != SHT_STRTAB)
+			goto fail;;
+
+		for (j = 0; j < shdr.sh_size / sizeof (sym); j++) {
+			if (copy_from_user(&sym, (void *) (spu_elf_start +
+						       shdr.sh_offset + j *
+							   sizeof (sym)),
+					   sizeof (sym)))
+				goto fail;
+
+			if (copy_from_user(name, (void *)
+					   (spu_elf_start + shdr_str.sh_offset +
+					    sym.st_name),
+					   20))
+				goto fail;
+
+			if (memcmp(name, "_ovly_table", 12) == 0)
+				ovly_table_sym = sym.st_value;
+			if (memcmp(name, "_ovly_buf_table", 16) == 0)
+				ovly_buf_table_sym = sym.st_value;
+			if (memcmp(name, "_ovly_table_end", 16) == 0)
+				ovly_table_end_sym = sym.st_value;
+			if (memcmp(name, "_ovly_buf_table_end", 20) == 0)
+				ovly_buf_table_end_sym = sym.st_value;
+		}
+	}
+
+	/* If we don't have overlays, we're done.  */
+	if (ovly_table_sym == 0 || ovly_buf_table_sym == 0
+	    || ovly_table_end_sym == 0 || ovly_buf_table_end_sym == 0) {
+		pr_debug("SPU_PROF: No overlay table found\n");
+		goto out;
+	} else {
+		pr_debug("SPU_PROF: Overlay table found\n");
+	}
+
+	/* The _ovly_table symbol represents a table with one entry
+	 * per overlay section.	 The _ovly_buf_table symbol represents
+	 * a table with one entry per overlay region.
+	 * The struct spu_overlay_info gives the structure of the _ovly_table
+	 * entries.  The structure of _ovly_table_buf is simply one
+	 * u32 word per entry.
+	 */
+	overlay_tbl_offset = vma_map_lookup(map, ovly_table_sym,
+					    aSpu, &grd_val);
+	if (overlay_tbl_offset < 0) {
+		printk(KERN_ERR "SPU_PROF: "
+		       "%s, line %d: Error finding SPU overlay table\n",
+		       __FUNCTION__, __LINE__);
+		goto fail;
+	}
+	ovly_table = spu_elf_start + overlay_tbl_offset;
+
+	n_ovlys = (ovly_table_end_sym -
+		   ovly_table_sym) / sizeof (ovly);
+
+	/* Traverse overlay table.  */
+	for (i = 0; i < n_ovlys; i++) {
+		if (copy_from_user(&ovly, (void *)
+				   (ovly_table + i * sizeof (ovly)),
+				   sizeof (ovly)))
+			goto fail;
+
+		/* The ovly.vma/size/offset arguments are analogous to the same
+		 * arguments used above for non-overlay maps.  The final two
+		 * args are referred to as the guard pointer and the guard
+		 * value.
+		 * The guard pointer is an entry in the _ovly_buf_table,
+		 * computed using ovly.buf as the index into the table.	 Since
+		 * ovly.buf values begin at '1' to reference the first (or 0th)
+		 * entry in the _ovly_buf_table, the computation subtracts 1
+		 * from ovly.buf.
+		 * The guard value is stored in the _ovly_buf_table entry and
+		 * is an index (starting at 1) back to the _ovly_table entry
+		 * that is pointing at this _ovly_buf_table entry.  So, for
+		 * example, for an overlay scenario with one overlay segment
+		 * and two overlay sections:
+		 *	- Section 1 points to the first entry of the
+		 *	  _ovly_buf_table, which contains a guard value
+		 *	  of '1', referencing the first (index=0) entry of
+		 *	  _ovly_table.
+		 *	- Section 2 points to the second entry of the
+		 *	  _ovly_buf_table, which contains a guard value
+		 *	  of '2', referencing the second (index=1) entry of
+		 *	  _ovly_table.
+		 */
+		map = vma_map_add(map, ovly.vma, ovly.size, ovly.offset,
+				  ovly_buf_table_sym + (ovly.buf-1) * 4, i+1);
+		if (!map)
+			goto fail;
+	}
+	goto out;
+
+ fail:
+	map = NULL;
+ out:
+	return map;
+}
Index: powerpc.git/arch/powerpc/oprofile/common.c
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/common.c
+++ powerpc.git/arch/powerpc/oprofile/common.c
@@ -29,6 +29,8 @@ static struct op_powerpc_model *model;
 static struct op_counter_config ctr[OP_MAX_COUNTER];
 static struct op_system_config sys;
 
+static int op_per_cpu_rc;
+
 static void op_handle_interrupt(struct pt_regs *regs)
 {
 	model->handle_interrupt(regs, ctr);
@@ -36,25 +38,41 @@ static void op_handle_interrupt(struct p
 
 static void op_powerpc_cpu_setup(void *dummy)
 {
-	model->cpu_setup(ctr);
+	int ret;
+
+	ret = model->cpu_setup(ctr);
+
+	if (ret != 0)
+		op_per_cpu_rc = ret;
 }
 
 static int op_powerpc_setup(void)
 {
 	int err;
 
+	op_per_cpu_rc = 0;
+
 	/* Grab the hardware */
 	err = reserve_pmc_hardware(op_handle_interrupt);
 	if (err)
 		return err;
 
 	/* Pre-compute the values to stuff in the hardware registers.  */
-	model->reg_setup(ctr, &sys, model->num_counters);
+	op_per_cpu_rc = model->reg_setup(ctr, &sys, model->num_counters);
 
-	/* Configure the registers on all cpus.  */
+	if (op_per_cpu_rc)
+		goto out;
+
+	/* Configure the registers on all cpus.	 If an error occurs on one
+	 * of the cpus, op_per_cpu_rc will be set to the error */
 	on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1);
 
-	return 0;
+out:	if (op_per_cpu_rc) {
+		/* error on setup release the performance counter hardware */
+		release_pmc_hardware();
+	}
+
+	return op_per_cpu_rc;
 }
 
 static void op_powerpc_shutdown(void)
@@ -64,16 +82,29 @@ static void op_powerpc_shutdown(void)
 
 static void op_powerpc_cpu_start(void *dummy)
 {
-	model->start(ctr);
+	/* If any of the cpus have return an error, set the
+	 * global flag to the error so it can be returned
+	 * to the generic OProfile caller.
+	 */
+	int ret;
+
+	ret = model->start(ctr);
+	if (ret != 0)
+		op_per_cpu_rc = ret;
 }
 
 static int op_powerpc_start(void)
 {
+	op_per_cpu_rc = 0;
+
 	if (model->global_start)
-		model->global_start(ctr);
-	if (model->start)
+		return model->global_start(ctr);
+	if (model->start) {
 		on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
-	return 0;
+		return op_per_cpu_rc;
+	}
+	return -EIO; /* No start function is defined for this
+			power architecture */
 }
 
 static inline void op_powerpc_cpu_stop(void *dummy)
@@ -147,11 +178,13 @@ int __init oprofile_arch_init(struct opr
 
 	switch (cur_cpu_spec->oprofile_type) {
 #ifdef CONFIG_PPC64
-#ifdef CONFIG_PPC_CELL_NATIVE
+#ifdef CONFIG_OPROFILE_CELL
 		case PPC_OPROFILE_CELL:
 			if (firmware_has_feature(FW_FEATURE_LPAR))
 				return -ENODEV;
 			model = &op_model_cell;
+			ops->sync_start = model->sync_start;
+			ops->sync_stop = model->sync_stop;
 			break;
 #endif
 		case PPC_OPROFILE_RS64:
Index: powerpc.git/arch/powerpc/oprofile/Kconfig
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/Kconfig
+++ powerpc.git/arch/powerpc/oprofile/Kconfig
@@ -15,3 +15,10 @@ config OPROFILE
 
 	  If unsure, say N.
 
+config OPROFILE_CELL
+	bool "OProfile for Cell Broadband Engine"
+	depends on (SPU_FS = y && OPROFILE = m) || (SPU_FS = y && OPROFILE = y) || 
(SPU_FS = m && OPROFILE = m)
+	default y
+	help
+	  Profiling of Cell BE SPUs requires special support enabled
+	  by this option.
Index: powerpc.git/arch/powerpc/oprofile/Makefile
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/Makefile
+++ powerpc.git/arch/powerpc/oprofile/Makefile
@@ -11,7 +11,9 @@ DRIVER_OBJS := $(addprefix ../../../driv
 		timer_int.o )
 
 oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
-oprofile-$(CONFIG_PPC_CELL_NATIVE) += op_model_cell.o
+oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \
+		cell/spu_profiler.o cell/vma_map.o \
+		cell/spu_task_sync.o
 oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o op_model_pa6t.o
 oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
 oprofile-$(CONFIG_6xx) += op_model_7450.o
Index: powerpc.git/arch/powerpc/oprofile/op_model_cell.c
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/op_model_cell.c
+++ powerpc.git/arch/powerpc/oprofile/op_model_cell.c
@@ -5,8 +5,8 @@
  *
  * Author: David Erb (djerb@us.ibm.com)
  * Modifications:
- *         Carl Love <carll@us.ibm.com>
- *         Maynard Johnson <maynardj@us.ibm.com>
+ *	   Carl Love <carll@us.ibm.com>
+ *	   Maynard Johnson <maynardj@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
@@ -38,12 +38,25 @@
 
 #include "../platforms/cell/interrupt.h"
 #include "../platforms/cell/cbe_regs.h"
+#include "cell/pr_util.h"
+
+static void cell_global_stop_spu(void);
+
+/*
+ * spu_cycle_reset is the number of cycles between samples.
+ * This variable is used for SPU profiling and should ONLY be set
+ * at the beginning of cell_reg_setup; otherwise, it's read-only.
+ */
+static unsigned int spu_cycle_reset;
+
+#define NUM_SPUS_PER_NODE    8
+#define SPU_CYCLES_EVENT_NUM 2	/*  event number for SPU_CYCLES */
 
 #define PPU_CYCLES_EVENT_NUM 1	/*  event number for CYCLES */
-#define PPU_CYCLES_GRP_NUM   1  /* special group number for identifying
-                                 * PPU_CYCLES event
-                                 */
-#define CBE_COUNT_ALL_CYCLES 0x42800000	/* PPU cycle event specifier */
+#define PPU_CYCLES_GRP_NUM   1	/* special group number for identifying
+				 * PPU_CYCLES event
+				 */
+#define CBE_COUNT_ALL_CYCLES 0x42800000 /* PPU cycle event specifier */
 
 #define NUM_THREADS 2         /* number of physical threads in
 			       * physical processor
@@ -51,6 +64,7 @@
 #define NUM_TRACE_BUS_WORDS 4
 #define NUM_INPUT_BUS_WORDS 2
 
+#define MAX_SPU_COUNT 0xFFFFFF	/* maximum 24 bit LFSR value */
 
 struct pmc_cntrl_data {
 	unsigned long vcntr;
@@ -62,11 +76,10 @@ struct pmc_cntrl_data {
 /*
  * ibm,cbe-perftools rtas parameters
  */
-
 struct pm_signal {
 	u16 cpu;		/* Processor to modify */
-	u16 sub_unit;		/* hw subunit this applies to (if applicable) */
-	short int signal_group;	/* Signal Group to Enable/Disable */
+	u16 sub_unit;		/* hw subunit this applies to (if applicable)*/
+	short int signal_group; /* Signal Group to Enable/Disable */
 	u8 bus_word;		/* Enable/Disable on this Trace/Trigger/Event
 				 * Bus Word(s) (bitmask)
 				 */
@@ -112,21 +125,42 @@ static DEFINE_PER_CPU(unsigned long[NR_P
 
 static struct pmc_cntrl_data pmc_cntrl[NUM_THREADS][NR_PHYS_CTRS];
 
-/* Interpetation of hdw_thread:
+/*
+ * The CELL profiling code makes rtas calls to setup the debug bus to
+ * route the performance signals.  Additionally, SPU profiling requires
+ * a second rtas call to setup the hardware to capture the SPU PCs.
+ * The EIO error value is returned if the token lookups or the rtas
+ * call fail.  The EIO error number is the best choice of the existing
+ * error numbers.  The probability of rtas related error is very low.  But
+ * by returning EIO and printing additional information to dmsg the user
+ * will know that OProfile did not start and dmesg will tell them why.
+ * OProfile does not support returning errors on Stop.	Not a huge issue
+ * since failure to reset the debug bus or stop the SPU PC collection is
+ * not a fatel issue.  Chances are if the Stop failed, Start doesn't work
+ * either.
+ */
+
+/*
+ * Interpetation of hdw_thread:
  * 0 - even virtual cpus 0, 2, 4,...
  * 1 - odd virtual cpus 1, 3, 5, ...
+ *
+ * FIXME: this is strictly wrong, we need to clean this up in a number
+ * of places. It works for now. -arnd
  */
 static u32 hdw_thread;
 
 static u32 virt_cntr_inter_mask;
 static struct timer_list timer_virt_cntr;
 
-/* pm_signal needs to be global since it is initialized in
+/*
+ * pm_signal needs to be global since it is initialized in
  * cell_reg_setup at the time when the necessary information
  * is available.
  */
 static struct pm_signal pm_signal[NR_PHYS_CTRS];
-static int pm_rtas_token;
+static int pm_rtas_token;    /* token for debug bus setup call */
+static int spu_rtas_token;   /* token for SPU cycle profiling */
 
 static u32 reset_value[NR_PHYS_CTRS];
 static int num_counters;
@@ -147,8 +181,8 @@ rtas_ibm_cbe_perftools(int subfunc, int 
 {
 	u64 paddr = __pa(address);
 
-	return rtas_call(pm_rtas_token, 5, 1, NULL, subfunc, passthru,
-			 paddr >> 32, paddr & 0xffffffff, length);
+	return rtas_call(pm_rtas_token, 5, 1, NULL, subfunc,
+			 passthru, paddr >> 32, paddr & 0xffffffff, length);
 }
 
 static void pm_rtas_reset_signals(u32 node)
@@ -156,12 +190,13 @@ static void pm_rtas_reset_signals(u32 no
 	int ret;
 	struct pm_signal pm_signal_local;
 
-	/*  The debug bus is being set to the passthru disable state.
-	 *  However, the FW still expects atleast one legal signal routing
-	 *  entry or it will return an error on the arguments.  If we don't
-	 *  supply a valid entry, we must ignore all return values.  Ignoring
-	 *  all return values means we might miss an error we should be
-	 *  concerned about.
+	/*
+	 * The debug bus is being set to the passthru disable state.
+	 * However, the FW still expects atleast one legal signal routing
+	 * entry or it will return an error on the arguments.	If we don't
+	 * supply a valid entry, we must ignore all return values.  Ignoring
+	 * all return values means we might miss an error we should be
+	 * concerned about.
 	 */
 
 	/*  fw expects physical cpu #. */
@@ -175,18 +210,24 @@ static void pm_rtas_reset_signals(u32 no
 				     &pm_signal_local,
 				     sizeof(struct pm_signal));
 
-	if (ret)
+	if (unlikely(ret))
+		/*
+		 * Not a fatal error. For Oprofile stop, the oprofile
+		 * functions do not support returning an error for
+		 * failure to stop OProfile.
+		 */
 		printk(KERN_WARNING "%s: rtas returned: %d\n",
 		       __FUNCTION__, ret);
 }
 
-static void pm_rtas_activate_signals(u32 node, u32 count)
+static int pm_rtas_activate_signals(u32 node, u32 count)
 {
 	int ret;
 	int i, j;
 	struct pm_signal pm_signal_local[NR_PHYS_CTRS];
 
-	/* There is no debug setup required for the cycles event.
+	/*
+	 * There is no debug setup required for the cycles event.
 	 * Note that only events in the same group can be used.
 	 * Otherwise, there will be conflicts in correctly routing
 	 * the signals on the debug bus.  It is the responsiblity
@@ -213,10 +254,14 @@ static void pm_rtas_activate_signals(u32
 					     pm_signal_local,
 					     i * sizeof(struct pm_signal));
 
-		if (ret)
+		if (unlikely(ret)) {
 			printk(KERN_WARNING "%s: rtas returned: %d\n",
 			       __FUNCTION__, ret);
+			return -EIO;
+		}
 	}
+
+	return 0;
 }
 
 /*
@@ -260,11 +305,12 @@ static void set_pm_event(u32 ctr, int ev
 	pm_regs.pm07_cntrl[ctr] |= PM07_CTR_POLARITY(polarity);
 	pm_regs.pm07_cntrl[ctr] |= PM07_CTR_INPUT_CONTROL(input_control);
 
-	/* Some of the islands signal selection is based on 64 bit words.
+	/*
+	 * Some of the islands signal selection is based on 64 bit words.
 	 * The debug bus words are 32 bits, the input words to the performance
 	 * counters are defined as 32 bits.  Need to convert the 64 bit island
 	 * specification to the appropriate 32 input bit and bus word for the
-	 * performance counter event selection.  See the CELL Performance
+	 * performance counter event selection.	 See the CELL Performance
 	 * monitoring signals manual and the Perf cntr hardware descriptions
 	 * for the details.
 	 */
@@ -298,6 +344,7 @@ static void set_pm_event(u32 ctr, int ev
 					input_bus[j] = i;
 					pm_regs.group_control |=
 					    (i << (31 - i));
+
 					break;
 				}
 			}
@@ -309,7 +356,8 @@ out:
 
 static void write_pm_cntrl(int cpu)
 {
-	/* Oprofile will use 32 bit counters, set bits 7:10 to 0
+	/*
+	 * Oprofile will use 32 bit counters, set bits 7:10 to 0
 	 * pmregs.pm_cntrl is a global
 	 */
 
@@ -326,7 +374,8 @@ static void write_pm_cntrl(int cpu)
 	if (pm_regs.pm_cntrl.freeze == 1)
 		val |= CBE_PM_FREEZE_ALL_CTRS;
 
-	/* Routine set_count_mode must be called previously to set
+	/*
+	 * Routine set_count_mode must be called previously to set
 	 * the count mode based on the user selection of user and kernel.
 	 */
 	val |= CBE_PM_COUNT_MODE_SET(pm_regs.pm_cntrl.count_mode);
@@ -336,7 +385,8 @@ static void write_pm_cntrl(int cpu)
 static inline void
 set_count_mode(u32 kernel, u32 user)
 {
-	/* The user must specify user and kernel if they want them. If
+	/*
+	 * The user must specify user and kernel if they want them. If
 	 *  neither is specified, OProfile will count in hypervisor mode.
 	 *  pm_regs.pm_cntrl is a global
 	 */
@@ -364,7 +414,7 @@ static inline void enable_ctr(u32 cpu, u
 
 /*
  * Oprofile is expected to collect data on all CPUs simultaneously.
- * However, there is one set of performance counters per node.  There are
+ * However, there is one set of performance counters per node.	There are
  * two hardware threads or virtual CPUs on each node.  Hence, OProfile must
  * multiplex in time the performance counter collection on the two virtual
  * CPUs.  The multiplexing of the performance counters is done by this
@@ -377,19 +427,19 @@ static inline void enable_ctr(u32 cpu, u
  * pair of per-cpu arrays is used for storing the previous and next
  * pmc values for a given node.
  * NOTE: We use the per-cpu variable to improve cache performance.
+ *
+ * This routine will alternate loading the virtual counters for
+ * virtual CPUs
  */
 static void cell_virtual_cntr(unsigned long data)
 {
-	/* This routine will alternate loading the virtual counters for
-	 * virtual CPUs
-	 */
 	int i, prev_hdw_thread, next_hdw_thread;
 	u32 cpu;
 	unsigned long flags;
 
-	/* Make sure that the interrupt_hander and
-	 * the virt counter are not both playing with
-	 * the counters on the same node.
+	/*
+	 * Make sure that the interrupt_hander and the virt counter are
+	 * not both playing with the counters on the same node.
 	 */
 
 	spin_lock_irqsave(&virt_cntr_lock, flags);
@@ -400,22 +450,25 @@ static void cell_virtual_cntr(unsigned l
 	hdw_thread = 1 ^ hdw_thread;
 	next_hdw_thread = hdw_thread;
 
-	for (i = 0; i < num_counters; i++)
-	/* There are some per thread events.  Must do the
+	/*
+	 * There are some per thread events.  Must do the
 	 * set event, for the thread that is being started
 	 */
+	for (i = 0; i < num_counters; i++)
 		set_pm_event(i,
 			pmc_cntrl[next_hdw_thread][i].evnts,
 			pmc_cntrl[next_hdw_thread][i].masks);
 
-	/* The following is done only once per each node, but
+	/*
+	 * The following is done only once per each node, but
 	 * we need cpu #, not node #, to pass to the cbe_xxx functions.
 	 */
 	for_each_online_cpu(cpu) {
 		if (cbe_get_hw_thread_id(cpu))
 			continue;
 
-		/* stop counters, save counter values, restore counts
+		/*
+		 * stop counters, save counter values, restore counts
 		 * for previous thread
 		 */
 		cbe_disable_pm(cpu);
@@ -428,7 +481,7 @@ static void cell_virtual_cntr(unsigned l
 			    == 0xFFFFFFFF)
 				/* If the cntr value is 0xffffffff, we must
 				 * reset that to 0xfffffff0 when the current
-				 * thread is restarted.  This will generate a
+				 * thread is restarted.	 This will generate a
 				 * new interrupt and make sure that we never
 				 * restore the counters to the max value.  If
 				 * the counters were restored to the max value,
@@ -444,13 +497,15 @@ static void cell_virtual_cntr(unsigned l
 						      next_hdw_thread)[i]);
 		}
 
-		/* Switch to the other thread. Change the interrupt
+		/*
+		 * Switch to the other thread. Change the interrupt
 		 * and control regs to be scheduled on the CPU
 		 * corresponding to the thread to execute.
 		 */
 		for (i = 0; i < num_counters; i++) {
 			if (pmc_cntrl[next_hdw_thread][i].enabled) {
-				/* There are some per thread events.
+				/*
+				 * There are some per thread events.
 				 * Must do the set event, enable_cntr
 				 * for each cpu.
 				 */
@@ -482,17 +537,42 @@ static void start_virt_cntrs(void)
 }
 
 /* This function is called once for all cpus combined */
-static void
-cell_reg_setup(struct op_counter_config *ctr,
-	       struct op_system_config *sys, int num_ctrs)
+static int cell_reg_setup(struct op_counter_config *ctr,
+			struct op_system_config *sys, int num_ctrs)
 {
 	int i, j, cpu;
+	spu_cycle_reset = 0;
+
+	if (ctr[0].event == SPU_CYCLES_EVENT_NUM) {
+		spu_cycle_reset = ctr[0].count;
+
+		/*
+		 * Each node will need to make the rtas call to start
+		 * and stop SPU profiling.  Get the token once and store it.
+		 */
+		spu_rtas_token = rtas_token("ibm,cbe-spu-perftools");
+
+		if (unlikely(spu_rtas_token == RTAS_UNKNOWN_SERVICE)) {
+			printk(KERN_ERR
+			       "%s: rtas token ibm,cbe-spu-perftools unknown\n",
+			       __FUNCTION__);
+			return -EIO;
+		}
+	}
 
 	pm_rtas_token = rtas_token("ibm,cbe-perftools");
-	if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) {
-		printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n",
+
+	/*
+	 * For all events excetp PPU CYCLEs, each node will need to make
+	 * the rtas cbe-perftools call to setup and reset the debug bus.
+	 * Make the token lookup call once and store it in the global
+	 * variable pm_rtas_token.
+	 */
+	if (unlikely(pm_rtas_token == RTAS_UNKNOWN_SERVICE)) {
+		printk(KERN_ERR
+		       "%s: rtas token ibm,cbe-perftools unknown\n",
 		       __FUNCTION__);
-		goto out;
+		return -EIO;
 	}
 
 	num_counters = num_ctrs;
@@ -520,7 +600,8 @@ cell_reg_setup(struct op_counter_config 
 			per_cpu(pmc_values, j)[i] = 0;
 	}
 
-	/* Setup the thread 1 events, map the thread 0 event to the
+	/*
+	 * Setup the thread 1 events, map the thread 0 event to the
 	 * equivalent thread 1 event.
 	 */
 	for (i = 0; i < num_ctrs; ++i) {
@@ -544,9 +625,10 @@ cell_reg_setup(struct op_counter_config 
 	for (i = 0; i < NUM_INPUT_BUS_WORDS; i++)
 		input_bus[i] = 0xff;
 
-	/* Our counters count up, and "count" refers to
+	/*
+	 * Our counters count up, and "count" refers to
 	 * how much before the next interrupt, and we interrupt
-	 * on overflow.  So we calculate the starting value
+	 * on overflow.	 So we calculate the starting value
 	 * which will give us "count" until overflow.
 	 * Then we set the events on the enabled counters.
 	 */
@@ -569,28 +651,27 @@ cell_reg_setup(struct op_counter_config 
 		for (i = 0; i < num_counters; ++i) {
 			per_cpu(pmc_values, cpu)[i] = reset_value[i];
 		}
-out:
-	;
+
+	return 0;
 }
 
+
+
 /* This function is called once for each cpu */
-static void cell_cpu_setup(struct op_counter_config *cntr)
+static int cell_cpu_setup(struct op_counter_config *cntr)
 {
 	u32 cpu = smp_processor_id();
 	u32 num_enabled = 0;
 	int i;
 
+	if (spu_cycle_reset)
+		return 0;
+
 	/* There is one performance monitor per processor chip (i.e. node),
 	 * so we only need to perform this function once per node.
 	 */
 	if (cbe_get_hw_thread_id(cpu))
-		goto out;
-
-	if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) {
-		printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n",
-		       __FUNCTION__);
-		goto out;
-	}
+		return 0;
 
 	/* Stop all counters */
 	cbe_disable_pm(cpu);
@@ -609,16 +690,286 @@ static void cell_cpu_setup(struct op_cou
 		}
 	}
 
-	pm_rtas_activate_signals(cbe_cpu_to_node(cpu), num_enabled);
+	/*
+	 * The pm_rtas_activate_signals will return -EIO if the FW
+	 * call failed.
+	 */
+	return pm_rtas_activate_signals(cbe_cpu_to_node(cpu), num_enabled);
+}
+
+#define ENTRIES	 303
+#define MAXLFSR	 0xFFFFFF
+
+/* precomputed table of 24 bit LFSR values */
+static int initial_lfsr[] = {
+ 8221349, 12579195, 5379618, 10097839, 7512963, 7519310, 3955098, 10753424,
+ 15507573, 7458917, 285419, 2641121, 9780088, 3915503, 6668768, 1548716,
+ 4885000, 8774424, 9650099, 2044357, 2304411, 9326253, 10332526, 4421547,
+ 3440748, 10179459, 13332843, 10375561, 1313462, 8375100, 5198480, 6071392,
+ 9341783, 1526887, 3985002, 1439429, 13923762, 7010104, 11969769, 4547026,
+ 2040072, 4025602, 3437678, 7939992, 11444177, 4496094, 9803157, 10745556,
+ 3671780, 4257846, 5662259, 13196905, 3237343, 12077182, 16222879, 7587769,
+ 14706824, 2184640, 12591135, 10420257, 7406075, 3648978, 11042541, 15906893,
+ 11914928, 4732944, 10695697, 12928164, 11980531, 4430912, 11939291, 2917017,
+ 6119256, 4172004, 9373765, 8410071, 14788383, 5047459, 5474428, 1737756,
+ 15967514, 13351758, 6691285, 8034329, 2856544, 14394753, 11310160, 12149558,
+ 7487528, 7542781, 15668898, 12525138, 12790975, 3707933, 9106617, 1965401,
+ 16219109, 12801644, 2443203, 4909502, 8762329, 3120803, 6360315, 9309720,
+ 15164599, 10844842, 4456529, 6667610, 14924259, 884312, 6234963, 3326042,
+ 15973422, 13919464, 5272099, 6414643, 3909029, 2764324, 5237926, 4774955,
+ 10445906, 4955302, 5203726, 10798229, 11443419, 2303395, 333836, 9646934,
+ 3464726, 4159182, 568492, 995747, 10318756, 13299332, 4836017, 8237783,
+ 3878992, 2581665, 11394667, 5672745, 14412947, 3159169, 9094251, 16467278,
+ 8671392, 15230076, 4843545, 7009238, 15504095, 1494895, 9627886, 14485051,
+ 8304291, 252817, 12421642, 16085736, 4774072, 2456177, 4160695, 15409741,
+ 4902868, 5793091, 13162925, 16039714, 782255, 11347835, 14884586, 366972,
+ 16308990, 11913488, 13390465, 2958444, 10340278, 1177858, 1319431, 10426302,
+ 2868597, 126119, 5784857, 5245324, 10903900, 16436004, 3389013, 1742384,
+ 14674502, 10279218, 8536112, 10364279, 6877778, 14051163, 1025130, 6072469,
+ 1988305, 8354440, 8216060, 16342977, 13112639, 3976679, 5913576, 8816697,
+ 6879995, 14043764, 3339515, 9364420, 15808858, 12261651, 2141560, 5636398,
+ 10345425, 10414756, 781725, 6155650, 4746914, 5078683, 7469001, 6799140,
+ 10156444, 9667150, 10116470, 4133858, 2121972, 1124204, 1003577, 1611214,
+ 14304602, 16221850, 13878465, 13577744, 3629235, 8772583, 10881308, 2410386,
+ 7300044, 5378855, 9301235, 12755149, 4977682, 8083074, 10327581, 6395087,
+ 9155434, 15501696, 7514362, 14520507, 15808945, 3244584, 4741962, 9658130,
+ 14336147, 8654727, 7969093, 15759799, 14029445, 5038459, 9894848, 8659300,
+ 13699287, 8834306, 10712885, 14753895, 10410465, 3373251, 309501, 9561475,
+ 5526688, 14647426, 14209836, 5339224, 207299, 14069911, 8722990, 2290950,
+ 3258216, 12505185, 6007317, 9218111, 14661019, 10537428, 11731949, 9027003,
+ 6641507, 9490160, 200241, 9720425, 16277895, 10816638, 1554761, 10431375,
+ 7467528, 6790302, 3429078, 14633753, 14428997, 11463204, 3576212, 2003426,
+ 6123687, 820520, 9992513, 15784513, 5778891, 6428165, 8388607
+};
+
+/*
+ * The hardware uses an LFSR counting sequence to determine when to capture
+ * the SPU PCs.	 An LFSR sequence is like a puesdo random number sequence
+ * where each number occurs once in the sequence but the sequence is not in
+ * numerical order. The SPU PC capture is done when the LFSR sequence reaches
+ * the last value in the sequence.  Hence the user specified value N
+ * corresponds to the LFSR number that is N from the end of the sequence.
+ *
+ * To avoid the time to compute the LFSR, a lookup table is used.  The 24 bit
+ * LFSR sequence is broken into four ranges.  The spacing of the precomputed
+ * values is adjusted in each range so the error between the user specifed
+ * number (N) of events between samples and the actual number of events based
+ * on the precomputed value will be les then about 6.2%.  Note, if the user
+ * specifies N < 2^16, the LFSR value that is 2^16 from the end will be used.
+ * This is to prevent the loss of samples because the trace buffer is full.
+ *
+ *	   User specified N		     Step between	   Index in
+ *					 precomputed values	 precomputed
+ *								    table
+ * 0		    to	2^16-1			----		      0
+ * 2^16	    to	2^16+2^19-1		2^12		    1 to 128
+ * 2^16+2^19	    to	2^16+2^19+2^22-1	2^15		  129 to 256
+ * 2^16+2^19+2^22  to	2^24-1			2^18		  257 to 302
+ *
+ *
+ * For example, the LFSR values in the second range are computed for 2^16,
+ * 2^16+2^12, ... , 2^19-2^16, 2^19 and stored in the table at indicies
+ * 1, 2,..., 127, 128.
+ *
+ * The 24 bit LFSR value for the nth number in the sequence can be
+ * calculated using the following code:
+ *
+ * #define size 24
+ * int calculate_lfsr(int n)
+ * {
+ *	int i;
+ *	unsigned int newlfsr0;
+ *	unsigned int lfsr = 0xFFFFFF;
+ *	unsigned int howmany = n;
+ *
+ *	for (i = 2; i < howmany + 2; i++) {
+ *		newlfsr0 = (((lfsr >> (size - 1 - 0)) & 1) ^
+ *		((lfsr >> (size - 1 - 1)) & 1) ^
+ *		(((lfsr >> (size - 1 - 6)) & 1) ^
+ *		((lfsr >> (size - 1 - 23)) & 1)));
+ *
+ *		lfsr >>= 1;
+ *		lfsr = lfsr | (newlfsr0 << (size - 1));
+ *	}
+ *	return lfsr;
+ * }
+ */
+
+#define V2_16  (0x1 << 16)
+#define V2_19  (0x1 << 19)
+#define V2_22  (0x1 << 22)
+
+static int calculate_lfsr(int n)
+{
+	/*
+	 * The ranges and steps are in powers of 2 so the calculations
+	 * can be done using shifts rather then divide.
+	 */
+	int index;
+
+	if ((n >> 16) == 0)
+		index = 0;
+	else if (((n - V2_16) >> 19) == 0)
+		index = ((n - V2_16) >> 12) + 1;
+	else if (((n - V2_16 - V2_19) >> 22) == 0)
+		index = ((n - V2_16 - V2_19) >> 15 ) + 1 + 128;
+	else if (((n - V2_16 - V2_19 - V2_22) >> 24) == 0)
+		index = ((n - V2_16 - V2_19 - V2_22) >> 18 ) + 1 + 256;
+	else
+		index = ENTRIES-1;
+
+	/* make sure index is valid */
+	if ((index > ENTRIES) || (index < 0))
+		index = ENTRIES-1;
+
+	return initial_lfsr[index];
+}
+
+static int pm_rtas_activate_spu_profiling(u32 node)
+{
+	int ret, i;
+	struct pm_signal pm_signal_local[NR_PHYS_CTRS];
+
+	/*
+	 * Set up the rtas call to configure the debug bus to
+	 * route the SPU PCs.  Setup the pm_signal for each SPU
+	 */
+	for (i = 0; i < NUM_SPUS_PER_NODE; i++) {
+		pm_signal_local[i].cpu = node;
+		pm_signal_local[i].signal_group = 41;
+		/* spu i on word (i/2) */
+		pm_signal_local[i].bus_word = 1 << i / 2;
+		/* spu i */
+		pm_signal_local[i].sub_unit = i;
+		pm_signal_local[i].bit = 63;
+	}
+
+	ret = rtas_ibm_cbe_perftools(SUBFUNC_ACTIVATE,
+				     PASSTHRU_ENABLE, pm_signal_local,
+				     (NUM_SPUS_PER_NODE
+				      * sizeof(struct pm_signal)));
+
+	if (unlikely(ret)) {
+		printk(KERN_WARNING "%s: rtas returned: %d\n",
+		       __FUNCTION__, ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+static int
+oprof_cpufreq_notify(struct notifier_block *nb, unsigned long val, void 
*data)
+{
+	int ret = 0;
+	struct cpufreq_freqs *frq = data;
+	if ((val == CPUFREQ_PRECHANGE && frq->old < frq->new) ||
+	    (val == CPUFREQ_POSTCHANGE && frq->old > frq->new) ||
+	    (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE))
+		set_profiling_frequency(frq->new, spu_cycle_reset);
+	return ret;
+}
+
+static struct notifier_block cpu_freq_notifier_block = {
+	.notifier_call	= oprof_cpufreq_notify
+};
+#endif
+
+static int cell_global_start_spu(struct op_counter_config *ctr)
+{
+	int subfunc;
+	unsigned int lfsr_value;
+	int cpu;
+	int ret;
+	int rtas_error;
+	unsigned int cpu_khzfreq = 0;
+
+	/* The SPU profiling uses time-based profiling based on
+	 * cpu frequency, so if configured with the CPU_FREQ
+	 * option, we should detect frequency changes and react
+	 * accordingly.
+	 */
+#ifdef CONFIG_CPU_FREQ
+	ret = cpufreq_register_notifier(&cpu_freq_notifier_block,
+					CPUFREQ_TRANSITION_NOTIFIER);
+	if (ret < 0)
+		/* this is not a fatal error */
+		printk(KERN_ERR "CPU freq change registration failed: %d\n",
+		       ret);
+
+	else
+		cpu_khzfreq = cpufreq_quick_get(smp_processor_id());
+#endif
+
+	set_profiling_frequency(cpu_khzfreq, spu_cycle_reset);
+
+	for_each_online_cpu(cpu) {
+		if (cbe_get_hw_thread_id(cpu))
+			continue;
+
+		/*
+		 * Setup SPU cycle-based profiling.
+		 * Set perf_mon_control bit 0 to a zero before
+		 * enabling spu collection hardware.
+		 */
+		cbe_write_pm(cpu, pm_control, 0);
+
+		if (spu_cycle_reset > MAX_SPU_COUNT)
+			/* use largest possible value */
+			lfsr_value = calculate_lfsr(MAX_SPU_COUNT-1);
+		else
+			lfsr_value = calculate_lfsr(spu_cycle_reset);
+
+		/* must use a non zero value. Zero disables data collection. */
+		if (lfsr_value == 0)
+			lfsr_value = calculate_lfsr(1);
+
+		lfsr_value = lfsr_value << 8; /* shift lfsr to correct
+						* register location
+						*/
+
+		/* debug bus setup */
+		ret = pm_rtas_activate_spu_profiling(cbe_cpu_to_node(cpu));
+
+		if (unlikely(ret)) {
+			rtas_error = ret;
+			goto out;
+		}
+
+
+		subfunc = 2;	/* 2 - activate SPU tracing, 3 - deactivate */
+
+		/* start profiling */
+		ret = rtas_call(spu_rtas_token, 3, 1, NULL, subfunc,
+		  cbe_cpu_to_node(cpu), lfsr_value);
+
+		if (unlikely(ret != 0)) {
+			printk(KERN_ERR
+			       "%s: rtas call ibm,cbe-spu-perftools failed, return = %d\n",
+			       __FUNCTION__, ret);
+			rtas_error = -EIO;
+			goto out;
+		}
+	}
+
+	rtas_error = start_spu_profiling(spu_cycle_reset);
+	if (rtas_error)
+		goto out_stop;
+
+	oprofile_running = 1;
+	return 0;
+
+out_stop:
+	cell_global_stop_spu();		/* clean up the PMU/debug bus */
 out:
-	;
+	return rtas_error;
 }
 
-static void cell_global_start(struct op_counter_config *ctr)
+static int cell_global_start_ppu(struct op_counter_config *ctr)
 {
-	u32 cpu;
+	u32 cpu, i;
 	u32 interrupt_mask = 0;
-	u32 i;
 
 	/* This routine gets called once for the system.
 	 * There is one performance monitor per node, so we
@@ -651,19 +1002,80 @@ static void cell_global_start(struct op_
 	oprofile_running = 1;
 	smp_wmb();
 
-	/* NOTE: start_virt_cntrs will result in cell_virtual_cntr() being
-	 * executed which manipulates the PMU.  We start the "virtual counter"
+	/*
+	 * NOTE: start_virt_cntrs will result in cell_virtual_cntr() being
+	 * executed which manipulates the PMU.	We start the "virtual counter"
 	 * here so that we do not need to synchronize access to the PMU in
 	 * the above for-loop.
 	 */
 	start_virt_cntrs();
+
+	return 0;
 }
 
-static void cell_global_stop(void)
+static int cell_global_start(struct op_counter_config *ctr)
+{
+	if (spu_cycle_reset) {
+		return cell_global_start_spu(ctr);
+	} else {
+		return cell_global_start_ppu(ctr);
+	}
+}
+
+/*
+ * Note the generic OProfile stop calls do not support returning
+ * an error on stop.  Hence, will not return an error if the FW
+ * calls fail on stop.	Failure to reset the debug bus is not an issue.
+ * Failure to disable the SPU profiling is not an issue.  The FW calls
+ * to enable the performance counters and debug bus will work even if
+ * the hardware was not cleanly reset.
+ */
+static void cell_global_stop_spu(void)
+{
+	int subfunc, rtn_value;
+	unsigned int lfsr_value;
+	int cpu;
+
+	oprofile_running = 0;
+
+#ifdef CONFIG_CPU_FREQ
+	cpufreq_unregister_notifier(&cpu_freq_notifier_block,
+				    CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+
+	for_each_online_cpu(cpu) {
+		if (cbe_get_hw_thread_id(cpu))
+			continue;
+
+		subfunc = 3;	/*
+				 * 2 - activate SPU tracing,
+				 * 3 - deactivate
+				 */
+		lfsr_value = 0x8f100000;
+
+		rtn_value = rtas_call(spu_rtas_token, 3, 1, NULL,
+				      subfunc, cbe_cpu_to_node(cpu),
+				      lfsr_value);
+
+		if (unlikely(rtn_value != 0)) {
+			printk(KERN_ERR
+			       "%s: rtas call ibm,cbe-spu-perftools failed, return = %d\n",
+			       __FUNCTION__, rtn_value);
+		}
+
+		/* Deactivate the signals */
+		pm_rtas_reset_signals(cbe_cpu_to_node(cpu));
+	}
+
+	stop_spu_profiling();
+}
+
+static void cell_global_stop_ppu(void)
 {
 	int cpu;
 
-	/* This routine will be called once for the system.
+	/*
+	 * This routine will be called once for the system.
 	 * There is one performance monitor per node, so we
 	 * only need to perform this function once per node.
 	 */
@@ -687,8 +1099,17 @@ static void cell_global_stop(void)
 	}
 }
 
-static void
-cell_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr)
+static void cell_global_stop(void)
+{
+	if (spu_cycle_reset) {
+		cell_global_stop_spu();
+	} else {
+		cell_global_stop_ppu();
+	}
+}
+
+static void cell_handle_interrupt(struct pt_regs *regs,
+				struct op_counter_config *ctr)
 {
 	u32 cpu;
 	u64 pc;
@@ -699,13 +1120,15 @@ cell_handle_interrupt(struct pt_regs *re
 
 	cpu = smp_processor_id();
 
-	/* Need to make sure the interrupt handler and the virt counter
+	/*
+	 * Need to make sure the interrupt handler and the virt counter
 	 * routine are not running at the same time. See the
 	 * cell_virtual_cntr() routine for additional comments.
 	 */
 	spin_lock_irqsave(&virt_cntr_lock, flags);
 
-	/* Need to disable and reenable the performance counters
+	/*
+	 * Need to disable and reenable the performance counters
 	 * to get the desired behavior from the hardware.  This
 	 * is hardware specific.
 	 */
@@ -714,7 +1137,8 @@ cell_handle_interrupt(struct pt_regs *re
 
 	interrupt_mask = cbe_get_and_clear_pm_interrupts(cpu);
 
-	/* If the interrupt mask has been cleared, then the virt cntr
+	/*
+	 * If the interrupt mask has been cleared, then the virt cntr
 	 * has cleared the interrupt.  When the thread that generated
 	 * the interrupt is restored, the data count will be restored to
 	 * 0xffffff0 to cause the interrupt to be regenerated.
@@ -732,18 +1156,20 @@ cell_handle_interrupt(struct pt_regs *re
 			}
 		}
 
-		/* The counters were frozen by the interrupt.
+		/*
+		 * The counters were frozen by the interrupt.
 		 * Reenable the interrupt and restart the counters.
 		 * If there was a race between the interrupt handler and
-		 * the virtual counter routine.  The virutal counter
+		 * the virtual counter routine.	 The virutal counter
 		 * routine may have cleared the interrupts.  Hence must
 		 * use the virt_cntr_inter_mask to re-enable the interrupts.
 		 */
 		cbe_enable_pm_interrupts(cpu, hdw_thread,
 					 virt_cntr_inter_mask);
 
-		/* The writes to the various performance counters only writes
-		 * to a latch.  The new values (interrupt setting bits, reset
+		/*
+		 * The writes to the various performance counters only writes
+		 * to a latch.	The new values (interrupt setting bits, reset
 		 * counter value etc.) are not copied to the actual registers
 		 * until the performance monitor is enabled.  In order to get
 		 * this to work as desired, the permormance monitor needs to
@@ -755,10 +1181,33 @@ cell_handle_interrupt(struct pt_regs *re
 	spin_unlock_irqrestore(&virt_cntr_lock, flags);
 }
 
+/*
+ * This function is called from the generic OProfile
+ * driver.  When profiling PPUs, we need to do the
+ * generic sync start; otherwise, do spu_sync_start.
+ */
+static int cell_sync_start(void)
+{
+	if (spu_cycle_reset)
+		return spu_sync_start();
+	else
+		return DO_GENERIC_SYNC;
+}
+
+static int cell_sync_stop(void)
+{
+	if (spu_cycle_reset)
+		return spu_sync_stop();
+	else
+		return 1;
+}
+
 struct op_powerpc_model op_model_cell = {
 	.reg_setup = cell_reg_setup,
 	.cpu_setup = cell_cpu_setup,
 	.global_start = cell_global_start,
 	.global_stop = cell_global_stop,
+	.sync_start = cell_sync_start,
+	.sync_stop = cell_sync_stop,
 	.handle_interrupt = cell_handle_interrupt,
 };
Index: powerpc.git/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/spufs/sched.c
+++ powerpc.git/arch/powerpc/platforms/cell/spufs/sched.c
@@ -264,6 +264,7 @@ static void spu_bind_context(struct spu 
 	ctx->spu = spu;
 	ctx->ops = &spu_hw_ops;
 	spu->pid = current->pid;
+	spu->tgid = current->tgid;
 	spu_associate_mm(spu, ctx->owner);
 	spu->ibox_callback = spufs_ibox_callback;
 	spu->wbox_callback = spufs_wbox_callback;
@@ -304,6 +305,7 @@ static void spu_unbind_context(struct sp
 	spu->dma_callback = NULL;
 	spu_associate_mm(spu, NULL);
 	spu->pid = 0;
+	spu->tgid = 0;
 	ctx->ops = &spu_backing_ops;
 	ctx->spu = NULL;
 	spu->flags = 0;
@@ -590,7 +592,7 @@ void spu_deactivate(struct spu_context *
 }
 
 /**
- * spu_yield -  yield a physical spu if others are waiting
+ * spu_yield -	yield a physical spu if others are waiting
  * @ctx:	spu context to yield
  *
  * Check if there is a higher priority context waiting and if yes
Index: powerpc.git/drivers/oprofile/buffer_sync.c
===================================================================
--- powerpc.git.orig/drivers/oprofile/buffer_sync.c
+++ powerpc.git/drivers/oprofile/buffer_sync.c
@@ -26,8 +26,9 @@
 #include <linux/profile.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/oprofile.h>
 #include <linux/sched.h>
- 
+
 #include "oprofile_stats.h"
 #include "event_buffer.h"
 #include "cpu_buffer.h"
Index: powerpc.git/drivers/oprofile/event_buffer.h
===================================================================
--- powerpc.git.orig/drivers/oprofile/event_buffer.h
+++ powerpc.git/drivers/oprofile/event_buffer.h
@@ -19,28 +19,10 @@ void free_event_buffer(void);
  
 /* wake up the process sleeping on the event file */
 void wake_up_buffer_waiter(void);
- 
-/* Each escaped entry is prefixed by ESCAPE_CODE
- * then one of the following codes, then the
- * relevant data.
- */
-#define ESCAPE_CODE			~0UL
-#define CTX_SWITCH_CODE 		1
-#define CPU_SWITCH_CODE 		2
-#define COOKIE_SWITCH_CODE 		3
-#define KERNEL_ENTER_SWITCH_CODE	4
-#define KERNEL_EXIT_SWITCH_CODE		5
-#define MODULE_LOADED_CODE		6
-#define CTX_TGID_CODE			7
-#define TRACE_BEGIN_CODE		8
-#define TRACE_END_CODE			9
- 
+
 #define INVALID_COOKIE ~0UL
 #define NO_COOKIE 0UL
 
-/* add data to the event buffer */
-void add_event_entry(unsigned long data);
- 
 extern const struct file_operations event_buffer_fops;
  
 /* mutex between sync_cpu_buffers() and the
Index: powerpc.git/drivers/oprofile/oprof.c
===================================================================
--- powerpc.git.orig/drivers/oprofile/oprof.c
+++ powerpc.git/drivers/oprofile/oprof.c
@@ -53,9 +53,24 @@ int oprofile_setup(void)
 	 * us missing task deaths and eventually oopsing
 	 * when trying to process the event buffer.
 	 */
+	if (oprofile_ops.sync_start) {
+		int sync_ret = oprofile_ops.sync_start();
+		switch (sync_ret) {
+		case 0:
+			goto post_sync;
+		case 1:
+			goto do_generic;
+		case -1:
+			goto out3;
+		default:
+			goto out3;
+		}
+	}
+do_generic:
 	if ((err = sync_start()))
 		goto out3;
 
+post_sync:
 	is_setup = 1;
 	mutex_unlock(&start_mutex);
 	return 0;
@@ -118,7 +133,20 @@ out:
 void oprofile_shutdown(void)
 {
 	mutex_lock(&start_mutex);
+	if (oprofile_ops.sync_stop) {
+		int sync_ret = oprofile_ops.sync_stop();
+		switch (sync_ret) {
+		case 0:
+			goto post_sync;
+		case 1:
+			goto do_generic;
+		default:
+			goto post_sync;
+		}
+	}
+do_generic:
 	sync_stop();
+post_sync:
 	if (oprofile_ops.shutdown)
 		oprofile_ops.shutdown();
 	is_setup = 0;
Index: powerpc.git/include/asm-powerpc/oprofile_impl.h
===================================================================
--- powerpc.git.orig/include/asm-powerpc/oprofile_impl.h
+++ powerpc.git/include/asm-powerpc/oprofile_impl.h
@@ -39,14 +39,16 @@ struct op_system_config {
 
 /* Per-arch configuration */
 struct op_powerpc_model {
-	void (*reg_setup) (struct op_counter_config *,
+	int (*reg_setup) (struct op_counter_config *,
 			   struct op_system_config *,
 			   int num_counters);
-	void (*cpu_setup) (struct op_counter_config *);
-	void (*start) (struct op_counter_config *);
-        void (*global_start) (struct op_counter_config *);
+	int  (*cpu_setup) (struct op_counter_config *);
+	int  (*start) (struct op_counter_config *);
+	int  (*global_start) (struct op_counter_config *);
 	void (*stop) (void);
 	void (*global_stop) (void);
+	int (*sync_start)(void);
+	int (*sync_stop)(void);
 	void (*handle_interrupt) (struct pt_regs *,
 				  struct op_counter_config *);
 	int num_counters;
Index: powerpc.git/include/asm-powerpc/spu.h
===================================================================
--- powerpc.git.orig/include/asm-powerpc/spu.h
+++ powerpc.git/include/asm-powerpc/spu.h
@@ -137,6 +137,7 @@ struct spu {
 	struct spu_runqueue *rq;
 	unsigned long long timestamp;
 	pid_t pid;
+	pid_t tgid;
 	int class_0_pending;
 	spinlock_t register_lock;
 
@@ -195,6 +196,20 @@ extern void spu_associate_mm(struct spu 
 struct mm_struct;
 extern void spu_flush_all_slbs(struct mm_struct *mm);
 
+/* This interface allows a profiler (e.g., OProfile) to store a ref
+ * to spu context information that it creates.	This caching technique
+ * avoids the need to recreate this information after a save/restore 
operation.
+ *
+ * Assumes the caller has already incremented the ref count to
+ * profile_info; then spu_context_destroy must call kref_put
+ * on prof_info_kref.
+ */
+void spu_set_profile_private_kref(struct spu_context *ctx,
+				  struct kref *prof_info_kref,
+				  void ( * prof_info_release) (struct kref *kref));
+
+void *spu_get_profile_private_kref(struct spu_context *ctx);
+
 /* system callbacks from the SPU */
 struct spu_syscall_block {
 	u64 nr_ret;
Index: powerpc.git/include/linux/oprofile.h
===================================================================
--- powerpc.git.orig/include/linux/oprofile.h
+++ powerpc.git/include/linux/oprofile.h
@@ -17,6 +17,26 @@
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
  
+/* Each escaped entry is prefixed by ESCAPE_CODE
+ * then one of the following codes, then the
+ * relevant data.
+ * These #defines live in this file so that arch-specific
+ * buffer sync'ing code can access them.
+ */
+#define ESCAPE_CODE			~0UL
+#define CTX_SWITCH_CODE			1
+#define CPU_SWITCH_CODE			2
+#define COOKIE_SWITCH_CODE		3
+#define KERNEL_ENTER_SWITCH_CODE	4
+#define KERNEL_EXIT_SWITCH_CODE		5
+#define MODULE_LOADED_CODE		6
+#define CTX_TGID_CODE			7
+#define TRACE_BEGIN_CODE		8
+#define TRACE_END_CODE			9
+#define XEN_ENTER_SWITCH_CODE		10
+#define SPU_PROFILING_CODE		11
+#define SPU_CTX_SWITCH_CODE		12
+
 struct super_block;
 struct dentry;
 struct file_operations;
@@ -35,6 +55,14 @@ struct oprofile_operations {
 	int (*start)(void);
 	/* Stop delivering interrupts. */
 	void (*stop)(void);
+	/* Arch-specific buffer sync functions.
+	 * Return value = 0:  Success
+	 * Return value = -1: Failure
+	 * Return value = 1:  Run generic sync function
+	 */
+	int (*sync_start)(void);
+	int (*sync_stop)(void);
+
 	/* Initiate a stack backtrace. Optional. */
 	void (*backtrace)(struct pt_regs * const regs, unsigned int depth);
 	/* CPU identification string. */
@@ -56,6 +84,13 @@ int oprofile_arch_init(struct oprofile_o
 void oprofile_arch_exit(void);
 
 /**
+ * Add data to the event buffer.
+ * The data passed is free-form, but typically consists of
+ * file offsets, dcookies, context information, and ESCAPE codes.
+ */
+void add_event_entry(unsigned long data);
+
+/**
  * Add a sample. This may be called from any context. Pass
  * smp_processor_id() as cpu.
  */
Index: powerpc.git/arch/powerpc/kernel/time.c
===================================================================
--- powerpc.git.orig/arch/powerpc/kernel/time.c
+++ powerpc.git/arch/powerpc/kernel/time.c
@@ -121,6 +121,7 @@ extern struct timezone sys_tz;
 static long timezone_offset;
 
 unsigned long ppc_proc_freq;
+EXPORT_SYMBOL(ppc_proc_freq);
 unsigned long ppc_tb_freq;
 
 static u64 tb_last_jiffy __cacheline_aligned_in_smp;
Index: powerpc.git/arch/powerpc/platforms/cell/spufs/spufs.h
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/spufs/spufs.h
+++ powerpc.git/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -94,6 +94,8 @@ struct spu_context {
 
 	struct list_head gang_list;
 	struct spu_gang *gang;
+	struct kref *prof_priv_kref;
+	void ( * prof_priv_release) (struct kref *kref);
 
 	/* owner thread */
 	pid_t tid;
Index: powerpc.git/arch/powerpc/platforms/cell/spufs/context.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/spufs/context.c
+++ powerpc.git/arch/powerpc/platforms/cell/spufs/context.c
@@ -22,6 +22,7 @@
 
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/spu.h>
@@ -81,6 +82,8 @@ void destroy_spu_context(struct kref *kr
 	spu_fini_csa(&ctx->csa);
 	if (ctx->gang)
 		spu_gang_remove_ctx(ctx->gang, ctx);
+	if (ctx->prof_priv_kref)
+		kref_put(ctx->prof_priv_kref, ctx->prof_priv_release);
 	BUG_ON(!list_empty(&ctx->rq));
 	atomic_dec(&nr_spu_contexts);
 	kfree(ctx);
@@ -169,3 +172,20 @@ void spu_acquire_saved(struct spu_contex
 	if (ctx->state != SPU_STATE_SAVED)
 		spu_deactivate(ctx);
 }
+
+void spu_set_profile_private_kref(struct spu_context *ctx,
+				  struct kref *prof_info_kref,
+				  void ( * prof_info_release) (struct kref *kref))
+{
+	ctx->prof_priv_kref = prof_info_kref;
+	ctx->prof_priv_release = prof_info_release;
+}
+EXPORT_SYMBOL_GPL(spu_set_profile_private_kref);
+
+void *spu_get_profile_private_kref(struct spu_context *ctx)
+{
+	return ctx->prof_priv_kref;
+}
+EXPORT_SYMBOL_GPL(spu_get_profile_private_kref);
+
+
Index: powerpc.git/include/linux/dcookies.h
===================================================================
--- powerpc.git.orig/include/linux/dcookies.h
+++ powerpc.git/include/linux/dcookies.h
@@ -12,6 +12,7 @@
 
 #ifdef CONFIG_PROFILING
  
+#include <linux/dcache.h>
 #include <linux/types.h>
  
 struct dcookie_user;
Index: powerpc.git/include/linux/elf-em.h
===================================================================
--- powerpc.git.orig/include/linux/elf-em.h
+++ powerpc.git/include/linux/elf-em.h
@@ -20,7 +20,8 @@
 #define EM_PARISC	15	/* HPPA */
 #define EM_SPARC32PLUS	18	/* Sun's "v8plus" */
 #define EM_PPC		20	/* PowerPC */
-#define EM_PPC64	21       /* PowerPC64 */
+#define EM_PPC64	21	 /* PowerPC64 */
+#define EM_SPU		23	/* Cell BE SPU */
 #define EM_SH		42	/* SuperH */
 #define EM_SPARCV9	43	/* SPARC v9 64-bit */
 #define EM_IA_64	50	/* HP/Intel IA-64 */
Index: powerpc.git/arch/powerpc/oprofile/op_model_rs64.c
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/op_model_rs64.c
+++ powerpc.git/arch/powerpc/oprofile/op_model_rs64.c
@@ -88,7 +88,7 @@ static unsigned long reset_value[OP_MAX_
 
 static int num_counters;
 
-static void rs64_reg_setup(struct op_counter_config *ctr,
+static int rs64_reg_setup(struct op_counter_config *ctr,
 			   struct op_system_config *sys,
 			   int num_ctrs)
 {
@@ -100,9 +100,10 @@ static void rs64_reg_setup(struct op_cou
 		reset_value[i] = 0x80000000UL - ctr[i].count;
 
 	/* XXX setup user and kernel profiling */
+	return 0;
 }
 
-static void rs64_cpu_setup(struct op_counter_config *ctr)
+static int rs64_cpu_setup(struct op_counter_config *ctr)
 {
 	unsigned int mmcr0;
 
@@ -125,9 +126,11 @@ static void rs64_cpu_setup(struct op_cou
 	    mfspr(SPRN_MMCR0));
 	dbg("setup on cpu %d, mmcr1 %lx\n", smp_processor_id(),
 	    mfspr(SPRN_MMCR1));
+
+	return 0;
 }
 
-static void rs64_start(struct op_counter_config *ctr)
+static int rs64_start(struct op_counter_config *ctr)
 {
 	int i;
 	unsigned int mmcr0;
@@ -155,6 +158,7 @@ static void rs64_start(struct op_counter
 	mtspr(SPRN_MMCR0, mmcr0);
 
 	dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
+	return 0;
 }
 
 static void rs64_stop(void)
Index: powerpc.git/arch/powerpc/oprofile/op_model_power4.c
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/op_model_power4.c
+++ powerpc.git/arch/powerpc/oprofile/op_model_power4.c
@@ -30,7 +30,7 @@ static u32 mmcr0_val;
 static u64 mmcr1_val;
 static u64 mmcra_val;
 
-static void power4_reg_setup(struct op_counter_config *ctr,
+static int power4_reg_setup(struct op_counter_config *ctr,
 			     struct op_system_config *sys,
 			     int num_ctrs)
 {
@@ -58,6 +58,8 @@ static void power4_reg_setup(struct op_c
 		mmcr0_val &= ~MMCR0_PROBLEM_DISABLE;
 	else
 		mmcr0_val |= MMCR0_PROBLEM_DISABLE;
+
+	return 0;
 }
 
 extern void ppc64_enable_pmcs(void);
@@ -82,7 +84,7 @@ static inline int mmcra_must_set_sample(
 	return 0;
 }
 
-static void power4_cpu_setup(struct op_counter_config *ctr)
+static int power4_cpu_setup(struct op_counter_config *ctr)
 {
 	unsigned int mmcr0 = mmcr0_val;
 	unsigned long mmcra = mmcra_val;
@@ -109,9 +111,11 @@ static void power4_cpu_setup(struct op_c
 	    mfspr(SPRN_MMCR1));
 	dbg("setup on cpu %d, mmcra %lx\n", smp_processor_id(),
 	    mfspr(SPRN_MMCRA));
+
+	return 0;
 }
 
-static void power4_start(struct op_counter_config *ctr)
+static int power4_start(struct op_counter_config *ctr)
 {
 	int i;
 	unsigned int mmcr0;
@@ -146,6 +150,7 @@ static void power4_start(struct op_count
 	oprofile_running = 1;
 
 	dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);
+	return 0;
 }
 
 static void power4_stop(void)
Index: powerpc.git/arch/powerpc/oprofile/op_model_7450.c
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/op_model_7450.c
+++ powerpc.git/arch/powerpc/oprofile/op_model_7450.c
@@ -81,7 +81,7 @@ static void pmc_stop_ctrs(void)
 
 /* Configures the counters on this CPU based on the global
  * settings */
-static void fsl7450_cpu_setup(struct op_counter_config *ctr)
+static int fsl7450_cpu_setup(struct op_counter_config *ctr)
 {
 	/* freeze all counters */
 	pmc_stop_ctrs();
@@ -89,12 +89,14 @@ static void fsl7450_cpu_setup(struct op_
 	mtspr(SPRN_MMCR0, mmcr0_val);
 	mtspr(SPRN_MMCR1, mmcr1_val);
 	mtspr(SPRN_MMCR2, mmcr2_val);
+
+	return 0;
 }
 
 #define NUM_CTRS 6
 
 /* Configures the global settings for the countes on all CPUs. */
-static void fsl7450_reg_setup(struct op_counter_config *ctr,
+static int fsl7450_reg_setup(struct op_counter_config *ctr,
 			     struct op_system_config *sys,
 			     int num_ctrs)
 {
@@ -126,10 +128,12 @@ static void fsl7450_reg_setup(struct op_
 		| mmcr1_event6(ctr[5].event);
 
 	mmcr2_val = 0;
+
+	return 0;
 }
 
 /* Sets the counters on this CPU to the chosen values, and starts them */
-static void fsl7450_start(struct op_counter_config *ctr)
+static int fsl7450_start(struct op_counter_config *ctr)
 {
 	int i;
 
@@ -148,6 +152,8 @@ static void fsl7450_start(struct op_coun
 	pmc_start_ctrs();
 
 	oprofile_running = 1;
+
+	return 0;
 }
 
 /* Stop the counters on this CPU */
@@ -193,7 +199,7 @@ static void fsl7450_handle_interrupt(str
 	/* The freeze bit was set by the interrupt. */
 	/* Clear the freeze bit, and reenable the interrupt.
 	 * The counters won't actually start until the rfi clears
-	 * the PMM bit */
+	 * the PM/M bit */
 	pmc_start_ctrs();
 }
 
Index: powerpc.git/arch/powerpc/oprofile/op_model_fsl_booke.c
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ powerpc.git/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -244,7 +244,7 @@ static void dump_pmcs(void)
 			mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
 }
 
-static void fsl_booke_cpu_setup(struct op_counter_config *ctr)
+static int fsl_booke_cpu_setup(struct op_counter_config *ctr)
 {
 	int i;
 
@@ -258,9 +258,11 @@ static void fsl_booke_cpu_setup(struct o
 
 		set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
 	}
+
+	return 0;
 }
 
-static void fsl_booke_reg_setup(struct op_counter_config *ctr,
+static int fsl_booke_reg_setup(struct op_counter_config *ctr,
 			     struct op_system_config *sys,
 			     int num_ctrs)
 {
@@ -276,9 +278,10 @@ static void fsl_booke_reg_setup(struct o
 	for (i = 0; i < num_counters; ++i)
 		reset_value[i] = 0x80000000UL - ctr[i].count;
 
+	return 0;
 }
 
-static void fsl_booke_start(struct op_counter_config *ctr)
+static int fsl_booke_start(struct op_counter_config *ctr)
 {
 	int i;
 
@@ -308,6 +311,8 @@ static void fsl_booke_start(struct op_co
 
 	pr_debug("start on cpu %d, pmgc0 %x\n", smp_processor_id(),
 			mfpmr(PMRN_PMGC0));
+
+	return 0;
 }
 
 static void fsl_booke_stop(void)
Index: powerpc.git/arch/powerpc/oprofile/op_model_pa6t.c
===================================================================
--- powerpc.git.orig/arch/powerpc/oprofile/op_model_pa6t.c
+++ powerpc.git/arch/powerpc/oprofile/op_model_pa6t.c
@@ -89,7 +89,7 @@ static inline void ctr_write(unsigned in
 
 
 /* precompute the values to stuff in the hardware registers */
-static void pa6t_reg_setup(struct op_counter_config *ctr,
+static int pa6t_reg_setup(struct op_counter_config *ctr,
 			   struct op_system_config *sys,
 			   int num_ctrs)
 {
@@ -135,10 +135,12 @@ static void pa6t_reg_setup(struct op_cou
 		pr_debug("reset_value for pmc%u inited to 0x%lx\n",
 				 pmc, reset_value[pmc]);
 	}
+
+	return 0;
 }
 
 /* configure registers on this cpu */
-static void pa6t_cpu_setup(struct op_counter_config *ctr)
+static int pa6t_cpu_setup(struct op_counter_config *ctr)
 {
 	u64 mmcr0 = mmcr0_val;
 	u64 mmcr1 = mmcr1_val;
@@ -154,9 +156,11 @@ static void pa6t_cpu_setup(struct op_cou
 		mfspr(SPRN_PA6T_MMCR0));
 	pr_debug("setup on cpu %d, mmcr1 %016lx\n", smp_processor_id(),
 		mfspr(SPRN_PA6T_MMCR1));
+
+	return 0;
 }
 
-static void pa6t_start(struct op_counter_config *ctr)
+static int pa6t_start(struct op_counter_config *ctr)
 {
 	int i;
 
@@ -174,6 +178,8 @@ static void pa6t_start(struct op_counter
 	oprofile_running = 1;
 
 	pr_debug("start on cpu %d, mmcr0 %lx\n", smp_processor_id(), mmcr0);
+
+	return 0;
 }
 
 static void pa6t_stop(void)

^ permalink raw reply

* Re: questions about mpc82xx_ads and porting to other, similar, platform
From: Scott Wood @ 2007-07-13 18:24 UTC (permalink / raw)
  To: Alexandros Kostopoulos; +Cc: linuxppc-dev
In-Reply-To: <op.tveavpvdnhx3hy@phoenix>

On Fri, Jul 13, 2007 at 11:51:15AM +0300, Alexandros Kostopoulos wrote:
> I am trying to port kernel 2.6.22.1 to my own platform, which incorporates  
> an mpc8275 chip. I'm using platform code for mpc82xx_ads as a template (is  
> this right in the first place?). I have a couple of questions:

I suggest waiting until I can get my 8xx/82xx patchset out (which should
happen early next week...  it would have been earlier if I hadn't gotten
distracted trying to get PCI to work right).  It addresses the things you
point out.

> 1. mpc82xx_ads.c uses init_scc_ioports function to initialize the scc
> uarts. However, this function is only used by the code in
> arch/powerpc/sysdev/fsl_soc.c, and spefically in fs_enet_of_init(),
> which is used to initialize the ethernet driver and not the cpm_uart
> driver. On the other hand, cpm_uart_of_init() function seems to be the
> one that initializes the uarts in cpm, and actually makes use of the
> device-id, model, rx-clock and tx-clock properties of the scc nodes in
> OF tree. So, AFAICT, init_scc_ioports should not be there, since it
> won't be actually called at all (although I have not actually tested
> this - I haven't yet managed to boot the kernel). Instead,
> cpm_uart_of_init should take care of everything, except for the pport
> initialization, which is done in u-boot anyway (at least in my case).
> Any thoughts on this?

All such port configuration callbacks are removed in my patchset; the
bootloader and/or platform code is responsible for setting it up.

> 2. I have also some questions regarding the device tree. Why are there two  
> nodes regarding the interrupt controller in there? 

There are two interrupt controllers on the mpc8272ads: one for PCI, and
another for everything else.

> and in the top level node, what does this property means: reg =
> <f8200000 f8200004>; 

It means the device tree is buggy.  It should say <f8200000 8>.

> Finally, in the memory node, the reg property defines a second mem
> region, (f4500000 f4500020). What is this? 

More device tree brokenness.  It's the board control and status register
block, which has nothing to do with memory.

> maybe a special memory mapped peripheral of this board? If I have a
> board with many mem configurations (e.g. it uses a DIMM SDRAM what can
> be changed), what value should I place in the mem node? I have to
> change dts every time I insert a new DIMM?

No, u-boot or the bootwrapper should fill in the memory size.

-Scott

^ permalink raw reply

* [PATCH 1/2] OProfile - Enable SPU switch notification to detect currently active SPU tasks
From: Bob Nelson @ 2007-07-13 18:27 UTC (permalink / raw)
  To: Andrew Morton, Philippe Elie, linuxppc, oprofile

From: Maynard Johnson <mpjohn@us.ibm.com>

This patch adds to the capability of spu_switch_event_register so that the
caller is also notified of currently active SPU tasks.  It also exports
spu_switch_event_register and spu_switch_event_unregister.

Signed-off-by: Maynard Johnson <mpjohn@us.ibm.com>
Signed-off-by: Carl Love <carll@us.ibm.com>
Signed-off-by: Bob Nelson <rrnelson@us.ibm.com>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>

---

We would like this patch included in -mm and 2.6.23.

Index: powerpc.git/arch/powerpc/platforms/cell/spufs/sched.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/spufs/sched.c
+++ powerpc.git/arch/powerpc/platforms/cell/spufs/sched.c
@@ -204,21 +204,50 @@ static void spu_remove_from_active_list(
 
 static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier);
 
-static void spu_switch_notify(struct spu *spu, struct spu_context *ctx)
+void spu_switch_notify(struct spu *spu, struct spu_context *ctx)
 {
 	blocking_notifier_call_chain(&spu_switch_notifier,
 			    ctx ? ctx->object_id : 0, spu);
 }
 
+static void notify_spus_active(void)
+{
+	int node;
+
+	/*
+	 * Wake up the active spu_contexts.
+	 *
+	 * When the awakened processes see their "notify_active" flag is set,
+	 * they will call spu_switch_notify();
+	 */
+	for (node = 0; node < MAX_NUMNODES; node++) {
+		struct spu *spu;
+		mutex_lock(&spu_prio->active_mutex[node]);
+		list_for_each_entry(spu, &spu_prio->active_list[node], list) {
+			struct spu_context *ctx = spu->ctx;
+			set_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags);
+			mb();
+			wake_up_all(&ctx->stop_wq);
+		}
+		mutex_unlock(&spu_prio->active_mutex[node]);
+	}
+}
+
 int spu_switch_event_register(struct notifier_block * n)
 {
-	return blocking_notifier_chain_register(&spu_switch_notifier, n);
+	int ret;
+	ret = blocking_notifier_chain_register(&spu_switch_notifier, n);
+	if (!ret)
+		notify_spus_active();
+	return ret;
 }
+EXPORT_SYMBOL_GPL(spu_switch_event_register);
 
 int spu_switch_event_unregister(struct notifier_block * n)
 {
 	return blocking_notifier_chain_unregister(&spu_switch_notifier, n);
 }
+EXPORT_SYMBOL_GPL(spu_switch_event_unregister);
 
 /**
  * spu_bind_context - bind spu context to physical spu
Index: powerpc.git/arch/powerpc/platforms/cell/spufs/spufs.h
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/spufs/spufs.h
+++ powerpc.git/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -53,6 +53,11 @@ enum spuctx_execution_state {
 	SPUCTX_UTIL_MAX
 };
 
+/* ctx->sched_flags */
+enum {
+	SPU_SCHED_NOTIFY_ACTIVE,
+};
+
 struct spu_context {
 	struct spu *spu;		  /* pointer to a physical SPU */
 	struct spu_state csa;		  /* SPU context save area. */
@@ -231,6 +236,7 @@ void spu_acquire_saved(struct spu_contex
 int spu_activate(struct spu_context *ctx, unsigned long flags);
 void spu_deactivate(struct spu_context *ctx);
 void spu_yield(struct spu_context *ctx);
+void spu_switch_notify(struct spu *spu, struct spu_context *ctx);
 void spu_set_timeslice(struct spu_context *ctx);
 void spu_update_sched_info(struct spu_context *ctx);
 void __spu_update_sched_info(struct spu_context *ctx);
Index: powerpc.git/arch/powerpc/platforms/cell/spufs/run.c
===================================================================
--- powerpc.git.orig/arch/powerpc/platforms/cell/spufs/run.c
+++ powerpc.git/arch/powerpc/platforms/cell/spufs/run.c
@@ -18,15 +18,17 @@ void spufs_stop_callback(struct spu *spu
 	wake_up_all(&ctx->stop_wq);
 }
 
-static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
+static inline int spu_stopped(struct spu_context *ctx, u32 *stat)
 {
 	struct spu *spu;
 	u64 pte_fault;
 
 	*stat = ctx->ops->status_read(ctx);
-	if (ctx->state != SPU_STATE_RUNNABLE)
-		return 1;
+
 	spu = ctx->spu;
+	if (ctx->state != SPU_STATE_RUNNABLE ||
+	    test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags))
+		return 1;
 	pte_fault = spu->dsisr &
 	    (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED);
 	return (!(*stat & SPU_STATUS_RUNNING) || pte_fault || 
spu->class_0_pending) ?
@@ -124,7 +126,7 @@ out:
 	return ret;
 }
 
-static int spu_run_init(struct spu_context *ctx, u32 * npc)
+static int spu_run_init(struct spu_context *ctx, u32 *npc)
 {
 	if (ctx->flags & SPU_CREATE_ISOLATE) {
 		unsigned long runcntl;
@@ -154,8 +156,8 @@ static int spu_run_init(struct spu_conte
 	return 0;
 }
 
-static int spu_run_fini(struct spu_context *ctx, u32 * npc,
-			       u32 * status)
+static int spu_run_fini(struct spu_context *ctx, u32 *npc,
+			       u32 *status)
 {
 	int ret = 0;
 
@@ -293,6 +295,7 @@ long spufs_run_spu(struct file *file, st
 		   u32 *npc, u32 *event)
 {
 	int ret;
+	struct spu *spu;
 	u32 status;
 
 	if (mutex_lock_interruptible(&ctx->run_mutex))
@@ -326,8 +329,16 @@ long spufs_run_spu(struct file *file, st
 
 	do {
 		ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, &status));
+		spu = ctx->spu;
 		if (unlikely(ret))
 			break;
+		if (unlikely(test_and_clear_bit(SPU_SCHED_NOTIFY_ACTIVE,
+						&ctx->sched_flags))) {
+			if (!(status & SPU_STATUS_STOPPED_BY_STOP)) {
+				spu_switch_notify(spu, ctx);
+				continue;
+			}
+		}
 		if ((status & SPU_STATUS_STOPPED_BY_STOP) &&
 		    (status >> SPU_STOP_STATUS_SHIFT == 0x2104)) {
 			ret = spu_process_callback(ctx);

^ permalink raw reply

* Re: [PATCH 3/4] pm: Handle HID0_SLEEP in the TLF_NAPPING hack.
From: Scott Wood @ 2007-07-13 18:04 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18071.7389.640461.229828@cargo.ozlabs.ibm.com>

Paul Mackerras wrote:
> Scott Wood writes:
> 
> 
>>The e300 core (and probably most other 6xx chips) can only come out of
>>sleep mode with an interrupt.  However, interrupts are logically disabled
>>by the power management layer.
> 
> 
> On powerbooks it's typically a hard reset rather than an interrupt.
> Is it possible to use a hard reset on e300-based systems?

The 8313 can do this (see the deep sleep portion of the 83xx PM patch 
that I posted), but others can't.  Even on the 8313, it's not always 
desireable to use deep sleep, due to limited wakeup sourcers, higher 
latency, etc.

> Also, if you use an interrupt, presumably the cpu has to do something
> to clear the interrupt condition.  What would that be?

The caller's MSR[EE] is cleared in power_save_6xx_restore, so the 
interrupt won't happen again until the PM code re-enables MSR[EE].

-Scott

^ permalink raw reply

* Re: [PATCH] Xilinx SystemACE device driver
From: Grant Likely @ 2007-07-13 17:36 UTC (permalink / raw)
  To: Robertson, Joseph M.; +Cc: Linux PPC Linux PPC
In-Reply-To: <939D37AEB47F1F49B88FAB6599B6023501A17210@hsv1dafpew02.das.gov.sanm.corp>

On 7/13/07, Robertson, Joseph M. <joseph.robertson@sanmina-sci.com> wrote:
>
> Hi,
>
>  Ok, so outlook is a problem.  The horror is that, where I work thats all I
> can use.  They block all the outside systems like gmail, yahoo, etc.  So
> under linux, I have to use the web access for outlook.  ugh.
>  Why I work here I don't know, they think all software HAS to be bought.
>
>  Um, so your patch creates another xsysace.c file, all by itself, which is a
> NEW driver?
>  This replaces the 8 files of the previous driver?  What happens to all the
> low level funcs?
>
>  Where can I get your 2.6.22 tree to see how this is all supposed to go
> together?  Is there a tar.bz2 package?

Start with installing 'git'.  http://git.or.cz/

Then clone Linus' tree:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

if you're company blocks the git port, then you can use HTTP instead:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

There are a number of different git repos out there with virtex
support integrated, but I'm going to use the example of my tree...  (I
rebased my tree onto 2.6.22, so it's very up to date)

$ git fetch git://git.secretlab.ca/git/linux-2.6.git virtex-dev:virtex-dev
(Again, you can use http:// if the git port is blocked)

Now you'll have a branch in your git tree called 'virtex-dev' that
includes my patchset.

You can checkout that branch with:
$ git branch mybranch virtex-dev
$ git checkout mybranch

You can view the patchset with:
$ gitk virtex-dev

You can look at in individual patch with:
$ git show <SHA1 id>
(All git commits are identified with a SHA1 hash; you'll see them in
gitk, or when you do a 'git log)

Also, you can view the tree online at:
http://git.secretlab.ca/cgi-bin/gitweb.cgi?p=linux-2.6.git;a=summary

If you click on the 'commitdiff' link for a patch, followed by
'plain', you should get a downloadable version of the patch.

Cheers,
g.


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ 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