LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] viocons: make powerpc allmodconfig build
From: Stephen Rothwell @ 2006-10-18  3:39 UTC (permalink / raw)
  To: Randy.Dunlap; +Cc: ppcdev, paulus
In-Reply-To: <4535824F.1020407@oracle.com>

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

On Tue, 17 Oct 2006 18:24:31 -0700 "Randy.Dunlap" <randy.dunlap@oracle.com> wrote:
>
> OK.  Makes sense.  Will you just build VT in that combo *series
> config and not build VIOCONS?  If so, that would still fix
> "make allmodconfig" to build cleanly (I think).

Yes, VIOCONS is now obsolete (it is replaced by HVC_ISERIES which doesn't
clash with VT), but it is used by the distros so I don't want to remove
it (yet).

--
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

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

^ permalink raw reply

* Re: [PATCH 2/2] viocons: make powerpc allmodconfig build
From: Randy.Dunlap @ 2006-10-18  3:46 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppcdev, paulus
In-Reply-To: <20061018133947.20a2c84f.sfr@canb.auug.org.au>

Stephen Rothwell wrote:
> On Tue, 17 Oct 2006 18:24:31 -0700 "Randy.Dunlap" <randy.dunlap@oracle.com> wrote:
>> OK.  Makes sense.  Will you just build VT in that combo *series
>> config and not build VIOCONS?  If so, that would still fix
>> "make allmodconfig" to build cleanly (I think).
> 
> Yes, VIOCONS is now obsolete (it is replaced by HVC_ISERIES which doesn't
> clash with VT), but it is used by the distros so I don't want to remove
> it (yet).

OK, I wasn't suggesting removing it, just tweaking the dependencies etc.
Is that doable now or do we wait for the integrated I/P series configs?

-- 
~Randy

^ permalink raw reply

* Re: [PATCH 1/2] ramdisk: make powerpc allmodconfig build
From: Randy.Dunlap @ 2006-10-18  4:56 UTC (permalink / raw)
  To: michael; +Cc: ppcdev, paulus
In-Reply-To: <1161141055.7906.0.camel@localhost.localdomain>

Michael Ellerman wrote:
> On Tue, 2006-10-17 at 11:04 -0700, Judith Lebzelter wrote:
>> Hi Randy,
>>
>> There is another section in that function which depends on 
>> 'CONFIG_BLK_DEV_INITRD' being defined.  Although it does not throw an
>> error, it does depend on some of the variables set in this section,
>> but not 'rd_size'.  I think for consistancy it might be better to do 
>> somthing like this(below)?  Or else add the same ifdef down there...
>>
>> Judith
>>
>>
>> Index: 2/linux/arch/powerpc/platforms/iseries/setup.c
>> ===================================================================
>> --- 2.orig/linux/arch/powerpc/platforms/iseries/setup.c	2006-10-17 10:49:31.423551104 -0700
>> +++ 2/linux/arch/powerpc/platforms/iseries/setup.c	2006-10-17 10:52:22.682515784 -0700
>> @@ -305,8 +305,10 @@
>>  		initrd_end = initrd_start + naca.xRamDiskSize * HW_PAGE_SIZE;
>>  		initrd_below_start_ok = 1;	// ramdisk in kernel space
>>  		ROOT_DEV = Root_RAM0;
>> +#if defined(CONFIG_BLK_DEV_RAM)
>>  		if (((rd_size * 1024) / HW_PAGE_SIZE) < naca.xRamDiskSize)
>>  			rd_size = (naca.xRamDiskSize * HW_PAGE_SIZE) / 1024;
>> +#endif /* CONFIG_BLK_DEV_RAM */
>>  	} else
>>  #endif /* CONFIG_BLK_DEV_INITRD */
>>  	{
> 
> That code is bogus, we'll remove it entirely.

Great, thanks.  :)

-- 
~Randy

^ permalink raw reply

* ibmveth and LIOBN field
From: Benjamin Herrenschmidt @ 2006-10-18  5:41 UTC (permalink / raw)
  To: Santiago Leon; +Cc: linuxppc-dev list, Paul Mackerras, David Gibson

Hi Santiago !

I'm a bit annoyed by a bit of code in the ibmveth driver:

It accesses the iommu table pointer, to get the index and put it into
it's own private adapter->liobn member. However, that is never used
anywhere except in ibmveth_seq_show() for the /proc stuff to display
this LIOBN value.

Is this actually useful ? I'd like to just remove that code. I'm
changing the DMA operations management globally in the powerpc
architecture and that code now needs fixups. I've done them, but it
annoys me to have this driver dive into data structures like iommu_table
that is should have no business mucking with.

Cheers,
Ben.

^ permalink raw reply

* [PATCH] Move iSeries initrd logic into device tree
From: Michael Ellerman @ 2006-10-18  5:53 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, Stephen Rothwell

Remove the iSeries initrd logic, instead just store the initrd location and
size in the device tree so generic code can do the rest for us.

The iSeries code had a "feature" which the generic code lacks, ie. if the
compressed initrd is bigger than the configured ram disk size, we make
the ram disk size bigger. That's bogus, as the compressed size of the initrd
tells us nothing about how big the ram disk needs to be. If the ram disk
isn't big enough you just need to make CONFIG_BLK_DEV_RAM_SIZE larger.

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

 arch/powerpc/platforms/iseries/dt.c    |   15 +++++++++++++--
 arch/powerpc/platforms/iseries/setup.c |   32 --------------------------------
 2 files changed, 13 insertions(+), 34 deletions(-)

Index: to-merge/arch/powerpc/platforms/iseries/dt.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/iseries/dt.c
+++ to-merge/arch/powerpc/platforms/iseries/dt.c
@@ -41,6 +41,7 @@
 #include "call_pci.h"
 #include "pci.h"
 #include "it_exp_vpd_panel.h"
+#include "naca.h"
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -205,13 +206,11 @@ static void __init dt_prop_u32(struct is
 	dt_prop(dt, name, &data, sizeof(u32));
 }
 
-#ifdef notyet
 static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name,
 		u64 data)
 {
 	dt_prop(dt, name, &data, sizeof(u64));
 }
-#endif
 
 static void __init dt_prop_u64_list(struct iseries_flat_dt *dt,
 		const char *name, u64 *data, int n)
@@ -306,6 +305,17 @@ static void __init dt_model(struct iseri
 	dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex());
 }
 
+static void __init dt_initrd(struct iseries_flat_dt *dt)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (naca.xRamDisk) {
+		dt_prop_u64(dt, "linux,initrd-start", (u64)naca.xRamDisk);
+		dt_prop_u64(dt, "linux,initrd-end",
+			(u64)naca.xRamDisk + naca.xRamDiskSize * HW_PAGE_SIZE);
+	}
+#endif
+}
+
 static void __init dt_do_vdevice(struct iseries_flat_dt *dt,
 		const char *name, u32 reg, int unit,
 		const char *type, const char *compat, int end)
@@ -641,6 +651,7 @@ void * __init build_flat_dt(unsigned lon
 	/* /chosen */
 	dt_start_node(iseries_dt, "chosen");
 	dt_prop_str(iseries_dt, "bootargs", cmd_line);
+	dt_initrd(iseries_dt);
 	dt_end_node(iseries_dt);
 
 	dt_cpus(iseries_dt);
Index: to-merge/arch/powerpc/platforms/iseries/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/iseries/setup.c
+++ to-merge/arch/powerpc/platforms/iseries/setup.c
@@ -21,7 +21,6 @@
 #include <linux/smp.h>
 #include <linux/param.h>
 #include <linux/string.h>
-#include <linux/initrd.h>
 #include <linux/seq_file.h>
 #include <linux/kdev_t.h>
 #include <linux/major.h>
@@ -80,8 +79,6 @@ extern void iSeries_pci_final_fixup(void
 static void iSeries_pci_final_fixup(void) { }
 #endif
 
-extern int rd_size;		/* Defined in drivers/block/rd.c */
-
 extern unsigned long iSeries_recal_tb;
 extern unsigned long iSeries_recal_titan;
 
@@ -295,24 +292,6 @@ static void __init iSeries_init_early(vo
 {
 	DBG(" -> iSeries_init_early()\n");
 
-#if defined(CONFIG_BLK_DEV_INITRD)
-	/*
-	 * If the init RAM disk has been configured and there is
-	 * a non-zero starting address for it, set it up
-	 */
-	if (naca.xRamDisk) {
-		initrd_start = (unsigned long)__va(naca.xRamDisk);
-		initrd_end = initrd_start + naca.xRamDiskSize * HW_PAGE_SIZE;
-		initrd_below_start_ok = 1;	// ramdisk in kernel space
-		ROOT_DEV = Root_RAM0;
-		if (((rd_size * 1024) / HW_PAGE_SIZE) < naca.xRamDiskSize)
-			rd_size = (naca.xRamDiskSize * HW_PAGE_SIZE) / 1024;
-	} else
-#endif /* CONFIG_BLK_DEV_INITRD */
-	{
-	    /* ROOT_DEV = MKDEV(VIODASD_MAJOR, 1); */
-	}
-
 	iSeries_recal_tb = get_tb();
 	iSeries_recal_titan = HvCallXm_loadTod();
 
@@ -331,17 +310,6 @@ static void __init iSeries_init_early(vo
 
 	mf_init();
 
-	/* If we were passed an initrd, set the ROOT_DEV properly if the values
-	 * look sensible. If not, clear initrd reference.
-	 */
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
-	    initrd_end > initrd_start)
-		ROOT_DEV = Root_RAM0;
-	else
-		initrd_start = initrd_end = 0;
-#endif /* CONFIG_BLK_DEV_INITRD */
-
 	DBG(" <- iSeries_init_early()\n");
 }
 

^ permalink raw reply

* Re: [PATCH] enable RTAS /proc for PowerPC/CHRP platform
From: Nicolas DET @ 2006-10-18  5:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: akpm, linuxppc-dev, Sven Luther, tilmann
In-Reply-To: <20061017132243.GA6773@lst.de>

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

Christoph Hellwig wrote:
 >> --- a/arch/powerpc/kernel/rtas-proc.c    2006-10-14 
05:34:03.000000000 +0200
 >> +++ b/arch/powerpc/kernel/rtas-proc.c    2006-10-16 
10:46:16.000000000 +0200
 >> @@ -253,43 +253,70 @@ static void get_location_code(struct seq
 >>  static void check_location_string(struct seq_file *m, char *c);
 >>  static void check_location(struct seq_file *m, char *c);
 >>
 >> +#ifdef CONFIG_PPC64
 >> +#define PROCRTAS_ROOT "ppc64"
 >> +#else
 >> +#define PROCRTAS_ROOT "ppc"
 >
 > Please don't do any pathname changes.  Even if ppc64 isn't correct it's
 > what applications expect and what we should provide for a coherent user
 > interface.

Humm, ok.
However, in this case 'ppc' (could be 32 or 64 as it is not specified) 
is more generic than 'ppc64'.

 > This should be the only change you need, and it should follow kernel
 > coding style, aka:
 >
 >     if (!machine_is(pseries) && !machine_is(chrp))
 >         return -ENODEV;
 >
 >>      rtas_node = of_find_node_by_name(NULL, "rtas");
 >>      if (rtas_node == NULL)
 >>          return -ENODEV;
 >
 > And given this check I wonder why we need the platform check at all.  It
 > should be safe to just remove it.
 >
 >

Indeed, however I can only test on CHRP. I'll remove the check in the 
upcomming patch.

The patch also include a small code to create the /proc/ppc/rtas entry. 
Should this be done here, or somewhere in arch/powerpc/chrp/setup.c ?

I will re submit a patch as soon as I can.

[-- Attachment #2: nd.vcf --]
[-- Type: text/x-vcard, Size: 249 bytes --]

begin:vcard
fn:Nicolas DET ( bplan GmbH )
n:DET;Nicolas
org:bplan GmbH
adr:;;;;;;Germany
email;internet:nd@bplan-gmbh.de
title:Software Entwicklung
tel;work:+49 6171 9187 - 31
x-mozilla-html:FALSE
url:http://www.bplan-gmbh.de
version:2.1
end:vcard


^ permalink raw reply

* Re: kernel BUG in __cache_alloc_node at linux-2.6.git/mm/slab.c:3177!
From: Paul Mackerras @ 2006-10-18  6:11 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: akpm, linuxppc-dev, linux-kernel
In-Reply-To: <Pine.LNX.4.64.0610161630430.8341@schroedinger.engr.sgi.com>

Christoph,

I also am hitting this BUG on a POWER5 partition.  The relevant boot
messages are:

Zone PFN ranges:
  DMA             0 ->   524288
  Normal     524288 ->   524288
early_node_map[3] active PFN ranges
    1:        0 ->    32768
    0:    32768 ->   278528
    1:   278528 ->   524288
[boot]0015 Setup Done
Built 2 zonelists.  Total pages: 513760
Kernel command line: root=/dev/sdc3
[snip]
freeing bootmem node 0
freeing bootmem node 1
Memory: 2046852k/2097152k available (5512k kernel code, 65056k reserved, 2204k data, 554k bss, 256k init)
kernel BUG in __cache_alloc_node at /home/paulus/kernel/powerpc/mm/slab.c:3177!

Since this is a virtualized system there is every possibility that the
memory we get won't be divided into nodes in the nice neat manner you
seem to be expecting.  It just depends on what memory the hypervisor
has free, and on what nodes, when the partition is booted.

In other words, the assumption that node pfn ranges won't overlap is
completely untenable for us.

Linus' tree is currently broken for us.  Any suggestions for how to
fix it, since I am not very familiar with the NUMA code?

Paul.

^ permalink raw reply

* Re: [PATCH] enable RTAS /proc for PowerPC/CHRP platform
From: Sven Luther @ 2006-10-18  6:05 UTC (permalink / raw)
  To: Nicolas DET; +Cc: akpm, linuxppc-dev, Sven Luther, tilmann
In-Reply-To: <4535C0F8.1070905@bplan-gmbh.de>

On Wed, Oct 18, 2006 at 07:51:52AM +0200, Nicolas DET wrote:
> Christoph Hellwig wrote:
> >> --- a/arch/powerpc/kernel/rtas-proc.c    2006-10-14 
> 05:34:03.000000000 +0200
> >> +++ b/arch/powerpc/kernel/rtas-proc.c    2006-10-16 
> 10:46:16.000000000 +0200
> >> @@ -253,43 +253,70 @@ static void get_location_code(struct seq
> >>  static void check_location_string(struct seq_file *m, char *c);
> >>  static void check_location(struct seq_file *m, char *c);
> >>
> >> +#ifdef CONFIG_PPC64
> >> +#define PROCRTAS_ROOT "ppc64"
> >> +#else
> >> +#define PROCRTAS_ROOT "ppc"
> >
> > Please don't do any pathname changes.  Even if ppc64 isn't correct it's
> > what applications expect and what we should provide for a coherent user
> > interface.
> 
> Humm, ok.
> However, in this case 'ppc' (could be 32 or 64 as it is not specified) 
> is more generic than 'ppc64'.

Christoph, Nicolas, ...

What about doing the logical thing, and switching it to "powerpc" like the
recent arch change, or more logically, to "power" like the current rebranding
of the whole thing ?

I suppose we can also provide some symlinking or similar for compatibility ?
Or move the whole stuff under /sys/.../power/rtas ? 

Friendly,

Sven Luther

^ permalink raw reply

* Re: [PATCH] enable RTAS /proc for PowerPC/CHRP platform
From: Michael Ellerman @ 2006-10-18  6:15 UTC (permalink / raw)
  To: Nicolas DET; +Cc: akpm, linuxppc-dev, Sven Luther, tilmann
In-Reply-To: <4535C0F8.1070905@bplan-gmbh.de>

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

On Wed, 2006-10-18 at 07:51 +0200, Nicolas DET wrote:
> Christoph Hellwig wrote:
>  >> --- a/arch/powerpc/kernel/rtas-proc.c    2006-10-14 
> 05:34:03.000000000 +0200
>  >> +++ b/arch/powerpc/kernel/rtas-proc.c    2006-10-16 
> 10:46:16.000000000 +0200
>  >> @@ -253,43 +253,70 @@ static void get_location_code(struct seq
>  >>  static void check_location_string(struct seq_file *m, char *c);
>  >>  static void check_location(struct seq_file *m, char *c);
>  >>
>  >> +#ifdef CONFIG_PPC64
>  >> +#define PROCRTAS_ROOT "ppc64"
>  >> +#else
>  >> +#define PROCRTAS_ROOT "ppc"
>  >
>  > Please don't do any pathname changes.  Even if ppc64 isn't correct it's
>  > what applications expect and what we should provide for a coherent user
>  > interface.
> 
> Humm, ok.
> However, in this case 'ppc' (could be 32 or 64 as it is not specified) 
> is more generic than 'ppc64'.

But it's called '/proc/ppc64' right now on lots of machines, so you
can't go changing it.

>  > This should be the only change you need, and it should follow kernel
>  > coding style, aka:
>  >
>  >     if (!machine_is(pseries) && !machine_is(chrp))
>  >         return -ENODEV;
>  >
>  >>      rtas_node = of_find_node_by_name(NULL, "rtas");
>  >>      if (rtas_node == NULL)
>  >>          return -ENODEV;
>  >
>  > And given this check I wonder why we need the platform check at all.  It
>  > should be safe to just remove it.
>  >
>  >
> 
> Indeed, however I can only test on CHRP. I'll remove the check in the 
> upcomming patch.

That should be fine AFAICT, you should probably just check that each of
the proc routines checks for errors - ie. just because you have an
"/rtas" node doesn't mean you necessarily have "/rtas/set-indicator" or
whatever.

> The patch also include a small code to create the /proc/ppc/rtas entry. 
> Should this be done here, or somewhere in arch/powerpc/chrp/setup.c ?

That code is almost entirely the same as proc_ppc64_create(), so I think
you should try and merge them - we want to minimise the number of
foo_ppc64() and foo_ppc32() routines we have.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* Problem in EHCI controller Driver and NEC D720100 chip set
From: Balaji N @ 2006-10-18  6:27 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <30d8ddcf0610172247u3d536fa3h96ee13cdafde92ef@mail.gmail.com>

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

Hi,
   I am working on NEC D720100 chip set and I configured the EHCI, OHCI
controller drivers in the kernel 2.6.11. When the kernel boots,  it gave the
following error on the EHCI controller.

ehci_hcd 0000:00:11.2: Unlink after no-IRQ?  Controller is probably using
the wrong IRQ.
For OHCI controllers, it gave the following error.

ohci_hcd 0000:00:11.1: bogus NDP=255, rereads as NDP=255
ohci_hcd 0000:00:11.0: bogus NDP=255, rereads as NDP=255

I do not know that what is the problem. Please give ur suggestions to solve
this problem.

Thanks
  -N.Balaji

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

^ permalink raw reply

* Re: [PATCH] enable RTAS /proc for PowerPC/CHRP platform
From: Nicolas DET @ 2006-10-18  6:34 UTC (permalink / raw)
  To: michael; +Cc: akpm, linuxppc-dev, Sven Luther, tilmann
In-Reply-To: <1161152109.7906.6.camel@localhost.localdomain>

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

Michael Ellerman wrote:

 >>  >> +#ifdef CONFIG_PPC64
 >>  >> +#define PROCRTAS_ROOT "ppc64"
 >>  >> +#else
 >>  >> +#define PROCRTAS_ROOT "ppc"
 >>  >
 >>  > Please don't do any pathname changes.  Even if ppc64 isn't 
correct it's
 >>  > what applications expect and what we should provide for a 
coherent user
 >>  > interface.
 >>
 >> Humm, ok.
 >> However, in this case 'ppc' (could be 32 or 64 as it is not specified)
 >> is more generic than 'ppc64'.
 >
 > But it's called '/proc/ppc64' right now on lots of machines, so you
 > can't go changing it.

Ok. No problem


 >>
 >> Indeed, however I can only test on CHRP. I'll remove the check in the
 >> upcomming patch.
 >
 > That should be fine AFAICT, you should probably just check that each of
 > the proc routines checks for errors - ie. just because you have an
 > "/rtas" node doesn't mean you necessarily have "/rtas/set-indicator" or
 > whatever.

ok

 >
 >> The patch also include a small code to create the /proc/ppc/rtas entry.
 >> Should this be done here, or somewhere in arch/powerpc/chrp/setup.c ?
 >
 > That code is almost entirely the same as proc_ppc64_create(), so I think
 > you should try and merge them - we want to minimise the number of
 > foo_ppc64() and foo_ppc32() routines we have.
 >

Ok.
proc_ppc64_create() is now locate in arch/powerpc/kernel/proc_ppc64.c. 
Maybe a new file could be created (arch/powerpc/kernel/proc_ppc.c) ?

Any other suggestions?

Just indicate me the direction, and I would provide others patches.

Regards

[-- Attachment #2: nd.vcf --]
[-- Type: text/x-vcard, Size: 249 bytes --]

begin:vcard
fn:Nicolas DET ( bplan GmbH )
n:DET;Nicolas
org:bplan GmbH
adr:;;;;;;Germany
email;internet:nd@bplan-gmbh.de
title:Software Entwicklung
tel;work:+49 6171 9187 - 31
x-mozilla-html:FALSE
url:http://www.bplan-gmbh.de
version:2.1
end:vcard


^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH 2/2] Add support for dumping spu info from xmon
From: Michael Ellerman @ 2006-10-18  6:56 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <452E7E8E.8000808@am.sony.com>

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

On Thu, 2006-10-12 at 10:42 -0700, Geoff Levand wrote:
> Michael Ellerman wrote:
> > This patch adds a command to xmon for dumping information about
> > spu structs. The command is 'sf' for "spu fields" perhaps, and
> > takes the spu number as an argument. This is the same value as the
> > spu->number field, or the "phys-id" value of a context when it is
> > bound to a physical spu.
> 
> > +static void dump_spu_fields(struct spu *spu)
> > +{
> ...
> > +	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
> > +	DUMP_FIELD(spu, "0x%p", priv1);
> > +
> > +	if (spu->priv1)
> > +		DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW);
> > +
> > +	DUMP_FIELD(spu, "0x%p", priv2);
> 
> Just to let you know, I've been doing some work to abstract the platform
> specific parts out of the spu support to better support running on a
> hypervisor.  It shouldn't make much difference, but maybe I'll try to set
> something up like this for you:
>  
> 	DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
> 	DUMP_FIELD(spu, "0x%p", priv2);
> 	spu_dump_platform_fields(spu);

We already have the spu_priv1_ops abstracted out, is that not enough? I
decided to check explicitly for the priv1 pointer because calling the
hypervisor from a panicked kernel is risky at best. Although I haven't
seen how you guys implement hypervisor calls, so perhaps it's not so
bad.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* Re: [PATCH 1/2] Add support for stopping spus from xmon
From: Michael Ellerman @ 2006-10-18  7:13 UTC (permalink / raw)
  To: Linas Vepstas; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <20061012161845.GY4381@austin.ibm.com>

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

On Thu, 2006-10-12 at 11:18 -0500, Linas Vepstas wrote:
> On Thu, Oct 12, 2006 at 10:03:08PM +1000, Michael Ellerman wrote:
> > 
> >  arch/powerpc/platforms/cell/spu_base.c |    4 
> >  arch/powerpc/xmon/xmon.c               |  142 ++++++++++++++++++++++++++++++++-
> >  include/asm-powerpc/xmon.h             |    2 
> >  3 files changed, 146 insertions(+), 2 deletions(-)
> 
> The next patch adds another 60 lines to xmon.c, which 
> is already a bit too big. Perhaps you could instead
> put this code in "xmon/cell.c" or something like that?

I did originally, but that requires exporting several globals from
xmon.c, which struck me as even less pleasant.

I looked at some way of wrapping the if(setjmp) .. logic into a
function, but I couldn't come up with anything neat in the little time I
had.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* Re: [PATCH 1/2] Add support for stopping spus from xmon
From: Michael Ellerman @ 2006-10-18  7:14 UTC (permalink / raw)
  To: Luke Browning; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <OF47E899DB.A06D1502-ON83257206.00106CF2-83257206.00122A1D@us.ibm.com>

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

On Fri, 2006-10-13 at 01:18 -0200, Luke Browning wrote:
> 
> linuxppc-dev-bounces+lukebrowning=us.ibm.com@ozlabs.org wrote on
> 10/12/2006 09:03:08 AM:
> 
> > This patch adds support for stopping, and restarting, spus
> > from xmon. We use the spu master runcntl bit to stop execution,
> > this is apparently the "right" way to control spu execution and
> > spufs will be changed in the future to use this bit.
> > 
> > Testing has shown that to restart execution we have to turn the
> > master runcntl bit on and also rewrite the spu runcntl bit, even
> > if it is already set to 1 (running).
> > 
> > Stopping spus is triggered by the xmon command 'ss' - "spus stop"
> > perhaps. Restarting them is triggered via 'sr'. Restart doesn't
> > start execution on spus unless they were running prior to being
> > stopped by xmon.
> > 
> > Walking the spu->full_list in xmon after a panic, would mean
> > corruption of any spu struct would make all the others
> > inaccessible. To avoid this, and also to make the next patch
> > easier, we cache pointers to all spus during boot.
> 
> The spe affinity code drop created an array of spu pointers that 
> is indexed by spu->number.  We have a couple of other fields in 
> there that are needed for multiple spu scheduling operations.   
> Maybe, you can use this array.  The name of the arry is lspu[] 
> for logical spus. 

I'll have a look at it, but part of the rationale for xmon keeping its
own array is that there should be no code during normal kernel operation
that touches that array, and therefore less chance that a programming
error will corrupt the array.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* Re: [PATCH 1/2] Add support for stopping spus from xmon
From: Michael Ellerman @ 2006-10-18  7:16 UTC (permalink / raw)
  To: Haren Myneni; +Cc: linuxppc-dev, Arnd Bergmann, cbe-oss-dev
In-Reply-To: <452F03AB.7030505@us.ibm.com>

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

On Thu, 2006-10-12 at 20:10 -0700, Haren Myneni wrote:
> Michael Ellerman wrote:
> 
> >This patch adds support for stopping, and restarting, spus
> >from xmon. We use the spu master runcntl bit to stop execution,
> >this is apparently the "right" way to control spu execution and
> >spufs will be changed in the future to use this bit.
> >
> >Testing has shown that to restart execution we have to turn the
> >master runcntl bit on and also rewrite the spu runcntl bit, even
> >if it is already set to 1 (running).
> >
> >Stopping spus is triggered by the xmon command 'ss' - "spus stop"
> >perhaps. Restarting them is triggered via 'sr'. Restart doesn't
> >start execution on spus unless they were running prior to being
> >stopped by xmon.
> >
> >Walking the spu->full_list in xmon after a panic, would mean
> >corruption of any spu struct would make all the others
> >inaccessible. To avoid this, and also to make the next patch
> >easier, we cache pointers to all spus during boot.
> >
> >We attempt to catch and recover from errors while stopping and
> >restarting the spus, but as with most xmon functionality there are
> >no guarantees that performing these operations won't crash xmon
> >itself.
> >
> >  
> >
> I think, kdump also need stop_spus() functionality when the dump support 
> is included on cell. If so, how about both stop_spus() and start_spus() 
> in platforms/cell/.

Good point. We haven't got that far with kdump on cell so I hadn't
thought of it. We won't need start_spus(), but we will need something to
stop spus for kdump. I'll leave it for now, but keep it in mind for when
we get kdump going on cell.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* Re: [PATCH] enable RTAS /proc for PowerPC/CHRP platform
From: Olaf Hering @ 2006-10-18  7:38 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: akpm, linuxppc-dev, tilmann, Sven Luther
In-Reply-To: <1161152109.7906.6.camel@localhost.localdomain>

On Wed, Oct 18, Michael Ellerman wrote:

> But it's called '/proc/ppc64' right now on lots of machines, so you
> can't go changing it.

if test -d /proc/ppc64 .. is a quick way to check wether the system is
64bit or not. Similar to if test -d /proc/iSeries ..
You better leave that simple interface.

^ permalink raw reply

* [PATCH/RFC] Refactor powerpc DMA ops
From: Benjamin Herrenschmidt @ 2006-10-18  7:57 UTC (permalink / raw)
  To: linuxppc-dev list

This patch completely refactors DMA operations for 64 bits powerpc. 32 bits
is untouched for now (though also untested yet thus I might still have broken
something :). The patch is definitely not yet ready for upstream as some
platforms will still not build/run. It works for powermac and pseries as it
is though (not ebus yet though).

The basic idea is to define an auxilliary structure (struct device_ext) that
can be attached to any struct device in the system. We use the "firmware_data"
pointer to reference it for now, though I kept that very isolated so I can
change it in the future, especially if I get my way with Greg KH and add a
sysdata pointer to struct device instead.

This structure holds the optional OF device node pointer, the DMA ops and
associated void *data (to be used by the ops, typically, the iommu table
pointer for machines with more than one), and a numa node id (if useful)
to constraint consistent memory allocs.

The old vio, pci-iommu and pci-direct DMA ops are gone. They are now replaced
by a set of generic iommu and direct DMA ops (non PCI specific) that can be
used by bus types.

In the case of busses we control completely, like vio, the bus layer will
fill up this structure and all is easy (see the changes to vio.c, ebus will
get a similar treatement as soon as I get to it).

In the case of "foreign" busses like PCI, what I've done is that I create
the data structure in the PCI fixup code (which is run after discovery but
before the struct device is actually registered with the core, as PCI keeps
those two steps separate) and use the old ppc_md. callbacks that I renamed
for consistency, to setup the iommu table pointer if necessary. By default
the dma_ops are set to the content of a global pci_dma_ops that your platform
can set. So if you have no iommu, you can just set that dma_direct_ops and
not implement any of the callbacks.

I need to add a similar callback (or a pair, not sure yet) to handle the
platform and of_platform busses. In fact, I'm not yet sure wether I'll make
the existing pair of callbacks more generic and take a struct device * instead
of pci_device * (and thus rename it again)... though it's unclear what to do
with the one taking a pci_bus as an argument. Also the current implementation
for pSeries is very PCI centric, but I can just test the bus type in there and
make sure it only ever does anything on PCI. So at first, I think I'll just
add a separate callback for of_platform devices.

So it's all here for comments. I hope to have a more polished/finished/tested
version tomorrow or friday but I'm posting it as-is for reviews anyway since
I might have overlooked additional possible cleanups.

Cheers,
Ben.


Index: linux-cell/include/asm-powerpc/device_ext.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/device_ext.h	2006-10-18 17:34:55.000000000 +1000
@@ -0,0 +1,43 @@
+#ifndef _POWERPC_DEVICE_EXT_H
+#define _POWERPC_DEVICE_EXT_H
+#ifdef __KERNEL__
+
+struct dma_mapping_ops;
+struct device_node;
+
+/*
+ * Auxilliary data structure that can be attached to any struct device
+ * in the system. (Currently using firmware_data, though I'd like to
+ * see a system_data in there instead).
+ *
+ * The structure can be wrapped within a bus-type specific data structure.
+ *
+ * There are no strict lifetime rules for this structure, it's entirely up
+ * to the bus to manage it's lifetime.
+ */
+struct device_ext {
+	/* Optional pointer to an OF device node */
+	struct device_node	*of_node;
+
+	/* DMA operations on that device */
+	struct dma_mapping_ops	*dma_ops;
+	void			*dma_data;
+
+	/* NUMA node if applicable */
+	int			numa_node;
+};
+
+/* Provide accessors in case we move it to some other field */
+static inline struct device_ext *device_get_ext(const struct device *dev)
+{
+	return dev->firmware_data;
+}
+
+static inline void device_set_ext(struct device *dev, struct device_ext *ext)
+{
+	dev->firmware_data = ext;
+}
+
+
+#endif /* __KERNEL__ */
+#endif /* _POWERPC_DEVICE_EXT_H */
Index: linux-cell/arch/powerpc/kernel/dma_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/dma_64.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/dma_64.c	2006-10-18 17:34:55.000000000 +1000
@@ -13,49 +13,55 @@
 #include <asm/ibmebus.h>
 #include <asm/scatterlist.h>
 #include <asm/bug.h>
+#include <asm/device_ext.h>
+#include <asm/iommu.h>
+#include <asm/abs_addr.h>
+
+/*
+ * Top level DMA callbacks
+ */
 
 static struct dma_mapping_ops *get_dma_ops(struct device *dev)
 {
-#ifdef CONFIG_PCI
-	if (dev->bus == &pci_bus_type)
-		return &pci_dma_ops;
-#endif
-#ifdef CONFIG_IBMVIO
-	if (dev->bus == &vio_bus_type)
-		return &vio_dma_ops;
-#endif
-#ifdef CONFIG_IBMEBUS
-	if (dev->bus == &ibmebus_bus_type)
-		return &ibmebus_dma_ops;
-#endif
-	return NULL;
+	struct device_ext *dext;
+
+	/* --> If we ever want to handle ISA devices passing NULL here,
+	 * do it right there.
+	 */
+
+	dext = device_get_ext(dev);
+
+	if (unlikely(dext == NULL))
+		return NULL;
+	return dext->dma_ops;
 }
 
 int dma_supported(struct device *dev, u64 mask)
 {
 	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
 
-	BUG_ON(!dma_ops);
-
+	if (unlikely(dma_ops == NULL))
+		return 0;
+	if (dma_ops->dma_supported == NULL)
+		return 1;
 	return dma_ops->dma_supported(dev, mask);
 }
 EXPORT_SYMBOL(dma_supported);
 
 int dma_set_mask(struct device *dev, u64 dma_mask)
 {
-#ifdef CONFIG_PCI
-	if (dev->bus == &pci_bus_type)
-		return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
-#ifdef CONFIG_IBMVIO
-	if (dev->bus == &vio_bus_type)
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (unlikely(dma_ops == NULL))
 		return -EIO;
-#endif /* CONFIG_IBMVIO */
-#ifdef CONFIG_IBMEBUS
-	if (dev->bus == &ibmebus_bus_type)
+
+	if (dma_ops->set_dma_mask != NULL)
+		return dma_ops->set_dma_mask(dev, dma_mask);
+
+	if (!dev->dma_mask || !dma_supported(dev, *dev->dma_mask))
 		return -EIO;
-#endif
-	BUG();
+
+	*dev->dma_mask = dma_mask;
 	return 0;
 }
 EXPORT_SYMBOL(dma_set_mask);
@@ -149,3 +155,196 @@ void dma_unmap_sg(struct device *dev, st
 	dma_ops->unmap_sg(dev, sg, nhwentries, direction);
 }
 EXPORT_SYMBOL(dma_unmap_sg);
+
+
+/*
+ * Generic iommu implementation
+ */
+
+static inline unsigned long device_to_mask(struct device *dev)
+{
+	if (dev->dma_mask && *dev->dma_mask)
+		return *dev->dma_mask;
+	/* Assume devices without mask can take 32 bit addresses */
+	return 0xfffffffful;
+}
+
+
+/* Allocates a contiguous real buffer and creates mappings over it.
+ * Returns the virtual address of the buffer and sets dma_handle
+ * to the dma address (mapping) of the first page.
+ */
+static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
+				      dma_addr_t *dma_handle, gfp_t flag)
+{
+	struct device_ext *dext = device_get_ext(dev);
+
+	if (unlikely(dext == NULL))
+		return NULL;
+	return iommu_alloc_coherent(dext->dma_data, size, dma_handle,
+				    device_to_mask(dev), flag,
+				    dext->numa_node);
+}
+
+static void dma_iommu_free_coherent(struct device *dev, size_t size,
+				    void *vaddr, dma_addr_t dma_handle)
+{
+	struct device_ext *dext = device_get_ext(dev);
+
+	if (unlikely(dext == NULL))
+		return;
+	iommu_free_coherent(dext->dma_data, size, vaddr, dma_handle);
+}
+
+/* Creates TCEs for a user provided buffer.  The user buffer must be
+ * contiguous real kernel storage (not vmalloc).  The address of the buffer
+ * passed here is the kernel (virtual) address of the buffer.  The buffer
+ * need not be page aligned, the dma_addr_t returned will point to the same
+ * byte within the page as vaddr.
+ */
+static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
+				       size_t size,
+				       enum dma_data_direction direction)
+{
+	struct device_ext *dext = device_get_ext(dev);
+
+	if (unlikely(dext == NULL))
+		return DMA_ERROR_CODE;
+	return iommu_map_single(dext->dma_data, vaddr, size,
+			        device_to_mask(dev), direction);
+}
+
+
+static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
+				   size_t size,
+				   enum dma_data_direction direction)
+{
+	struct device_ext *dext = device_get_ext(dev);
+
+	if (unlikely(dext == NULL))
+		return;
+	iommu_unmap_single(dext->dma_data, dma_handle, size, direction);
+}
+
+
+static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
+			    int nelems, enum dma_data_direction direction)
+{
+	struct device_ext *dext = device_get_ext(dev);
+
+	if (unlikely(dext == NULL))
+		return -ENXIO;
+	return iommu_map_sg(dext->dma_data, sglist, nelems,
+			    device_to_mask(dev), direction);
+}
+
+static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
+		int nelems, enum dma_data_direction direction)
+{
+	struct device_ext *dext = device_get_ext(dev);
+
+	if (unlikely(dext == NULL))
+		return;
+	iommu_unmap_sg(dext->dma_data, sglist, nelems, direction);
+}
+
+/* We support DMA to/from any memory page via the iommu */
+static int dma_iommu_dma_supported(struct device *dev, u64 mask)
+{
+	struct device_ext *dext = device_get_ext(dev);
+	struct iommu_table *tbl = dext->dma_data;
+
+	if (!tbl || tbl->it_offset > mask) {
+		printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
+		if (tbl)
+			printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
+				mask, tbl->it_offset);
+		else
+			printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
+				mask);
+		return 0;
+	} else
+		return 1;
+}
+
+struct dma_mapping_ops dma_iommu_ops = {
+	.alloc_coherent	= dma_iommu_alloc_coherent,
+	.free_coherent	= dma_iommu_free_coherent,
+	.map_single	= dma_iommu_map_single,
+	.unmap_single	= dma_iommu_unmap_single,
+	.map_sg		= dma_iommu_map_sg,
+	.unmap_sg	= dma_iommu_unmap_sg,
+	.dma_supported	= dma_iommu_dma_supported,
+};
+
+
+/*
+ * Generic direct DMA implementation
+ */
+
+static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *dma_handle, gfp_t flag)
+{
+	void *ret;
+
+	/* TODO: Maybe use the numa node here too ? */
+	ret = (void *)__get_free_pages(flag, get_order(size));
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_abs(ret);
+	}
+	return ret;
+}
+
+static void dma_direct_free_coherent(struct device *dev, size_t size,
+				     void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
+					size_t size,
+					enum dma_data_direction direction)
+{
+	return virt_to_abs(ptr);
+}
+
+static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
+				    size_t size,
+				    enum dma_data_direction direction)
+{
+}
+
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg,
+			     int nents, enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; i++, sg++) {
+		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_length = sg->length;
+	}
+
+	return nents;
+}
+
+static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
+				int nents, enum dma_data_direction direction)
+{
+}
+
+static int dma_direct_dma_supported(struct device *dev, u64 mask)
+{
+	return mask < 0x100000000ull;
+}
+
+struct dma_mapping_ops dma_direct_ops = {
+	.alloc_coherent	= dma_direct_alloc_coherent,
+	.free_coherent	= dma_direct_free_coherent,
+	.map_single	= dma_direct_map_single,
+	.unmap_single	= dma_direct_unmap_single,
+	.map_sg		= dma_direct_map_sg,
+	.unmap_sg	= dma_direct_unmap_sg,
+	.dma_supported	= dma_direct_dma_supported,
+};
+
Index: linux-cell/arch/powerpc/kernel/iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/iommu.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/iommu.c	2006-10-18 17:34:55.000000000 +1000
@@ -247,9 +247,9 @@ static void iommu_free(struct iommu_tabl
 	spin_unlock_irqrestore(&(tbl->it_lock), flags);
 }
 
