* Re: [RFC/PATCH] powerpc: Rewrite IO allocation & mapping on powerpc64
From: Segher Boessenkool @ 2007-05-14 13:50 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Paul Mackerras, Anton Blanchard
In-Reply-To: <20070514075415.7999BDDEC8@ozlabs.org>
> - Cleanup and separate tracking of the ISA space in the reserved
> low 64K of IO space. No ISA -> Nothing mapped there.
> I now always reserve the first 64K of IO space for the bridge with
> the ISA bus on it.
This is wrong -- there are systems with ISA that
also have PCI devices that require 16-bit legacy
I/O windows (e.g., systems with the AMD8111 chip,
like Maple).
Or do you mean you reserve the low 64k for the PHB?
That would work in this case, but still not in
general. Not sure if we care though.
Segher
^ permalink raw reply
* Re: Small fixes for the Ebony device tree
From: Josh Boyer @ 2007-05-14 12:22 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070514045404.GP6517@localhost.localdomain>
On Mon, 2007-05-14 at 14:54 +1000, David Gibson wrote:
> This patch corrects a number of minor errors in the Ebony device tree:
> - Missing (given as 0) cache sizes are added to the CPU node
> - device_type properties are removed from nodes which don't
> have a reasonably well defined device_type binding. This does require
> a very small code change to locate the busses to be probed for
> of_platform devices by 'compatible' instead of 'device_type'.
> - A node is added for the SRAM controller
> - The unit address of the small-flash node is adjusted to
> correctly reflect the reg property.
> - device_type values for the MAL and ZMII are updated to
> reflected more up-to-date versions of the binding.
> - An incorrect offset in the partition map for the large-flash
> node is corrected.
> - Some redundant values, already commented out are removed
> entirely.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
^ permalink raw reply
* Re: [PATCH 10/13] powerpc: check cache coherency of kernel vs firmware
From: Segher Boessenkool @ 2007-05-14 12:34 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070514004014.GF6517@localhost.localdomain>
>> check_cache_coherency() verifies that the cache coherency setting of
>> the kernel (CONFIG_NOT_COHERENT_CACHE) matches that left by the
>> firmware,
>> as indicated by coherency-off device tree property.
>
> This looks really bogus. If the firmware reports a coherency state,
> then presumably there's some hardware switch to turn coherency on or
> off. In which case, can't the kernel just toggle that switch to
> whatever's appropriate for it?
But can the kernel know in all cases what is the
appropriate setting? This kind of thing is a
typical firmware job.
Segher
^ permalink raw reply
* Re: [RFC/PATCH] powerpc: Rewrite IO allocation & mapping on powerpc64
From: Benjamin Herrenschmidt @ 2007-05-14 9:18 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Anton Blanchard
In-Reply-To: <20070514075415.7999BDDEC8@ozlabs.org>
> + /* If this not a PHB, we don't do anything on mapping */
> + if (bus->self) {
> + DBG("IO mapping for PCI-PCI bridge %s\n",
> + pci_name(bus->self));
> + DBG(" virt=0x%016lx...0x%016lx\n",
> + bus->resource[0]->start + pci_io_base,
> + bus->resource[0]->end + pci_io_base);
> + return 0;
> }
Hrm... the above is incorrect. Since I iounmap_at() when removing a P2P
bridge, I need to ioremap_at() when mapping it back in. I'll fix that
in the next iteration.
One of the cool thing is that mapping over a previous mapping is
harmless, so if the PHB is inserted and create a mapping for the full
PHB range, and later on, a P2P is added to this PHB, doing an
ioremap_at() will work fine wether that sub-range was part of the
initial PHB mapping or wether it was unmapped by a previous removal of a
bridge...
Ben.
^ permalink raw reply
* Re: [PATCH] [POWERPC] Wire up some more syscalls
From: Arnd Bergmann @ 2007-05-14 9:16 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: ppc-dev, Andrew Morton, paulus
In-Reply-To: <20070514135033.07c1b840.sfr@canb.auug.org.au>
On Monday 14 May 2007, Stephen Rothwell wrote:
> This depends on the patch I just sent to declare compat_sys_signalfd and
> compat_sys_timerfd. =A0And I am assuming that the SPU's want these.
Yes, it's the right thing for SPUs.
signalfd might actually be important since we normally don't have a way
to get signals into an SPU, so some application programmers will love it.
Arnd <><
^ permalink raw reply
* Re: [patch 5/5] powerpc 2.6.21-rt1] fix clocksource_timebase.shift value
From: Tsutomu OWA @ 2007-05-14 8:23 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyisl9z97hg.wl@toshiba.co.jp>
Calculate clocksource_timebase.shift from tb_ticks_per_jiffy to get an
accurate translation, though I don't understand why current version of
clocksource_timebase.shift could be constant...
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
--- linux-2.6.21-rt1/arch/powerpc/kernel/time.c 2007-05-09 18:05:57.000000000 +0900
+++ rt/arch/powerpc/kernel/time.c 2007-05-09 18:06:24.000000000 +0900
@@ -945,6 +945,9 @@ static int __init init_timebase_clocksou
if (__USE_RTC())
return -ENODEV;
+#ifdef CONFIG_PPC64
+ clocksource_timebase.shift = tb_ticks_per_jiffy / 1000000;
+#endif
clocksource_timebase.mult = clocksource_hz2mult(tb_ticks_per_sec,
clocksource_timebase.shift);
return clocksource_register(&clocksource_timebase);
^ permalink raw reply
* Re: [patch 4/5] powerpc 2.6.21-rt1: rename mcount variable in xmon to xmon_mcount
From: Tsutomu OWA @ 2007-05-14 8:19 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyisl9z97hg.wl@toshiba.co.jp>
Rename variable name "mcount" in xmon to xmon_mcount, since it conflicts
with mcount() function used by latency trace function.
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/arch/powerpc/xmon/xmon.c rt/arch/powerpc/xmon/xmon.c
--- linux-2.6.21-rt1/arch/powerpc/xmon/xmon.c 2007-05-07 14:08:12.000000000 +0900
+++ rt/arch/powerpc/xmon/xmon.c 2007-05-07 14:05:30.000000000 +0900
@@ -2129,7 +2129,7 @@ print_address(unsigned long addr)
static unsigned long mdest; /* destination address */
static unsigned long msrc; /* source address */
static unsigned long mval; /* byte value to set memory to */
-static unsigned long mcount; /* # bytes to affect */
+static unsigned long xmon_mcount; /* # bytes to affect */
static unsigned long mdiffs; /* max # differences to print */
void
@@ -2141,19 +2141,20 @@ memops(int cmd)
scanhex((void *)(cmd == 's'? &mval: &msrc));
if( termch != '\n' )
termch = 0;
- scanhex((void *)&mcount);
+ scanhex((void *)&xmon_mcount);
switch( cmd ){
case 'm':
- memmove((void *)mdest, (void *)msrc, mcount);
+ memmove((void *)mdest, (void *)msrc, xmon_mcount);
break;
case 's':
- memset((void *)mdest, mval, mcount);
+ memset((void *)mdest, mval, xmon_mcount);
break;
case 'd':
if( termch != '\n' )
termch = 0;
scanhex((void *)&mdiffs);
- memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
+ memdiffs((unsigned char *)mdest, (unsigned char *)msrc,
+ xmon_mcount, mdiffs);
break;
}
}
^ permalink raw reply
* Re: [patch 3/5] powerpc 2.6.21-rt1: mark raw_local_irq_restore() and timebase_read() as notrace
From: Tsutomu OWA @ 2007-05-14 8:17 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyisl9z97hg.wl@toshiba.co.jp>
mark raw_local_irq_restore() and timebase_read() as notrace since
these are called from __trace().
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/arch/powerpc/kernel/irq.c rt/arch/powerpc/kernel/irq.c
--- linux-2.6.21-rt1/arch/powerpc/kernel/irq.c 2007-05-07 14:08:12.000000000 +0900
+++ rt/arch/powerpc/kernel/irq.c 2007-05-07 14:05:30.000000000 +0900
@@ -111,7 +111,7 @@ static inline void set_soft_enabled(unsi
: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
}
-void raw_local_irq_restore(unsigned long en)
+void notrace raw_local_irq_restore(unsigned long en)
{
/*
* get_paca()->soft_enabled = en;
--- linux-2.6.21-rt1/arch/powerpc/kernel/time.c 2007-05-09 17:52:05.000000000 +0900
+++ rt/arch/powerpc/kernel/time.c 2007-05-09 18:03:39.000000000 +0900
@@ -923,7 +923,7 @@ void div128_by_32(u64 dividend_high, u64
#include <linux/clocksource.h>
-static cycle_t timebase_read(void)
+static cycle_t notrace timebase_read(void)
{
return (cycle_t)get_tb();
}
^ permalink raw reply
* Re: [patch 2/5] powerpc 2.6.21-rt1: dummy functions and export _mcount to compile
From: Tsutomu OWA @ 2007-05-14 8:16 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyisl9z97hg.wl@toshiba.co.jp>
add dummy functions save_stack_trace(), early_printk() for now and
export _mcount to compile.
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/arch/powerpc/kernel/setup_64.c rt/arch/powerpc/kernel/setup_64.c
--- linux-2.6.21-rt1/arch/powerpc/kernel/setup_64.c 2007-04-26 12:08:32.000000000 +0900
+++ rt/arch/powerpc/kernel/setup_64.c 2007-05-08 18:50:46.000000000 +0900
@@ -606,3 +606,22 @@ struct ppc_pci_io ppc_pci_io;
EXPORT_SYMBOL(ppc_pci_io);
#endif /* CONFIG_PPC_INDIRECT_IO */
+#ifdef CONFIG_STACKTRACE
+#include <linux/stacktrace.h>
+void notrace save_stack_trace(struct stack_trace *trace,
+ struct task_struct *task)
+{
+}
+#endif /* CONFIG_STACKTRACE */
+
+#ifdef CONFIG_EARLY_PRINTK
+void notrace early_printk(const char *fmt, ...)
+{
+ BUG();
+}
+#endif /* CONFIG_EARLY_PRINTK */
+
+#ifdef CONFIG_MCOUNT
+extern void _mcount(void);
+EXPORT_SYMBOL(_mcount);
+#endif /* CONFIG_MCOUNT */
^ permalink raw reply
* Re: [patch 1/5] powerpc 2.6.21-rt1: add mcount() and _mcount()
From: Tsutomu OWA @ 2007-05-14 8:15 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyisl9z97hg.wl@toshiba.co.jp>
add mcount() and _mcount() for latency trace support.
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/arch/powerpc/kernel/entry_64.S rt/arch/powerpc/kernel/entry_64.S
--- linux-2.6.21-rt1/arch/powerpc/kernel/entry_64.S 2007-05-07 14:08:12.000000000 +0900
+++ rt/arch/powerpc/kernel/entry_64.S 2007-05-08 18:54:07.000000000 +0900
@@ -832,3 +832,63 @@ _GLOBAL(enter_prom)
ld r0,16(r1)
mtlr r0
blr
+
+#ifdef CONFIG_MCOUNT
+/*
+ * code almost taken from entry_32.S
+ */
+#define MCOUNT_FRAME_SIZE 32
+_GLOBAL(mcount)
+ stdu r1,-MCOUNT_FRAME_SIZE(r1)
+ mflr r3
+
+ LOAD_REG_ADDR(r5,mcount_enabled)
+ lwz r5,0(r5)
+ std r3,MCOUNT_FRAME_SIZE+16(r1)
+ cmpwi r5,0
+ beq 1f
+
+ /* r3 contains lr (eip), put parent lr (parent_eip) in r4 */
+ ld r4,MCOUNT_FRAME_SIZE(r1)
+ ld r4,16(r4)
+ bl .__trace
+ nop
+1:
+ ld r0,MCOUNT_FRAME_SIZE+16(r1)
+ mtlr r0
+ addi r1,r1,MCOUNT_FRAME_SIZE
+ blr
+
+/*
+ * Based on glibc-2.4/sysdeps/powerpc/powerpc64/ppc-mcount.S
+ *
+ * We don't need to save the parameter-passing registers as gcc takes
+ * care of that for us. Thus this function looks fairly normal.
+ * In fact, the generic code would work for us.
+ */
+_GLOBAL(_mcount)
+ /* return if we're in real mode. */
+ mfmsr r3
+ andi. r0,r3,MSR_IR|MSR_DR /* see if relocation is on? */
+ beqlr /* if not, do nothing. */
+ /* we're in translation mode. keep going. */
+ mflr r3
+ ld r11,0(r1) /* load back chain ptr */
+ stdu r1,-STACK_FRAME_OVERHEAD(r1)
+ std r3,STACK_FRAME_OVERHEAD+16(r1)
+ ld r4,16(r11) /* LR in back chain */
+ LOAD_REG_ADDR(r5,mcount_enabled)
+ lwz r5,0(r5)
+ cmpwi r5,0 /* see if mcount_enabled? */
+ beq 1f /* if disabled, then skip */
+
+ /* r3 contains lr (eip), put parent lr (parent_eip) in r4 */
+ bl .__trace
+ nop
+1:
+ ld r0,STACK_FRAME_OVERHEAD+16(r1) /* restore saved LR */
+ mtlr r0
+ addi r1,r1,STACK_FRAME_OVERHEAD
+ blr
+
+#endif /* CONFIG_MCOUNT */
^ permalink raw reply
* [patch 0/5] powerpc 2.6.21-rt1] latency trace support for powerpc
From: Tsutomu OWA @ 2007-05-14 7:42 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
Hi Ingo,
Please consider for inclusion.
This series of patches adds very basic latency trace support for powerpc.
Compile, boot and trace tested (a little) on Celleb.
Thanks in advance.
-- owa
TOSHIBA, Corprate Software Engineering Center.
^ permalink raw reply
* Re: [RFC/PATCH] powerpc: Rewrite IO allocation & mapping on powerpc64
From: Benjamin Herrenschmidt @ 2007-05-14 8:03 UTC (permalink / raw)
To: linuxppc-dev
Cc: Olof Johansson, Paul Mackerras, Anton Blanchard, Arnd Bergmann
In-Reply-To: <20070514075415.7999BDDEC8@ozlabs.org>
On Mon, 2007-05-14 at 17:53 +1000, Benjamin Herrenschmidt wrote:
> - Handle allocation constraints of PIO for all bridges including
> hot plugged ones within the 2GB space reserved for IO ports,
> so that devices on hotplugged busses will now work with drivers
> that assume IO ports fit in an int.
Olof, Arnd, that should fix your problem but it's not 2.6.22 material.
I'll post a separate patch for 2.6.22 that does a temporary band aid,
basically calling pci_setup_phb_io() + remap_bus_range() rather than
pci_setup_phb_io_dynamic() from the of_device/PCI code and add a
spinlock to reserve_phb_iospace().
I found also a couple of other nits for which I'll do patches for
2.6.22. For example, we don't mask out the "tokens" at the top of IO
addresses in iounmap() which means it probably doesn't work on cell.
Ouch.
There's a number of other issues that my bigger patch fixes for which I
won't bother with a 2.6.22 backport though.
Cheers,
Ben.
^ permalink raw reply
* Re: [RFC/PATCH] powerpc: Rewrite IO allocation & mapping on powerpc64
From: Benjamin Herrenschmidt @ 2007-05-14 7:59 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Anton Blanchard
In-Reply-To: <20070514075415.7999BDDEC8@ozlabs.org>
> Note that it depends on a patch I posted earlier today to add a
> prototype for __vunmap to include/linux/vmalloc.h
Actually it's me being stupid, I can just use vunmap() without
underscores :-) Oh well, you can still review the patch, I'll add that
fix to future versions.
Ben.
^ permalink raw reply
* Re: [patch 4/4] powerpc 2.6.21-rt1: reduce scheduling latency by changing tlb flush size
From: Tsutomu OWA @ 2007-05-14 7:28 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: linuxppc-dev, mingo, linux-kernel
In-Reply-To: <1179125506.22481.297.camel@localhost.localdomain>
At Mon, 14 May 2007 08:51:46 +0200, Thomas Gleixner wrote:
> On Mon, 2007-05-14 at 15:38 +0900, Tsutomu OWA wrote:
> > As I don't know how long it takes on other platforms, it would be better to
> > enclose it within #ifdef CONFIG_PPC_CELLEB.
>
> Yes, that might be appropriate. Can you add this and resend please ?
Certainly, and thanks for your comment.
To reduce scheduling latecy by changing tlb flush size to 1.
Since tlb flush on Celleb is done by calling (an) expensive hypervisor call(s),
it takes a long time to flush tlbs and causes scheduing latency.
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
--- linux-2.6.21-rt1/include/asm-powerpc/tlbflush.h 2007-04-26 12:08:32.000000000 +0900
+++ rt/include/asm-powerpc/tlbflush.h 2007-05-14 16:12:47.000000000 +0900
@@ -25,7 +25,12 @@ struct mm_struct;
#include <linux/percpu.h>
#include <asm/page.h>
+#if defined(CONFIG_PPC_CELLEB) && defined(CONFIG_PREEMPT_RT)
+/* Since tlb flush takes long time on Celleb, reduce it to 1 when Celleb && RT */
+#define PPC64_TLB_BATCH_NR 1
+#else
#define PPC64_TLB_BATCH_NR 192
+#endif /* defined(CONFIG_PPC_CELLEB) && defined(CONFIG_PREEMPT_RT) */
struct ppc64_tlb_batch {
unsigned long index;
^ permalink raw reply
* [RFC/PATCH] powerpc: Rewrite IO allocation & mapping on powerpc64
From: Benjamin Herrenschmidt @ 2007-05-14 7:53 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Anton Blanchard
This patch rewrites pretty much from scratch the handling of
MMIO and PIO space allocations on powerpc64. The main goals
are:
- Get rid of imalloc and use more common code where possible
- Simplify the current mess so that PIO space is allocated and
mapped in a single place for PCI bridges
- Handle allocation constraints of PIO for all bridges including
hot plugged ones within the 2GB space reserved for IO ports,
so that devices on hotplugged busses will now work with drivers
that assume IO ports fit in an int.
- Cleanup and separate tracking of the ISA space in the reserved
low 64K of IO space. No ISA -> Nothing mapped there.
The patch is mostly untested ! This is not aimed at 2.6.22 but
rather the next merge window since it's pretty big and we need to
test well the hotplug stuff among others.
With this patch, all allocations are done using the code in
mm/vmalloc.c, though we use the low level __get_vm_area with
explicit start/stop constraints in order to manage separate
areas for vmalloc/vmap, ioremap, and PCI IOs.
This greatly simplifies a lot of things, as you can see in the
diffstat of that patch :-)
A new pair of functions pcibios_map/unmap_io_space() now replace
all of the previous code that used to manipulate PCI IOs space.
The allocation is done at mapping time, which is now called from
scan_phb's, just before the devices are probed (instead of after,
which is by itself a bug fix). The only other caller is the PCI
hotplug code for hot adding PCI-PCI bridges (slots).
imalloc is gone, as is the "sub-allocation" thing, but I do beleive
that hotplug should still work in the sense that the space allocation
is always done by the PHB, but if you unmap a child bus of this PHB
(which seems to be possible), then the code should properly tear
down all the PTE mappings for that area of the PHB allocated IO space.
I now always reserve the first 64K of IO space for the bridge with
the ISA bus on it. I have moved the code for tracking ISA in a separate
file which should also make it smarter if we ever are capable of
hot unplugging or re-plugging an ISA bridge.
This should have a side effect on platforms like powermac where VGA IOs
will no longer work. This is done on purpose though as they would have
worked semi-randomly before. The idea at this point is to isolate drivers
that might need to access those and fix them by providing a proper
function to obtain an offset to the legacy IOs of a given bus.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Note that it depends on a patch I posted earlier today to add a
prototype for __vunmap to include/linux/vmalloc.h
arch/powerpc/kernel/Makefile | 2
arch/powerpc/kernel/isa-bridge.c | 271 +++++++++++++++++++++++
arch/powerpc/kernel/of_platform.c | 6
arch/powerpc/kernel/pci_64.c | 291 +++++++------------------
arch/powerpc/kernel/rtas_pci.c | 7
arch/powerpc/mm/Makefile | 3
arch/powerpc/mm/imalloc.c | 313 ---------------------------
arch/powerpc/mm/mmu_decl.h | 12 -
arch/powerpc/mm/pgtable_64.c | 201 ++++-------------
arch/powerpc/platforms/cell/io-workarounds.c | 2
arch/powerpc/platforms/maple/pci.c | 35 ---
arch/powerpc/platforms/pasemi/pci.c | 20 -
arch/powerpc/platforms/powermac/pci.c | 32 --
arch/powerpc/platforms/pseries/pci_dlpar.c | 2
drivers/pci/hotplug/rpadlpar_core.c | 6
include/asm-powerpc/floppy.h | 6
include/asm-powerpc/io.h | 15 -
include/asm-powerpc/pci-bridge.h | 6
include/asm-powerpc/pci.h | 4
include/asm-powerpc/pgtable-ppc64.h | 22 +
include/asm-powerpc/ppc-pci.h | 2
21 files changed, 450 insertions(+), 808 deletions(-)
Index: linux-cell/include/asm-powerpc/pgtable-ppc64.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/pgtable-ppc64.h 2007-05-10 13:21:05.000000000 +1000
+++ linux-cell/include/asm-powerpc/pgtable-ppc64.h 2007-05-14 16:43:03.000000000 +1000
@@ -27,7 +27,7 @@ struct mm_struct;
*/
#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
-#define PGTABLE_RANGE (1UL << PGTABLE_EADDR_SIZE)
+#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
#if TASK_SIZE_USER64 > PGTABLE_RANGE
#error TASK_SIZE_USER64 exceeds pagetable range
@@ -37,19 +37,27 @@ struct mm_struct;
#error TASK_SIZE_USER64 exceeds user VSID range
#endif
+
/*
* Define the address range of the vmalloc VM area.
*/
#define VMALLOC_START ASM_CONST(0xD000000000000000)
-#define VMALLOC_SIZE ASM_CONST(0x80000000000)
+#define VMALLOC_SIZE (PGTABLE_RANGE >> 1)
#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
/*
- * Define the address range of the imalloc VM area.
- */
-#define PHBS_IO_BASE VMALLOC_END
-#define IMALLOC_BASE (PHBS_IO_BASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */
-#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE)
+ * Define the address ranges for MMIO and IO space :
+ *
+ * ISA_IO_BASE = VMALLOC_END, 64K reserved area
+ * PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces
+ * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE
+ */
+#define ISA_IO_BASE (VMALLOC_END)
+#define ISA_IO_END (VMALLOC_END + 0x10000ul)
+#define PHB_IO_BASE (ISA_IO_END)
+#define PHB_IO_END (VMALLOC_END + 0x80000000ul)
+#define IOREMAP_BASE (PHB_IO_END)
+#define IOREMAP_END (VMALLOC_START + PGTABLE_RANGE)
/*
* Region IDs
Index: linux-cell/arch/powerpc/kernel/Makefile
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/Makefile 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/Makefile 2007-05-14 16:43:03.000000000 +1000
@@ -65,7 +65,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
+pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o isa-bridge.o
pci32-$(CONFIG_PPC32) := pci_32.o
obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
obj-$(CONFIG_PCI_MSI) += msi.o
Index: linux-cell/arch/powerpc/kernel/isa-bridge.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/arch/powerpc/kernel/isa-bridge.c 2007-05-14 16:43:03.000000000 +1000
@@ -0,0 +1,271 @@
+/*
+ * Routines for tracking a legacy ISA bridge
+ *
+ * Copyrigh 2007 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * Some bits and pieces moved over from pci_64.c
+ *
+ * Copyrigh 2003 Anton Blanchard <anton@au.ibm.com>, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/notifier.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/firmware.h>
+
+unsigned long isa_io_base; /* NULL if no ISA bus */
+EXPORT_SYMBOL(isa_io_base);
+
+/* Cached ISA bridge dev. */
+static struct device_node *isa_bridge_devnode;
+struct pci_dev *isa_bridge_pcidev;
+EXPORT_SYMBOL_GPL(isa_bridge_pcidev);
+
+#define ISA_SPACE_MASK 0x1
+#define ISA_SPACE_IO 0x1
+
+static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
+ unsigned long phb_io_base_phys)
+{
+ /* We should get some saner parsing here and remove these structs */
+ struct pci_address {
+ u32 a_hi;
+ u32 a_mid;
+ u32 a_lo;
+ };
+
+ struct isa_address {
+ u32 a_hi;
+ u32 a_lo;
+ };
+
+ struct isa_range {
+ struct isa_address isa_addr;
+ struct pci_address pci_addr;
+ unsigned int size;
+ };
+
+ const struct isa_range *range;
+ unsigned long pci_addr;
+ unsigned int isa_addr;
+ unsigned int size;
+ int rlen = 0;
+
+ range = of_get_property(isa_node, "ranges", &rlen);
+ if (range == NULL || (rlen < sizeof(struct isa_range)))
+ goto inval_range;
+
+ /* From "ISA Binding to 1275"
+ * The ranges property is laid out as an array of elements,
+ * each of which comprises:
+ * cells 0 - 1: an ISA address
+ * cells 2 - 4: a PCI address
+ * (size depending on dev->n_addr_cells)
+ * cell 5: the size of the range
+ */
+ if ((range->isa_addr.a_hi && ISA_SPACE_MASK) != ISA_SPACE_IO) {
+ range++;
+ rlen -= sizeof(struct isa_range);
+ if (rlen < sizeof(struct isa_range))
+ goto inval_range;
+ }
+ if ((range->isa_addr.a_hi && ISA_SPACE_MASK) != ISA_SPACE_IO)
+ goto inval_range;
+
+ isa_addr = range->isa_addr.a_lo;
+ pci_addr = (unsigned long) range->pci_addr.a_mid << 32 |
+ range->pci_addr.a_lo;
+
+ /* Assume these are both zero. Note: We could fix that and
+ * do a proper parsing instead ... oh well, that will do for
+ * now as nobody uses fancy mappings for ISA bridges
+ */
+ if ((pci_addr != 0) || (isa_addr != 0)) {
+ printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
+ __FUNCTION__);
+ return;
+ }
+
+ /* Align size and make sure it's cropped to 64K */
+ size = PAGE_ALIGN(range->size);
+ if (size > 0x10000)
+ size = 0x10000;
+
+ printk(KERN_ERR "no ISA IO ranges or unexpected isa range,"
+ "mapping 64k\n");
+
+ __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
+ size, _PAGE_NO_CACHE|_PAGE_GUARDED);
+ return;
+
+inval_range:
+ printk(KERN_ERR "no ISA IO ranges or unexpected isa range,"
+ "mapping 64k\n");
+ __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
+ 0x10000, _PAGE_NO_CACHE|_PAGE_GUARDED);
+}
+
+
+/**
+ * isa_bridge_find_early - Find and map the ISA IO space early before
+ * main PCI discovery. This is optionally called by
+ * the arch code when adding PCI PHBs to get early
+ * access to ISA IO ports
+ */
+void __init isa_bridge_find_early(struct pci_controller *hose)
+{
+ struct device_node *np, *parent = NULL, *tmp;
+
+ /* If we already have an ISA bridge, bail off */
+ if (isa_bridge_devnode != NULL)
+ return;
+
+ /* For each "isa" node in the system. Note : we do a search by
+ * type and not by name. It might be better to do by name but that's
+ * what the code used to do and I don't want to break too much at
+ * once. We can look into changing that separately
+ */
+ for_each_node_by_type(np, "isa") {
+ /* Look for our hose being a parent */
+ for (parent = of_get_parent(np); parent;) {
+ if (parent == hose->arch_data) {
+ of_node_put(parent);
+ break;
+ }
+ tmp = parent;
+ parent = of_get_parent(parent);
+ of_node_put(tmp);
+ }
+ if (parent != NULL)
+ break;
+ }
+ if (np == NULL)
+ return;
+ isa_bridge_devnode = np;
+
+ /* Now parse the "ranges" property and setup the ISA mapping */
+ pci_process_ISA_OF_ranges(np, hose->io_base_phys);
+
+ /* Set the global ISA io base to indicate we have an ISA bridge */
+ isa_io_base = ISA_IO_BASE;
+
+ pr_debug("ISA bridge (early) is %s\n", np->full_name);
+}
+
+/**
+ * isa_bridge_find_late - Find and map the ISA IO space upon discovery of
+ * a new ISA bridge
+ */
+static void isa_bridge_find_late(struct pci_dev *pdev,
+ struct device_node *devnode)
+{
+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+
+ /* Store ISA device node and PCI device */
+ isa_bridge_devnode = of_node_get(devnode);
+ isa_bridge_pcidev = pdev;
+
+ /* Now parse the "ranges" property and setup the ISA mapping */
+ pci_process_ISA_OF_ranges(devnode, hose->io_base_phys);
+
+ /* Set the global ISA io base to indicate we have an ISA bridge */
+ isa_io_base = ISA_IO_BASE;
+
+ pr_debug("ISA bridge (late) is %s on %s\n",
+ devnode->full_name, pci_name(pdev));
+}
+
+/**
+ * isa_bridge_remove - Remove/unmap an ISA bridge
+ */
+static void isa_bridge_remove(void)
+{
+ pr_debug("ISA bridge removed !\n");
+
+ /* Clear the global ISA io base to indicate that we have no more
+ * ISA bridge. Note that drivers don't quite handle that, though
+ * we should probably do something about it. But do we ever really
+ * have ISA bridges being removed on machines using legacy devices ?
+ */
+ isa_io_base = ISA_IO_BASE;
+
+ /* Clear references to the bridge */
+ of_node_put(isa_bridge_devnode);
+ isa_bridge_devnode = NULL;
+ isa_bridge_pcidev = NULL;
+
+ /* Unmap the ISA area */
+ __iounmap_at((void *)ISA_IO_BASE, 0x10000);
+}
+
+/**
+ * isa_bridge_notify - Get notified of PCI devices addition/removal
+ */
+static int isa_bridge_notify(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct device_node *devnode = pci_device_to_OF_node(pdev);
+
+ switch(action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ /* Check if we have an early ISA device, without PCI dev */
+ if (isa_bridge_devnode && isa_bridge_devnode == devnode &&
+ !isa_bridge_pcidev) {
+ pr_debug("ISA bridge PCI attached: %s\n",
+ pci_name(pdev));
+ isa_bridge_pcidev = pdev;
+ }
+
+ /* Check if we have no ISA device, and this happens to be one,
+ * register it as such if it has an OF device
+ */
+ if (!isa_bridge_devnode && devnode &&
+ !strcmp(devnode->type, "isa"))
+ isa_bridge_find_late(pdev, devnode);
+
+ return 0;
+ case BUS_NOTIFY_DEL_DEVICE:
+ /* Check if this our existing ISA device */
+ if (pdev == isa_bridge_pcidev ||
+ (devnode && devnode == isa_bridge_devnode))
+ isa_bridge_remove();
+ return 0;
+ }
+ return 0;
+}
+
+static struct notifier_block isa_bridge_notifier = {
+ .notifier_call = isa_bridge_notify
+};
+
+/**
+ * isa_bridge_init - register to be notified of ISA bridge addition/removal
+ *
+ */
+static int __init isa_bridge_init(void)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ return 0;
+ bus_register_notifier(&pci_bus_type, &isa_bridge_notifier);
+ return 0;
+}
+arch_initcall(isa_bridge_init);
Index: linux-cell/arch/powerpc/kernel/of_platform.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/of_platform.c 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/of_platform.c 2007-05-14 16:43:03.000000000 +1000
@@ -427,12 +427,6 @@ static int __devinit of_pci_phb_probe(st
/* Process "ranges" property */
pci_process_bridge_OF_ranges(phb, dev->node, 0);
- /* Setup IO space.
- * This will not work properly for ISA IOs, something needs to be done
- * about it if we ever generalize that way of probing PCI brigdes
- */
- pci_setup_phb_io_dynamic(phb, 0);
-
/* Init pci_dn data structures */
pci_devs_phb_init_dynamic(phb);
Index: linux-cell/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_64.c 2007-05-14 16:32:34.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/pci_64.c 2007-05-14 17:30:02.000000000 +1000
@@ -11,7 +11,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#undef DEBUG
+#define DEBUG
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -22,6 +22,7 @@
#include <linux/list.h>
#include <linux/syscalls.h>
#include <linux/irq.h>
+#include <linux/vmalloc.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -44,17 +45,13 @@ int pci_assign_all_buses = 0;
static void fixup_resource(struct resource *res, struct pci_dev *dev);
static void do_bus_setup(struct pci_bus *bus);
-static void phbs_remap_io(void);
/* pci_io_base -- the base address from which io bars are offsets.
* This is the lowest I/O base address (so bar values are always positive),
* and it *must* be the start of ISA space if an ISA bus exists because
- * ISA drivers use hard coded offsets. If no ISA bus exists a dummy
- * page is mapped and isa_io_limit prevents access to it.
+ * ISA drivers use hard coded offsets.
*/
-unsigned long isa_io_base; /* NULL if no ISA bus */
-EXPORT_SYMBOL(isa_io_base);
-unsigned long pci_io_base;
+unsigned long pci_io_base = ISA_IO_BASE;
EXPORT_SYMBOL(pci_io_base);
void iSeries_pcibios_init(void);
@@ -65,10 +62,6 @@ static struct dma_mapping_ops *pci_dma_o
int global_phb_number; /* Global phb counter */
-/* Cached ISA bridge dev. */
-struct pci_dev *ppc64_isabridge_dev = NULL;
-EXPORT_SYMBOL_GPL(ppc64_isabridge_dev);
-
void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
{
pci_dma_ops = dma_ops;
@@ -534,10 +527,16 @@ void __devinit scan_phb(struct pci_contr
bus->secondary = hose->first_busno;
hose->bus = bus;
+ if (!firmware_has_feature(FW_FEATURE_ISERIES))
+ pcibios_map_io_space(bus);
+
bus->resource[0] = res = &hose->io_resource;
- if (res->flags && request_resource(&ioport_resource, res))
+ if (res->flags && request_resource(&ioport_resource, res)) {
printk(KERN_ERR "Failed to request PCI IO region "
"on PCI domain %04x\n", hose->global_number);
+ DBG("res->start = 0x%016lx, res->end = 0x%016lx\n",
+ res->start, res->end);
+ }
for (i = 0; i < 3; ++i) {
res = &hose->mem_resources[i];
@@ -595,15 +594,6 @@ static int __init pcibios_init(void)
if (ppc_md.pcibios_fixup)
ppc_md.pcibios_fixup();
- /* Cache the location of the ISA bridge (if we have one) */
- ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
- if (ppc64_isabridge_dev != NULL)
- printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
-
- if (!firmware_has_feature(FW_FEATURE_ISERIES))
- /* map in PCI I/O space */
- phbs_remap_io();
-
printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
return 0;
@@ -878,76 +868,6 @@ void pcibios_add_platform_entries(struct
device_create_file(&pdev->dev, &dev_attr_devspec);
}
-#define ISA_SPACE_MASK 0x1
-#define ISA_SPACE_IO 0x1
-
-static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
- unsigned long phb_io_base_phys,
- void __iomem * phb_io_base_virt)
-{
- /* Remove these asap */
-
- struct pci_address {
- u32 a_hi;
- u32 a_mid;
- u32 a_lo;
- };
-
- struct isa_address {
- u32 a_hi;
- u32 a_lo;
- };
-
- struct isa_range {
- struct isa_address isa_addr;
- struct pci_address pci_addr;
- unsigned int size;
- };
-
- const struct isa_range *range;
- unsigned long pci_addr;
- unsigned int isa_addr;
- unsigned int size;
- int rlen = 0;
-
- range = of_get_property(isa_node, "ranges", &rlen);
- if (range == NULL || (rlen < sizeof(struct isa_range))) {
- printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
- "mapping 64k\n");
- __ioremap_explicit(phb_io_base_phys,
- (unsigned long)phb_io_base_virt,
- 0x10000, _PAGE_NO_CACHE | _PAGE_GUARDED);
- return;
- }
-
- /* From "ISA Binding to 1275"
- * The ranges property is laid out as an array of elements,
- * each of which comprises:
- * cells 0 - 1: an ISA address
- * cells 2 - 4: a PCI address
- * (size depending on dev->n_addr_cells)
- * cell 5: the size of the range
- */
- if ((range->isa_addr.a_hi && ISA_SPACE_MASK) == ISA_SPACE_IO) {
- isa_addr = range->isa_addr.a_lo;
- pci_addr = (unsigned long) range->pci_addr.a_mid << 32 |
- range->pci_addr.a_lo;
-
- /* Assume these are both zero */
- if ((pci_addr != 0) || (isa_addr != 0)) {
- printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
- __FUNCTION__);
- return;
- }
-
- size = PAGE_ALIGN(range->size);
-
- __ioremap_explicit(phb_io_base_phys,
- (unsigned long) phb_io_base_virt,
- size, _PAGE_NO_CACHE | _PAGE_GUARDED);
- }
-}
-
void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
struct device_node *dev, int prim)
{
@@ -1042,137 +962,108 @@ void __devinit pci_process_bridge_OF_ran
}
}
-void __init pci_setup_phb_io(struct pci_controller *hose, int primary)
-{
- unsigned long size = hose->pci_io_size;
- unsigned long io_virt_offset;
- struct resource *res;
- struct device_node *isa_dn;
-
- hose->io_base_virt = reserve_phb_iospace(size);
- DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
- hose->global_number, hose->io_base_phys,
- (unsigned long) hose->io_base_virt);
-
- if (primary) {
- pci_io_base = (unsigned long)hose->io_base_virt;
- isa_dn = of_find_node_by_type(NULL, "isa");
- if (isa_dn) {
- isa_io_base = pci_io_base;
- pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys,
- hose->io_base_virt);
- of_node_put(isa_dn);
- }
- }
-
- io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
- res = &hose->io_resource;
- res->start += io_virt_offset;
- res->end += io_virt_offset;
-}
-
-void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose,
- int primary)
+int pcibios_unmap_io_space(struct pci_bus *bus)
{
- unsigned long size = hose->pci_io_size;
- unsigned long io_virt_offset;
- struct resource *res;
+ struct pci_controller *hose;
- hose->io_base_virt = __ioremap(hose->io_base_phys, size,
- _PAGE_NO_CACHE | _PAGE_GUARDED);
- DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
- hose->global_number, hose->io_base_phys,
- (unsigned long) hose->io_base_virt);
+ WARN_ON(bus == NULL);
- if (primary)
- pci_io_base = (unsigned long)hose->io_base_virt;
-
- io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
- res = &hose->io_resource;
- res->start += io_virt_offset;
- res->end += io_virt_offset;
-}
+ /* If this is not a PHB, we only flush the PTE's and hash table over
+ * the area mapped by this bridge.
+ */
+ if (bus->self) {
+ struct resource *res = bus->resource[0];
+ DBG("IO unmapping for PCI-PCI bridge %s\n",
+ pci_name(bus->self));
+ __iounmap_at((void *)res->start + pci_io_base,
+ res->end - res->start + 1);
+ return 0;
+ }
-static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
- unsigned long *start_virt, unsigned long *size)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
- struct resource *res;
+ /* Get the host bridge */
+ hose = pci_bus_to_host(bus);
- if (bus->self)
- res = bus->resource[0];
- else
- /* Root Bus */
- res = &hose->io_resource;
+ /* Check if we have IOs allocated */
+ if (hose->io_base_alloc == 0)
+ return 0;
- *start_virt = pci_io_base + res->start;
- *start_phys = *start_virt + hose->io_base_phys
- - (unsigned long) hose->io_base_virt;
+ DBG("IO unmapping for PHB %s\n",
+ ((struct device_node *)hose->arch_data)->full_name);
+ DBG(" alloc=0x%p\n", hose->io_base_alloc);
- if (res->end > res->start)
- *size = res->end - res->start + 1;
- else {
- printk("%s(): unexpected region 0x%lx->0x%lx\n",
- __FUNCTION__, res->start, res->end);
- return 1;
- }
+ /* This is a PHB, we fully unmap the IO area */
+ __vunmap(hose->io_base_alloc, 0);
return 0;
}
+EXPORT_SYMBOL_GPL(pcibios_unmap_io_space);
-int unmap_bus_range(struct pci_bus *bus)
+int pcibios_map_io_space(struct pci_bus *bus)
{
- unsigned long start_phys;
- unsigned long start_virt;
- unsigned long size;
+ struct vm_struct *area;
+ unsigned long phys_page;
+ unsigned long size_page;
+ unsigned long io_virt_offset;
+ struct pci_controller *hose;
- if (!bus) {
- printk(KERN_ERR "%s() expected bus\n", __FUNCTION__);
- return 1;
+ WARN_ON(bus == NULL);
+
+ /* If this not a PHB, we don't do anything on mapping */
+ if (bus->self) {
+ DBG("IO mapping for PCI-PCI bridge %s\n",
+ pci_name(bus->self));
+ DBG(" virt=0x%016lx...0x%016lx\n",
+ bus->resource[0]->start + pci_io_base,
+ bus->resource[0]->end + pci_io_base);
+ return 0;
}
-
- if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
- return 1;
- if (__iounmap_explicit((void __iomem *) start_virt, size))
- return 1;
- return 0;
-}
-EXPORT_SYMBOL(unmap_bus_range);
+ /* Get the host bridge */
+ hose = pci_bus_to_host(bus);
+ phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
+ size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
-int remap_bus_range(struct pci_bus *bus)
-{
- unsigned long start_phys;
- unsigned long start_virt;
- unsigned long size;
+ /* Make sure IO area address is clear */
+ hose->io_base_alloc = NULL;
- if (!bus) {
- printk(KERN_ERR "%s() expected bus\n", __FUNCTION__);
- return 1;
- }
-
-
- if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
- return 1;
- if (start_phys == 0)
- return 1;
- printk(KERN_DEBUG "mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size);
- if (__ioremap_explicit(start_phys, start_virt, size,
- _PAGE_NO_CACHE | _PAGE_GUARDED))
- return 1;
+ /* If there's no IO to map on that bus, get away too */
+ if (hose->pci_io_size == 0 || hose->io_base_phys == 0)
+ return 0;
- return 0;
-}
-EXPORT_SYMBOL(remap_bus_range);
+ /* Let's allocate some IO space for that guy. We don't pass
+ * VM_IOREMAP because we don't care about alignment tricks that
+ * the core does in that case. Maybe we should due to stupid card
+ * with incomplete address decoding but I'd rather not deal with
+ * those outside of the reserved 64K legacy region.
+ */
+ area = __get_vm_area(size_page, 0, PHB_IO_BASE, PHB_IO_END);
+ if (area == NULL)
+ return -ENOMEM;
+ hose->io_base_alloc = area->addr;
+ hose->io_base_virt = (void __iomem *)(area->addr +
+ hose->io_base_phys - phys_page);
+
+ DBG("IO mapping for PHB %s\n",
+ ((struct device_node *)hose->arch_data)->full_name);
+ DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
+ hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
+ DBG(" size=0x%016lx (alloc=0x%016lx)\n",
+ hose->pci_io_size, size_page);
+
+ /* Establish the mapping */
+ if (__ioremap_at(phys_page, area->addr, size_page,
+ _PAGE_NO_CACHE | _PAGE_GUARDED) == NULL)
+ return -ENOMEM;
-static void phbs_remap_io(void)
-{
- struct pci_controller *hose, *tmp;
+ /* Fixup hose IO resource */
+ io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
+ hose->io_resource.start += io_virt_offset;
+ hose->io_resource.end += io_virt_offset;
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
- remap_bus_range(hose->bus);
+ return 0;
}
+EXPORT_SYMBOL_GPL(pcibios_map_io_space);
static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
{
Index: linux-cell/arch/powerpc/kernel/rtas_pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/rtas_pci.c 2007-05-02 16:37:19.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/rtas_pci.c 2007-05-14 16:43:03.000000000 +1000
@@ -278,10 +278,8 @@ void __init find_and_init_phbs(void)
{
struct device_node *node;
struct pci_controller *phb;
- unsigned int index;
struct device_node *root = of_find_node_by_path("/");
- index = 0;
for (node = of_get_next_child(root, NULL);
node != NULL;
node = of_get_next_child(root, node)) {
@@ -295,8 +293,7 @@ void __init find_and_init_phbs(void)
continue;
rtas_setup_phb(phb);
pci_process_bridge_OF_ranges(phb, node, 0);
- pci_setup_phb_io(phb, index == 0);
- index++;
+ isa_bridge_find_early(phb);
}
of_node_put(root);
@@ -335,7 +332,7 @@ int pcibios_remove_root_bus(struct pci_c
return 1;
}
- rc = unmap_bus_range(b);
+ rc = pcibios_unmap_io_space(b);
if (rc) {
printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
__FUNCTION__, b->name);
Index: linux-cell/arch/powerpc/mm/imalloc.c
===================================================================
--- linux-cell.orig/arch/powerpc/mm/imalloc.c 2007-04-27 14:12:39.000000000 +1000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,313 +0,0 @@
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <linux/mutex.h>
-#include <asm/cacheflush.h>
-
-#include "mmu_decl.h"
-
-static DEFINE_MUTEX(imlist_mutex);
-struct vm_struct * imlist = NULL;
-
-static int get_free_im_addr(unsigned long size, unsigned long *im_addr)
-{
- unsigned long addr;
- struct vm_struct **p, *tmp;
-
- addr = ioremap_bot;
- for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
- if (size + addr < (unsigned long) tmp->addr)
- break;
- if ((unsigned long)tmp->addr >= ioremap_bot)
- addr = tmp->size + (unsigned long) tmp->addr;
- if (addr >= IMALLOC_END-size)
- return 1;
- }
- *im_addr = addr;
-
- return 0;
-}
-
-/* Return whether the region described by v_addr and size is a subset
- * of the region described by parent
- */
-static inline int im_region_is_subset(unsigned long v_addr, unsigned long size,
- struct vm_struct *parent)
-{
- return (int) (v_addr >= (unsigned long) parent->addr &&
- v_addr < (unsigned long) parent->addr + parent->size &&
- size < parent->size);
-}
-
-/* Return whether the region described by v_addr and size is a superset
- * of the region described by child
- */
-static int im_region_is_superset(unsigned long v_addr, unsigned long size,
- struct vm_struct *child)
-{
- struct vm_struct parent;
-
- parent.addr = (void *) v_addr;
- parent.size = size;
-
- return im_region_is_subset((unsigned long) child->addr, child->size,
- &parent);
-}
-
-/* Return whether the region described by v_addr and size overlaps
- * the region described by vm. Overlapping regions meet the
- * following conditions:
- * 1) The regions share some part of the address space
- * 2) The regions aren't identical
- * 3) Neither region is a subset of the other
- */
-static int im_region_overlaps(unsigned long v_addr, unsigned long size,
- struct vm_struct *vm)
-{
- if (im_region_is_superset(v_addr, size, vm))
- return 0;
-
- return (v_addr + size > (unsigned long) vm->addr + vm->size &&
- v_addr < (unsigned long) vm->addr + vm->size) ||
- (v_addr < (unsigned long) vm->addr &&
- v_addr + size > (unsigned long) vm->addr);
-}
-
-/* Determine imalloc status of region described by v_addr and size.
- * Can return one of the following:
- * IM_REGION_UNUSED - Entire region is unallocated in imalloc space.
- * IM_REGION_SUBSET - Region is a subset of a region that is already
- * allocated in imalloc space.
- * vm will be assigned to a ptr to the parent region.
- * IM_REGION_EXISTS - Exact region already allocated in imalloc space.
- * vm will be assigned to a ptr to the existing imlist
- * member.
- * IM_REGION_OVERLAPS - Region overlaps an allocated region in imalloc space.
- * IM_REGION_SUPERSET - Region is a superset of a region that is already
- * allocated in imalloc space.
- */
-static int im_region_status(unsigned long v_addr, unsigned long size,
- struct vm_struct **vm)
-{
- struct vm_struct *tmp;
-
- for (tmp = imlist; tmp; tmp = tmp->next)
- if (v_addr < (unsigned long) tmp->addr + tmp->size)
- break;
-
- *vm = NULL;
- if (tmp) {
- if (im_region_overlaps(v_addr, size, tmp))
- return IM_REGION_OVERLAP;
-
- *vm = tmp;
- if (im_region_is_subset(v_addr, size, tmp)) {
- /* Return with tmp pointing to superset */
- return IM_REGION_SUBSET;
- }
- if (im_region_is_superset(v_addr, size, tmp)) {
- /* Return with tmp pointing to first subset */
- return IM_REGION_SUPERSET;
- }
- else if (v_addr == (unsigned long) tmp->addr &&
- size == tmp->size) {
- /* Return with tmp pointing to exact region */
- return IM_REGION_EXISTS;
- }
- }
-
- return IM_REGION_UNUSED;
-}
-
-static struct vm_struct * split_im_region(unsigned long v_addr,
- unsigned long size, struct vm_struct *parent)
-{
- struct vm_struct *vm1 = NULL;
- struct vm_struct *vm2 = NULL;
- struct vm_struct *new_vm = NULL;
-
- vm1 = kmalloc(sizeof(*vm1), GFP_KERNEL);
- if (vm1 == NULL) {
- printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
- return NULL;
- }
-
- if (v_addr == (unsigned long) parent->addr) {
- /* Use existing parent vm_struct to represent child, allocate
- * new one for the remainder of parent range
- */
- vm1->size = parent->size - size;
- vm1->addr = (void *) (v_addr + size);
- vm1->next = parent->next;
-
- parent->size = size;
- parent->next = vm1;
- new_vm = parent;
- } else if (v_addr + size == (unsigned long) parent->addr +
- parent->size) {
- /* Allocate new vm_struct to represent child, use existing
- * parent one for remainder of parent range
- */
- vm1->size = size;
- vm1->addr = (void *) v_addr;
- vm1->next = parent->next;
- new_vm = vm1;
-
- parent->size -= size;
- parent->next = vm1;
- } else {
- /* Allocate two new vm_structs for the new child and
- * uppermost remainder, and use existing parent one for the
- * lower remainder of parent range
- */
- vm2 = kmalloc(sizeof(*vm2), GFP_KERNEL);
- if (vm2 == NULL) {
- printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
- kfree(vm1);
- return NULL;
- }
-
- vm1->size = size;
- vm1->addr = (void *) v_addr;
- vm1->next = vm2;
- new_vm = vm1;
-
- vm2->size = ((unsigned long) parent->addr + parent->size) -
- (v_addr + size);
- vm2->addr = (void *) v_addr + size;
- vm2->next = parent->next;
-
- parent->size = v_addr - (unsigned long) parent->addr;
- parent->next = vm1;
- }
-
- return new_vm;
-}
-
-static struct vm_struct * __add_new_im_area(unsigned long req_addr,
- unsigned long size)
-{
- struct vm_struct **p, *tmp, *area;
-
- for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
- if (req_addr + size <= (unsigned long)tmp->addr)
- break;
- }
-
- area = kmalloc(sizeof(*area), GFP_KERNEL);
- if (!area)
- return NULL;
- area->flags = 0;
- area->addr = (void *)req_addr;
- area->size = size;
- area->next = *p;
- *p = area;
-
- return area;
-}
-
-static struct vm_struct * __im_get_area(unsigned long req_addr,
- unsigned long size,
- int criteria)
-{
- struct vm_struct *tmp;
- int status;
-
- status = im_region_status(req_addr, size, &tmp);
- if ((criteria & status) == 0) {
- return NULL;
- }
-
- switch (status) {
- case IM_REGION_UNUSED:
- tmp = __add_new_im_area(req_addr, size);
- break;
- case IM_REGION_SUBSET:
- tmp = split_im_region(req_addr, size, tmp);
- break;
- case IM_REGION_EXISTS:
- /* Return requested region */
- break;
- case IM_REGION_SUPERSET:
- /* Return first existing subset of requested region */
- break;
- default:
- printk(KERN_ERR "%s() unexpected imalloc region status\n",
- __FUNCTION__);
- tmp = NULL;
- }
-
- return tmp;
-}
-
-struct vm_struct * im_get_free_area(unsigned long size)
-{
- struct vm_struct *area;
- unsigned long addr;
-
- mutex_lock(&imlist_mutex);
- if (get_free_im_addr(size, &addr)) {
- printk(KERN_ERR "%s() cannot obtain addr for size 0x%lx\n",
- __FUNCTION__, size);
- area = NULL;
- goto next_im_done;
- }
-
- area = __im_get_area(addr, size, IM_REGION_UNUSED);
- if (area == NULL) {
- printk(KERN_ERR
- "%s() cannot obtain area for addr 0x%lx size 0x%lx\n",
- __FUNCTION__, addr, size);
- }
-next_im_done:
- mutex_unlock(&imlist_mutex);
- return area;
-}
-
-struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
- int criteria)
-{
- struct vm_struct *area;
-
- mutex_lock(&imlist_mutex);
- area = __im_get_area(v_addr, size, criteria);
- mutex_unlock(&imlist_mutex);
- return area;
-}
-
-void im_free(void * addr)
-{
- struct vm_struct **p, *tmp;
-
- if (!addr)
- return;
- if ((unsigned long) addr & ~PAGE_MASK) {
- printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__, addr);
- return;
- }
- mutex_lock(&imlist_mutex);
- for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
- if (tmp->addr == addr) {
- *p = tmp->next;
- unmap_vm_area(tmp);
- kfree(tmp);
- mutex_unlock(&imlist_mutex);
- return;
- }
- }
- mutex_unlock(&imlist_mutex);
- printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__,
- addr);
-}
Index: linux-cell/arch/powerpc/mm/mmu_decl.h
===================================================================
--- linux-cell.orig/arch/powerpc/mm/mmu_decl.h 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/mm/mmu_decl.h 2007-05-14 16:43:03.000000000 +1000
@@ -90,16 +90,4 @@ static inline void flush_HPTE(unsigned c
else
_tlbie(va);
}
-#else /* CONFIG_PPC64 */
-/* imalloc region types */
-#define IM_REGION_UNUSED 0x1
-#define IM_REGION_SUBSET 0x2
-#define IM_REGION_EXISTS 0x4
-#define IM_REGION_OVERLAP 0x8
-#define IM_REGION_SUPERSET 0x10
-
-extern struct vm_struct * im_get_free_area(unsigned long size);
-extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
- int region_type);
-extern void im_free(void *addr);
#endif
Index: linux-cell/arch/powerpc/mm/pgtable_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/mm/pgtable_64.c 2007-04-27 14:12:39.000000000 +1000
+++ linux-cell/arch/powerpc/mm/pgtable_64.c 2007-05-14 17:33:27.000000000 +1000
@@ -34,41 +34,27 @@
#include <linux/stddef.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bootmem.h>
-#include <linux/highmem.h>
-#include <linux/idr.h>
-#include <linux/nodemask.h>
-#include <linux/module.h>
#include <asm/pgalloc.h>
#include <asm/page.h>
#include <asm/prom.h>
-#include <asm/lmb.h>
-#include <asm/rtas.h>
#include <asm/io.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
-#include <asm/uaccess.h>
#include <asm/smp.h>
#include <asm/machdep.h>
#include <asm/tlb.h>
-#include <asm/eeh.h>
#include <asm/processor.h>
-#include <asm/mmzone.h>
#include <asm/cputable.h>
#include <asm/sections.h>
#include <asm/system.h>
-#include <asm/iommu.h>
#include <asm/abs_addr.h>
-#include <asm/vdso.h>
#include <asm/firmware.h>
#include "mmu_decl.h"
-unsigned long ioremap_bot = IMALLOC_BASE;
-static unsigned long phbs_io_bot = PHBS_IO_BASE;
+unsigned long ioremap_bot = IOREMAP_BASE;
/*
* map_io_page currently only called by __ioremap
@@ -102,8 +88,8 @@ static int map_io_page(unsigned long ea,
* entry in the hardware page table.
*
*/
- if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
- mmu_io_psize)) {
+ if (htab_bolt_mapping(ea, (unsigned long)ea + PAGE_SIZE,
+ pa, flags, mmu_io_psize)) {
printk(KERN_ERR "Failed to do bolted mapping IO "
"memory at %016lx !\n", pa);
return -ENOMEM;
@@ -113,8 +99,11 @@ static int map_io_page(unsigned long ea,
}
-static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa,
- unsigned long ea, unsigned long size,
+/**
+ * __ioremap_at - Low level function to establish the page tables
+ * for an IO mapping
+ */
+void __iomem * __ioremap_at(phys_addr_t pa, void *ea, unsigned long size,
unsigned long flags)
{
unsigned long i;
@@ -122,17 +111,40 @@ static void __iomem * __ioremap_com(phys
if ((flags & _PAGE_PRESENT) == 0)
flags |= pgprot_val(PAGE_KERNEL);
+ WARN_ON(pa & ~PAGE_MASK);
+ WARN_ON(size & ~PAGE_MASK);
+
for (i = 0; i < size; i += PAGE_SIZE)
- if (map_io_page(ea+i, pa+i, flags))
+ if (map_io_page((unsigned long)ea+i, pa+i, flags))
return NULL;
- return (void __iomem *) (ea + (addr & ~PAGE_MASK));
+ return (void __iomem *)ea;
+}
+
+/**
+ * __iounmap_from - Low level function to tear down the page tables
+ * for an IO mapping. This is used for mappings that
+ * are manipulated manually, like partial unmapping of
+ * PCI IOs or ISA space.
+ */
+void __iounmap_at(void *ea, unsigned long size)
+{
+ struct vm_struct fake_area;
+
+ /* Hack alert ! We use a fake vm_struct here in order to be able
+ * to use unmap_vm_area(). This is a bit ugly but avoids a lot of
+ * code duplication
+ */
+ memset(&fake_area, 0, sizeof(struct vm_struct));
+ fake_area.addr = (void *)ea;
+ fake_area.size = size;
+ unmap_vm_area(&fake_area);
}
void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
unsigned long flags)
{
- unsigned long pa, ea;
+ phys_addr_t paligned;
void __iomem *ret;
/*
@@ -144,27 +156,30 @@ void __iomem * __ioremap(phys_addr_t add
* IMALLOC_END
*
*/
- pa = addr & PAGE_MASK;
- size = PAGE_ALIGN(addr + size) - pa;
+ paligned = addr & PAGE_MASK;
+ size = PAGE_ALIGN(addr + size) - paligned;
- if ((size == 0) || (pa == 0))
+ if ((size == 0) || (paligned == 0))
return NULL;
if (mem_init_done) {
struct vm_struct *area;
- area = im_get_free_area(size);
+
+ area = __get_vm_area(size, VM_IOREMAP,
+ ioremap_bot, IOREMAP_END);
if (area == NULL)
return NULL;
- ea = (unsigned long)(area->addr);
- ret = __ioremap_com(addr, pa, ea, size, flags);
+ ret = __ioremap_at(paligned, area->addr, size, flags);
if (!ret)
- im_free(area->addr);
+ __vunmap(area->addr, 0);
} else {
- ea = ioremap_bot;
- ret = __ioremap_com(addr, pa, ea, size, flags);
+ ret = __ioremap_at(paligned, (void *)ioremap_bot, size, flags);
if (ret)
ioremap_bot += size;
}
+
+ if (ret)
+ ret += addr & ~PAGE_MASK;
return ret;
}
@@ -187,62 +202,9 @@ void __iomem * ioremap_flags(phys_addr_t
}
-#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
-
-int __ioremap_explicit(phys_addr_t pa, unsigned long ea,
- unsigned long size, unsigned long flags)
-{
- struct vm_struct *area;
- void __iomem *ret;
-
- /* For now, require page-aligned values for pa, ea, and size */
- if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
- !IS_PAGE_ALIGNED(size)) {
- printk(KERN_ERR "unaligned value in %s\n", __FUNCTION__);
- return 1;
- }
-
- if (!mem_init_done) {
- /* Two things to consider in this case:
- * 1) No records will be kept (imalloc, etc) that the region
- * has been remapped
- * 2) It won't be easy to iounmap() the region later (because
- * of 1)
- */
- ;
- } else {
- area = im_get_area(ea, size,
- IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
- if (area == NULL) {
- /* Expected when PHB-dlpar is in play */
- return 1;
- }
- if (ea != (unsigned long) area->addr) {
- printk(KERN_ERR "unexpected addr return from "
- "im_get_area\n");
- return 1;
- }
- }
-
- ret = __ioremap_com(pa, pa, ea, size, flags);
- if (ret == NULL) {
- printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
- return 1;
- }
- if (ret != (void *) ea) {
- printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
- return 1;
- }
-
- return 0;
-}
-
/*
* Unmap an IO region and remove it from imalloc'd list.
* Access to IO memory should be serialized by driver.
- * This code is modeled after vmalloc code - unmap_vm_area()
- *
- * XXX what about calls before mem_init_done (ie python_countermeasures())
*/
void __iounmap(volatile void __iomem *token)
{
@@ -251,9 +213,9 @@ void __iounmap(volatile void __iomem *to
if (!mem_init_done)
return;
- addr = (void *) ((unsigned long __force) token & PAGE_MASK);
-
- im_free(addr);
+ addr = (void *) ((unsigned long __force)
+ PCI_FIX_ADDR(token) & PAGE_MASK);
+ __vunmap(addr, 0);
}
void iounmap(volatile void __iomem *token)
@@ -264,73 +226,8 @@ void iounmap(volatile void __iomem *toke
__iounmap(token);
}
-static int iounmap_subset_regions(unsigned long addr, unsigned long size)
-{
- struct vm_struct *area;
-
- /* Check whether subsets of this region exist */
- area = im_get_area(addr, size, IM_REGION_SUPERSET);
- if (area == NULL)
- return 1;
-
- while (area) {
- iounmap((void __iomem *) area->addr);
- area = im_get_area(addr, size,
- IM_REGION_SUPERSET);
- }
-
- return 0;
-}
-
-int __iounmap_explicit(volatile void __iomem *start, unsigned long size)
-{
- struct vm_struct *area;
- unsigned long addr;
- int rc;
-
- addr = (unsigned long __force) start & PAGE_MASK;
-
- /* Verify that the region either exists or is a subset of an existing
- * region. In the latter case, split the parent region to create
- * the exact region
- */
- area = im_get_area(addr, size,
- IM_REGION_EXISTS | IM_REGION_SUBSET);
- if (area == NULL) {
- /* Determine whether subset regions exist. If so, unmap */
- rc = iounmap_subset_regions(addr, size);
- if (rc) {
- printk(KERN_ERR
- "%s() cannot unmap nonexistent range 0x%lx\n",
- __FUNCTION__, addr);
- return 1;
- }
- } else {
- iounmap((void __iomem *) area->addr);
- }
- /*
- * FIXME! This can't be right:
- iounmap(area->addr);
- * Maybe it should be "iounmap(area);"
- */
- return 0;
-}
-
EXPORT_SYMBOL(ioremap);
EXPORT_SYMBOL(ioremap_flags);
EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(__iounmap);
-
-void __iomem * reserve_phb_iospace(unsigned long size)
-{
- void __iomem *virt_addr;
-
- if (phbs_io_bot >= IMALLOC_BASE)
- panic("reserve_phb_iospace(): phb io space overflow\n");
-
- virt_addr = (void __iomem *) phbs_io_bot;
- phbs_io_bot += size;
-
- return virt_addr;
-}
Index: linux-cell/arch/powerpc/platforms/maple/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/maple/pci.c 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/maple/pci.c 2007-05-14 16:43:03.000000000 +1000
@@ -519,23 +519,6 @@ void __devinit maple_pci_irq_fixup(struc
DBG(" <- maple_pci_irq_fixup\n");
}
-static void __init maple_fixup_phb_resources(void)
-{
- struct pci_controller *hose, *tmp;
-
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
-
- hose->io_resource.start += offset;
- hose->io_resource.end += offset;
-
- printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n",
- hose->global_number,
- (unsigned long long)hose->io_resource.start,
- (unsigned long long)hose->io_resource.end);
- }
-}
-
void __init maple_pci_init(void)
{
struct device_node *np, *root;
@@ -573,24 +556,6 @@ void __init maple_pci_init(void)
if (ht && add_bridge(ht) != 0)
of_node_put(ht);
- /*
- * We need to call pci_setup_phb_io for the HT bridge first
- * so it gets the I/O port numbers starting at 0, and we
- * need to call it for the AGP bridge after that so it gets
- * small positive I/O port numbers.
- */
- if (u3_ht)
- pci_setup_phb_io(u3_ht, 1);
- if (u3_agp)
- pci_setup_phb_io(u3_agp, 0);
- if (u4_pcie)
- pci_setup_phb_io(u4_pcie, 0);
-
- /* Fixup the IO resources on our host bridges as the common code
- * does it only for childs of the host bridges
- */
- maple_fixup_phb_resources();
-
/* Setup the linkage between OF nodes and PHBs */
pci_devs_phb_init();
Index: linux-cell/arch/powerpc/platforms/pasemi/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pasemi/pci.c 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/pasemi/pci.c 2007-05-14 16:43:03.000000000 +1000
@@ -150,29 +150,11 @@ static int __init add_bridge(struct devi
printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
/* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
pci_process_bridge_OF_ranges(hose, dev, 1);
- pci_setup_phb_io(hose, 1);
return 0;
}
-
-static void __init pas_fixup_phb_resources(void)
-{
- struct pci_controller *hose, *tmp;
-
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
- hose->io_resource.start += offset;
- hose->io_resource.end += offset;
- printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
- hose->global_number,
- hose->io_resource.start, hose->io_resource.end);
- }
-}
-
-
void __init pas_pci_init(void)
{
struct device_node *np, *root;
@@ -190,8 +172,6 @@ void __init pas_pci_init(void)
of_node_put(root);
- pas_fixup_phb_resources();
-
/* Setup the linkage between OF nodes and PHBs */
pci_devs_phb_init();
Index: linux-cell/arch/powerpc/platforms/powermac/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/powermac/pci.c 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/powermac/pci.c 2007-05-14 16:43:03.000000000 +1000
@@ -1006,19 +1006,6 @@ void __devinit pmac_pci_irq_fixup(struct
#endif /* CONFIG_PPC32 */
}
-#ifdef CONFIG_PPC64
-static void __init pmac_fixup_phb_resources(void)
-{
- struct pci_controller *hose, *tmp;
-
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
- hose->global_number,
- hose->io_resource.start, hose->io_resource.end);
- }
-}
-#endif
-
void __init pmac_pci_init(void)
{
struct device_node *np, *root;
@@ -1053,25 +1040,6 @@ void __init pmac_pci_init(void)
if (ht && add_bridge(ht) != 0)
of_node_put(ht);
- /*
- * We need to call pci_setup_phb_io for the HT bridge first
- * so it gets the I/O port numbers starting at 0, and we
- * need to call it for the AGP bridge after that so it gets
- * small positive I/O port numbers.
- */
- if (u3_ht)
- pci_setup_phb_io(u3_ht, 1);
- if (u3_agp)
- pci_setup_phb_io(u3_agp, 0);
- if (u4_pcie)
- pci_setup_phb_io(u4_pcie, 0);
-
- /*
- * On ppc64, fixup the IO resources on our host bridges as
- * the common code does it only for children of the host bridges
- */
- pmac_fixup_phb_resources();
-
/* Setup the linkage between OF nodes and PHBs */
pci_devs_phb_init();
Index: linux-cell/arch/powerpc/platforms/pseries/pci_dlpar.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/pci_dlpar.c 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/pseries/pci_dlpar.c 2007-05-14 16:43:03.000000000 +1000
@@ -200,8 +200,6 @@ struct pci_controller * __devinit init_p
rtas_setup_phb(phb);
pci_process_bridge_OF_ranges(phb, dn, 0);
- pci_setup_phb_io_dynamic(phb, primary);
-
pci_devs_phb_init_dynamic(phb);
if (dn->child)
Index: linux-cell/drivers/pci/hotplug/rpadlpar_core.c
===================================================================
--- linux-cell.orig/drivers/pci/hotplug/rpadlpar_core.c 2007-05-07 12:53:22.000000000 +1000
+++ linux-cell/drivers/pci/hotplug/rpadlpar_core.c 2007-05-14 16:43:03.000000000 +1000
@@ -159,8 +159,8 @@ static void dlpar_pci_add_bus(struct dev
/* Claim new bus resources */
pcibios_claim_one_bus(dev->bus);
- /* ioremap() for child bus, which may or may not succeed */
- remap_bus_range(dev->subordinate);
+ /* Map IO space for child bus, which may or may not succeed */
+ pcibios_map_io_space(dev->subordinate);
/* Add new devices to global lists. Register in proc, sysfs. */
pci_bus_add_devices(phb->bus);
@@ -390,7 +390,7 @@ int dlpar_remove_pci_slot(char *drc_name
} else
pcibios_remove_pci_devices(bus);
- if (unmap_bus_range(bus)) {
+ if (pcibios_unmap_io_space(bus)) {
printk(KERN_ERR "%s: failed to unmap bus range\n",
__FUNCTION__);
return -ERANGE;
Index: linux-cell/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/pci-bridge.h 2007-04-27 14:13:24.000000000 +1000
+++ linux-cell/include/asm-powerpc/pci-bridge.h 2007-05-14 16:43:03.000000000 +1000
@@ -31,6 +31,7 @@ struct pci_controller {
int last_busno;
void __iomem *io_base_virt;
+ void *io_base_alloc;
resource_size_t io_base_phys;
/* Some machines have a non 1:1 mapping of
@@ -164,6 +165,11 @@ static inline unsigned long pci_address_
}
#endif
+extern void isa_bridge_find_early(struct pci_controller *hose);
+
+extern int pcibios_unmap_io_space(struct pci_bus *bus);
+extern int pcibios_map_io_space(struct pci_bus *bus);
+
/* 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 2007-05-02 16:37:22.000000000 +1000
+++ linux-cell/include/asm-powerpc/pci.h 2007-05-14 16:43:03.000000000 +1000
@@ -220,10 +220,6 @@ static inline struct resource *pcibios_s
return root;
}
-extern int unmap_bus_range(struct pci_bus *bus);
-
-extern int remap_bus_range(struct pci_bus *bus);
-
extern void pcibios_fixup_device_resources(struct pci_dev *dev,
struct pci_bus *bus);
Index: linux-cell/include/asm-powerpc/io.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/io.h 2007-05-02 16:37:22.000000000 +1000
+++ linux-cell/include/asm-powerpc/io.h 2007-05-14 16:43:03.000000000 +1000
@@ -607,9 +607,9 @@ static inline void iosync(void)
*
* * iounmap undoes such a mapping and can be hooked
*
- * * __ioremap_explicit (and the pending __iounmap_explicit) are low level
- * functions to create hand-made mappings for use only by the PCI code
- * and cannot currently be hooked.
+ * * __ioremap_at (and the pending __iounmap_at) are low level functions to
+ * create hand-made mappings for use only by the PCI code and cannot
+ * currently be hooked. Must be page aligned.
*
* * __ioremap is the low level implementation used by ioremap and
* ioremap_flags and cannot be hooked (but can be used by a hook on one
@@ -629,12 +629,9 @@ extern void __iomem *__ioremap(phys_addr
unsigned long flags);
extern void __iounmap(volatile void __iomem *addr);
-extern int __ioremap_explicit(phys_addr_t p_addr, unsigned long v_addr,
- unsigned long size, unsigned long flags);
-extern int __iounmap_explicit(volatile void __iomem *start,
- unsigned long size);
-
-extern void __iomem * reserve_phb_iospace(unsigned long size);
+extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea,
+ unsigned long size, unsigned long flags);
+extern void __iounmap_at(void *ea, unsigned long size);
/* Those are more 32 bits only functions */
extern unsigned long iopa(unsigned long addr);
Index: linux-cell/arch/powerpc/mm/Makefile
===================================================================
--- linux-cell.orig/arch/powerpc/mm/Makefile 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/mm/Makefile 2007-05-14 16:43:03.000000000 +1000
@@ -11,8 +11,7 @@ obj-$(CONFIG_PPC32) += init_32.o pgtabl
hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o
obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \
hash_utils_64.o hash_low_64.o tlb_64.o \
- slb_low.o slb.o stab.o mmap.o imalloc.o \
- $(hash-y)
+ slb_low.o slb.o stab.o mmap.o $(hash-y)
obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o tlb_32.o
obj-$(CONFIG_40x) += 4xx_mmu.o
obj-$(CONFIG_44x) += 44x_mmu.o
Index: linux-cell/arch/powerpc/platforms/cell/io-workarounds.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/cell/io-workarounds.c 2007-05-10 13:21:02.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/cell/io-workarounds.c 2007-05-14 16:43:03.000000000 +1000
@@ -102,7 +102,7 @@ static void spider_io_flush(const volati
vaddr = (unsigned long)PCI_FIX_ADDR(addr);
/* Check if it's in allowed range for PIO */
- if (vaddr < PHBS_IO_BASE || vaddr >= IMALLOC_BASE)
+ if (vaddr < PHB_IO_BASE || vaddr > PHB_IO_END)
return;
/* Try to find a PTE. If not, clear the paddr, we'll do
Index: linux-cell/include/asm-powerpc/floppy.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/floppy.h 2007-05-14 17:10:20.000000000 +1000
+++ linux-cell/include/asm-powerpc/floppy.h 2007-05-14 17:10:47.000000000 +1000
@@ -29,7 +29,7 @@
#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL);
#include <linux/pci.h>
-#include <asm/ppc-pci.h> /* for ppc64_isabridge_dev */
+#include <asm/ppc-pci.h> /* for isa_bridge_pcidev */
#define fd_dma_setup(addr,size,mode,io) fd_ops->_dma_setup(addr,size,mode,io)
@@ -139,12 +139,12 @@ static int hard_dma_setup(char *addr, un
if (bus_addr
&& (addr != prev_addr || size != prev_size || dir != prev_dir)) {
/* different from last time -- unmap prev */
- pci_unmap_single(ppc64_isabridge_dev, bus_addr, prev_size, prev_dir);
+ pci_unmap_single(isa_bridge_pcidev, bus_addr, prev_size, prev_dir);
bus_addr = 0;
}
if (!bus_addr) /* need to map it */
- bus_addr = pci_map_single(ppc64_isabridge_dev, addr, size, dir);
+ bus_addr = pci_map_single(isa_bridge_pcidev, addr, size, dir);
/* remember this one as prev */
prev_addr = addr;
Index: linux-cell/include/asm-powerpc/ppc-pci.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/ppc-pci.h 2007-05-14 17:09:34.000000000 +1000
+++ linux-cell/include/asm-powerpc/ppc-pci.h 2007-05-14 17:09:42.000000000 +1000
@@ -26,7 +26,7 @@ extern int global_phb_number;
extern void find_and_init_phbs(void);
-extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */
+extern struct pci_dev *isa_bridge_pcidev; /* may be NULL if no ISA bus */
/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */
#define BUID_HI(buid) ((buid) >> 32)
^ permalink raw reply
* Re: [patch 4/4] powerpc 2.6.21-rt1: reduce scheduling latency by changing tlb flush size
From: Thomas Gleixner @ 2007-05-14 6:51 UTC (permalink / raw)
To: Tsutomu OWA; +Cc: linuxppc-dev, mingo, linux-kernel
In-Reply-To: <yyiveev9afk.wl@toshiba.co.jp>
Tsutomu-san,
On Mon, 2007-05-14 at 15:38 +0900, Tsutomu OWA wrote:
> Oopps, Subject was wrong.... resending it. Sorry.
>
> To reduce scheduling latecy by changing tlb flush size to 1.
> Since tlb flush on Celleb is done by calling (an) expensive hypervisor call(s),
> it takes a long time to flush tlbs and causes scheduing latency.
>
> As I don't know how long it takes on other platforms, it would be better to
> enclose it within #ifdef CONFIG_PPC_CELLEB.
Yes, that might be appropriate. Can you add this and resend please ?
tglx
^ permalink raw reply
* Re: [patch 4/4] powerpc 2.6.21-rt1: reduce scheduling latency by changing tlb flush size
From: Tsutomu OWA @ 2007-05-14 6:38 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyiwszb9asq.wl@toshiba.co.jp>
Oopps, Subject was wrong.... resending it. Sorry.
To reduce scheduling latecy by changing tlb flush size to 1.
Since tlb flush on Celleb is done by calling (an) expensive hypervisor call(s),
it takes a long time to flush tlbs and causes scheduing latency.
As I don't know how long it takes on other platforms, it would be better to
enclose it within #ifdef CONFIG_PPC_CELLEB.
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/include/asm-powerpc/tlbflush.h rt/include/asm-powerpc/tlbflush.h
--- linux-2.6.21-rt1/include/asm-powerpc/tlbflush.h 2007-04-26 12:08:32.000000000 +0900
+++ rt/include/asm-powerpc/tlbflush.h 2007-05-07 14:23:50.000000000 +0900
@@ -25,7 +25,11 @@ struct mm_struct;
#include <linux/percpu.h>
#include <asm/page.h>
+#ifdef CONFIG_PREEMPT_RT
+#define PPC64_TLB_BATCH_NR 1 /* Since tlb flush takes long time, reduce it to 1 when RT */
+#else
#define PPC64_TLB_BATCH_NR 192
+#endif /* CONFIG_PREEMPT_RT */
struct ppc64_tlb_batch {
unsigned long index;
^ permalink raw reply
* [PATCH] [POWERPC] remove build warnings in windfarm_core
From: Stephen Rothwell @ 2007-05-14 6:32 UTC (permalink / raw)
To: paulus, benh; +Cc: ppc-dev
drivers/macintosh/windfarm_core.c: In function 'wf_register_control':
drivers/macintosh/windfarm_core.c:219: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/windfarm_core.c: In function 'wf_register_sensor':
drivers/macintosh/windfarm_core.c:329: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
drivers/macintosh/windfarm_core.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 192b26e..a306d67 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -198,14 +198,15 @@ static ssize_t wf_store_control(struct device *dev,
int wf_register_control(struct wf_control *new_ct)
{
struct wf_control *ct;
+ int ret = 0;
mutex_lock(&wf_lock);
list_for_each_entry(ct, &wf_controls, link) {
if (!strcmp(ct->name, new_ct->name)) {
printk(KERN_WARNING "windfarm: trying to register"
" duplicate control %s\n", ct->name);
- mutex_unlock(&wf_lock);
- return -EEXIST;
+ ret = -EEXIST;
+ goto out_unlock;
}
}
kref_init(&new_ct->ref);
@@ -216,14 +217,21 @@ int wf_register_control(struct wf_control *new_ct)
new_ct->attr.attr.mode = 0644;
new_ct->attr.show = wf_show_control;
new_ct->attr.store = wf_store_control;
- device_create_file(&wf_platform_device.dev, &new_ct->attr);
+ ret = device_create_file(&wf_platform_device.dev, &new_ct->attr);
+ if (ret) {
+ list_del(&new_ct->link);
+ printk(KERN_WARNING "windfarm: device_creat_file failed"
+ "for %s\n", new_ct->name);
+ goto out_unlock;
+ }
DBG("wf: Registered control %s\n", new_ct->name);
wf_notify(WF_EVENT_NEW_CONTROL, new_ct);
+out_unlock:
mutex_unlock(&wf_lock);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(wf_register_control);
@@ -308,14 +316,15 @@ static ssize_t wf_show_sensor(struct device *dev,
int wf_register_sensor(struct wf_sensor *new_sr)
{
struct wf_sensor *sr;
+ int ret;
mutex_lock(&wf_lock);
list_for_each_entry(sr, &wf_sensors, link) {
if (!strcmp(sr->name, new_sr->name)) {
printk(KERN_WARNING "windfarm: trying to register"
" duplicate sensor %s\n", sr->name);
- mutex_unlock(&wf_lock);
- return -EEXIST;
+ ret = -EEXIST;
+ goto out_unlock;
}
}
kref_init(&new_sr->ref);
@@ -326,14 +335,21 @@ int wf_register_sensor(struct wf_sensor *new_sr)
new_sr->attr.attr.mode = 0444;
new_sr->attr.show = wf_show_sensor;
new_sr->attr.store = NULL;
- device_create_file(&wf_platform_device.dev, &new_sr->attr);
+ ret = device_create_file(&wf_platform_device.dev, &new_sr->attr);
+ if (ret) {
+ list_del(&new_sr->link);
+ printk(KERN_WARNING "windfarm: device_create_file failed"
+ " for %s\n", new_sr->name);
+ goto out_unlock;
+ }
DBG("wf: Registered sensor %s\n", new_sr->name);
wf_notify(WF_EVENT_NEW_SENSOR, new_sr);
+out_unlock:
mutex_unlock(&wf_lock);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(wf_register_sensor);
--
1.5.1.4
^ permalink raw reply related
* Re: [patch 0/4] powerpc 2.6.21-rt1: reduce scheduling latency by changing tlb flush size
From: Tsutomu OWA @ 2007-05-14 6:30 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyi3b1zapqa.wl@toshiba.co.jp>
To reduce scheduling latecy by changing tlb flush size to 1.
Since tlb flush on Celleb is done by calling (an) expensive hypervisor call(s),
it takes a long time to flush tlbs and causes scheduing latency.
As I don't know how long it takes on other platforms, it would be better to
enclose it within #ifdef CONFIG_PPC_CELLEB.
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/include/asm-powerpc/tlbflush.h rt/include/asm-powerpc/tlbflush.h
--- linux-2.6.21-rt1/include/asm-powerpc/tlbflush.h 2007-04-26 12:08:32.000000000 +0900
+++ rt/include/asm-powerpc/tlbflush.h 2007-05-07 14:23:50.000000000 +0900
@@ -25,7 +25,11 @@ struct mm_struct;
#include <linux/percpu.h>
#include <asm/page.h>
+#ifdef CONFIG_PREEMPT_RT
+#define PPC64_TLB_BATCH_NR 1 /* Since tlb flush takes long time, reduce it to 1 when RT */
+#else
#define PPC64_TLB_BATCH_NR 192
+#endif /* CONFIG_PREEMPT_RT */
struct ppc64_tlb_batch {
unsigned long index;
^ permalink raw reply
* Re: [patch 3/4] powerpc 2.6.21-rt1: add a need_resched_delayed() check
From: Tsutomu OWA @ 2007-05-14 6:29 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyi3b1zapqa.wl@toshiba.co.jp>
Add a need_resched_delayed() check.
This was pointed by Sergei Shtylyov;
http://ozlabs.org/pipermail/linuxppc-dev/2007-March/033148.html
Signed-off-by: Tsutomu Owa <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/arch/powerpc/kernel/idle.c rt/arch/powerpc/kernel/idle.c
--- linux-2.6.21-rt1/arch/powerpc/kernel/idle.c 2007-05-07 14:08:12.000000000 +0900
+++ rt/arch/powerpc/kernel/idle.c 2007-05-07 14:05:30.000000000 +0900
@@ -70,7 +70,9 @@ void cpu_idle(void)
local_irq_disable();
/* check again after disabling irqs */
- if (!need_resched() && !cpu_should_die())
+ if (!need_resched() &&
+ !need_resched_delayed() &&
+ !cpu_should_die())
ppc_md.power_save();
local_irq_enable();
^ permalink raw reply
* Re: [patch 2/4] powerpc 2.6.21-rt1: convert spinlocks to raw ones for Celleb.
From: Tsutomu OWA @ 2007-05-14 6:28 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyi3b1zapqa.wl@toshiba.co.jp>
Convert more spinlocks to raw ones for Celleb.
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/arch/powerpc/platforms/celleb/htab.c rt/arch/powerpc/platforms/celleb/htab.c
--- linux-2.6.21-rt1/arch/powerpc/platforms/celleb/htab.c 2007-04-26 12:08:32.000000000 +0900
+++ rt/arch/powerpc/platforms/celleb/htab.c 2007-05-07 14:05:30.000000000 +0900
@@ -40,7 +40,7 @@
#define DBG_LOW(fmt...) do { } while(0)
#endif
-static DEFINE_SPINLOCK(beat_htab_lock);
+static DEFINE_RAW_SPINLOCK(beat_htab_lock);
static inline unsigned int beat_read_mask(unsigned hpte_group)
{
--- linux-2.6.21-rt1/arch/powerpc/platforms/celleb/interrupt.c 2007-04-26 12:08:32.000000000 +0900
+++ rt/arch/powerpc/platforms/celleb/interrupt.c 2007-05-09 17:02:33.000000000 +0900
@@ -30,7 +30,7 @@
#include "beat_wrapper.h"
#define MAX_IRQS NR_IRQS
-static DEFINE_SPINLOCK(beatic_irq_mask_lock);
+static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock);
static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64];
static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64];
^ permalink raw reply
* Re: [patch 1/4] powerpc 2.6.21-rt1: fix a build breakage by adding __raw_*_relax() macros
From: Tsutomu OWA @ 2007-05-14 6:26 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
In-Reply-To: <yyi3b1zapqa.wl@toshiba.co.jp>
Add missing macros to fix a build breakage for PREEMPT_DESKTOP.
Signed-off-by: Tsutomu OWA <tsutomu.owa@toshiba.co.jp>
-- owa
diff -rup linux-2.6.21-rt1/include/asm-powerpc/spinlock.h rt/include/asm-powerpc/spinlock.h
--- linux-2.6.21-rt1/include/asm-powerpc/spinlock.h 2007-05-07 14:08:12.000000000 +0900
+++ rt/include/asm-powerpc/spinlock.h 2007-05-07 16:56:41.000000000 +0900
@@ -289,5 +289,9 @@ static __inline__ void __raw_write_unloc
#define _raw_read_relax(lock) __rw_yield(lock)
#define _raw_write_relax(lock) __rw_yield(lock)
+#define __raw_spin_relax(lock) cpu_relax()
+#define __raw_read_relax(lock) cpu_relax()
+#define __raw_write_relax(lock) cpu_relax()
+
#endif /* __KERNEL__ */
#endif /* __ASM_SPINLOCK_H */
^ permalink raw reply
* [patch 0/4] powerpc 2.6.21-rt1: fix build a breakage and some minor issues
From: Tsutomu OWA @ 2007-05-14 6:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mingo, tglx
Hi Ingo,
Please apply.
This series of patches fixes a build breakage and some minor issues
including oonverting spinlocks to raw ones, adding a need_resched_delayed
check, etc. for powerpc64.
This applies on top of linux-2.6.21 and patch-2.6.21-rt1.
Compile and boot tested for both PREEMPT_NONE and PREEMPT_RT on Celleb.
Compile tested for PREEMPT_DESKTOP.
Thanks in advance.
-- owa
TOSHIBA, Corprate Software Engineering Center.
^ permalink raw reply
* NFS: Portmap Sever Not responding
From: jitendra.jain @ 2007-05-14 5:47 UTC (permalink / raw)
To: linuxppc-embedded
Hello All,
I am using kernel 2.6.20.
I want to load my kernel on my target board with ARM architecture.
But I am getting the following message and
I am not able to mount NFS file system.
NET: Registered protocol family 1
NET: Registered protocol family 17
IP-Config: Guessing netmask 255.0.0.0
IP-Config: Complete:
device=eth0, addr=62.0.0.0, mask=255.0.0.0, gw=255.255.255.255,
host=62.0.0.0, domain=, nis-domain=(none),
bootserver=255.255.255.255, rootserver=192.168.1.214, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.214
portmap: server 192.168.1.214 not responding, timed out
Root-NFS: Unable to get nfsd port number from server, using default
Looking up port of RPC 100005/1 on 192.168.1.214
portmap: server 192.168.1.214 not responding, timed out
Root-NFS: Unable to get mountd port number from server, using default
mount: server 192.168.1.214 not responding, timed out
Root-NFS: Server returned error -5 while mounting /dhruval/fs/root
VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device "nfs" or unknown-block(2,0)
Please append a correct "root=" boot option
Kernel panic - not syncing: VFS: Unable to mount root fs on
unknown-block(2,0)
What could be the problem, where I am doing the mistake.
I had checked my NFS server is working for another board.
Can anyone pls help me for the same.
Thanks in advance
Regards
Jitendra Jain
eInfochips Business Disclaimer:
This message may contain confidential, proprietary or legally Privileged information. In case you are not the original intended Recipient of the message, you must not, directly or indirectly, use, Disclose, distribute, print, or copy any part of this message and you are requested to delete it and inform the sender. Any views expressed in this message are those of the individual sender unless otherwise stated. Nothing contained in this message shall be construed as an offer or acceptance of any offer by eInfochips Limited and/or eInfochips Inc("eInfochips") unless sent with that express intent and with due authority of eInfochips. eInfochips has taken enough precautions to prevent the spread of viruses. However the company accepts no liability for any damage caused by any virus transmitted by this email.
^ permalink raw reply
* Re: [PATCH 3/9] powerpc/ppc32: Update mpc52xx_psc structure with B revision changes
From: Sylvain Munaut @ 2007-05-14 5:27 UTC (permalink / raw)
To: Matt Sealey; +Cc: Linux PPC dev ML
In-Reply-To: <4647A35B.40407@genesi-usa.com>
Matt Sealey wrote:
> Would a note next to these new fields be worth it? "5200B only" or
> "reserved on 5200" or even create a new PSC structure for the old
> processor and recast it in drivers that really want to support both
> revisions of the CPU?
>
A comment next to them yes, that looks a good idea.
A new structure certainly not.
> Real nitpick:
>
> Setting the CCR on the MPC5200 (not B) now means you need to left
> shift your required CCR values by 16 bits before applying them into
> the field for the desired effect.
>
> If you were being lazy and just wanted to set some low-order bits
> in the CCR on the 5200, with the old structure that's fine. With
> the new structure, it will be writing into previously reserved
> space on the 5200. The 5200B might work fine, unless it's a driver
> someone missed, and is programming a value that should be in the
> upper 16 bits of the new CCR, in which case now you have to left
> shift by 16 bits.. :)
I know about the ccr that's annoying.
I guess I could make ccr a union and have it contains ccr16 and ccr32.
Note that old driver will still work ... then most likely do
out_be16(&psc->ccr, ...) and the &psc->ccr address didn't change. They
will just have a warning because ccr is a u32 so &psc->ccr is a u32* and
they give it to out_be16 ...
Sylvain
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox