LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [patch 2/2] Cell: Wrap master run control bit
From: Geoff Levand @ 2007-09-04 11:54 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Masato Noguchi, linuxppc-dev@ozlabs.org, Paul Mackerras


From: Masato Noguchi <Masato.Noguchi@jp.sony.com>

Add platform specific SPU run control routines.

The current spufs_run_spu() implementation uses the SPU master
run control bit (MFC_SR1[S]) to control SPE execution, but the
PS3 hypervisor does not support the use of this feature.  This
change adds run control wrapper routines.  The  bare metal
routines use the master run control bit, and the PS3 specific
routines use the priv2 run control register.

Signed-off-by: Masato Noguchi <Masato.Noguchi@jp.sony.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---

Arnd, please consider for 2.6.24.

 arch/powerpc/platforms/cell/spu_manage.c        |   15 +++++++++++++++
 arch/powerpc/platforms/cell/spufs/backing_ops.c |    6 ++++++
 arch/powerpc/platforms/cell/spufs/hw_ops.c      |   10 ++++++++++
 arch/powerpc/platforms/cell/spufs/run.c         |    4 ++--
 arch/powerpc/platforms/cell/spufs/spufs.h       |    1 +
 arch/powerpc/platforms/ps3/spu.c                |   14 ++++++++++++++
 include/asm-powerpc/spu_priv1.h                 |   15 +++++++++++++++
 7 files changed, 63 insertions(+), 2 deletions(-)

--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -35,6 +35,7 @@
 #include <asm/firmware.h>
 #include <asm/prom.h>
 
+#include "spufs/spufs.h"
 #include "interrupt.h"
 
 struct device_node *spu_devnode(struct spu *spu)
@@ -369,6 +370,18 @@ static int of_destroy_spu(struct spu *sp
 	return 0;
 }
 
+static int enable_spu_by_master_run(struct spu_context *ctx)
+{
+	ctx->ops->master_start(ctx);
+	return 0;
+}
+
+static int disable_spu_by_master_run(struct spu_context *ctx)
+{
+	ctx->ops->master_stop(ctx);
+	return 0;
+}
+
 /* Hardcoded affinity idxs for qs20 */
 #define QS20_SPES_PER_BE 8
 static int qs20_reg_idxs[QS20_SPES_PER_BE] =   { 0, 2, 4, 6, 7, 5, 3, 1 };
@@ -535,5 +548,7 @@ const struct spu_management_ops spu_mana
 	.enumerate_spus = of_enumerate_spus,
 	.create_spu = of_create_spu,
 	.destroy_spu = of_destroy_spu,
+	.enable_spu = enable_spu_by_master_run,
+	.disable_spu = disable_spu_by_master_run,
 	.init_affinity = init_affinity,
 };
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -285,6 +285,11 @@ static void spu_backing_runcntl_write(st
 	spin_unlock(&ctx->csa.register_lock);
 }
 