-int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
-		struct scatterlist *sglist, int nelems,
-		unsigned long mask, enum dma_data_direction direction)
+int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
+		 int nelems, unsigned long mask,
+		 enum dma_data_direction direction)
 {
 	dma_addr_t dma_next = 0, dma_addr;
 	unsigned long flags;
Index: linux-cell/arch/powerpc/kernel/pci_direct_iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_direct_iommu.c	2006-10-18 17:33:45.000000000 +1000
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,98 +0,0 @@
-/*
- * Support for DMA from PCI devices to main memory on
- * machines without an iommu or with directly addressable
- * RAM (typically a pmac with 2Gb of RAM or less)
- *
- * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/mm.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/abs_addr.h>
-#include <asm/ppc-pci.h>
-
-static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
-				   dma_addr_t *dma_handle, gfp_t flag)
-{
-	void *ret;
-
-	ret = (void *)__get_free_pages(flag, get_order(size));
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = virt_to_abs(ret);
-	}
-	return ret;
-}
-
-static void pci_direct_free_coherent(struct device *hwdev, size_t size,
-				 void *vaddr, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long)vaddr, get_order(size));
-}
-
-static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr,
-		size_t size, enum dma_data_direction direction)
-{
-	return virt_to_abs(ptr);
-}
-
-static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
-		size_t size, enum dma_data_direction direction)
-{
-}
-
-static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg,
-		int nents, enum dma_data_direction direction)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
-		sg->dma_length = sg->length;
-	}
-
-	return nents;
-}
-
-static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg,
-		int nents, enum dma_data_direction direction)
-{
-}
-
-static int pci_direct_dma_supported(struct device *dev, u64 mask)
-{
-	return mask < 0x100000000ull;
-}
-
-static struct dma_mapping_ops pci_direct_ops = {
-	.alloc_coherent = pci_direct_alloc_coherent,
-	.free_coherent = pci_direct_free_coherent,
-	.map_single = pci_direct_map_single,
-	.unmap_single = pci_direct_unmap_single,
-	.map_sg = pci_direct_map_sg,
-	.unmap_sg = pci_direct_unmap_sg,
-	.dma_supported = pci_direct_dma_supported,
-};
-
-void __init pci_direct_iommu_init(void)
-{
-	pci_dma_ops = pci_direct_ops;
-}
Index: linux-cell/arch/powerpc/kernel/pci_iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_iommu.c	2006-10-18 17:33:45.000000000 +1000
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- *
- * Rewrite, cleanup, new allocation schemes:
- * Copyright (C) 2004 Olof Johansson, IBM Corporation
- *
- * Dynamic DMA mapping support, platform-independent parts.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/iommu.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/ppc-pci.h>
-
-/*
- * We can use ->sysdata directly and avoid the extra work in
- * pci_device_to_OF_node since ->sysdata will have been initialised
- * in the iommu init code for all devices.
- */
-#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
-
-static inline struct iommu_table *device_to_table(struct device *hwdev)
-{
-	struct pci_dev *pdev;
-
-	if (!hwdev) {
-		pdev = ppc64_isabridge_dev;
-		if (!pdev)
-			return NULL;
-	} else
-		pdev = to_pci_dev(hwdev);
-
-	return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
-}
-
-
-static inline unsigned long device_to_mask(struct device *hwdev)
-{
-	struct pci_dev *pdev;
-
-	if (!hwdev) {
-		pdev = ppc64_isabridge_dev;
-		if (!pdev) /* This is the best guess we can do */
-			return 0xfffffffful;
-	} else
-		pdev = to_pci_dev(hwdev);
-
-	if (pdev->dma_mask)
-		return pdev->dma_mask;
-
-	/* Assume devices without mask can take 32 bit addresses */
-	return 0xfffffffful;
-}
-
-
-/* Allocates a contiguous real buffer and creates mappings over it.
- * Returns the virtual address of the buffer and sets dma_handle
- * to the dma address (mapping) of the first page.
- */
-static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
-			   dma_addr_t *dma_handle, gfp_t flag)
-{
-	return iommu_alloc_coherent(device_to_table(hwdev), size, dma_handle,
-			device_to_mask(hwdev), flag,
-			pcibus_to_node(to_pci_dev(hwdev)->bus));
-}
-
-static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	iommu_free_coherent(device_to_table(hwdev), size, vaddr, dma_handle);
-}
-
-/* Creates TCEs for a user provided buffer.  The user buffer must be 
- * contiguous real kernel storage (not vmalloc).  The address of the buffer
- * passed here is the kernel (virtual) address of the buffer.  The buffer
- * need not be page aligned, the dma_addr_t returned will point to the same
- * byte within the page as vaddr.
- */
-static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
-		size_t size, enum dma_data_direction direction)
-{
-	return iommu_map_single(device_to_table(hwdev), vaddr, size,
-			        device_to_mask(hwdev), direction);
-}
-
-
-static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle,
-		size_t size, enum dma_data_direction direction)
-{
-	iommu_unmap_single(device_to_table(hwdev), dma_handle, size, direction);
-}
-
-
-static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
-{
-	return iommu_map_sg(pdev, device_to_table(pdev), sglist,
-			nelems, device_to_mask(pdev), direction);
-}
-
-static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
-{
-	iommu_unmap_sg(device_to_table(pdev), sglist, nelems, direction);
-}
-
-/* We support DMA to/from any memory page via the iommu */
-static int pci_iommu_dma_supported(struct device *dev, u64 mask)
-{
-	struct iommu_table *tbl = device_to_table(dev);
-
-	if (!tbl || tbl->it_offset > mask) {
-		printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
-		if (tbl)
-			printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
-				mask, tbl->it_offset);
-		else
-			printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
-				mask);
-		return 0;
-	} else
-		return 1;
-}
-
-struct dma_mapping_ops pci_iommu_ops = {
-	.alloc_coherent = pci_iommu_alloc_coherent,
-	.free_coherent = pci_iommu_free_coherent,
-	.map_single = pci_iommu_map_single,
-	.unmap_single = pci_iommu_unmap_single,
-	.map_sg = pci_iommu_map_sg,
-	.unmap_sg = pci_iommu_unmap_sg,
-	.dma_supported = pci_iommu_dma_supported,
-};
-
-void pci_iommu_init(void)
-{
-	pci_dma_ops = pci_iommu_ops;
-}
Index: linux-cell/include/asm-powerpc/dma-mapping.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/dma-mapping.h	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/include/asm-powerpc/dma-mapping.h	2006-10-18 17:34:55.000000000 +1000
@@ -65,6 +65,33 @@ extern int dma_map_sg(struct device *dev
 extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 		int nhwentries, enum dma_data_direction direction);
 
+/*
+ * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
+ */
+struct dma_mapping_ops {
+	void *		(*alloc_coherent)(struct device *dev, size_t size,
+				dma_addr_t *dma_handle, gfp_t flag);
+	void		(*free_coherent)(struct device *dev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+	dma_addr_t	(*map_single)(struct device *dev, void *ptr,
+				size_t size, enum dma_data_direction direction);
+	void		(*unmap_single)(struct device *dev, dma_addr_t dma_addr,
+				size_t size, enum dma_data_direction direction);
+	int		(*map_sg)(struct device *dev, struct scatterlist *sg,
+				int nents, enum dma_data_direction direction);
+	void		(*unmap_sg)(struct device *dev, struct scatterlist *sg,
+				int nents, enum dma_data_direction direction);
+	int		(*dma_supported)(struct device *dev, u64 mask);
+	int		(*dac_dma_supported)(struct device *dev, u64 mask);
+	int		(*set_dma_mask)(struct device *dev, u64 dma_mask);
+};
+
+/*
+ * Available generic sets of operations
+ */
+extern struct dma_mapping_ops dma_iommu_ops;
+extern struct dma_mapping_ops dma_direct_ops;
+
 #else /* CONFIG_PPC64 */
 
 #define dma_supported(dev, mask)	(1)
@@ -261,25 +288,5 @@ static inline void dma_cache_sync(void *
 	__dma_sync(vaddr, size, (int)direction);
 }
 
-/*
- * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
- */
-struct dma_mapping_ops {
-	void *		(*alloc_coherent)(struct device *dev, size_t size,
-				dma_addr_t *dma_handle, gfp_t flag);
-	void		(*free_coherent)(struct device *dev, size_t size,
-				void *vaddr, dma_addr_t dma_handle);
-	dma_addr_t	(*map_single)(struct device *dev, void *ptr,
-				size_t size, enum dma_data_direction direction);
-	void		(*unmap_single)(struct device *dev, dma_addr_t dma_addr,
-				size_t size, enum dma_data_direction direction);
-	int		(*map_sg)(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction direction);
-	void		(*unmap_sg)(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction direction);
-	int		(*dma_supported)(struct device *dev, u64 mask);
-	int		(*dac_dma_supported)(struct device *dev, u64 mask);
-};
-
 #endif /* __KERNEL__ */
 #endif	/* _ASM_DMA_MAPPING_H */
Index: linux-cell/include/asm-powerpc/iommu.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/iommu.h	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/include/asm-powerpc/iommu.h	2006-10-18 17:34:55.000000000 +1000
@@ -69,22 +69,22 @@ extern void iommu_free_table(struct devi
 extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
 					    int nid);
 
-extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
-		struct scatterlist *sglist, int nelems, unsigned long mask,
-		enum dma_data_direction direction);
+extern int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
+			int nelems, unsigned long mask,
+			enum dma_data_direction direction);
 extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction);