+static void spu_backing_runcntl_stop(struct spu_context *ctx)
+{
+	spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
+}
+
 static void spu_backing_master_start(struct spu_context *ctx)
 {
 	struct spu_state *csa = &ctx->csa;
@@ -381,6 +386,7 @@ struct spu_context_ops spu_backing_ops =
 	.get_ls = spu_backing_get_ls,
 	.runcntl_read = spu_backing_runcntl_read,
 	.runcntl_write = spu_backing_runcntl_write,
+	.runcntl_stop = spu_backing_runcntl_stop,
 	.master_start = spu_backing_master_start,
 	.master_stop = spu_backing_master_stop,
 	.set_mfc_query = spu_backing_set_mfc_query,
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -220,6 +220,15 @@ static void spu_hw_runcntl_write(struct 
 	spin_unlock_irq(&ctx->spu->register_lock);
 }
 
+static void spu_hw_runcntl_stop(struct spu_context *ctx)
+{
+	spin_lock_irq(&ctx->spu->register_lock);
+	out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
+	while(in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
+		cpu_relax();
+	spin_unlock_irq(&ctx->spu->register_lock);
+}
+
 static void spu_hw_master_start(struct spu_context *ctx)
 {
 	struct spu *spu = ctx->spu;
@@ -321,6 +330,7 @@ struct spu_context_ops spu_hw_ops = {
 	.get_ls = spu_hw_get_ls,
 	.runcntl_read = spu_hw_runcntl_read,
 	.runcntl_write = spu_hw_runcntl_write,
+	.runcntl_stop = spu_hw_runcntl_stop,
 	.master_start = spu_hw_master_start,
 	.master_stop = spu_hw_master_stop,
 	.set_mfc_query = spu_hw_set_mfc_query,
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -302,7 +302,7 @@ long spufs_run_spu(struct spu_context *c
 	if (mutex_lock_interruptible(&ctx->run_mutex))
 		return -ERESTARTSYS;
 
-	ctx->ops->master_start(ctx);
+	spu_enable_spu(ctx);
 	ctx->event_return = 0;
 
 	spu_acquire(ctx);
@@ -376,7 +376,7 @@ long spufs_run_spu(struct spu_context *c
 		ctx->stats.libassist++;
 
 
-	ctx->ops->master_stop(ctx);
+	spu_disable_spu(ctx);
 	ret = spu_run_fini(ctx, npc, &status);
 	spu_yield(ctx);
 
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -170,6 +170,7 @@ struct spu_context_ops {
 	char*(*get_ls) (struct spu_context * ctx);
 	 u32 (*runcntl_read) (struct spu_context * ctx);
 	void (*runcntl_write) (struct spu_context * ctx, u32 data);
+	void (*runcntl_stop) (struct spu_context * ctx);
 	void (*master_start) (struct spu_context * ctx);
 	void (*master_stop) (struct spu_context * ctx);
 	int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -28,6 +28,7 @@
 #include <asm/spu_priv1.h>
 #include <asm/lv1call.h>
 
+#include "../cell/spufs/spufs.h"
 #include "platform.h"
 
 /* spu_management_ops */
@@ -419,10 +420,23 @@ static int ps3_init_affinity(void)
 	return 0;
 }
 
+static int ps3_enable_spu(struct spu_context *ctx)
+{
+	return -ENOSYS;
+}
+
+static int ps3_disable_spu(struct spu_context *ctx)
+{
+	ctx->ops->runcntl_stop(ctx);
+	return -ENOSYS;
+}
+
 const struct spu_management_ops spu_management_ps3_ops = {
 	.enumerate_spus = ps3_enumerate_spus,
 	.create_spu = ps3_create_spu,
 	.destroy_spu = ps3_destroy_spu,
+	.enable_spu = ps3_enable_spu,
+	.disable_spu = ps3_disable_spu,
 	.init_affinity = ps3_init_affinity,
 };
 
--- a/include/asm-powerpc/spu_priv1.h
+++ b/include/asm-powerpc/spu_priv1.h
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 
 struct spu;
+struct spu_context;
 
 /* access to priv1 registers */
 
@@ -178,6 +179,8 @@ struct spu_management_ops {
 	int (*enumerate_spus)(int (*fn)(void *data));
 	int (*create_spu)(struct spu *spu, void *data);
 	int (*destroy_spu)(struct spu *spu);
+	int (*enable_spu)(struct spu_context *ctx);
+	int (*disable_spu)(struct spu_context *ctx);
 	int (*init_affinity)(void);
 };
 
@@ -207,6 +210,18 @@ spu_init_affinity (void)
 	return spu_management_ops->init_affinity();
 }
 
+static inline int
+spu_enable_spu (struct spu_context *ctx)
+{
+	return spu_management_ops->enable_spu(ctx);
+}
+
+static inline int
+spu_disable_spu (struct spu_context *ctx)
+{
+	return spu_management_ops->disable_spu(ctx);
+}
+
 /*
  * The declarations folowing are put here for convenience
  * and only intended to be used by the platform setup code.

^ permalink raw reply

* [patch 1/2] PS3: Clear SPU Class 0 interrupts in handler
From: Geoff Levand @ 2007-09-04 11:54 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Noguchi, Masato, linuxppc-dev@ozlabs.org, Paul Mackerras


From: Masato Noguchi <Masato.Noguchi@jp.sony.com>

Fix a bug that causes the PS3 to hang on the SPU Class 0 interrupt.

The Cell BE Architecture spec states that the SPU MFC Class 0 interrupt
is delivered as a pulse.  The current spu interrupt handler assumes this
behavior and does not clear the interrupt status.

The PS3 hypervisor visualizes all SPU interrupts as level, and on return
from the interrupt handler the hypervisor will deliver a new virtual
interrupt for any unmasked interrupts which for which the status has not
been cleared.  This fix clears the interrupt status in the interrupt
handler.

Signed-off-by: Masato Noguchi <Masato.Noguchi@jp.sony.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---

Arnd, please consider for 2.6.24.
Tested on QS20, and seems OK.

 arch/powerpc/platforms/cell/spu_base.c |   23 +++++++++++++++--------
 include/asm-powerpc/spu.h              |    2 +-
 2 files changed, 16 insertions(+), 9 deletions(-)

--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -236,27 +236,34 @@ static irqreturn_t
 spu_irq_class_0(int irq, void *data)
 {
 	struct spu *spu;
+	unsigned long stat, mask;
 
 	spu = data;
-	spu->class_0_pending = 1;
+
+	mask = spu_int_mask_get(spu, 0);
+	stat = spu_int_stat_get(spu, 0);
+	stat &= mask;
+
+	spin_lock(&spu->register_lock);
+	spu->class_0_pending |= stat;
+	spin_unlock(&spu->register_lock);
+
 	spu->stop_callback(spu);
 
+	spu_int_stat_clear(spu, 0, stat);
+
 	return IRQ_HANDLED;
 }
 
 int
 spu_irq_class_0_bottom(struct spu *spu)
 {
-	unsigned long stat, mask;
 	unsigned long flags;
-
-	spu->class_0_pending = 0;
+	unsigned long stat;
 
 	spin_lock_irqsave(&spu->register_lock, flags);
-	mask = spu_int_mask_get(spu, 0);
-	stat = spu_int_stat_get(spu, 0);
-
-	stat &= mask;
+	stat = spu->class_0_pending;
+	spu->class_0_pending = 0;
 
 	if (stat & 1) /* invalid DMA alignment */
 		__spu_trap_dma_align(spu);
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -130,6 +130,7 @@ struct spu {
 	u64 flags;
 	u64 dar;
 	u64 dsisr;
+	u64 class_0_pending;
 	size_t ls_size;
 	unsigned int slb_replace;
 	struct mm_struct *mm;
@@ -138,7 +139,6 @@ struct spu {
 	unsigned long long timestamp;
 	pid_t pid;
 	pid_t tgid;
-	int class_0_pending;
 	spinlock_t register_lock;
 
 	void (* wbox_callback)(struct spu *spu);

^ permalink raw reply

* Re: [RFC] AmigaOne device tree source v2
From: Gerhard Pircher @ 2007-09-04 11:49 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev, david
In-Reply-To: <f460b176a7c30dae101bfc00d1d4b8e9@kernel.crashing.org>


-------- Original-Nachricht --------
> Datum: Tue, 4 Sep 2007 00:32:57 +0200
> Von: Segher Boessenkool <segher@kernel.crashing.org>
> An: "Gerhard Pircher" <gerhard_pircher@gmx.net>
> CC: linuxppc-dev@ozlabs.org, David Gibson <david@gibson.dropbear.id.au>
> Betreff: Re: [RFC] AmigaOne device tree source v2

> PCI memory space sits on the PCI bus, not on the PCI host bridge,
> so is not part of "reg" but is part of "ranges" here, since it is
> direct mapped into the host's address space.
That's right, but what about this example here (from a Pegasos II):

/proc/device-tree/pci@80000000:
name             "pci"
linux,phandle    0fc59260 (264606304)
bus-range        00000000 00000000
pci-bridge-number 00000000
reg              80000000 40000000
8259-interrupt-acknowledge f1000cb4
ranges           01000000 00000000 00000000 fe000000 00000000 00010000
		 02000000 00000000 80000000 80000000 00000000 40000000
clock-frequency  01fca055 (33333333)
#size-cells      00000002
#address-cells   00000003
device_type      "pci"

AFAIU the reg property overlaps the ranges property for the PCI memory
space from 0x80000000 to 0xC0000000 or the CPU address space at the
same location!? Would be good to know, why it was defined like this.

> PCI legacy I/O is not direct mapped: there is no legacy I/O on a
> PowerPC system bus.  So, it can not be mentioned in the "ranges"
> property, but the PHB registers used to access it should be shown
> in the "reg" property.  It could be a simple linear window (it
> sounds like it is here?), but it could for example also be implemented
> via an address/data register pair.
Yes, it is a simple linear address window. I'll remove its address range
from the reg property.

> The order of the "reg" entries depends on the exact model of PCI
> bridge, so a device binding for it has to be written.
Only the Pegasos I and the AmigaOne use this PCI bridge. I guess it should
be enough to check for the board type, but a compatible property doesn't
hurt.

Thanks,

Gerhard

-- 
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kanns mit allen: http://www.gmx.net/de/go/multimessenger

^ permalink raw reply

* Re: Need Pegasos I/II device tree
From: Matt Sealey @ 2007-09-04 11:17 UTC (permalink / raw)
  To: Gerhard Pircher; +Cc: linuxppc-dev
In-Reply-To: <20070904094954.303440@gmx.net>

https://bugzilla.novell.com/attachment.cgi?id=98271

Have fun.

-- 
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations

Gerhard Pircher wrote:
> Hi,
> 
> Can somebody post the device tree of a Pegasos I (prefered) or a Pegasos II
> (or any other similar machine) here, please.
> 
> Thanks!
> 
> regards,
> 
> Gerhard

^ permalink raw reply

* "atomic" 64-bit math on 32-bit ppc's?
From: Matt Sealey @ 2007-09-04 11:09 UTC (permalink / raw)
  To: ppc-dev

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

Hi guys,

Since this is a generic PPC coding question I figured I'd send it here. We're
looking to make the small effort to get ZFS-FUSE working on PPC and there is
a need (as is implemented on Solaris) for some 'atomic' math operations to
ease multithreading in ZFS.

The Solaris PPC code drop included most of these functions for 32-bit ops on
32-bit PPC architectures but the 64-bit operations are not present. What I
a not clear on is the operation of lwarx and stwcx. and if they will work if
you are doing operations on two words at a time.

There has to be something somewhere that implemented these already (gcc??)
and if anyone knows I'd love to know..

-- 
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations

[-- Attachment #2: atomic.c --]
[-- Type: text/plain, Size: 12966 bytes --]

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 2006 by Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident   "%Z%%M% %I%     %E% SML"

#include <sys/atomic.h>

/*
 * Theses are the void returning variants
 */

#define ATOMIC_INC(name, type) \
	void atomic_inc_##name(volatile type *target)	\
	{							\
		type lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	addi	%[lock],%[lock],1\n"		\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target)				\
		: "cc");					\
	}

ATOMIC_INC(long, unsigned long)
ATOMIC_INC(8, uint8_t)
ATOMIC_INC(uchar, uchar_t)
ATOMIC_INC(16, uint16_t)
ATOMIC_INC(ushort, ushort_t)
ATOMIC_INC(32, uint32_t)
ATOMIC_INC(uint, uint_t)
ATOMIC_INC(ulong, ulong_t)

#if defined(_KERNEL) || defined(_INT64_TYPE)
void atomic_inc_64(volatile uint64_t *target)
{
	/* XXX - Implement me */
	(*target)++;
}
#endif

#define ATOMIC_DEC(name, type) \
	void atomic_dec_##name(volatile type *target)	\
	{							\
		type lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	addi	%[lock],%[lock],-1\n"		\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target)				\
		: "cc");					\
	}

ATOMIC_DEC(long, unsigned long)
ATOMIC_DEC(8, uint8_t)
ATOMIC_DEC(uchar, uchar_t)
ATOMIC_DEC(16, uint16_t)
ATOMIC_DEC(ushort, ushort_t)
ATOMIC_DEC(32, uint32_t)
ATOMIC_DEC(uint, uint_t)
ATOMIC_DEC(ulong, ulong_t)

#if defined(_KERNEL) || defined(_INT64_TYPE)
void atomic_dec_64(volatile uint64_t *target)
{
	/* XXX - Implement me */
	(*target)--;
}
#endif

#define ATOMIC_ADD(name, type1, type2) \
	void atomic_add_##name(volatile type1 *target, type2 bits) \
	{							\
		type1 lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	add	%[lock],%[bits],%[lock]\n"	\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target), [bits] "r" (bits)	\
		: "cc");					\
	}

ATOMIC_ADD(8, uint8_t, int8_t)
ATOMIC_ADD(char, uchar_t, signed char)
ATOMIC_ADD(16, uint16_t, int16_t)
ATOMIC_ADD(short, ushort_t, short)
ATOMIC_ADD(32, uint32_t, int32_t)
ATOMIC_ADD(int, uint_t, int)
ATOMIC_ADD(long, ulong_t, long)

void atomic_add_ptr(volatile void *target, ssize_t bits)
{
	/* XXX - Implement me */
	*(caddr_t *)target += bits;
}

#if defined(_KERNEL) || defined(_INT64_TYPE)
void atomic_add_64(volatile uint64_t *target, int64_t bits)
{
	/* XXX - Implement me */
	*target += bits;
}
#endif

#define ATOMIC_OR(name, type) \
	void atomic_or_##name(volatile type *target, type bits) \
	{							\
		type lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	or	%[lock],%[bits],%[lock]\n"	\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target), [bits] "r" (bits)	\
		: "cc");					\
	}

//ATOMIC_OR(long, ulong_t)
ATOMIC_OR(8, uint8_t)
ATOMIC_OR(uchar, uchar_t)
ATOMIC_OR(16, uint16_t)
ATOMIC_OR(ushort, ushort_t)
ATOMIC_OR(32, uint32_t)
ATOMIC_OR(uint, uint_t)
ATOMIC_OR(ulong, ulong_t)

#if defined(_KERNEL) || defined(_INT64_TYPE)
void atomic_or_64(volatile uint64_t *target, uint64_t bits)
{
	/* XXX - Implement me */
	*target |= bits;
}
#endif

#define ATOMIC_AND(name, type) \
	void atomic_and_##name(volatile type *target, type bits) \
	{							\
		type lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	and	%[lock],%[bits],%[lock]\n"	\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target), [bits] "r" (bits)	\
		: "cc");					\
	}

//ATOMIC_AND(long, ulong_t)
ATOMIC_AND(8, uint8_t)
ATOMIC_AND(uchar, uchar_t)
ATOMIC_AND(16, uint16_t)
ATOMIC_AND(ushort, ushort_t)
ATOMIC_AND(32, uint32_t)
ATOMIC_AND(uint, uint_t)
ATOMIC_AND(ulong, ulong_t)

#if defined(_KERNEL) || defined(_INT64_TYPE)
void atomic_and_64(volatile uint64_t *target, uint64_t bits)
{
	/* XXX - Implement me */
	*target &= bits;
}
#endif

/*
 * New value returning variants
 */ 

#define ATOMIC_INC_NV(name, type) \
	type atomic_inc_##name##_nv(volatile type *target) \
	{							\
		type lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	addi	%[lock],%[lock],1\n"		\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target)				\
		: "cc");					\
								\
		return lock;					\
	}

ATOMIC_INC_NV(long, unsigned long)
ATOMIC_INC_NV(8, uint8_t)
ATOMIC_INC_NV(uchar, uchar_t)
ATOMIC_INC_NV(16, uint16_t)
ATOMIC_INC_NV(ushort, ushort_t)
ATOMIC_INC_NV(32, uint32_t)
ATOMIC_INC_NV(uint, uint_t)
ATOMIC_INC_NV(ulong, ulong_t)

#if defined(_KERNEL) || defined(_INT64_TYPE)
uint64_t atomic_inc_64_nv(volatile uint64_t *target)
{
	/* XXX - Implement me */
	return (++(*target));
}
#endif

#define ATOMIC_DEC_NV(name, type) \
	type atomic_dec_##name##_nv(volatile type *target) \
	{							\
		type lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	addi	%[lock],%[lock],-1\n"		\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target)				\
		: "cc");					\
								\
		return lock;					\
	}

ATOMIC_DEC_NV(long, unsigned long)
ATOMIC_DEC_NV(8, uint8_t)
ATOMIC_DEC_NV(uchar, uchar_t)
ATOMIC_DEC_NV(16, uint16_t)
ATOMIC_DEC_NV(ushort, ushort_t)
ATOMIC_DEC_NV(32, uint32_t)
ATOMIC_DEC_NV(uint, uint_t)
ATOMIC_DEC_NV(ulong, ulong_t)

#if defined(_KERNEL) || defined(_INT64_TYPE)
uint64_t atomic_dec_64_nv(volatile uint64_t *target)
{
	/* XXX - Implement me */
	return (--(*target));
}
#endif

#define ATOMIC_ADD_NV(name, type1, type2) \
	type1 atomic_add_##name##_nv(volatile type1 *target, type2 bits) \
	{							\
		type1 lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	add	%[lock],%[bits],%[lock]\n"	\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target), [bits] "r" (bits)	\
		: "cc");					\
								\
		return lock;					\
	}

ATOMIC_ADD_NV(8, uint8_t, int8_t)
ATOMIC_ADD_NV(char, uchar_t, signed char)
ATOMIC_ADD_NV(16, uint16_t, int16_t)
ATOMIC_ADD_NV(short, ushort_t, short)
ATOMIC_ADD_NV(32, uint32_t, int32_t)
ATOMIC_ADD_NV(int, uint_t, int)
ATOMIC_ADD_NV(long, ulong_t, long)

void *atomic_add_ptr_nv(volatile void *target, ssize_t bits)
{
	/* XXX - Implement me */
	return (*(caddr_t *)target += bits);
}

#if defined(_KERNEL) || defined(_INT64_TYPE)
uint64_t atomic_add_64_nv(volatile uint64_t *target, int64_t bits)
{
	/* XXX - Implement me */
	return (*target += bits);
}
#endif

#define ATOMIC_OR_NV(name, type) \
	type atomic_or_##name##_nv(volatile type *target, type bits) \
	{							\
		type lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	or	%[lock],%[bits],%[lock]\n"	\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target), [bits] "r" (bits)	\
		: "cc");					\
								\
		return lock;					\
	}

ATOMIC_OR_NV(long, unsigned long)
ATOMIC_OR_NV(8, uint8_t)
ATOMIC_OR_NV(uchar, uchar_t)
ATOMIC_OR_NV(16, uint16_t)
ATOMIC_OR_NV(ushort, ushort_t)
ATOMIC_OR_NV(32, uint32_t)
ATOMIC_OR_NV(uint, uint_t)
ATOMIC_OR_NV(ulong, ulong_t)

#if defined(_KERNEL) || defined(_INT64_TYPE)
uint64_t atomic_or_64_nv(volatile uint64_t *target, uint64_t bits)
{
	/* XXX - Implement me */
	return (*target |= bits);
}
#endif

#define ATOMIC_AND_NV(name, type) \
	type atomic_and_##name##_nv(volatile type *target, type bits) \
	{							\
		type lock;					\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	and	%[lock],%[bits],%[lock]\n"	\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-    1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target), [bits] "r" (bits)	\
		: "cc");					\
								\
		return lock;					\
	}

ATOMIC_AND_NV(long, unsigned long)
ATOMIC_AND_NV(8, uint8_t)
ATOMIC_AND_NV(uchar, uchar_t)
ATOMIC_AND_NV(16, uint16_t)
ATOMIC_AND_NV(ushort, ushort_t)
ATOMIC_AND_NV(32, uint32_t)
ATOMIC_AND_NV(uint, uint_t)
ATOMIC_AND_NV(ulong, ulong_t)

#if defined(_KERNEL) || defined(_INT64_TYPE)
uint64_t atomic_and_64_nv(volatile uint64_t *target, uint64_t bits)
{
	/* XXX - Implement me */
	return (*target &= bits);
}
#endif


/*
 *  If *arg1 == arg2, set *arg1 = arg3; return old value
 */

#define ATOMIC_CAS(name, type) \
	type atomic_cas_##name(volatile type *target, type arg1, type arg2) \
	{							\
		type lock, old = *target;			\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	cmpw	%[lock],%[arg1]\n"		\
		"	bne-	2f\n"				\
		"	mr	%[lock],%[arg2]\n"		\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-	1b\n"				\
		"2:"						\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target), [arg1] "r" (arg1), [arg2] "r" (arg2)	\
		: "cc");					\
								\
		return old;					\
	}

ATOMIC_CAS(8, uint8_t)
ATOMIC_CAS(uchar, uchar_t)
ATOMIC_CAS(16, uint16_t)
ATOMIC_CAS(ushort, ushort_t)
ATOMIC_CAS(32, uint32_t)
ATOMIC_CAS(uint, uint_t)
ATOMIC_CAS(ulong, ulong_t)

void *atomic_cas_ptr(volatile void *target, void *arg1, void *arg2)
{
	/* XXX - Implement me */
	void *old = *(void **)target;
        if (old == arg1)
                *(void **)target = arg2;
        return (old);
}

#if defined(_KERNEL) || defined(_INT64_TYPE)
uint64_t atomic_cas_64(volatile uint64_t *target, uint64_t arg1, uint64_t arg2)
{
	/* XXX - Implement me */
	uint64_t old = *target;
        if (old == arg1)
                *target = arg2;
        return (old);
}
#endif

/*
 * Swap target and return old value
 */

#define ATOMIC_SWAP(name, type) \
	type atomic_swap_##name(volatile type *target, type bits) \
	{							\
		type lock, old = *target;			\
								\
		__asm__ __volatile__(				\
		"1:	lwarx	%[lock],0,%[target]\n"		\
		"	mr	%[lock],%[bits]\n"		\
		"	stwcx.	%[lock],0,%[target]\n"		\
		"	bne-	1b"				\
		: [lock] "=&r" (lock)				\
		: [target] "r" (target), [bits] "r" (bits)	\
		: "cc");					\
								\
		return old;					\
	}

ATOMIC_SWAP(8, uint8_t)
ATOMIC_SWAP(uchar, uchar_t)
ATOMIC_SWAP(16, uint16_t)
ATOMIC_SWAP(ushort, ushort_t)
ATOMIC_SWAP(32, uint32_t)
ATOMIC_SWAP(uint, uint_t)
ATOMIC_SWAP(ulong, ulong_t)

void *atomic_swap_ptr(volatile void *target, void *bits)
{
	/* XXX - Implement me */
	void *old = *(void **)target;
	*(void **)target = bits;
	return (old);
}

#if defined(_KERNEL) || defined(_INT64_TYPE)
uint64_t atomic_swap_64(volatile uint64_t *target, uint64_t bits)
{
	/* XXX - Implement me */
	uint64_t old = *target;
	*target = bits;
	return (old);
}
#endif

int atomic_set_long_excl(volatile ulong_t *target, uint_t value)
{
	/* XXX - Implement me */
	ulong_t bit = (1UL << value);
	if ((*target & bit) != 0)
		return (-1);
	*target |= bit;
	return (0);
}

int atomic_clear_long_excl(volatile ulong_t *target, uint_t value)
{
	/* XXX - Implement me */
	ulong_t bit = (1UL << value);
	if ((*target & bit) != 0)
		return (-1);
	*target &= ~bit;
	return (0);
}

void membar_enter(void)
{
	/* XXX - Implement me */
}

void membar_exit(void)
{
	/* XXX - Implement me */
}

void membar_producer(void)
{
	/* XXX - Implement me */
}

void membar_consumer(void)
{
	/* XXX - Implement me */
}

/* Legacy kernel interfaces; they will go away (eventually). */

uint8_t cas8(uint8_t *target, uint8_t arg1, uint8_t arg2)
{
	return atomic_cas_8(target, arg1, arg2);
}

uint32_t cas32(uint32_t *target, uint32_t arg1, uint32_t arg2)
{
	return atomic_cas_32(target, arg1, arg2);
}

uint64_t cas64(uint64_t *target, uint64_t arg1, uint64_t arg2)
{
	return atomic_cas_64(target, arg1, arg2);
}

ulong_t caslong(ulong_t *target, ulong_t arg1, ulong_t arg2)
{
	return atomic_cas_ulong(target, arg1, arg2);
}

void *casptr(void *target, void *arg1, void *arg2)
{
	return atomic_cas_ptr(target, arg1, arg2);
}

void atomic_and_long(ulong_t *target, ulong_t bits)
{
	return atomic_and_ulong(target, bits);
}

void atomic_or_long(ulong_t *target, ulong_t bits)
{
	return atomic_or_ulong(target, bits);
}

^ permalink raw reply

* Re: [PATCH v7 3/3] [POWERPC] MPC832x_RDB: update dts to use SPI1in QE, register mmc_spi stub
From: Anton Vorontsov @ 2007-09-04 10:47 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev, Timur Tabi
In-Reply-To: <fdaf530168b099fcb5a3fbbe45e38271@kernel.crashing.org>

On Tue, Sep 04, 2007 at 01:17:51AM +0200, Segher Boessenkool wrote:
>> I expect very few things from the bootloader: setup memory controller,
>
> Setup CPUs, clocks and voltages, system busses, system controllers,
> memory controllers, memory itself,

Yup-yup, these little things. ;-) But clocks and voltages are set
up by the firmware to initially boot the kernel. After kernel
booted, it can, and should, and do manage this stuff. Power
management (includingturning on/off clocks, voltages), cpu freq
(this leads into whole other management issues, like changing
prescalers for companion chips and/or on-board CPLDs, if they're
getting clocks from the CPU-dependant source).

That's for clocks and voltages. Ok, let's back to GPIOs.

> _and system GPIOs_ :-)

Yup, firmware should set up gpios, to make initial kernel boot.
After that, kernel can and should manage GPIOs. Few examples.

Say units (like USB or SPI) can work in very different modes. And
it's okay if user want to change device mode in the runtime. Often
that means that we must also change GPIOs' dedicated functions or
even directions. Say, SPI slave or master, USB host/device/otg,
and so on.

Yes, probably there is no single powerpc driver actually doing this
today, because of many reasons. Some features unneeded today, some
are hard to implement. And maybe there is no single PowerPC device
yet that needs this, I don't know, but it's easy to imagine. ;-)

Another example, power management - if some unit temporarily unused,
to save power GPIOs should be set up differently. Say if SPI unit
turned off (unused just now), it's wise to bring their dedicated
GPIOs to "power saving" state (be it output0/1 or input, it
depends).

"Unneeded" GPIO pin drains less than 1 mA, but if there are bunch of
such GPIOs, this could be a real issue, especially on battery
powered devices.

And yet another GPIOs use from the kernel side I can bring, and it's
real use case: software-managed chip-selects, just like I have to
use for MMC-over-SPI.

To sum up: kernel anyway must be aware of GPIOs, and I'd prefer
smart kernel wrt GPIOs, instead of dumb kernel blindly relying on
the firmware setup.


At the same time I agree: doing gpio setup in the board file isn't a
great solution, just like doing it in the device tree. But hard-code
gpio setup in the firmware is much worse and short-sighted approach.

Thanks,

-- 
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2

^ permalink raw reply

* Need Pegasos I/II device tree
From: Gerhard Pircher @ 2007-09-04  9:49 UTC (permalink / raw)
  To: linuxppc-dev

Hi,

Can somebody post the device tree of a Pegasos I (prefered) or a Pegasos II
(or any other similar machine) here, please.

Thanks!

regards,

Gerhard
-- 
GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail

^ permalink raw reply

* Enabling Cache in MPC5200
From: sanguru @ 2007-09-04  8:22 UTC (permalink / raw)
  To: linuxppc-embedded


Hi,
I am using a LITE5200 evaluation board, and am not able to enable the
 cache.
The execution hangs in these calls.
void EnableInstCache(void)
{
     __asm(" mfspr   r5,1008");
     __asm(" ori     r5,r5,0x00008800");// # Set the ICE and ICFI bit
     __asm(" andi.   r6,r5,0x0000F7FF");// # clear the ICFI bit for the
 final store
     __asm(" mtspr   1008,r5");
     __asm(" isync");
     __asm(" isync");
     __asm(" isync");
     __asm(" isync");
     __asm(" sync");
    __asm(" mtspr   1008,r6");// # Do the final store
    __asm(" isync");
    __asm(" sync");

}

void EnableDataCache(void)
{
     __asm(" mfspr   r5,1008");
     __asm(" ori     r5,r5,0x00004400");// # Set the ICE and ICFI bit
     __asm(" andi.   r6,r5,0x0000FBFF");// # clear the ICFI bit for the
 final store
     __asm(" mtspr   1008,r5");
     __asm(" isync");
     __asm(" isync");
     __asm(" isync");
     __asm(" isync");
     __asm(" sync");
    __asm(" mtspr   1008,r6");// # Do the final store
    __asm(" isync");
    __asm(" sync");

}
What could be the problem?
Thanks
-San
-- 
View this message in context: http://www.nabble.com/Enabling-Cache-in-MPC5200-tf4376247.html#a12473922
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* Regarding immap_86xx.h
From: sivaji @ 2007-09-04  6:38 UTC (permalink / raw)
  To: linuxppc-dev


Hi,
         I am using 2.6.23-rc3 kernel. In this kernel immap_86xx.h file was
loacted in the path: include/asm-powerpc/immap_86xx.h.
        
          This file contains only PCI and Global utility Regsiters
Declarations. LocalBus Controller, Local Access Registers and Rapid IO
Register Declarations are missing.   Where i can find these registers
declaration and tell the reason why the CCSRBAR Registers are missing in the
file immap_86xx.h

by
Sivaji
           
-- 
View this message in context: http://www.nabble.com/Regarding-immap_86xx.h-tf4375801.html#a12472670
Sent from the linuxppc-dev mailing list archive at Nabble.com.

^ permalink raw reply

* Re: Breakpoint is not hitting for Kernel Debugging
From: Bill F @ 2007-09-04  4:07 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <F3D55679E1DCFF49A57570501B70475F070D83BC@CL5EXBE04.ad2.softcom.biz>

On 9/4/07, dnl <ssaravanan@mail2web.com> wrote:
>  I enabled the following options in Kernel for kernel Debugging,
> CONFIG_BDI_SWITCH=y CONFIG_DEBUG_INFO=y under kernel hacking and MMU XALT in
> BDI config file. After uboot initialization I fixed break point at
> start_kernel(0xc02784bc), and then I booted the kernel. Without breaking  at
> start_kernel, it came to login prompt. Please find attached config file with
> this mail. Could anybody help me to solve this problem?

Hi Saravanan,
Try adding this line to your BDI config to clear/invalidate the page
table base address so that the MMU translation works before the MMU
has been initialised.

  ;; Following is to clear the page table base address
  WM32    0x000000f0      0x00000000

Make sure that you reload the BDI config, I use the  the BDI "BOOT"
command to do this.

Are you obtaining the start_kernel address from your kernel System.map
file and setting the breakpoint using the BDI command "BI 0xc02784bc"
or are you using a gdb debugger frontend ?

Bill

^ permalink raw reply

* Re: [PATCH v7 3/3] [POWERPC] MPC832x_RDB: update dts to use SPI1in QE, register mmc_spi stub
From: Timur Tabi @ 2007-09-04  3:16 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev
In-Reply-To: <6c73dab2fcf21490edc64b9b7ec52295@kernel.crashing.org>

Segher Boessenkool wrote:

> This kind of thing is typically hardcoded into the firmware (just like
> the device tree is) -- just put it somewhere _next to_ the device tree,
> not _in_ it. 

What is next to the device tree?  AFAIK, there is no other standard data 
structure that could take place of the par_io nodes in the DTS.

I agree with your points, Segher, but replacing the par_io node with a bunch 
of par_io_config_pin() calls in the kernel is not really an improvement, I 
think.  Until we migrate the QE pin configuration code to U-boot, I suggest 
that we keep the device tree structure as-is and continue to use it for new 
code.  That way, it will all stay in one place.


-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply

* disable interrput under ppc?
From: Wang, Baojun @ 2007-09-04  2:44 UTC (permalink / raw)
  To: linuxppc-embedded

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

hi, list

  How can I disable interrput like `cli' in x86? I want the following code 
freeze the box but it doesn't, $MSR is altered however the box is still 
alive, how can I freeze the box like `cli' in x86? Thanks very much!

static
void cli(void)
{
        unsigned long msr;
        __asm__ __volatile__("": : :"memory");
        msr = mfmsr();
        printk("msr: 0x%lx\n", msr);

        __asm__ __volatile__("sync" : : :"memory");
        __asm__ __volatile__("wrteei 0" : : :"memory");

        msr = mfmsr();
        printk("msr: 0x%lx\n", msr);
        printk(KERN_EMERG"!!msr: 0x%lx\n", msr);
}

P.S: the box is BOOKE compatible, the printk has shown is altered!

  Regards,
Wang
-- 
Wang, Baojun                                        Lanzhou University
Distributed & Embedded System Lab              http://dslab.lzu.edu.cn
School of Information Science and Engeneering        wangbj@lzu.edu.cn
Tianshui South Road 222. Lanzhou 730000                     .P.R.China
Tel:+86-931-8912025                                Fax:+86-931-8912022

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

^ permalink raw reply

* Re: ML403 AC97 ALSA Driver problem
From: Qin Lin @ 2007-09-04  1:58 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <1188852155.5738.21.camel@localhost>


Hi Joachim
Every time aplay wavfile ,there is kernel stack overflow.And the "xsysace"
is a CF card driver .
when i just writing data to codec 0 with a simple program ,it is OK, but if
i read data from CF card=20
and play ,it overflow also.
Maybe there is something conflict with CF card driver and AC97 driver .

Thanks for your note ,i will test it again.

Qin Lin =20

Joachim F=C3=B6rster wrote:
>=20
> Hi Qin Lin,
>=20
> Do you get this overflow everytime you try aplay? Or, do you get it
> sometimes, only?
>=20
> What confuses me is, that in your kernel messages the "TASK =3D ...
> 'xsysace'" is mentioned. Perhaps there is some relation with the sysace
> driver? Or do I miss something, here?
> Did you try play a .wav file from a RAM disk or NFS-mounted location? I
> have to note, that I am not using sysace and I haven't tried it jet -
> especially together with my AC97 driver.
>=20
> As a first step, no matter what, you could compile your kernel with
> CONFIG_SND_DEBUG and additionally replace the line
>=20
> #define PDEBUG_FACILITIES (UNKNOWN | INIT_FAILURE | WORK_FAILURE)
>=20
> in ml403-ac97cr.c with
>=20
> #define PDEBUG_FACILITIES (UNKNOWN | INIT_FAILURE | WORK_FAILURE |
> WORK_INFO | INIT_INFO)
>=20
> This will give you a, well, huge amount of debugging messages
> (KERN_DEBUG). There we should see, how far my driver is getting (to some
> extent).
>=20
>  Joachim
>=20
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>=20
>=20

--=20
View this message in context: http://www.nabble.com/ML403-AC97-ALSA-Driver-=
problem-tf4351591.html#a12470485
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* Please help me with my opb_ethernet driver!!!
From: xu chen @ 2007-09-04  1:31 UTC (permalink / raw)
  To: linuxppc-dev

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

I have used ml403 reference board recently, and now I am porting the opb_ethernet driver downloaded from the net onto the board. I use the EDK9.1 developing environment, and the driver files like "xemac.c" are copied from the EDK drivers lib. My opb_ethernet driver can work in the "No DMA mode", but the speed of FIFO is too slow to transport big files. So I transfer to "Simple DMA mode". I configured the hardware IP core in the EDK, in details, I only changed the DMA mode of opb_ethernet IP core to "Simple DMA", and then synthesize the hardware again. After that I recompile the kernel of the new xparameters.h file. But when I ping the board, in the Recv ISR function, the result of DMA operation from Recv FIFO to kernel memory is always "DMA timed out". I checked the pdf of opb_ethernet and the ipif, but I can't find any problem, especially the manner of DMA. I can only guess that there are some problems in the hardware configuration, so who can help me about that problem?
 Thank you very much.

       
---------------------------------
 雅虎免费邮箱,全球第一邮箱品牌!

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

^ permalink raw reply

* dtc: Assume properties preced subnodes in the flattened tree
From: David Gibson @ 2007-09-04  0:43 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev

With kernel commit eff2ebd207af9f501af0ef667a7d14befcb36c1b, we
clarified that in the flattened tree format, a particular nodes
properties are required to precede its subdnodes.

At present however, both dtc and libfdt will process trees which don't
meet this condition.  This patch simplifies the code for
fdt_get_property() based on assuming that constraint.  dtc continues
to be able to handle such an invalid tree - on the grounds that it's
useful for dtc to be able to correct such a broken tree - but this
patch adds a warning when this condition is not met while reading a
flattened tree.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: dtc/libfdt/fdt_ro.c
===================================================================
--- dtc.orig/libfdt/fdt_ro.c	2007-08-31 15:59:38.000000000 +1000
+++ dtc/libfdt/fdt_ro.c	2007-08-31 16:23:09.000000000 +1000
@@ -197,7 +197,6 @@
 					    int nodeoffset,
 					    const char *name, int *lenp)
 {
-	int level = 0;
 	uint32_t tag;
 	const struct fdt_property *prop;
 	int namestroff;
@@ -225,17 +224,11 @@
 			goto fail;
 
 		case FDT_BEGIN_NODE:
-			level++;
-			break;
-
 		case FDT_END_NODE:
-			level--;
+		case FDT_NOP:
 			break;
 
 		case FDT_PROP:
-			if (level != 0)
-				continue;
-
 			err = -FDT_ERR_BADSTRUCTURE;
 			prop = fdt_offset_ptr_typed(fdt, offset, prop);
 			if (! prop)
@@ -256,14 +249,11 @@
 			}
 			break;
 
-		case FDT_NOP:
-			break;
-
 		default:
 			err = -FDT_ERR_BADSTRUCTURE;
 			goto fail;
 		}
-	} while (level >= 0);
+	} while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
 
 	err = -FDT_ERR_NOTFOUND;
  fail:
Index: dtc/flattree.c
===================================================================
--- dtc.orig/flattree.c	2007-08-31 16:34:34.000000000 +1000
+++ dtc/flattree.c	2007-08-31 16:39:11.000000000 +1000
@@ -779,6 +779,9 @@
 		val = flat_read_word(dtbuf);
 		switch (val) {
 		case OF_DT_PROP:
+			if (node->children)
+				fprintf(stderr, "Warning: Flat tree input has "
+					"subnodes preceding a property.\n");
 			prop = flat_read_property(dtbuf, strbuf, flags);
 			add_property(node, prop);
 			break;

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [RFC] AmigaOne device tree source v2
From: David Gibson @ 2007-09-04  0:27 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev
In-Reply-To: <6858c7a36ed061265937daa7b14cc5ac@kernel.crashing.org>

On Tue, Sep 04, 2007 at 12:52:02AM +0200, Segher Boessenkool wrote:
> >>> Yeah, PCI is a special case for Linux.  Maybe add a "pciclass,XXXX"
> >>> compatible property though, for good measure.  Anything else isn't
> >>> all that useful I think.
> > Wouldn't that be the same as the class-code property?
> 
> Sure, except it is a different property.  If you use the "class-code"
> thing, you really should implement _all_ of the PCI binding's required
> properties.  If you don't (since Linux doesn't use it anyway), it might
> still be nice to have a "compatible" property at least (since that is
> what is used for figuring out what device driver to use for this device
> node).  Linux doesn't currently use that either, so you don't have to,
> but you could put it there and it would make sense, that's all.
> 
> >> Indeed, since PCI is probable, it's unclear whether these device nodes
> >> are even necessary at all.  Depends on whether there's anything
> >> interesting in the omitted interrupt routing information.
> > Well, I mainly specified the device node for the IDE controller, 
> > because
> > it works in compatible mode and thus the IDE driver needs to know about
> > the I/O ports. I guess the driver doesn't probe the BARs, if the
> > controller is configured for compatible mode (and AFAIK a VIA IDE
> > controller cannot be made work in fully native mode).

Hrm.. IIRC, it is permissible under Linux to only include device nodes
for those PCI devices where something must be specified which can't be
proved via PCI.

> Yeah most of those are nasty.
> 
> If the driver grabs some hardcoded legacy I/O ranges if the controller
> is in legacy mode, the only thing that showing those ranges in the
> "reg" property helps are _other_ parts of the kernel that might care,
> not that driver since it hardcodes the address; and those other parts
> of the kernel shouldn't care anyway, since _they_ shouldn't use any
> hardcoded ranges either!
> 
> If those addresses really show up in the PCI BARs (most controllers
> don't do that in legacy mode), the kernel's own PCI probing will
> see it already; if they aren't in BARs, it is a bit tricky to encode
> that correctly in the "reg" (it's perfectly well-defined, just a bit
> hard to get it right).
> 
> > The interrupts for the IDE controller are another story. Judging from
> > what some developers wrote on this mailing list, there doesn't seem to
> > be a way to define legacy IDE interrupts (14 & 15) for a PCI device 
> > node.
> 
> There is no such thing as "interrupt 14 and 15" on PCI.  You can use
> the interrupt mapping recommended practice to show two interrupts
> (and their polarity, and how they are routed to the relevant interrupt
> controller) in the IDE node.

What he said.  More specifically, your IDE device node could specify
interrupts which are routed to the ISA i8259 (and are therefore
equivalent to the legacy interrupts) rather than to the main system
interrupt controller, or via the normal pci interrupt map.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH v7 3/3] [POWERPC] MPC832x_RDB: update dts to use SPI1in QE, register mmc_spi stub
From: Segher Boessenkool @ 2007-09-03 23:17 UTC (permalink / raw)
  To: avorontsov; +Cc: linuxppc-dev, Timur Tabi
In-Reply-To: <20070903151319.GA24840@localhost.localdomain>

> I expect very few things from the bootloader: setup memory controller,

Setup CPUs, clocks and voltages, system busses, system controllers,
memory controllers, memory itself, _and system GPIOs_ :-)

You know, all the basic and/or board-specific stuff that is needed to
run a system.  This kind of GPIOs definitely belongs to that category.


Segher

^ permalink raw reply

* Re: [PATCH v7 3/3] [POWERPC] MPC832x_RDB: update dts to use SPI1in QE, register mmc_spi stub
From: Segher Boessenkool @ 2007-09-03 23:12 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev
In-Reply-To: <46DC126C.9060603@freescale.com>

>> Not at all.  The device tree describe how the hardware _is_
>> set up (after firmware, bootloader etc.); now how it _should
>> be_ set up by the kernel.
>
> I agree with this general sentiment, but in the case of QE pin 
> configuration, then device tree, in a sense, does contain how the 
> hardware is set up.  The par_io section in the device tree describes 
> they layout of the wiring between the SOC and peripherals.  If the 
> par_io registers are not programmed correctly, the SOC won't be able 
> to communicate with the peripheral.
>
> Sure, the kernel currently reads the device tree and programs the 
> par_io registers accordingly, but that doesn't mean the information 
> *shouldn't* be in the device tree.

It is fine if the device tree describes how things are wired together;
that's part of the device tree's purpose, after all.

It is not fine if the device tree says _how to_ configure the hardware;
you are supposed to put your device drivers elsewhere, not in the
device tree!

>> It would make a lot of sense to do this work in the firmware
>> instead, but it doesn't make sense at all to put this stuff
>> into the device tree.
>
> 1) If the firmware does configure the pins, then the device tree 
> *will* describe how the hardware is set up.

Yes.  It won't show pario register contents though.

> 2) How would the firmware know how to do board configuration if it 
> doesn't have the instructions in the device tree?

This kind of thing is typically hardcoded into the firmware (just like
the device tree is) -- just put it somewhere _next to_ the device tree,
not _in_ it.  The device tree is not a config file for the firmware; it
is an interface between the firmware and its client (an OS, typically).

> Besides, every other board does it's par_io configuration based on the 
> device tree.  So if Anton is going to break that pattern, we should be 
> talking about moving all that code into U-boot, instead of just 
> putting in a one-time exception (especially since the patch contains 
> no explanation as to why these par_io pins are being configured 
> differently than every other board).

Yes, I definitely didn't mean to single out Anton's patch, sorry if it
sounded that way.


Segher

^ permalink raw reply

* Re: [RFC] AmigaOne device tree source v2
From: Segher Boessenkool @ 2007-09-03 22:52 UTC (permalink / raw)
  To: Gerhard Pircher; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <20070903161156.306700@gmx.net>

>>> Yeah, PCI is a special case for Linux.  Maybe add a "pciclass,XXXX"
>>> compatible property though, for good measure.  Anything else isn't
>>> all that useful I think.
> Wouldn't that be the same as the class-code property?

Sure, except it is a different property.  If you use the "class-code"
thing, you really should implement _all_ of the PCI binding's required
properties.  If you don't (since Linux doesn't use it anyway), it might
still be nice to have a "compatible" property at least (since that is
what is used for figuring out what device driver to use for this device
node).  Linux doesn't currently use that either, so you don't have to,
but you could put it there and it would make sense, that's all.

>> Indeed, since PCI is probable, it's unclear whether these device nodes
>> are even necessary at all.  Depends on whether there's anything
>> interesting in the omitted interrupt routing information.
> Well, I mainly specified the device node for the IDE controller, 
> because
> it works in compatible mode and thus the IDE driver needs to know about
> the I/O ports. I guess the driver doesn't probe the BARs, if the
> controller is configured for compatible mode (and AFAIK a VIA IDE
> controller cannot be made work in fully native mode).

Yeah most of those are nasty.

If the driver grabs some hardcoded legacy I/O ranges if the controller
is in legacy mode, the only thing that showing those ranges in the
"reg" property helps are _other_ parts of the kernel that might care,
not that driver since it hardcodes the address; and those other parts
of the kernel shouldn't care anyway, since _they_ shouldn't use any
hardcoded ranges either!

If those addresses really show up in the PCI BARs (most controllers
don't do that in legacy mode), the kernel's own PCI probing will
see it already; if they aren't in BARs, it is a bit tricky to encode
that correctly in the "reg" (it's perfectly well-defined, just a bit
hard to get it right).

> The interrupts for the IDE controller are another story. Judging from
> what some developers wrote on this mailing list, there doesn't seem to
> be a way to define legacy IDE interrupts (14 & 15) for a PCI device 
> node.

There is no such thing as "interrupt 14 and 15" on PCI.  You can use
the interrupt mapping recommended practice to show two interrupts
(and their polarity, and how they are routed to the relevant interrupt
controller) in the IDE node.


Segher

^ permalink raw reply

* Re: [RFC] AmigaOne device tree source v2
From: Segher Boessenkool @ 2007-09-03 22:32 UTC (permalink / raw)
  To: Gerhard Pircher; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <20070903145814.101070@gmx.net>

>>>   	pci@80000000 {
>>> 		device_type = "pci";
>>> 		bus-frequency = <01fca055>;		// 33.3MHz
>>> 		bus-range = <0 1>;
>>> 		reg = <80000000 7f000000>;				//
>>> Whole PCI space.
>>
>> 'reg' and 'ranges' should not typically overlap.  'reg' should only
>> encode control registers for the bridge, not the whole PCI space (not
>> that I'm even entirely sure what you mean by that).
> Hmm, strange. I'm sure I found this in another device tree. I define
> "whole PCI space" as PCI (prefetchable) memory and PCI I/O space.

PCI memory space sits on the PCI bus, not on the PCI host bridge,
so is not part of "reg" but is part of "ranges" here, since it is
direct mapped into the host's address space.

PCI legacy I/O is not direct mapped: there is no legacy I/O on a
PowerPC system bus.  So, it can not be mentioned in the "ranges"
property, but the PHB registers used to access it should be shown
in the "reg" property.  It could be a simple linear window (it
sounds like it is here?), but it could for example also be implemented
via an address/data register pair.

The order of the "reg" entries depends on the exact model of PCI
bridge, so a device binding for it has to be written.

>>> 		host@0 {
>>
>> The unit address (after the @) should be derived from the first range
>> listed in the 'reg' property.  It's a bus address, not a slot number.
> AFAIK it's the device number, which is 0 for this host/PCI bridge.

The unit address is relative to the parent bus.  The PCI host bridge
is not its own parent ;-)


Segher

^ permalink raw reply

* Re: wmb vs mmiowb
From: Nick Piggin @ 2007-09-03 20:48 UTC (permalink / raw)
  To: Brent Casavant; +Cc: linuxppc-dev, Linus Torvalds, linux-ia64, Anton Blanchard
In-Reply-To: <20070830134057.L22183@pkunk.americas.sgi.com>

On Thu, Aug 30, 2007 at 02:42:41PM -0500, Brent Casavant wrote:
> On Thu, 30 Aug 2007, Nick Piggin wrote:
> 
> > I don't know whether this is exactly a correct implementation of
> > Linux's barrier semantics. On one hand, wmb _is_ ordering the stores
> > as they come out of the CPU; on the other, it isn't ordering normal
> > stores with respect to writel from the POV of the device (which is
> > seems to be what is expected by the docs and device driver writers).
> 
> Or, as I think of it, it's not ordering cacheable stores with respect
> to uncacheable stores from the perspective of other CPUs in the system.
> That's what's really at the heart of the concern for SN2.

AFAIKS, the issue is simply that it is not ordering cacheable stores
with respect to uncacheable stores from a _single_ CPU. I'll elaborate
further down.


> > And on the other side, it just doesn't seem so useful just to know
> > that stores coming out of the CPU are ordered if they can be reordered
> > by an intermediate.
> 
> Well, it helps when certain classes of stores need to be ordered with
> respect to eachother.  On SN2, wmb() still ensures that cacheable stores
> are issued in a particular order, and thus seen by other CPUs in a
> particular order.  That is still important, even when IO devices are not
> in the mix.

Well, we have smp_wmb() for that.


> > Why even have wmb() at all, if it doesn't actually
> > order stores to IO and RAM?
> 
> It orders the class of stores which target RAM.  It doesn't order the
> two seperate classes of stores (RAM and IO) with respect to eachother.

wmb() *really* is supposed to order all stores. As far as I gather,
devices often need it for something like this:

*dma_buffer = blah;
wmb();
writel(START_DMA, iomem);

One problem for sn2 seems to be that wmb is called like 500 times in
drivers/ and would be really heavy to turn it into mmiowb. On the
other hand, I really don't like how it's just gone and said "oh the
normal Linux semantics are too hard, so make wmb() mean something
slightly different, and add a totally new mmiowb() concept". Device
driver writers already get barriers totally wrong. mmiowb is being
completely misused already (and probably wmb too).


> mmiowb() when used in conjunction with a lock which serializes access
> to an IO device ensures that the order of stores to the IO device from
> different CPUs is well-defined.  That's what we're really after here.

But if we're pragmatic, we could say that stores which are sitting in
the CPU's chipset where they can potentially be reordered, can still
_conceptually_ be considered to be in some kind of store queue of the
CPU. This would mean that wmb() does have to order these WRT cacheable
stores coming from a single CPU.

And once you do that, sn2 will _also_ do the right thing with multiple
CPUs.


> > I guess it is too expensive for you to have mmiowb() in every wmb(),
> > because _most_ of the time, all that's needed is ordering between IOs.
> 
> I think it's the other way around.  Most of the time all you need is
> ordering between RAM stores, so mmiowb() would kill performance if it
> was called every time wmb() was invoked.

No, we have smp_wmb() for that.

 
> > So why not have io_mb(), io_rmb(), io_wmb(), which order IOs but ignore
> > system memory. Then the non-prefixed primitives order everything (to the
> > point that wmb() is like mmiowb on sn2).
> 
> I'm not sure I follow.  Here's the bad sequence we're working with:
> 
> 	CPU A		CPU B		Lock owner	IO device sees 
> 	-----		-----		----------	--------------
> 	...		...		unowned
> 	lock()		...		CPU A
> 	writel(val_a)	lock()		...
> 	unlock()			CPU B
> 	...		write(val_b)	...
> 	...		unlock()	unowned
> 	...		...		...		val_b
> 	...		...		...		val_a
> 
> 
> The cacheable store to RAM from CPU A to perform the unlock was
> not ordered with respect to the uncacheable writel() to the IO device.
> CPU B, which has a different uncacheable store path to the IO device
> in the NUMA system, saw the effect of the RAM store before CPU A's
> uncacheable store arrived at the IO device.  CPU B then owned the
> lock, performed its own uncacheable store to the IO device, and
> released the lock.  The two uncacheable stores are taking different
> routes to the device, and end up arriving in the wrong order.
> 
> mmiowb() solves this by causing the following:
> 
> 	CPU A		CPU B		Lock owner	IO device sees 
> 	-----		-----		----------	--------------
> 	...		...		Unowned
> 	lock()		...		CPU A
> 	writel(val_a)	lock()		...
> 	mmiowb()			...		val_a
> 	unlock()			CPU B
> 	...		write(val_b)	...
> 	...		mmiowb()	...		val_b
> 	...		unlock()	unowned
> 
> The mmiowb() caused the IO device to see the uncacheable store from
> CPU A before CPU B saw the cacheable store from CPU A.  Now all is
> well with the world.
> 
> I might be exhausting your patience, but this is the key.  mmiowb()
> causes the IO fabric to see the effects of an uncacheable store
> before other CPUs see the effects of a subsequent cacheable store.
> That's what's really at the heart of the matter.

Yes, I like this, and this is what wmb() should do :) That's what
Linux expects it to do.

 
> > Now I guess it's strictly also needed if you want to ensure cacheable
> > stores and IO stores are visible to the device in the correct order
> > too. I think we'd normally hope wmb() does that for us too (hence all
> > my rambling above).
> 
> There's really three perspectives to consider, not just the CPU and IO
> device:
> 
> 	1. CPU A performing locking and issuing IO stores.
> 	2. The IO device receiving stores.
> 	3. CPU B performing locking and issuing IO stores.
> 
> The lock ensures that the IO device sees stores from a single CPU
> at a time.  wmb() ensures that CPU A and CPU B see the effect
> of cacheable stores in the same order as eachother.  mmiowb()
> ensures that the IO device has seen all the uncacheable stores from
> CPU A before CPU B sees the cacheable stores from CPU A.
> 
> Wow.  I like that last paragraph.  I think I'll send now...

OK, now we _could_ consider the path to the IO device to be a 3rd
party that can reorder the IOs, but I'm coming to think that such
a concept need not be added if we instead consider that the reordering
portion is still part of the originating CPU and thus subject to a
wmb().

I was talking with Linus about this today, and he might have had an
opinion. He didn't like my io_wmb() idea, but instead thinks that
_every_ IO operation should be ordered WRT one another (eg. get rid
of the fancy __relaxed ones). That's fine, and once you do that,
you can get rid of lots of wmb(), and wmb() remains just for the
places where you want to order cacheable and uncacheable stores.
And now that wmb() is called much less often, you can define it
to actually match the expected Linux model.

I'm really not just trying to cause trouble here ;) The ordering details
of IO and IO/memory seems to be a mess -- it is defined differently for
different architectures, barriers are doing different things, *writel*
etc. functions have different ordering rules depending on the arch, etc.

^ permalink raw reply

* Re: ML403 AC97 ALSA Driver problem
From: Joachim Foerster @ 2007-09-03 20:42 UTC (permalink / raw)
  To: Qin Lin; +Cc: linuxppc-embedded
In-Reply-To: <12399427.post@talk.nabble.com>

Hi Qin Lin,

On Wed, 2007-08-29 at 19:19 -0700, Qin Lin wrote:
> when i use the ac97driver posted by Joachim Förster  recently,there is a
> kernel stack overflow while testing .

> [   82.689668] Kernel stack overflow in process c02a6490, r1=c02f7f30
> [   82.763235] Oops: kernel access of bad area, sig: 11 [#1]
> [   82.827330] NIP: C001327C LR: C001666C CTR: 00000000
> [   82.886699] REGS: c01931f0 TRAP: 0300   Not tainted  (2.6.20)
> [   82.955428] MSR: 00021030 <ME,IR,DR>  CR: 28000028  XER: 00000000
> [   83.028333] DAR: 00000005, DSISR: 00000000
> [   83.077290] TASK = c02a6490[134] 'xsysace' THREAD: c02f8000
> [   83.141855] GPR00: 00000001 C01932A0 C02A6490 00000000 C01B3770 00000012
> 00000300 00000010
> [   83.241838] GPR08: FFFFFFFA 00000020 00000000 00000005 00000000 FFFF87B8
> 03FD0700 00000000
> [   83.341823] GPR16: 00000001 00800000 03FCF588 00000000 FFFFFFFF 007FFF00
> 03FC9FFC 00000002
> [   83.441806] GPR24: 03E667C0 C01B0000 C010600C C01B3770 00000012 00000000
> 00000000 C0193470
> [   83.543874] NIP [C001327C] xmon_write+0x38/0xbc
> [   83.598032] LR [C001666C] xmon_vfprintf+0x34/0x48
> [   83.654272] Call Trace:
> [   83.683435] Instruction dump:
> [   83.718848] bf61000c 90010024 3d20c01b 8009f1bc 7c9b2378 2f800000
> 7cbc2b78 40be0008
> [   83.811540] 4bfffe2d 3ba00000 3bc00000 48000054 <880b0000> 7c0a4839
> 4182fff8 7ffbf0ae

Do you get this overflow everytime you try aplay? Or, do you get it
sometimes, only?

What confuses me is, that in your kernel messages the "TASK = ...
'xsysace'" is mentioned. Perhaps there is some relation with the sysace
driver? Or do I miss something, here?
Did you try play a .wav file from a RAM disk or NFS-mounted location? I
have to note, that I am not using sysace and I haven't tried it jet -
especially together with my AC97 driver.

As a first step, no matter what, you could compile your kernel with
CONFIG_SND_DEBUG and additionally replace the line

#define PDEBUG_FACILITIES (UNKNOWN | INIT_FAILURE | WORK_FAILURE)

in ml403-ac97cr.c with

#define PDEBUG_FACILITIES (UNKNOWN | INIT_FAILURE | WORK_FAILURE |
WORK_INFO | INIT_INFO)

This will give you a, well, huge amount of debugging messages
(KERN_DEBUG). There we should see, how far my driver is getting (to some
extent).

 Joachim

^ permalink raw reply

* Re: Breakpoint is not hitting for Kernel Debugging
From: Dan Malek @ 2007-09-03 19:20 UTC (permalink / raw)
  To: dnl; +Cc: linuxppc-embedded
In-Reply-To: <F3D55679E1DCFF49A57570501B70475F070D83BC@CL5EXBE04.ad2.softcom.biz>

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


On Sep 3, 2007, at 7:02 AM, dnl wrote:

> Hi all,
>
> I am using uboot and montavista kernel for our custom MPC8555CDS  
> board.

You should contact MontaVista first, since we really
don't know what your source code looks like.  I'm
assuming it's a ppc, not powerpc, although the patch
is similar for either choice.  I'd suggest this as a starting
point:

diff -Naru linux-2.6.21/arch/ppc/kernel/head_fsl_booke.S linux-2.6.21- 
dbg/arch/ppc/kernel/head_fsl_booke.S
--- linux-2.6.21/arch/ppc/kernel/head_fsl_booke.S       2007-07-05  
13:08:16.000000000 -0800
+++ linux-2.6.21-dbg/arch/ppc/kernel/head_fsl_booke.S   2007-07-10  
03:45:33.000000000 -0800
@@ -317,6 +322,16 @@
         /* clear any residual debug events */
         li      r2,-1
         mtspr   SPRN_DBSR,r2
+#else
+       /* Enable BDI200 debugging beyond this point for "normal"
+        * kernel debugging.  If you are debugging code prior to this
+        * point, it needs to be done with more specific set up
+        * of configuration files and boot rom.
+        */
+       mfmsr   r2
+       ori     r2, r2, MSR_DE
+       mtmsr   r2
+       isync
#endif

Your first breakpoint should be a hard breakpoint
at the label start_kernel.  You can then switch to
soft breakpoints and continue your debugging.

Ultimate Solutions have some useful white papers
on kernel debugging with the BDI2000 (that some
people have plagiarized).  Check out ultsol.com

Good Luck.

	-- Dan


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

^ permalink raw reply

* Re: [RFC PATCH v0.2] net driver: mpc52xx fec
From: Grant Likely @ 2007-09-03 16:41 UTC (permalink / raw)
  To: Jon Smirl; +Cc: netdev, Domen Puncer, linuxppc-embedded
In-Reply-To: <9e4733910709030909j50710faaw96c95cb369a810b3@mail.gmail.com>

On 9/3/07, Jon Smirl <jonsmirl@gmail.com> wrote:
> On 9/3/07, Grant Likely <grant.likely@secretlab.ca> wrote:
> > On 9/2/07, Domen Puncer <domen@coderock.org> wrote:
> > > Hi!
> > >
> > > new in this version:
> > > - fixed stuff that was commented on.
> > > - added 7-wire support (compile at least, if someone has the hardware,
> > >         please test!)
> > > - ethtool support
> >
> > Thanks for this work Domen, comments below...
> >
> > This is a large patch, and it should be broken up into logical
> > changes.  ie. split into dts changes, bestcomm changes, fec driver and
> > mdio driver.  Easier to review that way.  The bestcomm and dts changes
> > don't need to go to the netdev list.
>
> A similar patch that is already broken up is available for Efika.
> http://dev.gentoo.org/~nixnut/efika/efika-patches-2.6.22.tar.bz2

No.  That series is Sylvain's full patchset including the old FEC
driver.  Domen's patch is a reworked FEC driver, and it only replaces
patch 0008 from that series.  However, this patch should be split up
further because it makes changes to both the device tree and the
bestcomm code.

Cheers,
g.

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

^ permalink raw reply

* Re: [RFC] AmigaOne device tree source v2
From: Gerhard Pircher @ 2007-09-03 16:11 UTC (permalink / raw)
  To: David Gibson, segher; +Cc: linuxppc-dev
In-Reply-To: <20070903101234.GA12212@localhost.localdomain>

Hi,

-------- Original-Nachricht --------
> Datum: Mon, 3 Sep 2007 20:12:34 +1000
> Von: David Gibson <david@gibson.dropbear.id.au>
> An: Segher Boessenkool <segher@kernel.crashing.org>
> CC: linuxppc-dev@ozlabs.org
> Betreff: Re: [RFC] AmigaOne device tree source v2

> On Mon, Sep 03, 2007 at 12:02:58PM +0200, Segher Boessenkool wrote:
> > Yeah, PCI is a special case for Linux.  Maybe add a "pciclass,XXXX"
> > compatible property though, for good measure.  Anything else isn't
> > all that useful I think.
Wouldn't that be the same as the class-code property?

> Indeed, since PCI is probable, it's unclear whether these device nodes
> are even necessary at all.  Depends on whether there's anything
> interesting in the omitted interrupt routing information.
Well, I mainly specified the device node for the IDE controller, because
it works in compatible mode and thus the IDE driver needs to know about
the I/O ports. I guess the driver doesn't probe the BARs, if the
controller is configured for compatible mode (and AFAIK a VIA IDE
controller cannot be made work in fully native mode). Also the ppc_ide_md
function hooks are considered obsolete.
The interrupts for the IDE controller are another story. Judging from
what some developers wrote on this mailing list, there doesn't seem to
be a way to define legacy IDE interrupts (14 & 15) for a PCI device node.
Therefore I'll reuse the IDE interrupt quirk for the Pegasos.

Gerhard
-- 
GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail

^ 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