+			   int nelems, enum dma_data_direction direction);
 
 extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
-		dma_addr_t *dma_handle, unsigned long mask,
-		gfp_t flag, int node);
+				  dma_addr_t *dma_handle, unsigned long mask,
+				  gfp_t flag, int node);
 extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
-		void *vaddr, dma_addr_t dma_handle);
+				void *vaddr, dma_addr_t dma_handle);
 extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
-		size_t size, unsigned long mask,
-		enum dma_data_direction direction);
+				   size_t size, unsigned long mask,
+				   enum dma_data_direction direction);
 extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
-		size_t size, enum dma_data_direction direction);
+			       size_t size, enum dma_data_direction direction);
 
 extern void iommu_init_early_pSeries(void);
 extern void iommu_init_early_iSeries(void);
Index: linux-cell/arch/powerpc/kernel/vio.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/vio.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/vio.c	2006-10-18 17:34:55.000000000 +1000
@@ -81,15 +81,15 @@ static struct iommu_table *vio_build_iom
 		struct iommu_table *tbl;
 		unsigned long offset, size;
 
-		dma_window = get_property(dev->dev.platform_data,
-				"ibm,my-dma-window", NULL);
+		dma_window = get_property(dev->dext.of_node,
+					  "ibm,my-dma-window", NULL);
 		if (!dma_window)
 			return NULL;
 
 		tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
 
-		of_parse_dma_window(dev->dev.platform_data, dma_window,
-				&tbl->it_index, &offset, &size);
+		of_parse_dma_window(dev->dext.of_node, dma_window,
+				    &tbl->it_index, &offset, &size);
 
 		/* TCE table size - measured in tce entries */
 		tbl->it_size = size >> PAGE_SHIFT;
@@ -115,9 +115,11 @@ static struct iommu_table *vio_build_iom
 static const struct vio_device_id *vio_match_device(
 		const struct vio_device_id *ids, const struct vio_dev *dev)
 {
+	struct device_ext *dext = device_get_ext(&dev->dev);
+
 	while (ids->type[0] != '\0') {
 		if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
-		    device_is_compatible(dev->dev.platform_data, ids->compat))
+		    device_is_compatible(dext->of_node, ids->compat))
 			return ids;
 		ids++;
 	}
@@ -198,9 +200,11 @@ EXPORT_SYMBOL(vio_unregister_driver);
 /* vio_dev refcount hit 0 */
 static void __devinit vio_dev_release(struct device *dev)
 {
-	if (dev->platform_data) {
+	struct device_ext *dext = device_get_ext(dev);
+
+	if (dext && dext->of_node) {
 		/* XXX free TCE table */
-		of_node_put(dev->platform_data);
+		of_node_put(dext->of_node);
 	}
 	kfree(to_vio_dev(dev));
 }
@@ -210,7 +214,7 @@ static void __devinit vio_dev_release(st
  * @of_node:	The OF node for this device.
  *
  * Creates and initializes a vio_dev structure from the data in
- * of_node (dev.platform_data) and adds it to the list of virtual devices.
+ * of_node and adds it to the list of virtual devices.
  * Returns a pointer to the created vio_dev or NULL if node has
  * NULL device_type or compatible fields.
  */
@@ -240,8 +244,6 @@ struct vio_dev * __devinit vio_register_
 	if (viodev == NULL)
 		return NULL;
 
-	viodev->dev.platform_data = of_node_get(of_node);
-
 	viodev->irq = irq_of_parse_and_map(of_node, 0);
 
 	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
@@ -254,7 +256,10 @@ struct vio_dev * __devinit vio_register_
 		if (unit_address != NULL)
 			viodev->unit_address = *unit_address;
 	}
-	viodev->iommu_table = vio_build_iommu_table(viodev);
+	device_set_ext(&viodev->dev, &viodev->dext);
+	viodev->dext.of_node = of_node_get(of_node);
+	viodev->dext.dma_ops = &dma_iommu_ops;
+	viodev->dext.dma_data = vio_build_iommu_table(viodev);
 
 	/* init generic 'struct device' fields: */
 	viodev->dev.parent = &vio_bus_device.dev;
@@ -282,13 +287,16 @@ static int __init vio_bus_init(void)
 	int err;
 	struct device_node *node_vroot;
 
+	device_set_ext(&vio_bus_device.dev, &vio_bus_device.dext);
+
 #ifdef CONFIG_PPC_ISERIES
 	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
 		iommu_vio_init();
-		vio_bus_device.iommu_table = &vio_iommu_table;
+		vio_bus_device.dext.dma_ops = &dma_iommu_ops;
+		vio_bus_device.dext.dma_data = &vio_iommu_table;
 		iSeries_vio_dev = &vio_bus_device.dev;
 	}
-#endif
+#endif /* CONFIG_PPC_ISERIES */
 
 	err = bus_register(&vio_bus_type);
 	if (err) {
@@ -336,7 +344,8 @@ static ssize_t name_show(struct device *
 static ssize_t devspec_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct device_node *of_node = dev->platform_data;
+	struct device_ext *dext = device_get_ext(dev);
+	struct device_node *of_node = dext->of_node;
 
 	return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
 }
@@ -353,62 +362,6 @@ void __devinit vio_unregister_device(str
 }
 EXPORT_SYMBOL(vio_unregister_device);
 
-static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
-			  size_t size, enum dma_data_direction direction)
-{
-	return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
-			~0ul, direction);
-}
-
-static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
-		      size_t size, enum dma_data_direction direction)
-{
-	iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size,
-			direction);
-}
-
-static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
-{
-	return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
-			nelems, ~0ul, direction);
-}
-
-static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
-{
-	iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction);
-}
-
-static void *vio_alloc_coherent(struct device *dev, size_t size,
-			   dma_addr_t *dma_handle, gfp_t flag)
-{
-	return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
-			dma_handle, ~0ul, flag, -1);
-}
-
-static void vio_free_coherent(struct device *dev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr,
-			dma_handle);
-}
-
-static int vio_dma_supported(struct device *dev, u64 mask)
-{
-	return 1;
-}
-
-struct dma_mapping_ops vio_dma_ops = {
-	.alloc_coherent = vio_alloc_coherent,
-	.free_coherent = vio_free_coherent,
-	.map_single = vio_map_single,
-	.unmap_single = vio_unmap_single,
-	.map_sg = vio_map_sg,
-	.unmap_sg = vio_unmap_sg,
-	.dma_supported = vio_dma_supported,
-};
-
 static int vio_bus_match(struct device *dev, struct device_driver *drv)
 {
 	const struct vio_dev *vio_dev = to_vio_dev(dev);
@@ -422,13 +375,17 @@ static int vio_hotplug(struct device *de
 			char *buffer, int buffer_size)
 {
 	const struct vio_dev *vio_dev = to_vio_dev(dev);
-	struct device_node *dn = dev->platform_data;
+	struct device_ext *dext = device_get_ext(dev);
+	struct device_node *dn;
 	const char *cp;
 	int length;
 
 	if (!num_envp)
 		return -ENOMEM;
+	if (!dext)
+		return -ENODEV;
 
+	dn = dext->of_node;
 	if (!dn)
 		return -ENODEV;
 	cp = get_property(dn, "compatible", &length);
@@ -465,7 +422,9 @@ struct bus_type vio_bus_type = {
 */
 const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length)
 {
-	return get_property(vdev->dev.platform_data, which, length);
+	struct device_ext *dext = device_get_ext(&vdev->dev);
+
+	return get_property(dext->of_node, which, length);
 }
 EXPORT_SYMBOL(vio_get_attribute);
 
Index: linux-cell/include/asm-powerpc/vio.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/vio.h	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/include/asm-powerpc/vio.h	2006-10-18 17:34:55.000000000 +1000
@@ -23,6 +23,7 @@
 
 #include <asm/hvcall.h>
 #include <asm/scatterlist.h>
+#include <asm/device_ext.h>
 
 /*
  * Architecture-specific constants for drivers to
@@ -45,12 +46,12 @@ struct iommu_table;
  * The vio_dev structure is used to describe virtual I/O devices.
  */
 struct vio_dev {
-	struct iommu_table *iommu_table;     /* vio_map_* uses this */
 	const char *name;
 	const char *type;
 	uint32_t unit_address;
 	unsigned int irq;
 	struct device dev;
+	struct device_ext dext;
 };
 
 struct vio_driver {
Index: linux-cell/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_64.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/pci_64.c	2006-10-18 17:34:55.000000000 +1000
@@ -31,6 +31,7 @@
 #include <asm/machdep.h>
 #include <asm/ppc-pci.h>
 #include <asm/firmware.h>
+#include <asm/device_ext.h>
 
 #ifdef DEBUG
 #include <asm/udbg.h>
@@ -63,7 +64,7 @@ void iSeries_pcibios_init(void);
 
 LIST_HEAD(hose_list);
 
-struct dma_mapping_ops pci_dma_ops;
+struct dma_mapping_ops *pci_dma_ops;
 EXPORT_SYMBOL(pci_dma_ops);
 
 int global_phb_number;		/* Global phb counter */
@@ -1207,15 +1208,43 @@ void __devinit pcibios_fixup_device_reso
 }
 EXPORT_SYMBOL(pcibios_fixup_device_resources);
 
+void __devinit pcibios_setup_new_device(struct pci_dev *dev)
+{
+	struct device_ext *dext;
+
+	if (device_get_ext(&dev->dev) != NULL)
+		return;
+
+	dext = kzalloc(sizeof(struct device_ext), GFP_KERNEL);
+	if (dext == NULL) {
+		printk(KERN_ERR "Failed to allocate device extension"
+		       " for PCI device %s\n", pci_name(dev));
+		return;
+	}
+	device_set_ext(&dev->dev, dext);
+	dext->of_node = pci_device_to_OF_node(dev);
+	printk("PCI device %s OF node: %s\n", pci_name(dev),
+	       dext->of_node ? dext->of_node->full_name : "<none>");
+	dext->dma_ops = pci_dma_ops;
+
+#ifdef CONFIG_NUMA
+	dext->numa_node = pcibus_to_node(dev->bus);
+#endif
+	if (ppc_md.pci_dma_dev_setup)
+		ppc_md.pci_dma_dev_setup(dev);
+}
+EXPORT_SYMBOL(pcibios_setup_new_device);
 
 static void __devinit do_bus_setup(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
 
-	ppc_md.iommu_bus_setup(bus);
+	if (ppc_md.pci_dma_bus_setup)
+		ppc_md.pci_dma_bus_setup(bus);
 
-	list_for_each_entry(dev, &bus->devices, bus_list)
-		ppc_md.iommu_dev_setup(dev);
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		pcibios_setup_new_device(dev);
+	}
 
 	if (ppc_md.irq_bus_setup)
 		ppc_md.irq_bus_setup(bus);
@@ -1419,3 +1448,25 @@ int pcibus_to_node(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pcibus_to_node);
 #endif
+
+int pci_platform_notify(struct device * dev)
+{
+	return 0;
+}
+
+int pci_platform_notify_remove(struct device * dev)
+{
+	struct device_ext *dext = device_get_ext(dev);
+
+	DBG("%s:%s platform notify remove !\n",
+	    dev_driver_string(dev), dev->bus_id);
+
+	if (dev->bus != &pci_bus_type)
+		return 0;
+
+	device_set_ext(dev, NULL);
+	mb();
+	kfree(dext);
+
+	return 0;
+}
Index: linux-cell/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/setup_64.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/setup_64.c	2006-10-18 17:34:55.000000000 +1000
@@ -33,6 +33,7 @@
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
 #include <linux/bootmem.h>
+#include <linux/pci.h>
 #include <asm/io.h>
 #include <asm/kdump.h>
 #include <asm/prom.h>
@@ -533,6 +534,10 @@ void __init setup_arch(char **cmdline_p)
 	conswitchp = &dummy_con;
 #endif
 
+#ifdef CONFIG_PCI
+	platform_notify = pci_platform_notify;
+	platform_notify_remove = pci_platform_notify_remove;
+#endif
 	ppc_md.setup_arch();
 
 	paging_init();
Index: linux-cell/arch/powerpc/platforms/pseries/iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/iommu.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/pseries/iommu.c	2006-10-18 17:34:55.000000000 +1000
@@ -44,6 +44,7 @@
 #include <asm/tce.h>
 #include <asm/ppc-pci.h>
 #include <asm/udbg.h>
+#include <asm/device_ext.h>
 
 #include "plpar_wrappers.h"
 
@@ -329,7 +330,7 @@ static void iommu_table_setparms_lpar(st
 	tbl->it_size = size >> PAGE_SHIFT;
 }
 
-static void iommu_bus_setup_pSeries(struct pci_bus *bus)
+static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
 {
 	struct device_node *dn;
 	struct iommu_table *tbl;
@@ -338,10 +339,9 @@ static void iommu_bus_setup_pSeries(stru
 	struct pci_dn *pci;
 	int children;
 
-	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
-
 	dn = pci_bus_to_OF_node(bus);
-	pci = PCI_DN(dn);
+
+	DBG("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name);
 
 	if (bus->self) {
 		/* This is not a root bus, any setup will be done for the
@@ -349,6 +349,7 @@ static void iommu_bus_setup_pSeries(stru
 		 */
 		return;
 	}
+	pci = PCI_DN(dn);
 
 	/* Check if the ISA bus on the system is under
 	 * this PHB.
@@ -410,17 +411,17 @@ static void iommu_bus_setup_pSeries(stru
 }
 
 
-static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
+static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
 {
 	struct iommu_table *tbl;
 	struct device_node *dn, *pdn;
 	struct pci_dn *ppci;
 	const void *dma_window = NULL;
 
-	DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
-
 	dn = pci_bus_to_OF_node(bus);
 
+	DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name);
+
 	/* Find nearest ibm,dma-window, walking up the device tree */
 	for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
 		dma_window = get_property(pdn, "ibm,dma-window", NULL);
@@ -429,11 +430,15 @@ static void iommu_bus_setup_pSeriesLP(st
 	}
 
 	if (dma_window == NULL) {
-		DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name);
+		DBG("  no ibm,dma-window property !\n");
 		return;
 	}
 
 	ppci = PCI_DN(pdn);
+
+	DBG("  parent is %s, iommu_table: 0x%p\n",
+	    pdn->full_name, ppci->iommu_table);
+
 	if (!ppci->iommu_table) {
 		/* Bussubno hasn't been copied yet.
 		 * Do it now because iommu_table_setparms_lpar needs it.
@@ -447,6 +452,7 @@ static void iommu_bus_setup_pSeriesLP(st
 		iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
 
 		ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
+		DBG("  created table: %p\n", ppci->iommu_table);
 	}
 
 	if (pdn != dn)
@@ -454,27 +460,34 @@ static void iommu_bus_setup_pSeriesLP(st
 }
 
 
-static void iommu_dev_setup_pSeries(struct pci_dev *dev)
+static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
 {
-	struct device_node *dn, *mydn;
+	struct device_ext *dext = device_get_ext(&dev->dev);
+	struct device_node *dn;
 	struct iommu_table *tbl;
 
-	DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev));
+	DBG("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev));
+
+	if (dext == NULL) {
+		printk(KERN_ERR "iommu: Attempt to setup PCI dev %s "
+		       "with no device extension !", pci_name(dev));
+		return;
+	}
 
-	mydn = dn = pci_device_to_OF_node(dev);
+	dn = dext->of_node;
 
 	/* If we're the direct child of a root bus, then we need to allocate
 	 * an iommu table ourselves. The bus setup code should have setup
 	 * the window sizes already.
 	 */
 	if (!dev->bus->self) {
+		struct pci_controller *phb = PCI_DN(dn)->phb;
+
 		DBG(" --> first child, no bridge. Allocating iommu table.\n");
 		tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
-				   PCI_DN(dn)->phb->node);
-		iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
-		PCI_DN(dn)->iommu_table = iommu_init_table(tbl,
-						PCI_DN(dn)->phb->node);
-
+				   phb->node);
+		iommu_table_setparms(phb, dn, tbl);
+		dext->dma_data = iommu_init_table(tbl, phb->node);
 		return;
 	}
 
@@ -485,11 +498,11 @@ static void iommu_dev_setup_pSeries(stru
 	while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL)
 		dn = dn->parent;
 
-	if (dn && PCI_DN(dn)) {
-		PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
-	} else {
-		DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));
-	}
+	if (dn && PCI_DN(dn))
+		dext->dma_data = PCI_DN(dn)->iommu_table;
+	else
+		printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
+		       pci_name(dev));
 }
 
 static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
@@ -515,14 +528,21 @@ static struct notifier_block iommu_recon
 	.notifier_call = iommu_reconfig_notifier,
 };
 
-static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
+static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
 {
+	struct device_ext *dext = device_get_ext(&dev->dev);
 	struct device_node *pdn, *dn;
 	struct iommu_table *tbl;
 	const void *dma_window = NULL;
 	struct pci_dn *pci;
 
-	DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
+	DBG("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev));
+
+	if (dext == NULL) {
+		printk(KERN_ERR "iommu: Attempt to setup PCI dev %s "
+		       "with no device extension !", pci_name(dev));
+		return;
+	}
 
 	/* dev setup for LPAR is a little tricky, since the device tree might
 	 * contain the dma-window properties per-device and not neccesarily
@@ -531,6 +551,7 @@ static void iommu_dev_setup_pSeriesLP(st
 	 * already allocated.
 	 */
 	dn = pci_device_to_OF_node(dev);
+	DBG("  node is %s\n", dn->full_name);
 
 	for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
 	     pdn = pdn->parent) {
@@ -539,16 +560,17 @@ static void iommu_dev_setup_pSeriesLP(st
 			break;
 	}
 
+	DBG("  parent is %s\n", pdn->full_name);
+
 	/* Check for parent == NULL so we don't try to setup the empty EADS
 	 * slots on POWER4 machines.
 	 */
 	if (dma_window == NULL || pdn->parent == NULL) {
-		DBG("No dma window for device, linking to parent\n");
-		PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table;
+		DBG("  no dma window for device, linking to parent\n");
+		dext->dma_data = PCI_DN(pdn)->iommu_table;
 		return;
-	} else {
-		DBG("Found DMA window, allocating table\n");
 	}
+	DBG("  found DMA window, table: %p\n", pci->iommu_table);
 
 	pci = PCI_DN(pdn);
 	if (!pci->iommu_table) {
@@ -561,24 +583,20 @@ static void iommu_dev_setup_pSeriesLP(st
 		iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
 
 		pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
+		DBG("  created table: %p\n", pci->iommu_table);
 	}
 
-	if (pdn != dn)
-		PCI_DN(dn)->iommu_table = pci->iommu_table;
+	dext->dma_data = pci->iommu_table;
 }
 
-static void iommu_bus_setup_null(struct pci_bus *b) { }
-static void iommu_dev_setup_null(struct pci_dev *d) { }
-
 /* These are called very early. */
 void iommu_init_early_pSeries(void)
 {
 	if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) {
 		/* Direct I/O, IOMMU off */
-		ppc_md.iommu_dev_setup = iommu_dev_setup_null;
-		ppc_md.iommu_bus_setup = iommu_bus_setup_null;
-		pci_direct_iommu_init();
-
+		ppc_md.pci_dma_dev_setup = NULL;
+		ppc_md.pci_dma_bus_setup = NULL;
+		pci_dma_ops = &dma_direct_ops;
 		return;
 	}
 
@@ -591,19 +609,19 @@ void iommu_init_early_pSeries(void)
 			ppc_md.tce_free	 = tce_free_pSeriesLP;
 		}
 		ppc_md.tce_get   = tce_get_pSeriesLP;
-		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP;
-		ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP;
+		ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
+		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
 	} else {
 		ppc_md.tce_build = tce_build_pSeries;
 		ppc_md.tce_free  = tce_free_pSeries;
 		ppc_md.tce_get   = tce_get_pseries;
-		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries;
-		ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries;
+		ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeries;
+		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeries;
 	}
 
 
 	pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
 
-	pci_iommu_init();
+	pci_dma_ops = &dma_iommu_ops;
 }
 
Index: linux-cell/arch/powerpc/platforms/pseries/pci_dlpar.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/pci_dlpar.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/pseries/pci_dlpar.c	2006-10-18 17:34:55.000000000 +1000
@@ -93,8 +93,8 @@ pcibios_fixup_new_pci_devices(struct pci
 		if (list_empty(&dev->global_list)) {
 			int i;
 
-			/* Need to setup IOMMU tables */
-			ppc_md.iommu_dev_setup(dev);
+			/* Create device extension and setup iommu table */
+			pcibios_setup_new_device(dev);
 
 			if(fix_bus)
 				pcibios_fixup_device_resources(dev, bus);
Index: linux-cell/arch/powerpc/sysdev/dart_iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/sysdev/dart_iommu.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/sysdev/dart_iommu.c	2006-10-18 17:34:55.000000000 +1000
@@ -45,6 +45,7 @@
 #include <asm/cacheflush.h>
 #include <asm/lmb.h>
 #include <asm/ppc-pci.h>
+#include <asm/device_ext.h>
 
 #include "dart.h"
 
@@ -295,24 +296,23 @@ static void iommu_table_dart_setup(void)
 	set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);
 }
 
-static void iommu_dev_setup_dart(struct pci_dev *dev)
+static void pci_dma_dev_setup_dart(struct pci_dev *dev)
 {
-	struct device_node *dn;
+	struct device_ext *dext = device_get_ext(&dev->dev);
+
+	if (dext == NULL) {
+		printk(KERN_ERR "dart: Attempt to setup PCI dev %s "
+		       "with no device extension !", pci_name(dev));
+		return;
+	}
 
 	/* We only have one iommu table on the mac for now, which makes
 	 * things simple. Setup all PCI devices to point to this table
-	 *
-	 * We must use pci_device_to_OF_node() to make sure that
-	 * we get the real "final" pointer to the device in the
-	 * pci_dev sysdata and not the temporary PHB one
 	 */
-	dn = pci_device_to_OF_node(dev);
-
-	if (dn)
-		PCI_DN(dn)->iommu_table = &iommu_table_dart;
+	dext->dma_data = &iommu_table_dart;
 }
 
-static void iommu_bus_setup_dart(struct pci_bus *bus)
+static void pci_dma_bus_setup_dart(struct pci_bus *bus)
 {
 	struct device_node *dn;
 
@@ -327,9 +327,6 @@ static void iommu_bus_setup_dart(struct 
 		PCI_DN(dn)->iommu_table = &iommu_table_dart;
 }
 
-static void iommu_dev_setup_null(struct pci_dev *dev) { }
-static void iommu_bus_setup_null(struct pci_bus *bus) { }
-
 void iommu_init_early_dart(void)
 {
 	struct device_node *dn;
@@ -350,22 +347,21 @@ void iommu_init_early_dart(void)
 
 	/* Initialize the DART HW */
 	if (dart_init(dn) == 0) {
-		ppc_md.iommu_dev_setup = iommu_dev_setup_dart;
-		ppc_md.iommu_bus_setup = iommu_bus_setup_dart;
+		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart;
+		ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart;
 
 		/* Setup pci_dma ops */
-		pci_iommu_init();
-
+		pci_dma_ops = &dma_iommu_ops;
 		return;
 	}
 
  bail:
 	/* If init failed, use direct iommu and null setup functions */
-	ppc_md.iommu_dev_setup = iommu_dev_setup_null;
-	ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+	ppc_md.pci_dma_dev_setup = NULL;
+	ppc_md.pci_dma_bus_setup = NULL;
 
 	/* Setup pci_dma ops */
-	pci_direct_iommu_init();
+	pci_dma_ops = &dma_direct_ops;
 }
 
 
Index: linux-cell/include/asm-powerpc/machdep.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/machdep.h	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/include/asm-powerpc/machdep.h	2006-10-18 17:34:55.000000000 +1000
@@ -84,8 +84,8 @@ struct machdep_calls {
 	unsigned long	(*tce_get)(struct iommu_table *tbl,
 				    long index);
 	void		(*tce_flush)(struct iommu_table *tbl);
-	void		(*iommu_dev_setup)(struct pci_dev *dev);
-	void		(*iommu_bus_setup)(struct pci_bus *bus);
+	void		(*pci_dma_dev_setup)(struct pci_dev *dev);
+	void		(*pci_dma_bus_setup)(struct pci_bus *bus);
 	void		(*irq_bus_setup)(struct pci_bus *bus);
 #endif /* CONFIG_PPC64 */
 
Index: linux-cell/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/pci-bridge.h	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/include/asm-powerpc/pci-bridge.h	2006-10-18 17:34:55.000000000 +1000
@@ -161,6 +161,9 @@ static inline unsigned long pci_address_
 }
 #endif
 
+extern int pci_platform_notify(struct device * dev);
+extern int pci_platform_notify_remove(struct device * dev);
+
 /* Return values for ppc_md.pci_probe_mode function */
 #define PCI_PROBE_NONE		-1	/* Don't look at this bus at all */
 #define PCI_PROBE_NORMAL	0	/* Do normal PCI probing */
Index: linux-cell/include/asm-powerpc/pci.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/pci.h	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/include/asm-powerpc/pci.h	2006-10-18 17:34:55.000000000 +1000
@@ -76,15 +76,15 @@ static inline int pcibios_prep_mwi(struc
 	return 0;
 }
 
-extern struct dma_mapping_ops pci_dma_ops;
+extern struct dma_mapping_ops *pci_dma_ops;
 
 /* For DAC DMA, we currently don't support it by default, but
  * we let 64-bit platforms override this.
  */
 static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
 {
-	if (pci_dma_ops.dac_dma_supported)
-		return pci_dma_ops.dac_dma_supported(&hwdev->dev, mask);
+	if (pci_dma_ops && pci_dma_ops->dac_dma_supported)
+		return pci_dma_ops->dac_dma_supported(&hwdev->dev, mask);
 	return 0;
 }
 
@@ -216,6 +216,8 @@ extern int remap_bus_range(struct pci_bu
 extern void pcibios_fixup_device_resources(struct pci_dev *dev,
 			struct pci_bus *bus);
 
+extern void pcibios_setup_new_device(struct pci_dev *dev);
+
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
 extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
Index: linux-cell/arch/powerpc/kernel/Makefile
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/Makefile	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/Makefile	2006-10-18 17:34:55.000000000 +1000
@@ -64,8 +64,7 @@ obj-$(CONFIG_PPC_UDBG_16550)	+= legacy_s
 module-$(CONFIG_PPC64)		+= module_64.o
 obj-$(CONFIG_MODULES)		+= $(module-y)
 
-pci64-$(CONFIG_PPC64)		+= pci_64.o pci_dn.o pci_iommu.o \
-				   pci_direct_iommu.o iomap.o
+pci64-$(CONFIG_PPC64)		+= pci_64.o pci_dn.o iomap.o
 pci32-$(CONFIG_PPC32)		:= pci_32.o
 obj-$(CONFIG_PCI)		+= $(pci64-y) $(pci32-y)
 kexec-$(CONFIG_PPC64)		:= machine_kexec_64.o
Index: linux-cell/drivers/net/ibmveth.c
===================================================================
--- linux-cell.orig/drivers/net/ibmveth.c	2006-10-18 17:33:45.000000000 +1000
+++ linux-cell/drivers/net/ibmveth.c	2006-10-18 17:34:55.000000000 +1000
@@ -945,7 +945,7 @@ static int __devinit ibmveth_probe(struc
 	int rc, i;
 	struct net_device *netdev;
 	struct ibmveth_adapter *adapter = NULL;
-
+	struct device_ext *dext;
 	unsigned char *mac_addr_p;
 	unsigned int *mcastFilterSize_p;
 
@@ -998,7 +998,12 @@ static int __devinit ibmveth_probe(struc
 	adapter->mac_addr = 0;
 	memcpy(&adapter->mac_addr, mac_addr_p, 6);
 
-	adapter->liobn = dev->iommu_table->it_index;
+	dext = device_get_ext(&dev->dev);
+	if (dext && dext->dma_data) {
+		struct iommu_table *tbl = dext->dma_data;
+		adapter->liobn = tbl->it_index;
+	} else
+		adapter->liobn = 0;
 
 	netdev->irq = dev->irq;
 	netdev->open               = ibmveth_open;

^ permalink raw reply

* implicit declaration of function set_irq_chip_and_handler
From: Olaf Hering @ 2006-10-18  8:04 UTC (permalink / raw)
  To: Ingo Molnar, linuxppc-dev, linux-kernel


Current Linus tree has two new warnings

arch/powerpc/kernel/irq.c: In function irq_dispose_mapping:
arch/powerpc/kernel/irq.c:642: warning: implicit declaration of function set_irq_chip_and_handler
arch/powerpc/sysdev/mpic.c: In function mpic_host_map:
arch/powerpc/sysdev/mpic.c:770: warning: implicit declaration of function set_irq_chip_and_handler

It links anyway for some reason.
There is no prototype anymore, but still many users.

a460e745e8f9c75a0525ff94154a0629f9d3e05d is likely the culprit:
 [PATCH] genirq: clean up irq-flow-type naming

^ permalink raw reply

* [patch] genirq: clean up irq-flow-type naming, fix
From: Ingo Molnar @ 2006-10-18  8:16 UTC (permalink / raw)
  To: Olaf Hering; +Cc: Andrew Morton, linuxppc-dev, linux-kernel
In-Reply-To: <20061018080411.GA13340@aepfle.de>


* Olaf Hering <olaf@aepfle.de> wrote:

> There is no prototype anymore, but still many users.
> 
> a460e745e8f9c75a0525ff94154a0629f9d3e05d is likely the culprit:
>  [PATCH] genirq: clean up irq-flow-type naming

oops, that was unintended. The patch below should fix this.

	Ingo

--------------->
Subject: genirq: clean up irq-flow-type naming, fix
From: Ingo Molnar <mingo@elte.hu>

re-add the set_irq_chip_and_handler() prototype, it's still widely used.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 include/linux/irq.h |    3 +++
 1 file changed, 3 insertions(+)

Index: linux/include/linux/irq.h
===================================================================
--- linux.orig/include/linux/irq.h
+++ linux/include/linux/irq.h
@@ -322,6 +322,9 @@ extern struct irq_chip no_irq_chip;
 extern struct irq_chip dummy_irq_chip;
 
 extern void
+set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
+			 irq_flow_handler_t handle);
+extern void
 set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
 			      irq_flow_handler_t handle, const char *name);
 

^ permalink raw reply

* Re: [PATCH -rt] powerpc update
From: Ingo Molnar @ 2006-10-18  7:32 UTC (permalink / raw)
  To: Daniel Walker; +Cc: linuxppc-dev, tglx, linux-kernel
In-Reply-To: <20061018072858.GA29576@elte.hu>


* Ingo Molnar <mingo@elte.hu> wrote:

> really, the ->eoi() op should only be called for true fasteoi cases. 
> What we want here is to turn the fasteoi handler into a handler that 
> does mask+ack and then unmask. Not 'mask+eoi ... unmask' as your patch 
> does.

i.e. like the much simpler patch below. That's what i've applied to the 
soon-to-be-rt6 tree, plus the other bits of your patch. Can you confirm 
this works well on PPC?

	Ingo

Index: linux-rt.q/kernel/irq/chip.c
===================================================================
--- linux-rt.q.orig/kernel/irq/chip.c
+++ linux-rt.q/kernel/irq/chip.c
@@ -386,13 +386,15 @@ handle_fasteoi_irq(unsigned int irq, str
 	}
 
 	desc->status |= IRQ_INPROGRESS;
+
 	/*
-	 * fasteoi should not be used for threaded IRQ handlers!
+	 * In the threaded case we fall back to a mask+ack sequence:
 	 */
 	if (redirect_hardirq(desc)) {
-		WARN_ON_ONCE(1);
+		mask_ack_irq(desc, irq);
 		goto out_unlock;
 	}
+
 	desc->status &= ~IRQ_PENDING;
 	spin_unlock(&desc->lock);
 

^ permalink raw reply

* [PATCH] Fix the UCC rx tx clock of QE
From: Liu Dave-r63238 @ 2006-10-18  8:36 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

CLK16 of CMXUCR3 and CMXUCR4 registers are missed in
ucc_set_qe_mux_rxtx().
This patch adds the CLK16 to the function. MPC8323EMDS board ethernet
interface
with RMII is use the CLK16 as the rx and tx clock.

Signed-off-by: Dave Liu <daveliu@freescale.com>

---
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c
b/arch/powerpc/sysdev/qe_lib/ucc.c
index 916c9e5..ac12a44 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -207,6 +207,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enu
                case QE_CLK18:  source =3D 8; break;
                case QE_CLK7:   source =3D 9; break;
                case QE_CLK8:   source =3D 10; break;
+               case QE_CLK16:  source =3D 11; break;
                default:        source =3D -1; break;
                }
                break;
@@ -222,6 +223,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enu
                case QE_CLK22:  source =3D 8; break;
                case QE_CLK7:   source =3D 9; break;
                case QE_CLK8:   source =3D 10; break;
+               case QE_CLK16:  source =3D 11; break;
                default:        source =3D -1; break;
                }
                break;

^ permalink raw reply related

* Re: [PATCH -rt] powerpc update
From: Ingo Molnar @ 2006-10-18  7:28 UTC (permalink / raw)
  To: Daniel Walker; +Cc: linuxppc-dev, tglx, linux-kernel
In-Reply-To: <20061003155358.756788000@dwalker1.mvista.com>


* Daniel Walker <dwalker@mvista.com> wrote:

> Pay close attention to the fasteoi interrupt threading. I added usage 
> of mask/unmask instead of using level handling, which worked well on 
> PPC.

this is wrong - it should be doing mask+ack.

also note that you changed:

> -		goto out_unlock;

to:

> +		goto out;

and you even tried to hide your tracks:

>  out:
>  	desc->chip->eoi(irq);
> -out_unlock:
>  	spin_unlock(&desc->lock);

:-)

really, the ->eoi() op should only be called for true fasteoi cases. 
What we want here is to turn the fasteoi handler into a handler that 
does mask+ack and then unmask. Not 'mask+eoi ... unmask' as your patch 
does.

	Ingo

^ permalink raw reply

* About the RFI instruction on Linux Powerpc
From: Wang Matthew-R59995 @ 2006-10-18 12:49 UTC (permalink / raw)
  To: linuxppc-embedded

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

Hi folks,
 
Currently I meet an issue about rfi instruction. Please see the
following source code. This source code is contained at the
head_fsl_booke.h of ./arch/powerpc/kernel directory.
 
 xori r6,r4,1
 slwi r6,r6,5  /* setup new context with other address space */
 bl 1f  /* Find our address */
1: mflr r9
 rlwimi r7,r9,0,20,31
 addi r7,r7,24
 mtspr SPRN_SRR0,r7
 mtspr SPRN_SRR1,r6
 rfi

I found that rfi instruction can't jump to the address of SRR0. I take
the MPC8555CDS board to do those test. And I don't take U-Boot as
bootloader, while the Vxwerks Bootrom.
 
I just want to try if Bootrom can bring up the Linux Powerpc kernel.
 
Any suggestion for that?
 
B.R
Wang Qi.
E-Mail: Qi.W@freescale.com <blocked::mailto:Qi.W@freescale.com> 
 
 

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

^ permalink raw reply

* status of mpc52xx with arch=powerpc?
From: Sascha Hauer @ 2006-10-18 13:06 UTC (permalink / raw)
  To: linuxppc-embedded

Is someone working on this already?

There are some Kconfig entries, but there seems to be no code, at least
not in vanilla.

Sascha

-- 
 Dipl.-Ing. Sascha Hauer | http://www.pengutronix.de
  Pengutronix - Linux Solutions for Science and Industry
    Handelsregister: Amtsgericht Hildesheim, HRA 2686
      Hannoversche Str. 2, 31134 Hildesheim, Germany
    Phone: +49-5121-206917-0 |  Fax: +49-5121-206917-9

^ permalink raw reply

* Re: [PATCH] Fix the UCC rx tx clock of QE
From: Kumar Gala @ 2006-10-18 13:32 UTC (permalink / raw)
  To: Liu Dave-r63238; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <995B09A8299C2C44B59866F6391D26351C2E54@zch01exm21.fsl.freescale.net>

Acked-by: Kumar Gala <galak@kernel.crashing.org>

- k

On Oct 18, 2006, at 3:36 AM, Liu Dave-r63238 wrote:

> CLK16 of CMXUCR3 and CMXUCR4 registers are missed in
> ucc_set_qe_mux_rxtx().
> This patch adds the CLK16 to the function. MPC8323EMDS board ethernet
> interface
> with RMII is use the CLK16 as the rx and tx clock.
>
> Signed-off-by: Dave Liu <daveliu@freescale.com>
>
> ---
> diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c
> b/arch/powerpc/sysdev/qe_lib/ucc.c
> index 916c9e5..ac12a44 100644
> --- a/arch/powerpc/sysdev/qe_lib/ucc.c
> +++ b/arch/powerpc/sysdev/qe_lib/ucc.c
> @@ -207,6 +207,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enu
>                 case QE_CLK18:  source = 8; break;
>                 case QE_CLK7:   source = 9; break;
>                 case QE_CLK8:   source = 10; break;
> +               case QE_CLK16:  source = 11; break;
>                 default:        source = -1; break;
>                 }
>                 break;
> @@ -222,6 +223,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enu
>                 case QE_CLK22:  source = 8; break;
>                 case QE_CLK7:   source = 9; break;
>                 case QE_CLK8:   source = 10; break;
> +               case QE_CLK16:  source = 11; break;
>                 default:        source = -1; break;
>                 }
>                 break;
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ 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